我遇到的Jenkins遷移項目並不是能夠經過簡單的物理文件複製就能夠輕鬆解決,須要考慮上千個不一樣項目的jobs分離,Jenkins 1.x和2.x大版本兼容性,Jenkins Plugins插件,Jenkins Credentials憑證,Jenkins Restrict節點約束,按view分類不一樣項目的jobs等各類因素。此次對Jenkins遷移作了大量的研究和實踐,但願總結出來的方法能對各位有幫助。php
Jenkins export and import jobs 遷移導出導入任務實踐小結
2020年01月06日 - 初稿java
閱讀原文 - https://wsgzao.github.io/post...node
擴展閱讀python
Is it possible to exchange jobs between 2 different Jenkins'? I'm searching for a way to export/import jobs.github
Jenkins has a rather good wiki, albeit hard to read when you’re new to CI software…json
They offer a simple solution for moving jobs between serversvim
The trick probably was the need to reload config from the Jenkins Configuration Page.api
Probably use jenkins command line is another option, see https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLIbash
So you can do
java -jar jenkins-cli.jar -s http://server get-job myjob > myjob.xml java -jar jenkins-cli.jar -s http://server create-job newmyjob < myjob.xml
It works fine for me and I am used to store in inside my version control system
A one-liner:
$ curl -s http://OLD_JENKINS/job/JOBNAME/config.xml | curl -X POST 'http://NEW_JENKINS/createItem?name=JOBNAME' --header "Content-Type: application/xml" -d @-
With authentication:
$ curl -s http:///<USER>:<API_TOKEN>@OLD_JENKINS/job/JOBNAME/config.xml | curl -X POST 'http:///<USER>:<API_TOKEN>@NEW_JENKINS/createItem?name=JOBNAME' --header "Content-Type: application/xml" -d @-
With Crumb, if CSRF is active (see details here):
Get crumb with:
$ CRUMB_OLD=$(curl -s 'http://<USER>:<API_TOKEN>@OLD_JENKINS/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') $ CRUMB_NEW=$(curl -s 'http://<USER>:<API_TOKEN>@NEW_JENKINS/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
Apply crumb with -H CRUMB
:
$ curl -s -H $CRUMB_OLD http:///<USER>:<API_TOKEN>@OLD_JENKINS/job/JOBNAME/config.xml | curl -X POST -H $CRUMB_NEW 'http:///<USER>:<API_TOKEN>@NEW_JENKINS/createItem?name=JOBNAME' --header "Content-Type: application/xml" -d @-
There’s a plugin called Job Import Plugin that may be what you are looking for. I have used it. It does have issues with importing projects from a server that doesn’t allow anonymous access.
For Completeness:
If you have command line access to both, you can do the procedure already mentioned by Khez for Moving, Copying and Renaming Jenkins Jobs.
Go to your Jenkins server’s front page, click on REST API at the bottom of the page:
Create Job
To create a new job, post config.xml
to this URL with query parameter name=JOBNAME
. You need to send a Content-Type: application/xml
header. You’ll get 200
status code if the creation is successful, or 4xx/5xx
code if it fails. config.xml
is the format Jenkins uses to store the project in the file system, so you can see examples of them in the Jenkins home directory, or by retrieving the XML configuration of existing jobs from /job/JOBNAME/config.xml
.
In my Jenkins instance (version 1.548) the configuration file is at:
/var/lib/jenkins/jobs/-the-project-name-/config.xml
Owned by jenkins user and jenkins group with 644 permissions. Copying the file to and from here should work. I haven’t tried changing it directly but have backed-up the config from this spot in case the project needs to be setup again.
Job Import plugin is the easy way here to import jobs from another Jenkins instance. Just need to provide the URL of the source Jenkins instance. The Remote Jenkins URL can take any of the following types of URLs:
http://$JENKINS
– get all jobs on remote instancehttp://$JENKINS/job/$JOBNAME
– get a single jobhttp://$JENKINS/view/$VIEWNAME
– get all jobs in a particular viewThanks to Larry Cai’s answer I managed to create a script to backup all my Jenkins jobs. I created a job that runs this every week. In case someone finds it useful, here it is:
#!/bin/bash #IFS for jobs with spaces. SAVEIFS=$IFS IFS=$(echo -en "\n\b") for i in $(java -jar /run/jenkins/war/WEB-INF/jenkins-cli.jar -s http://server:8080/ list-jobs); do java -jar /run/jenkins/war/WEB-INF/jenkins-cli.jar -s http://server:8080/ get-job ${i} > ${i}.xml; done IFS=$SAVEIFS mkdir deploy tar cvfj "jenkins-jobs.tar.bz2" ./*.xml
Jenkins export jobs to a directory
#! /bin/bash SAVEIFS=$IFS IFS=$(echo -en "\n\b") declare -i j=0 for i in $(java -jar jenkins-cli.jar -s http://server:8080/jenkins list-jobs --username **** --password ***); do let "j++"; echo $j; if [ $j -gt 283 ] // If you have more jobs do it in chunks as it will terminate in the middle of the process. So Resume your job from where it ends. then java -jar jenkins-cli.jar -s http://lxvbmcbma:8080/jenkins get-job --username **** --password **** ${i} > ${i}.xml; echo "done"; fi done
Import jobs
for f in *.xml; do echo "Processing ${f%.*} file.."; //truncate the .xml extention and load the xml file for job creation java -jar jenkins-cli.jar -s http://server:8080/jenkins create-job ${f%.*} < $f done
Simple php script worked for me.
Export:
// add all job codes in the array $jobs = array("job1", "job2", "job3"); foreach ($jobs as $value) { fwrite(STDOUT, $value. " \n") or die("Unable to open file!"); $path = "http://server1:8080/jenkins/job/".$value."/config.xml"; $myfile = fopen($value.".xml", "w"); fwrite($myfile, file_get_contents($path)); fclose($myfile); }
Import:
<?php // add all job codes in the array $jobs = array("job1", "job2", "job3"); foreach ($arr as $value) { fwrite(STDOUT, $value. " \n") or die("Unable to open file!"); $cmd = "java -jar jenkins-cli.jar -s http://server2:8080/jenkins/ create-job ".$value." < ".$value.".xml"; echo exec($cmd); }
This does not work for existing jobs, however there is Jenkins job builder.
This allows one to keep job definitions in yaml files and in a git repo which is very portable.
For those of us in the Windows world who may or may not have Bash available, here’s my PowerShell port of Katu and Larry Cai‘s approach. Hope it helps someone.
##### Config vars ##### $serverUri = 'http://localhost:8080/' # URI of your Jenkins server $jenkinsCli = 'C:\Program Files (x86)\Jenkins\war\WEB-INF\jenkins-cli.jar' # Path to jenkins-cli.jar on your machine $destFolder = 'C:\Jenkins Backup\' # Output folder (will be created if it doesn't exist) $destFile = 'jenkins-jobs.zip' # Output filename (will be overwritten if it exists) ######################## $work = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName()) New-Item -ItemType Directory -Force -Path $work | Out-Null # Suppress output noise echo "Created a temp working folder: $work" $jobs = (java -jar $jenkinsCli -s $serverUri list-jobs) echo "Found $($jobs.Length) existing jobs: [$jobs]" foreach ($j in $jobs) { $outfile = Join-Path $work "$j.xml" java -jar $jenkinsCli -s $serverUri get-job $j | Out-File $outfile } echo "Saved $($jobs.Length) jobs to temp XML files" New-Item -ItemType Directory -Force -Path $destFolder | Out-Null # Suppress output noise echo "Found (or created) $destFolder folder" $destPath = Join-Path $destFolder $destFile Get-ChildItem $work -Filter *.xml | Write-Zip -Level 9 -OutputPath $destPath -FlattenPaths | Out-Null # Suppress output noise echo "Copied $($jobs.Length) jobs to $destPath" Remove-Item $work -Recurse -Force echo "Removed temp working folder"
It is very easy just download plugin name
Enter the URL of your Remote Jenkins server and it will import the jobs automatically
The most easy way, with direct access to the machine is to copy the job folder from first jenkins to another one (you can exclude workspaces – workspace
folder), because the whole job configuration is stored in the xml file on the disk.
Then in the new jenkins just reload configuration
in the global settings (admin access is required) should be enough, if not, then you will need to restart Jenkins tool.
Another way can be to use plugins mentioned above this post.
edit:
– in case you can probably also exclude modules
folders
上面列舉有14種方法居多,但大多數是基於方案4進行擴展
上面列舉的方案基本已經很是全了,感受是否是有點眼花?其實概括總結主要有如下4種
<jenkinshost>/job/<jobname>/config.xml
,效果最佳Many objects of Jenkins provide the remote access API. They are available at /.../api/ where "..." portion is the object for which you'd like to access.
XML API
Access data exposed in HTML as XML for machine consumption. Schema is also available.
You can also specify optional XPath to control the fragment you'd like to obtain (but see below). For example, ../api/xml?xpath=//[0].
For XPath that matches multiple nodes, you need to also specify the "wrapper" query parameter to specify the name of the root XML element to be create so that the resulting XML becomes well-formed.
Similarly exclude query parameter can be used to exclude nodes that match the given XPath from the result. This is useful for trimming down the amount of data you fetch (but again see below). This query parameter can be specified multiple times.
XPath filtering is powerful, and you can have it only return a very small data, but note that the server still has to build a full DOM of the raw data, which could cause a large memory spike. To avoid overloading the server, consider using the tree parameter, or use the xpath parameter in conjunction with the tree parameter. When used together, the result of the tree parameter filtering is built into DOM, then the XPath is applied to compute the final return value. In this way, you can often substantially reduce the size of DOM built in memory.
JSON API
Access the same data as JSON for JavaScript-based access. tree may be used.
Python API
Access the same data as Python for Python clients. This can be parsed into Python object as eval(urllib.urlopen("...").read()) and the resulting object tree is identical to that of JSON. However, when you do this, beware of the security implication. If you are connecting to a non-trusted Jenkins, the server can send you malicious Python programs.
In Python 2.6 or later you can safely parse this output using ast.literal_eval(urllib.urlopen("...").read())
For more information about remote API in Jenkins, see the documentation.
https://jenkins.io/redirect/r...
使用Jenkins REST API建議關閉CSRF防禦
# To retrieve the job config.xml curl -X GET '<jenkinshost>/job/<jobname>/config.xml' -u username:API_TOKEN -o <jobname>.xml # to use this config to create a new job curl -s -XPOST '<jenkinshost>/createItem?name=<jobname>' -u username:API_TOKEN --data-binary @<jobname>.xml -H "Content-Type:text/xml" # get all jenkins jobs curl -X GET '<jenkinshost>/api/json?pretty=true' -u username:API_TOKEN -o jobs.json # get jenkins view curl -X GET '<jenkinshost>/view/<viewname>/api/json' -u username:API_TOKEN -o view.json
Obviously, replace:
mkdir config_xml vim jobs.txt vim jenkins_jobs_migration.sh #/bin/bash source_jenkins_host="xxx" source_jenkins_username="xxx" source_jenkins_password="xxx" target_jenkins_host="xxx" target_jenkins_username="xxx" target_jenkins_password="xxx" pull() { for line in `cat jobs.txt` do echo ${line} curl -X GET ${source_jenkins_host}job/${line}/config.xml -u ${source_jenkins_username}:${source_jenkins_password} -o config_xml/${line}.xml done } push() { for line in `cat jobs.txt` do echo $line curl -s -XPOST ${target_jenkins_host}createItem?name=${line} -u ${target_jenkins_username}:${target_jenkins_password} --data-binary @config_xml/${line}.xml -H "Content-Type:text/xml" done } case "$1" in push) push ;; pull) pull ;; *) echo "Usage: $NAME {pull|push}" exit 1 ;; esac
暫不方便公開
archive jenkins setting and plugins
你們應該都知道Jenkins備份插件目前主要就2種選擇:
嚴格意義上來講應該只能選擇Periodic Backup,可是若是是須要按期備份天然離不開編寫Bash腳本