devstream
devstream copied to clipboard
:four_leaf_clover: `Proposal`: Add a plugin to create a Jenkins pipeline
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.
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
- 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.
- 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
@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!
-
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. -
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
. -
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.
Jenkins API Token
is also available via temporary environment variables.
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
Environment variables use name:value
is better
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
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:
- 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.
- 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)
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.
Sorry, I don't have time to follow up right now. Interested friends can pick it up.
https://github.com/devstream-io/devstream/pull/1148 has add jenkinsfile pipeline for this issue