Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Backup Jenkins home periodicallly with git.
#!/bin/bash
# Setup
#
# - Create a new Jenkins Job
# - Mark "None" for Source Control Management
# - Select the "Build Periodically" build trigger
# - configure to run as frequently as you like
# - Add a new "Execute Shell" build step
# - Paste the contents of this file as the command
# - Save
#
# NOTE: before this job will work, you'll need to manually navigate to the $JENKINS_HOME directory
# and do the initial set up of the git repository.
# Make sure the appropriate remote is added and the default remote/branch set up.
#
# Jenkins Configuraitons Directory
cd $JENKINS_HOME
# Add general configurations, job configurations, and user content
git add -- *.xml jobs/*/*.xml userContent/*
# only add user configurations if they exist
if [ -d users ]; then
user_configs=`ls users/*/config.xml`
if [ -n "$user_configs" ]; then
git add $user_configs
fi
fi
# mark as deleted anything that's been, well, deleted
to_remove=`git status | grep "deleted" | awk '{print $3}'`
if [ -n "$to_remove" ]; then
git rm --ignore-unmatch $to_remove
fi
git commit -m "Automated Jenkins commit"
git push -q -u origin master
@rodriguezsergio

This comment has been minimized.

Copy link

commented Feb 24, 2016

Saved me the time of writing my own backup script. Thanks 👍

@kuldazbraslav

This comment has been minimized.

Copy link

commented Mar 21, 2016

Thanks, it saved me a lot of time too.

@AlexanderDobrodey

This comment has been minimized.

Copy link

commented Mar 29, 2016

Thank you!

@squrppi

This comment has been minimized.

Copy link

commented Feb 22, 2017

I wonder if the line 34 awk should actually read '{print $2}' instead of '{print $3}'?
The output of "git status" is like

   deleted:    test.py
@Alokdavita

This comment has been minimized.

Copy link

commented Jul 17, 2017

Thanks a lot !!

@gardner

This comment has been minimized.

Copy link

commented Aug 10, 2017

Thank you! I want to post a "You Da Real MVP" meme but I don't think that's allowed on GH.

@syquus

This comment has been minimized.

Copy link

commented Sep 13, 2017

Just a note:
'{print $3}'
is returning empty string for me. Therefore there are elements not being git rm-ed....

I replaced it for
'{print $2}'
and works correctly.

@franc3000

This comment has been minimized.

Copy link

commented Mar 8, 2018

this is great, thank you!

what do you add from the $JENKINS_HOME directory when doing the initial set up of the git repository?

git add * ?

I added all the secret files, and now I'm getting this:

ubuntu@:~/jenkins$ git status
jenkins-data/secrets/filepath-filters.d/30-default.conf: Permission denied
jenkins-data/secrets/hudson.util.Secret: Permission denied
jenkins-data/secrets/initialAdminPassword: Permission denied
jenkins-data/secrets/jenkins.model.Jenkins.crumbSalt: Permission denied
jenkins-data/secrets/jenkins.security.ApiTokenProperty.seed: Permission denied
jenkins-data/secrets/master.key: Permission denied
jenkins-data/secrets/org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY: Permission denied
jenkins-data/secrets/slave-to-master-security-kill-switch: Permission denied
jenkins-data/secrets/whitelisted-callables.d/default.conf: Permission denied
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
@maximba

This comment has been minimized.

Copy link

commented Mar 9, 2018

Modified "to_remove" expression to be more robust:
to_remove=$(git status | grep "deleted" | cut -d ":" -f2 | sed -r 's/^[ \t]*//p')

@greilly

This comment has been minimized.

Copy link

commented Mar 27, 2018

Adding user configurations gave me some errors, and can be simplified:

# only add user configurations if they exist
if [ -d users ]; then
    git add users/*/config.xml
fi
@msvticket

This comment has been minimized.

Copy link

commented Apr 18, 2018

A simpler way of doing deletion resilient to whitespace in file names:
git ls-files -dz | xargs -0r git rm

@transistorgit

This comment has been minimized.

Copy link

commented Feb 26, 2019

The initial script works fine for me, but leaves out some more complex (deeper nested) jobs.
So I added
shopt -s globstar
at the beginning and changed
git add -- .xml jobs//.xml userContent/
to
git add -- .xml jobs/**/config.xml userContent/

@ronensh-nice

This comment has been minimized.

Copy link

commented Feb 28, 2019

I used the following to cope with nested jobs folders
find -L jobs -type f -iname config.xml -follow -print0 -exec git add {} \;

@ilyaevseev

This comment has been minimized.

Copy link

commented Mar 18, 2019

This can be simplified:

if [ -d users ]; then
    user_configs=`ls users/*/config.xml`

    if [ -n "$user_configs" ]; then
        git add $user_configs
    fi
fi

to:

ls users/*/config.xml 2>/dev/null | xargs -r git add
@ilyaevseev

This comment has been minimized.

Copy link

commented Mar 18, 2019

And this can be simplified

to_remove=`git status | grep "deleted" | awk '{print $3}'`

if [ -n "$to_remove" ]; then
    git rm --ignore-unmatch $to_remove
fi

to:

git status | awk '/deleted/ { print $3 }' | xargs -r git rm --ignore-unmatch
@ilyaevseev

This comment has been minimized.

Copy link

commented Mar 18, 2019

Final edition:

#!/bin/sh -e

cd "$JENKINS_HOME"

# Add general configurations, secrets, job configurations, nodes, user content, users and plugins info:
ls -1d *.xml secrets/ jobs/*/*.xml nodes/*/*.xml userContent/* users/*/config.xml \
    plugins/*/META-INF/MANIFEST.MF 2>/dev/null | xargs -r -d '\n' git add --

# Track deleted files:
LANG=C git status | awk '$1 == "deleted:" { print $2; }' | xargs -r git rm --ignore-unmatch

LANG=C git status | grep -q '^nothing to commit' || {
    git commit -m "Automated Jenkins commit at $(date '+%Y-%m-%d %H:%M')"
    git push -q -u origin master
}
@ilyaevseev

This comment has been minimized.

Copy link

commented Mar 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.