New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-50282] Allow creating Pod templates from yaml #275

Merged
merged 9 commits into from Apr 1, 2018

Conversation

Projects
None yet
8 participants
@carlossg

carlossg commented Jan 21, 2018

To avoid having to manually add fields for all possible options current and future, just pass the yaml to be used as base.

Yaml is merged with other fields (if set) as it if were a parent Podtemplate

@carlossg carlossg changed the title from Allow creating Pod templates from yaml to [WiP] Allow creating Pod templates from yaml Jan 21, 2018

@chancez

This comment has been minimized.

chancez commented Jan 23, 2018

This is awesome. I am a huge supporter of this being a feature. 👍 This would mean I don't need to add explicit support for using taints/tolerations and other things, making many things easier!

Will the JNLP container be merged into the resulting pod template automatically with this?

@carlossg

This comment has been minimized.

carlossg commented Jan 24, 2018

Yes, if yaml doesn't include a jnlp container it will be added

@azweb76

This comment has been minimized.

azweb76 commented Jan 24, 2018

So we use a jnlp container. Correct me if Im wrong, if the container is a jnlp container, it will not be merged?

@hoshsadiq

This comment has been minimized.

hoshsadiq commented Feb 8, 2018

Big. Would also be nice to be able to load it from a file rather than as a string.

@chancez

This comment has been minimized.

chancez commented Feb 16, 2018

ALso, what does this mean for the declarative step? If it supported the yaml form, it would fix most of my issues with the declarative steps, assuming you could also use container() steps within.

@carlossg carlossg changed the title from [WiP] Allow creating Pod templates from yaml to [WiP][JENKINS-50282] Allow creating Pod templates from yaml Mar 20, 2018

@carlossg carlossg changed the title from [WiP][JENKINS-50282] Allow creating Pod templates from yaml to [JENKINS-50282] Allow creating Pod templates from yaml Mar 30, 2018

@carlossg

This comment has been minimized.

carlossg commented Mar 30, 2018

The rules from combination parent/yaml Pod and child Pod are set in

public static Pod combine(Pod parent, Pod template) {

Containers are also merged if present in both parent and child with the same name

To read from file instead of inline just use readFile

return this;
}
@Deprecated

This comment has been minimized.

@hoshsadiq

hoshsadiq Mar 30, 2018

Why is a new deprecated method being added?

This comment has been minimized.

@carlossg

carlossg Mar 31, 2018

this one is not new, the new one is public Pod build()

@carlossg carlossg merged commit bbf9a20 into master Apr 1, 2018

1 check passed

continuous-integration/jenkins/branch This commit looks good
Details

@carlossg carlossg deleted the yaml branch Apr 1, 2018

@bbzg

This comment has been minimized.

bbzg commented Apr 1, 2018

This is a great addition, but adding a yaml template for 5+ Jenkinsfiles quickly becomes a chore... It would have been so nice if it was possible to set the template from the global Jenkins configuration (since all our jobs share the same settings). Maybe it already is, but I can not seem to find it.

Maybe I am speaking out of line, if I am I apologize.

Thanks for all your great work!

@carlossg

This comment has been minimized.

carlossg commented Apr 1, 2018

That just needs the jelly UI code, PRs welcome

@siwyd

This comment has been minimized.

siwyd commented Apr 2, 2018

@bbzg You can use a Jenkins shared library to define a function that keeps all that logic in a single place?

@bbzg

This comment has been minimized.

bbzg commented Apr 2, 2018

@siwyd Hmm, that's a good idea actually since we already have that for other stuff. Thanks!

@bbzg

This comment has been minimized.

bbzg commented Apr 2, 2018

def kubernetesNode(Closure closureForPod) {
    String template = """
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: something
spec:
  tolerations:
  - key: "jenkins"
    operator: "Equal"
    value: "builder"
    effect: "NoSchedule"
"""
    GString label = "default-${UUID.randomUUID().toString()}"
    podTemplate(label: label, yaml: template, inheritFrom: "default") {
        node {
            closureForPod.call()
        }
    }
}

This schedules a pod but it does not get any of the attributes from the YAML

I also tried without "inheritFrom" and used name: "default", but with the same result.

(I am using scripted pipeline btw)

Any pointers would be greatly appreciated.

Edit:
For clarification I have a "Cloud" called "kubernetes" and a "Kubernetes pod template" called "default" with a bunch of settings that I want to (re-)use.

@bbzg

This comment has been minimized.

bbzg commented Apr 2, 2018

I finally got it working with these settings

def kubernetesNode(Closure closureForPod) {
    String template = """
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: something
spec:
  tolerations:
  - key: "jenkins"
    operator: "Equal"
    value: "builder"
    effect: "NoSchedule"
"""
    GString label = "default-${UUID.randomUUID().toString()}"
    podTemplate(label: label, yaml: template) {
        node(label) {
            closureForPod.call()
        }
    }
}

And in the global configuration for the Kubernetes plugin I set Defaults Provider Template Name to default

@rlees85

This comment has been minimized.

rlees85 commented Apr 3, 2018

I think this change has broken something. I am not using this new feature, but a plugin upgrade from 1.4.1 to 1.5 and a pod with an emptyDir and valid mountpath now just throws this error:

WARNING: Error in provisioning; agent=KubernetesSlave name: packer-slave-xz2bp, template=PodTemplate{inheritFrom='', name='packer-slave', namespace='devops-testing', instanceCap=25, idleMinutes=5, label='packer', nodeSelector='', nodeUsageMode=EXCLUSIVE, workspaceVolume=org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume@48b9a7ee, volumes=[org.csanchez.jenkins.plugins.kubernetes.volumes.EmptyDirVolume@14e5dc74], containers=[ContainerTemplate{name='jnlp', image='removed.dkr.ecr.eu-west-1.amazonaws.com/jenkins-slave-packer:latest', alwaysPullImage=true, workingDir='/home/jenkins', command='', args='${computer.jnlpmac} ${computer.name}', ttyEnabled=true, resourceRequestCpu='', resourceRequestMemory='512Mi', resourceLimitCpu='', resourceLimitMemory='512Mi', envVars=[KeyValueEnvVar [getValue()=-Xmx256M -Xms256M, getKey()=JAVA_OPTS], KeyValueEnvVar [getValue()=tcp://localhost:2375 , getKey()=DOCKER_HOST]], livenessProbe=org.csanchez.jenkins.plugins.kubernetes.ContainerLivenessProbe@8e44d37}, ContainerTemplate{name='docker', image='docker:stable-dind', privileged=true, alwaysPullImage=true, workingDir='', command='', args='', resourceRequestCpu='', resourceRequestMemory='512Mi', resourceLimitCpu='', resourceLimitMemory='512Mi', livenessProbe=org.csanchez.jenkins.plugins.kubernetes.ContainerLivenessProbe@53a14519}], annotations=[org.csanchez.jenkins.plugins.kubernetes.PodAnnotation@6bd82452]}
io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: POST at: https://api.removed/api/v1/namespaces/devops-testing/pods. Message: Pod "packer-slave-xz2bp" is invalid: spec.containers[1].volumeMounts[1].mountPath: Required value. Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec.containers[1].volumeMounts[1].mountPath, message=Required value, reason=FieldValueRequired, additionalProperties={})], group=null, kind=Pod, name=packer-slave-xz2bp, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=Pod "packer-slave-xz2bp" is invalid: spec.containers[1].volumeMounts[1].mountPath: Required value, metadata=ListMeta(resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={}).
	at io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:472)
	at io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:411)
	at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:381)
	at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:344)
	at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleCreate(OperationSupport.java:227)
	at io.fabric8.kubernetes.client.dsl.base.BaseOperation.handleCreate(BaseOperation.java:756)
	at io.fabric8.kubernetes.client.dsl.base.BaseOperation.create(BaseOperation.java:334)
	at org.csanchez.jenkins.plugins.kubernetes.KubernetesLauncher.launch(KubernetesLauncher.java:105)
	at hudson.slaves.SlaveComputer$1.call(SlaveComputer.java:288)
	at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Jenkins LTS latest

@carlossg

This comment has been minimized.

@bparees

This comment has been minimized.

bparees commented Apr 10, 2018

@carlossg any thoughts about exposing this in the config.xml (so you can paste a pod template yaml into the k8s cloud plugin config ui, instead of having to define it in your pipeline)? Or is this already possible and i'm missing it?

/cc @gabemontero

@carlossg

This comment has been minimized.

carlossg commented Apr 10, 2018

it's just a matter of adding a new yaml field to https://github.com/jenkinsci/kubernetes-plugin/blob/master/src/main/resources/org/csanchez/jenkins/plugins/kubernetes/PodTemplate/config.jelly and associated help file.
Lack of time on my side, PRs welcome

@bparees

This comment has been minimized.

bparees commented Apr 10, 2018

@carlossg we might be able to carve some cycles from @gabemontero to do it in the next few weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment