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

🍀 Proposal: Add a plugin to create a Jenkins pipeline #582

Closed
prodanlabs opened this issue May 22, 2022 · 10 comments
Closed

🍀 Proposal: Add a plugin to create a Jenkins pipeline #582

prodanlabs opened this issue May 22, 2022 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@prodanlabs
Copy link
Contributor

prodanlabs commented May 22, 2022

What Would You Like to Add? Why is This Needed?

Design

toolFile: config.yaml
tools:
  - name: jenkins-pipeline
    instanceID: demo-apply
    options:
      git:
        url: "https://github.com/prodanlabs/tekton-examples.git"
        branch: "main"
      mode: kubernetes
      jenkins:
        url: "http://124.71.14.222:31765"
        username: admin
        apitoken: oiio
        credential:
          id: "test"
          user: "admin"
          passwd: "xxxx"
          policy: IfNotExistCreate
      job:
        name: devstream-auto
      pipeline: |
        pod:
        - containertemplate:
            name: jnlp
            image: jenkins/inbound-agent:latest-alpine
        - containertemplate:
            name: golang
            image: "golang:alpine3.15",
            command: "sleep",
            args: "600s",
            envVars: |
            - key: 'CGO_ENABLED'
              value: '0'
        stages:
        -  stage:
             name: "Git Clone"
        -  stage:
             name: "Golang Test"
             script: |
               cd ${WORKSPACE}/
               go version
               go test

state:
  backend: local
  options:
    stateFile: devstream.state
prodan@ubuntu:/opt/workspaces/devstream$ ./dtm apply -y
2022-05-22 21:23:01 ℹ [INFO]  Apply started.
2022-05-22 21:23:01 ℹ [INFO]  { config.yaml 0xc0001c7310}
2022-05-22 21:23:01 ℹ [INFO]  Using dir <.devstream> to store plugins.
2022-05-22 21:23:01 ℹ [INFO]  Using local backend. State file: devstream.state.
2022-05-22 21:23:01 ℹ [INFO]  Tool (jenkins-pipeline/demo-apply) found in config but doesn't exist in the state, will be created.
2022-05-22 21:23:01 ℹ [INFO]  Start executing the plan.
2022-05-22 21:23:01 ℹ [INFO]  Changes count: 1.
2022-05-22 21:23:01 ℹ [INFO]  -------------------- [  Processing progress: 1/1.  ] --------------------
2022-05-22 21:23:01 ℹ [INFO]  Processing: (jenkins-pipeline/demo-apply) -> Create ...
2022-05-22 21:23:01 ℹ [INFO]  jenkins version: 2.332.3
2022-05-22 21:23:01 ℹ [INFO]  plugin: kubernetes version: 3580.v78271e5631dc
2022-05-22 21:23:01 ✔ [SUCCESS]  Tool (jenkins-pipeline/demo-apply) Create done.
2022-05-22 21:23:01 ℹ [INFO]  -------------------- [  Processing done.  ] --------------------
2022-05-22 21:23:01 ✔ [SUCCESS]  All plugins applied successfully.
2022-05-22 21:23:01 ✔ [SUCCESS]  Apply finished.

image

image

image

kubectl get po -n jenkins 
NAME                               READY   STATUS    RESTARTS   AGE
jenkins-master-0                   1/1     Running   1          3d1h
jenkins-slave-alpine-m14c4-tgghn   2/2     Running   0          12s

question

  1. There are many Jenkins operating environments, some running on kubernetes, docker or bare metal, and there are differences in configuration. A plan may be needed to implement it gradually.
  2. I looked at the third-party libraries related to Jenkins, and it seems that they are not active anymore. I don't know if devstream has requirements for third-party libraries.
    Generally speaking, large open source projects will not use inactive third-party libraries. I spent an hour implementing a simple Jenkins REST client,like this:
type PipelineInterface interface {
	Create(ctx context.Context, name string, body interface{}) error
	Update(ctx context.Context, name string, body interface{}) error
	Delete(ctx context.Context, name string) error
	Get(ctx context.Context, name string) (Pipeline, error)
	List(ctx context.Context)  ([]Pipeline, error)
}

What do you think about this plugin? This plugin is still a demo :)

Anything else

@daniel-hutao
Copy link
Member

@prodanlabs Thank you very much for the proposal and there is a great demo screenshot. For this plugin, maybe we need more detailed design before we can start development. For example, the password/token fields in the configuration file may not be suitable to save directly in plain text.

Also as you mentioned, jenkins can interface with docker, k8s, vm and many more, so which one should we implement first? Does one plugin support all of them?

Also we already have a jenkins plugin, so maybe there is some generic base configuration that can be added to the jenkins plugin. Perhaps you might consider looking at the jenkins plugin implementation first to see if there are enhancement points you can implement.

For pipeline, I think it's a good idea to start with the k8s way. Maybe it's a new plugin, I'm not sure if it should be called jenkins-pipeline or jenkins-k8s-pipeline or something else; look forward to more input @devstream-io/devstream!

@daniel-hutao daniel-hutao added the enhancement New feature or request label May 23, 2022
@prodanlabs
Copy link
Contributor Author

  1. password/token security.
    The passwords of git and docker registry can be added by users themselves on Jenkins, and the credential ID is passed in config.yaml.
    Jenkins API Token can be encrypted with some encryption algorithm.

  2. The current jenkins plugin seems to just install the plugin. In addition, as far as I know, the way Jenkins integrates with kubernetes is implemented through the kubernetes plugin, not through kubernetes crd and other methods. Therefore, creating Jenkins resource objects can only be done through jenkins REST API.

  3. I personally prefer jenkins-k8s-pipeline, jenkins-docker-pipeline, etc.

To be honest, in kubernetes , a general helm plugin can basically solve the problem of software installation, devstream should solve the complex problems of DevOps applications, such as simplifying the configuration, rather than doing too much work in installing DevOps applications, I Personally think so.

@prodanlabs
Copy link
Contributor Author

Jenkins API Token is also available via temporary environment variables.

@prodanlabs
Copy link
Contributor Author

Hi @daniel-hutao do you have any suggestions?

toolFile: config.yaml
tools:
- name: jenkins-k8s-pipeline
  instanceID: demo
  options:
    git:
      url: "https://github.com/prodanlabs/tekton-examples.git"
      branch: "main"
      credentialID: "1111" # Jenkins credential id
    jenkinsURL: "http://124.71.14.222:31765"
    jobName: devstream-auto
    pod: # kubernetes pod template
      label: "test" 
      container:
      - name: "jnlp"
        image: "jenkins/inbound-agent:latest-alpine"
      - name: "golang"
        image: "golang:alpine3.15"
        command: 
        - sleep
        args: 
        - 600s
        Env:
        - key: 'CGO_ENABLED'
          value: '0'
        - key: 'CGO_ENABLED_EE'
          value: '0'
      volumes:
        emptyDirVolume:
        - mountPath: "/tmp"
        - mountPath: "/tmp22"
        secretVolume:
        - mountPath: "/test"
          secretName: "test"
        - mountPath: "/test2"
          secretName: "test2"
    pipeline: # Jenkins Pipeline template
      environment:
      - key: 'PPPP'
        value: '22'
      stages:
      - name: "Git Clone"
        container: "jnlp"
        gitClone: true
      - name: "Go Test"
        container: "golang"
        script: |-
          cd ${WORKSPACE}/
          go version
          go test
state:
  backend: local
  options:
    stateFile: devstream.state

@prodanlabs
Copy link
Contributor Author

Environment variables use name:value is better

@prodanlabs
Copy link
Contributor Author

The discussion about this plugin seems to have stopped, I don't know how it's going.

There is no doubt that the devstream concept is cool, but from the existing functions, ROADMAP and development trends, devstream is not suitable for us, the function we need is to solve the integration of DevOps software, simplify DevOps configuration, etc., not based on helm does some simple installation. Unfortunately, I am looking for other tools or solutions, and I hope that devstream will become a CNCF incubation project soon.

In addition, for some of the work I have done on this plugin, I can submit a PR as a reference like #650. It doesn't matter if it's modified on my PR submitted or resubmitted by the community.

/cc @daniel-hutao @IronCore864

@IronCore864
Copy link
Member

Hi @prodanlabs,

We are sorry that this issue didn't get enough attention from the PMC.

Please do keep in mind that we are a tiny PMC consisting of only 2 members at the moment, and we have a not-so-tiny backlog to work through. It doesn't mean this isn't an important issue; I hope you keep it in mind.

I have the following concerns regarding this issue:

1. Jenkins Installation/Configuration

In order for the "jenkins-k8s-worker" to work:

  • user need to Fill in the Kubernetes plugin configuration
  • or the Jenkins is running in Kubernetes in which case the defaults work

I.E., if the user didn't use our existing jenkins plugin to install jenkins, but tries to use this plugin directly on an existing jenkins instance, it doesn't work.

I have a proposal: add a possibility to "fill in the k8s plugin config" as shown here.

2. Pipeline Definition

Most users define podTemplate directly in their Jeninsfile and put that Jenkinsfile in their repo. An example of the Jenkinsfile:

podTemplate(containers: [
    containerTemplate(name: 'maven', image: 'maven:3.8.1-jdk-8', command: 'sleep', args: '99d'),
    containerTemplate(name: 'golang', image: 'golang:1.16.5', command: 'sleep', args: '99d')
  ]) {

    node(POD_LABEL) {
        stage('Get a Maven project') {
            git 'https://github.com/jenkinsci/kubernetes-plugin.git'
            container('maven') {
                stage('Build a Maven project') {
                    sh 'mvn -B -ntp clean install'
                }
            }
        }

        stage('Get a Golang project') {
            git url: 'https://github.com/hashicorp/terraform.git', branch: 'main'
            container('golang') {
                stage('Build a Go project') {
                    sh '''
                    mkdir -p /go/src/github.com/hashicorp
                    ln -s `pwd` /go/src/github.com/hashicorp/terraform
                    cd /go/src/github.com/hashicorp/terraform && make
                    '''
                }
            }
        }

    }
}

I would argue that:

  1. The pipeline config in the format of the Jenkins file is much more human-readable than the YAML config in a DTM plugin. Users might already know how to use Jenkinsfile/groovy, but they'd have to convert the above definition into DTM config to let DevStream manage the pipeline.
  2. It's much easier to git clone, edit, and git commit to update the Jenkinsfile, rather than editing the YAML DTM config.

Based on the above thoughts, I have the following ideas:

  • the plugin takes a git repo URL as an input parameter, which indicates the location of the Jenkinsfile.
  • create a Jenkins job using that git repo which contains a Jenkinsfile

Benefits:

  • much easier DTM plugin parameters
  • no need to worry about Jenkins k8s plugin anymore (depends on the content of the Jenkins file)

@IronCore864
Copy link
Member

We are planning a plugin to create a jenkins job, and in the job, we will define a git repo to read the Jenkins file.

@aFlyBird0 please follow up on this one.

@IronCore864 IronCore864 assigned aFlyBird0 and unassigned prodanlabs and KeHaohaoke Jul 8, 2022
@prodanlabs
Copy link
Contributor Author

Sorry, I don't have time to follow up right now. Interested friends can pick it up.

@steinliber
Copy link
Contributor

#1148 has add jenkinsfile pipeline for this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants