Skip to content

allow a PodTemplate to be configured by name in declarative pipelines #260

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

Closed
wants to merge 1 commit into from

Conversation

jstrachan
Copy link
Contributor

allows either a nested podTemplate or the use of inheritFrom in declarative pipelines to specify a PodTemplate
includes lots of great feedback from @carlossg
fixes JENKINS-48140

cc @carlossg @shaiazulay

allows either a nested `podTemplate` or the use of `inheritFrom` in declarative pipelines to specify a `PodTemplate`
includes lots of great feedback from @carlossg
fixes JENKINS-48140
Copy link
Contributor

@iocanel iocanel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For selecting a podTemplate I think that we should stick to using the jenkins label, which is something that works globally regardless of cloud type, agent type etc.

Now, I do see value in being able to define or extend a podTemplate via declerative pipelines. Not sure to what degree it was already possible, so I'll just comment on how I think it should be.

@@ -266,6 +266,29 @@ Declarative Pipeline support requires Jenkins 2.66+

Example at [examples/declarative.groovy](examples/declarative.groovy)

### Referring to PodTemplates

You can refer to a named PodTemplate in the Jenkins configuration via the **inheritFrom** property as follows:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can already select via declerative pipelines a pod template by label.

The meaning of the values is as follows:

* **label** is used to add a kubernetes label to the build pods created by the pipeline jobs
* **inheritFrom** is used to lookup a named PodTemplate in the Jenkins configuration for the Kubernetes Cloud and uses that as the basis for the PodTemplate for this pipeline
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we are practically defining here a new pod template right?

@@ -71,6 +71,8 @@
public class KubernetesCloud extends Cloud {
public static final int DEFAULT_MAX_REQUESTS_PER_HOST = 32;

public static final String DEFAULT_CLOUD_NAME = "kubernetes";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this constant is already present somewhere in the code base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was @carlossg idea to move it here - I couldn't find any other constant/string in the main codebase I could reuse though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and yeah, makes more sense to move it in KubernetesCloud.

return argMap;
}

protected PodTemplate findPodTemplate(String inheritFrom) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


The meaning of the values is as follows:

* **label** is used to add a kubernetes label to the build pods created by the pipeline jobs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This confuses me. We already have the jenkins label present on the podTemplate.

If we are to be able to specify labels on the pod I'd like to use a proper map (if possible) instead of a single string value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess I'm now confused why there are label and inheritFrom properties on the KubernetesDeclarativeAgent - I figured label was so that you could override the label used?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one thing that confuses me is terminology. What I understand with kubernetes labels is the labels present in the metadata of the kubernetes resource. For the labels used in order to select nodes I usually go with jenkins labels.

The other thing that confuses me, is that label and inheritFrom seem to be usable both in and outside of the podTemplate.

From what I understand there used to be no notion of podTemplate under kubernetes and there were just raw key/value pairs (subset of the actual podTemplate).

I really like the idea of being able to have full control of the podTemplate from declerative pipelines. So +1 on this one. But we need to make it a bit more clear on how things work. To be fair this has to do more with how it already works, and less with what this pr brings in.

