How to export/import the Jenkins configuration? - jenkins

The Jenkins CLI provides the function to export&import single jobs, e.g.:
java -jar jenkins-cli.jar -s http://foo-jenkins.tld:8080 get-job myjob > myjob.xml
java -jar jenkins-cli.jar -s http://bar-jenkins.tld:8080 create-job newmyjob < myjob.xml
Is it also possible / How to backup&restore the configs?
I mean the whole settings:
the system configuration,
the global security configuration,
the credentials,
the global tool configuration,
the plugins configuration (the "HTTP Proxy Configuration" and the list of the installed plugins)
the nodes
the users
is anything missing?
The whole settings at once or maybe even as single backup/restore processes like e.g. MozBackup with its "Components selection"
or eclipse with its "Export Preferences" dialog

There is no simple way to backup/export selected parts of the configuration, since Jenkins configuration data is scattered among
several files (global config.xml, lots of plugin-specific files)
several sub-directories (credentials, nodes) and
some of the files are encrypted (credentials), so you must also backup the encryption keys
The cleanest solution will be to back-up the entire $JENKINS_HOME, and to exclude those parts that you do not want to be part of the backup (e.g., exclude jobs/*/builds). With that you'll end up with a resonable backup size also.
Such a backup must be done on filesystem level, as there's no API to access all those files/data.
Do not rely on thinBackup, as you depend on the plugin maintainers to not miss anything important. E.g., as of version 1.7.4, thinBackup does not backup Jenkins' secret keys, so it's impossible to restore credentials from scratch.

Maybe thinBackup plugin will help you.

The mentioned requirement can be easily achieved using the below plugin
https://wiki.jenkins-ci.org/display/JENKINS/JobConfigHistory+Plugin
Below issues will be solved while using this plugin
Config changes are versioned
Config changes can be compared
Config changes can be reverted back

Related

How to delete a build from Jenkins job workspace

I wonder if it is possible to remove only one build (including artifacts) from job workspace.
I tried to "Delete Build" in Build History but all it does is remove build reference from Build History table. I know I can ssh to a server and delete files from the command line but I am looking for a way to do it from Jenkins web interface.
After installing Workspace Cleanup Plugin I am able to wipe out current workspace but I want to keep my other builds in the workspace.
In your Jenkins instance, to be able to have folder/per build - set flag "Use custom workspace" in your job's settings. Here is a brief help info from the setting description:
For each job on Jenkins, Jenkins allocates a unique "workspace directory."
This is the directory where the code is checked out and builds happen.
Normally you should let Jenkins allocate and clean up workspace directories,
but in several situations this is problematic, and in such case, this option
lets you specify the workspace location manually.
One such situation is where paths are hard-coded and the code needs to be
built on a specific location. While there's no doubt that such a build is
not ideal, this option allows you to get going in such a situation.
...
And your custom directory path would look like this:
workspace\$JOB_NAME\$BUILD_NUMBER ~> workspace\my-job-name\123
where $JOB_NAME will be "my-job-name" and $BUILD_NUMBER is the build number, eq. "123".
There is one nasty problem with this approach and this is why I wouldn't recommend to use it - Jenkins will not be able to reclaim disk space for outdated builds. You would have to handle cleanup of outdated builds manually and it is a lot of hassle.
Alternative approach, that gives you more control, tools and is able to keep disk space usage under control (without your supervision) is to use default workspace settings and archive your build output (files, original source code, libraries and etc.) as a post-build action. Very-very handy and gives you access to a whole bunch of great tools like, Copy Artifact Plugin or ArtifactDeployer Plugin in other jobs.
Hope that info helps you make a decision that fits your needs best.
I also use "General/Advanced/Use custom workspace" (as in #pabloduo's answer) on a Windows machine with something like:
C:\${JOB_NAME}\${BUILD_NUMBER}
Just wanted to add a solution for getting rid of the build job's workspaces.
I use Groovy Events Listener Plugin for this.
Using the plug-in's standard configuration I just use the following Groovy script:
if (event == Event.JOB_DELETED){
new File(env.WORKSPACE).deleteDir()
}
And now the custom workspace is deleted when the build job is deleted.
Just be aware that this would also delete non-custom workspaces (because the event is triggered for all jobs on your Jenkins server).

configuring system properties for Jenkins service

Background
I have the following Jenkins config.
Ubuntu machine
Jenkins installed using apt-get, and is started as a service (service jenkins start).
To this point I have not made any modifications to Jenkins config.
We have several Ant projects for which I want to publish Javadocs using Jenkins.
After configuring the Javadoc plugin, I quickly hit this issue where only the Javadoc frames are displaying, without any content.
Some reading (here and here) told me that I need to configure Jenkins' Content Security Policy, and that this is done by modifying system properties passed to Jenkins.
However, despite digging around I have not found clear docs on how to pass these system properties to the Jenkins service. How do I do that?
Answering my own question.
To set system properties for the Jenkins service:
Steps
Stop Jenkins (service jenkins stop). You will need root privileges.
Edit the /etc/defaults/jenkins file.
Add an additional line for the JAVA_ARGS that you want to pass.
JAVA_ARGS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"your CSP configuration here\""
Start Jenkins (service jenkins start).
Explanation
Look at /etc/init.d/jenkins for a line similar to:
NAME=jenkins
SCRIPTNAME=/etc/init.d/$NAME
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
These tell us that the Jenkins daemon will look for a file named /etc/default/jenkins. If present, it .s that file.
If you set $JAVA_ARGS in /etc/default/jenkins it will be substituted in the line below, located later in the /etc/init.d/jenkins file:
$SU -l $JENKINS_USER --shell=/bin/bash -c "$DAEMON $DAEMON_ARGS -- $JAVA $JAVA_ARGS -jar $JENKINS_WAR $JENKINS_ARGS" || return 2
Notes
Even after you do the above, the Javadoc may not load properly. Try doing a hard refresh (Ctrl-Shift-R on Chrome).
As detailed in (the Jenkins docs)[https://wiki.jenkins-ci.org/display/JENKINS/Configuring+Content+Security+Policy] there is a temporary way to do this as well. Read that page and try to understand the implications well.
Changing the Content Security Policy has serious implications especially if your Jenkins is public. It's worth the effort to understand just what policies you are modifying.

in jenkins, how to copy artifacts from another server?

I have another project from which I need to copy artifacts.
However the problem I have is that it's from another server. Is there a way to do so with the copy artifact or I'll have to go through code?
You can accomplish by either publishing your artifact and using either file transfer or secure shell.
Here is info to read upon:
Jenkins Secure Shell Plugin
Jenkins FTP Plugin
The only other possibility is to modify the ant or maven project config file.
Here is a More Reference along the same lines.
I used a wget to fetch the file in the end, with fixed paths.
This link can help for someone not used with wget.
Using wget to recursively fetch a directory with arbitrary files in it
For a long time I use this python script to download artifacts from Jenkins. It takes advantage of the JSON API layer available to any Jenkins job. The format of that API call is:
http://_YOUR_BUILD_HOST_/job/_JOBNAME_/lastSuccessfulBuild/api/json
Beware script depends on PyCurl.
Publish over ssh plugin can also be used for copying the files/artifacts from one server (local/linux) to another server. It has retries option also in case there is network issue and no. of retires and timeout also can be configured.

Relevance of specifying Tool Locations in Jenkins Node Configuration

What does specifying tools under "Tool Locations" in Jenkins Node configuration, exactly do?
I wanted to run a mvn command in free style project. I specified the Maven tool and its home under "Tool Locations" and that didn't help. The job failed for not being able to find mvn. I followed this solution and modified the PATH variable to include maven path. That did the trick.
So how exactly does specifying Tool Locations help? Is it just to help users see the tool paths when they visit Jenkins node configuration site?
In Global Configuration, you can configure different tools, such as Maven, JDK, Ant, etc. When you do that, you also provide an installation method (usually an automatic online installer).
Now, on the Job Configuration, when you configure a buildstep using one of the tools, for example Invoke Ant, you will see a drop down. The first option is Default, the next is whatever tool installations that you've configured in Global Configuration.
If you choose Default it will use whatever is already installed on the system by simply executing a command like java, ant, or mvn. Obviously, if those commands are not in the path, it will fail.
If you choose one of the configured options, Jenkins will install it to the system (if not already done), and use that particular version (as opposed to the one you have under path).
This installation will happen on both the master and the slave nodes. If you do not want to use this automatic installation on a particular node, you can manually specify the location of the particular tool in the screenshot you provided.
The above is only useful if in your Job Configuration, you are selecting a specific version of the tool, other than Default, because as already explained: Default will use whatever is already installed on the system (not by Jenkins).
To answer your queries:
So how exactly does specifying Tool Locations help?
Well, not really i would say. It's meant to specify your custom installation directory path for any program that's already setup in your global config page in a different location. If you have configured mvn 2.0 in global settings but wish to use mvn 3.0 on this specific node, then you can use Tool Locations. However, it will work only if the path to the executable is already present in the PATH env variable of the user with which the slave process is running.
Is it just to help users see the tool paths when they visit Jenkins
node configuration site?
Well, yes, you can say that. I am saying so because whenever you specify a custom path, it generally isn't in the PATH of the user with which the process is running. That's true in most of the cases because such binaries don't run independently. They need other dependent modules to work properly otherwise simply dropping a binary in one of the directories that's already present in the PATH would have sufficed. So, it's safe to say that you explicitly have to add the path to executable in PATH to make it work.
If you have noticed the Help (?) section in the Tool Locations, even that doesn't sound very excited about using this feature :P It says:
You can specify the location of certain tools on this node, overriding the global configuration. (You may prefer to use automatic tool installers instead, removing the need to configure each node separately.)

hudson CI: how to delete all jobs?

I have about 100 jobs on my hudson CI, possible to mass delete them ?
The easiest way, IMHO, would be to use script. Go to http://your.hudson.url/script/
Delete jobs by running:
for(j in hudson.model.Hudson.theInstance.getProjects()) {
j.delete();
}
And this way gives you an option to easily use condition to filter out jobs to delete.
FOR JENKINS
Current versions (2.x):
for(j in jenkins.model.Jenkins.theInstance.getAllItems()) {
j.delete()
}
Older versions:
for(j in jenkins.model.Jenkins.getInstance().getProjects()) {
j.delete();
}
Just delete the job directories:
cd $HUDSON_HOME/jobs
rm -rf <JOB_NAME>
See: Administering Hudson
You can programmatically use the XML api (or use the JSON flavor if you prefer that):
http://your.hudson.url/api/xml?xpath=//job/name&wrapper=jobs
Returns:
<jobs>
<name>firstJob</name>
<name>secondJob</name>
<!-- etc -->
</jobs>
Now iterate over the job names and do a post request to
http://your.hudson.url/job/your.job.name/doDelete
(You can do this with any programming language you like that supports XML and HTTP)
I had similar manageability problems with a Hudson instance that was running 500+ build jobs - it was impractical to manually maintain that many jobs using the gui. However, you can provision jobs in Hudson remotely and programatically by using the CLI - which is supplied as a jar file [http://wiki.hudson-ci.org/display/HUDSON/Hudson+CLI].
The command to delete a job would be something like:
**java -jar hudson-cli.jar -s http://host:port/ delete-job jobname**
And the rest of the commands you will need are here:
**java -jar hudson-cli.jar -s http://host:port/** help
I wrapped the cli in python and created an XML file from which to hold the build configuration - then I could use this to manipulate my running instances of Hudson. This also provided the ability to 'reset' the CI instance back to a known configuration - handy if you suspect build failures were caused by manual changes in the UI or if you are using a different CI server for each environment you deploy to (ie dev, test, prod) and need to provision a new one.
This has also got me out of a few binds when badly written plugins have mangled Hudson's own XML and I've needed to rebuild my instances. Hudson is also I/O bound and for really loaded instances it is often faster to boot Hudson from scratch and populate it's configuration this way.

Resources