Skip to content
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
Merged

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

merged 9 commits into from Apr 1, 2018

Conversation

@carlossg
Copy link
Contributor

@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 Allow creating Pod templates from yaml [WiP] Allow creating Pod templates from yaml Jan 21, 2018
@chancez
Copy link
Contributor

@chancez 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
Copy link
Contributor Author

@carlossg carlossg commented Jan 24, 2018

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

@azweb76
Copy link

@azweb76 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
Copy link
Contributor

@hoshsadiq 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
Copy link
Contributor

@chancez 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 added 3 commits Feb 21, 2018
@carlossg carlossg changed the title [WiP] Allow creating Pod templates from yaml [WiP][JENKINS-50282] Allow creating Pod templates from yaml Mar 20, 2018
@carlossg carlossg changed the title [WiP][JENKINS-50282] Allow creating Pod templates from yaml [JENKINS-50282] Allow creating Pod templates from yaml Mar 30, 2018
@carlossg
Copy link
Contributor Author

@carlossg 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
Contributor

Why is a new deprecated method being added?

This comment has been minimized.

@carlossg

carlossg Mar 31, 2018
Author Contributor

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
1 check passed
continuous-integration/jenkins/branch This commit looks good
Details
@carlossg carlossg deleted the yaml branch Apr 1, 2018
@bbzg
Copy link

@bbzg 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
Copy link
Contributor Author

@carlossg carlossg commented Apr 1, 2018

That just needs the jelly UI code, PRs welcome

@siwyd
Copy link

@siwyd 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
Copy link

@bbzg bbzg commented Apr 2, 2018

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

@bbzg
Copy link

@bbzg 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
Copy link

@bbzg 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
Copy link

@rlees85 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

@bparees
Copy link
Contributor

@bparees 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
Copy link
Contributor Author

@carlossg 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
Copy link
Contributor

@bparees bparees commented Apr 10, 2018

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

@shdowofdeath
Copy link

@shdowofdeath shdowofdeath commented Jan 22, 2020

i cannot use it like this :

containerTemplate(name: 'basic',
                            image: slaveImage,
                            ttyEnabled: true,
                            shell: 'sh',
                            envVars: [ valueFrom(key: 'parentHost', fieldRef:  "status.hostIP")
                            ],
                            privileged: true,
                            workingDir: '/data/',
                            alwaysPullImage: false,

?? it;s not woking for me

@jasminen
Copy link

@jasminen jasminen commented Feb 23, 2020

@shdowofdeath It works if you use the 'yaml' attribute

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

10 participants