321

Is it possible to exchange jobs between 2 different Jenkins'? I'm searching for a way to export/import jobs.

CSchulz
  • 10,882
  • 11
  • 60
  • 114
Konstantin Milyutin
  • 11,946
  • 11
  • 59
  • 85
  • 5
    Not directly an answer to your question but some best practice: try to write your job configuration with the Jenkins Pipeline DSL and make it part of your projects' repositories. Like that, the jobs are easily portable from one Jenkins server to the other. See https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md – Michael Lihs Nov 08 '16 at 23:01
  • Some advice over at https://stackoverflow.com/questions/38585734/how-to-export-import-the-jenkins-configuration as well – Ben Creasy Feb 05 '18 at 19:30
  • A suggestion 'Thinbackup' plugin can also be used (not only for jobs but for all other configurations can be migrated with the history. – np2807 Nov 26 '20 at 15:32

19 Answers19

200

Probably use jenkins command line is another option, see https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI

  • create-job: Creates a new job by reading stdin as a configuration XML file.
  • get-job: Dumps the job definition XML to stdout

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

Larry Cai
  • 55,923
  • 34
  • 110
  • 156
  • 3
    For this to work, java on your old server, new server, and local machine needs to be of the same version. Otherwise, strange stream/version problems arise. Your jnlp ports need to be open, too. – MaratC Jun 01 '15 at 13:52
  • Full path to the CLI client is JENKINS_HOME/war/WEB-INF/jenkins-cli.jar where JENKINS_HOME is location of JENKINS_HOME – Rob Kielty May 30 '16 at 15:59
  • 1
    This method has issues with bare naked ampersands in the XML such as when you have & in Groovy code. – Rob Kielty May 30 '16 at 16:01
  • un-encoded ampersands in the exported XML can occur in Groovy code that back Active Choice Plugin (uno-choice) parameters; will present solution if I can. – Rob Kielty May 31 '16 at 06:40
  • @MaratC would it not be possible to just use a cURL or other request to grab the raw .xml, instead of using the CLI? Wouldn't that avoid java incompatibilities then? – information_interchange Dec 13 '17 at 21:27
  • 1
    @information_interchange exactly as proposed in my answer below. – MaratC Dec 27 '18 at 13:03
178

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 @-
Alexey Vazhnov
  • 1,291
  • 17
  • 20
MaratC
  • 6,418
  • 2
  • 20
  • 27
  • 1
    Need authentication tokens to work, but steel great job! – Viroide Jan 11 '16 at 14:06
  • 7
    curl -s http://:@OLD_JENKINS/job/JOBNAME/config.xml | curl -X POST 'http://:@NEW_JENKINS/createItem?name=JOBNAME' --header "Content-Type: application/xml" -d @-
    Get User API key from : http://JENKIS_URL/user//configure > API Token > Show API Token
    – Suhas Gaikwad Aug 16 '16 at 09:37
  • 1
    Just one additional contribution on this. When POSTing to the target server you're likely to get an error code HTTP 403 Problem accessing /createItem. Reason: No valid crumb was included in the request. You'll need to generate a CSRF protection token for the target Jenkins server. Follow the advice of @Kenorb from this thread: http://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job – Mig82 Jan 24 '17 at 18:26
  • 3
    Don't even need to use curl commands as you can just go to the `http://OLD_JENKINS/job/JOBNAME/config.xml` link in your browser to grab the `config.xml` file. – entpnerd Apr 25 '18 at 21:26
  • 3
    You need `--data-binary` instead of `-d` in the `curl` command, because `-d` might mess up the whitespace in your scripts. – Gabor Csardi Nov 08 '18 at 12:26
  • @GaborCsardi Thanks for this extra detail. Very important! – Javier Ruiz Feb 16 '21 at 13:58
  • This works. Thank you very much. This is amazing juggling skill with all the flags ;) – Hoang Tran Jun 22 '21 at 06:15
  • @GaborCsardi 's comment about `--data-binary` is correct. I just tested it. Thank you. – Hoang Tran Jun 22 '21 at 06:19
172

Jenkins has a rather good wiki, albeit hard to read when you're new to CI software...

They offer a simple solution for moving jobs between servers

The trick probably was the need to reload config from the Jenkins Configuration Page.

Update 2020.03.10

The JenkinsCI landscape has changed a lot... I've been using Job DSL for a while now. We have a SEED Job that generates the rest of the jobs.

This helps us both recreate or move for the Jenkins server whenever needed :) You could also version those files for even more maintainability!

Khez
  • 10,172
  • 2
  • 31
  • 51
44

In a web browser visit:

http://[jenkinshost]/job/[jobname]/config.xml