@@ -0,0 +1,21 @@
pipeline {
agent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works already and seems cleaner and less verbose to me.

agent { label 'maven' }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoah! I had no idea that'd work!!! I just tried it out and it seems to work!!! Many thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay!

agent {
kubernetes {
label 'mypod'
podTemplate {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me, but I'd like the label to be under podTemplate to reflect the actual structure of the PodTemplate.

kubernetes {
label 'mypod'
podTemplate {
inheritFrom 'maven'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1: Having inheritFrom like this (under podTemplate) makes much more sense!

Copy link
Contributor Author

@jstrachan jstrachan Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess we need to decide should there be a label under agent and kubernetes and if so why and do they have different semantics?

Also should there be inheritFrom under kubernetes and podTemplate? All these permutations are a little confusing

FWIW my 2 main use cases are:

  1. refer to a podTemplate by name/label
  2. inheritFrom a named podTemplate and change something (e.g. the maven containerTemplate's image version)

I guess for (1) we can just use:

agent {
  label "nameOfPodTemplate"
}

then for (2) we maybe go with something like this?

agent {
  kubernetes {
    podTemplate {
       inheritFrom 'maven'
      containerTemplate { 
          name  "maven"
          image "mycustom-maven-image"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 I totally agree on how these two use cases are handled.

Please note that on (1) its labelOfPodTemplate and not the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess its clear there's some confusion though over the current properties; so might be worth a bit of review and maybe some deprecation?

Copy link
Contributor Author

@jstrachan jstrachan Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess its clear that the use of label just refers to an existing podTemplate without any modification and inheritFrom always creates a new podTemplate by combining inline customisation with an existing podTemplate. Its just a tad confusing that there are so many places you can use label and inheritFrom.

Maybe we deprecate kubernetes.label and kubernetes.inheritFrom? Then you either use agent.label to use a pod template via label or agent.kubernetes.podTemplate.inheritFrom to create a new PodTemplate (and maybe override some configurations)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1000

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I can't remember why kubernetes.label exists. It's been a while. =) But agent { label 'foo' } will just try to run on an agent with the label foo, regardless of how that agent is created/provisioned/etc. So if you have the Kubernetes cloud set up on the Jenkins master with a pod template defined with the label foo, an agent will get spun up and used for that Pipeline. But if you have, say, an SSH agent set up with the label foo and it's got a free executor, that'll get used before it tries to provision any new agents.

And yeah, if the current functionality of kubernetes { label ... } is just to define a label on the podTemplate that gets created behind the scenes, I'd deprecate it in favor of the better podTemplate configuration options.

@carlossg
Copy link
Contributor

carlossg commented Dec 4, 2017

ping @abayer if you could review

jstrachan added a commit to jstrachan/kubernetes-plugin that referenced this pull request Dec 4, 2017
more background discussion in this PR jenkinsci#260
@timwebster9
Copy link

Any news on this? Eagerly awaiting this PR to be merged... :-)

@carlossg
Copy link
Contributor

So @jstrachan @iocanel is this ready to be reviewed or still WiP ? what's the final syntax?

@timwebster9
Copy link

Just had a thought - will this allow us to declare a different default JNLP container in our containerTemplate configuration in the Jenkinsfile?

@novitoll
Copy link

novitoll commented Feb 7, 2018

What is the status of this PR?

Currently, only last container template is created, e.g. multiple containers are not working with declarative syntax now

agent {
        kubernetes {
            label 'jenkins-slave'
            cloud 'myK8s'
            containerTemplate(..)
            containerTemplate(..)

@abayer
Copy link
Member

abayer commented Feb 12, 2018

@jstrachan So I've been thinking on this sort of thing - defining templates at the top level agent and then being able to specify the particular template to use in stage-level agents (with an optional default at the top level as well), and adding support for sidecar containers as well. I don't yet know what the syntax feels like yet, but I'm hoping to have a sense of that later this week. I'm thinking about it more generally than just this plugin - i.e., new agent syntax/types that can be extended for a particular implementation like Kubernetes. If you give me a week or two, I should have a draft replacement incorporating the guts of this PR with the new Declarative syntax.

@fredericrous
Copy link

fredericrous commented Feb 23, 2018

Hello, I went full declarative and would very much like the podtemplate configuration to be available.
In the mid time, can I configure it from jenkins system configuration page and call the pod template from declarative pipeline by name?

I configured the kubernetes pod in jenkins configuration page to reflect the below non declarative code

    podTemplate(
        name: 'mypod',
        label: uniqueId, 
        containers: [
            containerTemplate(
                name: 'jnlp', 
                image: 'custom.corp:51021/production/jnlp:3.7-1-alpine',
                args: '${computer.jnlpmac} ${computer.name}'
            ),
            containerTemplate (
                name: 'container-exec', 
                image: 'custom.corp:51021/production/mycontainer',
                command: '/usr/bin/tail -f /dev/null',
            )
        ]
    )

Could I call the pod in jenkins with something like

pipeline {
  agent {
    kubernetes {
            containerTemplate 'mypod'
    }
...
  }
}

The code above doesn't work. I tried different things without success.
If this is not possible. I'm not asking for a new feature, but for a workaround if you have any idea =)
Cheers

@colemickens
Copy link
Contributor

What's the status of this? Also, why is the implementation so complicated? Why is it more than just deleting "containerTemplate" and replacing it with "podTemplate" and just setting that single field in the "getArgs" function? Or is it this complexity so that it is backward compatible as well?

@jkinred
Copy link

jkinred commented Mar 20, 2018

There are many of us using declarative that are keen to see this feature land, it looks close!

@carlossg
Copy link
Contributor

carlossg commented Apr 6, 2018

This is now sort of superseded by #306, it allows defining multicontainer pods in declarative
Although it does not allow picking a predefined template by name I believe the original reason for this PR was using multi-container pods

@carlossg carlossg closed this May 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants