Automating Bamboo backup operations

Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.

Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Except Fisheye and Crucible

Summary

Bamboo supports two methods of taking a backup of the instance, which can be manual or scheduled backup, as explained in Exporting data for backup. The following script provides an example of an alternative method via a script that takes a dump of the native database. This is particularly useful when the instance is large, and the Bamboo XML backup functionality is slow.

Solution

This script should be used as a guide on what steps should be taken to proceed with an external backup of Bamboo. Each customer is expected to have particular requirements, and changes to this script might be necessary.

If you are using AWS Backup technology, please check the following KB article for specific recommendations regarding that technology adoption and Bamboo:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 #!/bin/bash # # Bamboo Backup script # # THIS IS NOT PLUG AND PLAY. YOU NEED TO READ THIS SCRIPT # AND ADAPT IT TO YOUR VERY REQUIREMENTS # # This script should be used as a guide on what steps should be taken to proceed # with an external backup of Bamboo. It is expected that each customer may have # particular requirements and changes to this script might be necessary # # This script will: # * Pause your Bamboo instance # * Sync your Bamboo home contents to a backup location # * Dump your MySQL/PostgreSQL/Favorite database # * Resume your Bamboo instance # Requirements: # * rsync # * curl # * python # * mysqldump or pg_dump (or any DB_dump tool you require) # * bamboo admin account credentials or a PAT (see below) # Usage: # Adjust any variables within the # VARIABLES block # Run it from the command line or cron # # VARIABLES # curl="/usr/bin/curl -s -k" rsync="/usr/bin/rsync -a --numeric-ids --sparse --delete" backup_dir="/path/to/backup/directory" backup_sql="${backup_dir}/bamboo_database.sql" bamboo_home="/path/to/bamboo_home" bamboo_url="http://localhost:10572/bamboo572" url="${bamboo_url}/rest/api/latest/server" verbose=1 # Define the authentication method: token, or user and password # We are using auth="userpass" by default # If you prefer to use a Personal Authentication Token (PAT), define auth="token" # https://confluence.atlassian.com/bamboo/personal-access-tokens-976779873.html auth="userpass" #auth="token" username="admin" password="admin" token="XXXXXYYYYYZZZZZZAAAAAABBBBBBCCCCCC" # Define the number of times and the interval between each state check # Once a request for a PAUSED state is issued, Bamboo will remain in a # PAUSING state until all jobs are completed before declaring itself # as PAUSED # * Default: Tries=60, Interval=30 (s) = Total 30m getStateTries=60 getStateInterval=30 # Try to revert to the initial Bamboo state if the script fails. Recommended revertIfFail=1 # # END OF VARIABLES # # -e will make this script fail on first error set -e # Print verbose logs verbose() { ((verbose)) && printf " ==> $*\n" } # Export the authentication method to curl case $auth in userpass) verbose "_CURL_AUTH=userpass" _CURL_AUTH="-u ${username}:${password}" ;; token) verbose "_CURL_AUTH=token" _CURL_AUTH="-H \"Authorization: Bearer ${token}\"" ;; *) echo "You must set \$auth to either \"userpass\" or \"token\"" ;; esac # Get the current state of Bamboo getState() { ${curl} -H "Content-Type:application/json" -H "Accept:application/json" \ ${_CURL_AUTH} -X GET ${url} 2>/dev/null \ | python -c 'import json,sys;print json.load(sys.stdin)["state"]' } # Define vars and actions according to the state defineState() { case $1 in resume|RUNNING) api_state="RUNNING" && action="resume" && revert="pause" ;; pause|PAUSING|PAUSED) api_state="PAUSED" && action="pause" && revert="resume" ;; esac } # Wait for a State to be present # Uses a combination of $getStateTries and $getStateInterval waitforState() { # ARG1 is the desired state RUNNING / PAUSED # ARG2 is the timeout (1 sec interval) trap 'return 1' SIGINT SIGTERM max_retry=$2 counter=1 defineState $1 verbose "Expected state: ${api_state^^}" until (getState | grep -q ${api_state^^}) ; do sleep ${getStateInterval} [[ ${counter} = ${max_retry} ]] && echo "State check failed" && return 1 echo "Waiting for ${api_state^^} state. Trying again. #${counter}" ((counter++)) done verbose "Acquired state: $(getState)" } # Modifies Bamboo state setState() { # ARG1 is the desired state RUNNING / PAUSED new_state=$1 curr_state="$(getState)" verbose "Current state: ${curr_state}" callsetState() { defineState $1 if [ "$2" = "revert" ] ; then _target="${url}/${revert}?os_authType=basic" else _target="${url}/${action}?os_authType=basic" fi verbose "Running ${curl} ***masked*** -X \"${_target}\"" eval $(echo ${curl} ${_CURL_AUTH} -X POST -o /dev/null ${_target}) } verbose "Sending API call state to ${new_state} Bamboo" callsetState ${new_state} verbose "Calling waitforState ${new_state} ${getStateTries}" waitforState ${new_state} ${getStateTries} || \ ( ((revertIfFail)) \ && echo "Failed to set state to ${new_state}. Reverting state" \ && echo "Current state: $(getState)" \ && callsetState ${new_state} revert \ && waitforState ${curr_state} ${getStateTries} \ && return 1) } # Collect Original state before anything INITIAL_STATE=$(getState) verbose "Initial state is: ${INITIAL_STATE}" # Pause server with validation # Will try to set Bamboo into a PAUSED state # It will try up (getStateTries x getStateInterval) echo "Starting Bamboo backup: $(date)" verbose "Calling Bamboo setState pause" setState pause && GOOD_TO_BACKUP=1 if [ ${GOOD_TO_BACKUP} ] ; then echo "Bamboo was set to a PAUSED state. Proceeding with FS/DB Backup" # Backup Bamboo home # It excludes the artifact folder # You may remove this exclusion but your backup size and time may increase considerably verbose "Calling Filesystem backup process" ${rsync} --exclude=build-dir --exclude=build_logs --exclude=artifacts ${bamboo_home} ${backup_dir} # Dump the database contents # Replace with the database user # Make sure your backup command works non-interactively (no confirmations/password # prompts). Some databases require ACLs to be set. Make sure it allows the script to # dump the DB. # Validate the command manually before using it with in the script verbose "Calling DB backup process" #pg_dump -U postgres -h localhost > ${backup_sql} mysqldump -uroot -proot bamboo > ${backup_sql} # Resume Bamboo # Puts Bamboo in a RUNNING state verbose "Calling Bamboo setState resume" setState resume && echo "Bamboo was set to a RUNNING state. Backup finished successfully" else echo "There was an issue with the backup. Exiting" exit 1 fi

The above script can be adapted based on the native database backup tool. In this case, we were using MySQL.

Updated on March 4, 2025

Still need help?

The Atlassian Community is here for you.