Just save the file to your disk.

Gayan Weerakutti
  • 11,904
  • 2
  • 71
  • 68
25

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.

jwernerny
  • 6,978
  • 2
  • 31
  • 32
17

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.

jimmont
  • 2,304
  • 1
  • 27
  • 29
14

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.

warvariuc
  • 57,116
  • 41
  • 173
  • 227
user1050755
  • 11,218
  • 4
  • 45
  • 56
8

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 instance

  • http://$JENKINS/job/$JOBNAME - get a single job

  • http://$JENKINS/view/$VIEWNAME - get all jobs in a particular view

xverges
  • 4,608
  • 1
  • 39
  • 60
GaneSH Malkar
  • 116
  • 1
  • 2
7

Thanks 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
Katu
  • 1,296
  • 1
  • 24
  • 38
6

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
karthick
  • 121
  • 1
  • 4
4

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"
Justin Morgan - On strike
  • 30,035
  • 12
  • 80
  • 104
3

It is very easy just download plugin name

Job Import Plugin

Enter the URL of your Remote Jenkins server and it will import the jobs automatically

Guardian
  • 383
  • 4
  • 17
  • 4
    This might work for some, but not for me. This only works if the new Jenkins instance has direct access to the old Jenkins instance. Mine were on two different networks. – Justin Domnitz Apr 10 '18 at 19:52
3

If you have exported the config.xml then use the same to import:

curl -k -X POST 'https:///<user>:<token>@<jenkins_url>/createItem?name=<job_name>' --header "Content-Type: application/xml" -d @config.xml

I am connecting via HTTPS and disabled certificate validation using -k.

  • This is how to generate user api token on Jenkins.
  • Jenkins REST API details can be seen if you click the link with same name at bottom right corner of your Jenkins instance.
Saikat
  • 14,222
  • 20
  • 104
  • 125
2

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 (config.xml in the job path folder)

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 and in case of pipelines as well shared libraries folders like workspace@libs
xxxvodnikxxx
  • 1,270
  • 2
  • 18
  • 37
2

2021 and the export & import process are a pain!!

If you have shell access to both jenkins instances: the old and new, follow these steps to perform a success jobs migration:

In your old jenkins

  • locate the jenkins home in your old jenkins. Usually /var/lib/jenkins. If you are using bitnami : /opt/bitnami/jenkins
  • inside jenkins home, enter to jobs folder
  • you should see folders with the name of your jobs. Inside of these folder, you just need the config.xml
  • backup all the required jobs. Just the folder and its config.xml. There are a lot of other files that is not required.

In your new jenkins:

  • locate the jenkins home
  • copy your jobs (previous backup) to the jobs folder
  • ensure that these new folder have the user "jenkins" as owner. If not use this: chown jenkins:jenkins /var/lib/jenkins -R
  • restart jenkins
  • use your jobs :D

According to the count of up-votes or comments, I could think the possibility of create a new plugin :)

JRichardsz
  • 14,356
  • 6
  • 59
  • 94
1

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);
}
1

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.

kenorb
  • 155,785
  • 88
  • 678
  • 743
pcrews
  • 150
  • 4
0

As a web user, you can export by going to Job Config History, then exporting XML.

I'm in the situation of not having access to the machine Jenkins is running on and wanted to export as a backup.

As for importing the xml as a web user, I'd still like to know.

SwimBikeRun
  • 4,192
  • 11
  • 49
  • 85
0

Here is a bash script for dumping / migrating all jobs from input Jenkins, with a filtering on job name with first param.
i.e. type io-jenkins.sh MyAppName

You'll need to install before httpie1 and jq tools to make it work.

#!/bin/bash

if [[ $# != 1 ]] ; then 
    echo "Please type filter as first arg"
    exit 127
fi
input="https://<username>:<api-token>@<input-jenkins-baseurl>/"
output="https://<username>:<api-token>@<output-jenkins-baseurl>/"

jobsTree=$(http $input/api/json?tree=jobs[name]|jq -r ".jobs[].name" |grep $1)

IFS=$'\n'
for job in $jobsTree ; do 
    echo "Get '$job' config.xml"
    https "$input/job/$job/config.xml" > /tmp/jenkins-job.xml
    https POST "$output/createItem?name=$job" Content-Type:"application/xml" < /tmp/jenkins-job.xml
done

rm /tmp/jenkins-job.xml

1 HTTPie is an awesome and super-synthetic REST command line client. They also provide UI client (quite like Postman).

# Quick setup
brew install httpie jq # MACOS
apt-get install httpie jq # Linux / Debian 
Damien C
  • 969
  • 1
  • 10
  • 16