forked from ersiko/rundeck-backup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrundeck-backup.sh
executable file
·238 lines (202 loc) · 10.5 KB
/
rundeck-backup.sh
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#!/bin/bash
# Original source: https://blog.tomas.cat/en/2013/03/27/tool-manage-rundeck-backups/
# Code forked to here: https://github.com/mysysadmin-ltd/rundeck-backup
RUNDECK_USER=rundeck
RUNDECK_CONFIG_DIR=/etc/rundeck
RUNDECK_SERVICE=rundeckd
TMPDIR=/tmp
DEFAULT_BACKUP_FILE=rundeck-backup-`date +%F"-"%H"-"%M`.tar.gz
function usage {
echo "Usage: $0 [OPTIONS...] {backup|restore} [backup_file] | -h --help"
}
function areyousure {
read -p "$1" bool
[ "$bool" != "y" ] && echo "Ok, aborting..." && exit 0
}
function backup {
[ -d "${backup_file}" ] && backup_file="${backup_file}/${DEFAULT_BACKUP_FILE}"
[ -f "${backup_file}" ] && [ -z ${force} ] && areyousure "${backup_file} already exists. Overwrite? (y/N) "
[ -d ${BACKUPDIR} ] && echo "Directory ${BACKUPDIR} already exists. Aborting" && exit 1
mkdir -p ${BACKUPDIR}
[ ! -d ${BACKUPDIR} ] && echo "Couldn't create ${BACKUPDIR}. Aborting" && exit 1
# Rundeck config
if [ -z "$exclude_config" ];then
cp -a ${RUNDECK_CONFIG_DIR} ${BACKUPDIR}
[ $? -ne 0 ] && errors_config=1
fi
# Project definitions
PROJECTS_VALUE=`grep ^project.dir ${RUNDECK_CONFIG_DIR}/project.properties|cut -d "=" -f 2`
PROJECTS_DIR=`dirname ${PROJECTS_VALUE}`
if [ -z "${exclude_projects}" ];then
cp -a ${PROJECTS_DIR} ${BACKUPDIR}
[ $? -ne 0 ] && errors_projects=1
fi
# Project keys
if [ -z "${exclude_keys}" ];then
for project in ${PROJECTS_DIR}/*;do
mkdir -p ${BACKUPDIR}/keys/`basename ${project}`
key=`grep project.ssh-keypath ${project}/etc/project.properties|cut -d"=" -f 2`
cp ${key} ${key}.pub ${BACKUPDIR}/keys/`basename ${project}`
[ $? -ne 0 ] && errors_keys=1
done
fi
# Job definitions
if [ -z "${exclude_jobs}" ];then
/sbin/service ${RUNDECK_SERVICE} status > /dev/null
if [ $? -ne 0 ] && [ -z ${force} ];then
areyousure "Rundeck service is not running, so jobs can't be exported. Do you want to start rundeck? (y/N) "
/sbin/service ${RUNDECK_SERVICE} start
sleep 60
/sbin/service ${RUNDECK_SERVICE} status > /dev/null
[ $? -ne 0 ] && echo "Rundeck could not start. Aborting..."
fi
mkdir -p ${BACKUPDIR}/jobs
for project in ${PROJECTS_DIR}/*;do rd-jobs list -f ${BACKUPDIR}/jobs/`basename ${project}.xml` -p `basename ${project}` > /dev/null
[ $? -ne 0 ] && errors_jobs=1;done
fi
# known_hosts
if [ -z "${exclude_hosts}" ];then
cp `getent passwd ${RUNDECK_USER}|cut -d":" -f6`/.ssh/known_hosts ${BACKUPDIR}
[ $? -ne 0 ] && errors_hosts=1
fi
# execution logs
if [ -n "${include_logs}" ];then
cp -a `grep ^framework.logs.dir ${RUNDECK_CONFIG_DIR}/framework.properties |cut -d"=" -f 2` ${BACKUPDIR}
[ $? -ne 0 ] && [ -n "${include_logs}" ] && errors_logs=1
fi
cd ${BACKUPDIR}
tar zcf "${backup_file}" *
[ $? -ne 0 ] && echo "Error creating tar file. Is there free space? Do you have permissions over this file?" && exit 1
rm -rf ${BACKUPDIR}
}
function restore {
/sbin/service ${RUNDECK_SERVICE} status > /dev/null
[ $? -eq 0 ] && [ -z ${force} ] && areyousure "Rundeck service is running. It's recommended to stop it before restoring a backup. Do you want to continue? (y/N) "
[ ! -f "${backup_file}" ] && echo "Error: file ${backup_file} not found" && usage && exit 1
[ -d ${BACKUPDIR} ] && echo "Directory ${BACKUPDIR} already exists. Aborting" && exit 1
mkdir -p ${BACKUPDIR}
[ ! -d ${BACKUPDIR} ] && echo "Unknown error. Couldn't create ${BACKUPDIR}. Aborting" && exit 1
cd ${BACKUPDIR}
tar zxf "${backup_file}"
[ $? -ne 0 ] && echo "ERROR - Could not unpack backup file. Maybe it's not a .tar.gz file, maybe there isn't enough free space, maybe you don't have permissions to write in ${BACKUPDIR}. Aborting ..." && exit 1
# Rundeck config
if [ -z "$exclude_config" ];then
cp -a `basename ${RUNDECK_CONFIG_DIR}` `dirname ${RUNDECK_CONFIG_DIR}`
[ $? -ne 0 ] && errors_config=1
fi
# Project definitions
configdir=`basename ${RUNDECK_CONFIG_DIR}`
PROJECTS_VALUE=`grep ^project.dir $configdir/project.properties|cut -d "=" -f 2`
PROJECTS_DIR=`dirname ${PROJECTS_VALUE}`
if [ -z "${exclude_projects}" ];then
cp -a projects/* ${PROJECTS_DIR}
[ $? -ne 0 ] && errors_projects=1
fi
# Project keys
if [ -z "${exclude_keys}" ];then
for project in projects/*;do
key=`grep project.ssh-keypath ${project}/etc/project.properties|cut -d"=" -f 2`
cp keys/`basename $project`/`basename ${key}` keys/`basename $project`/`basename ${key}`.pub `dirname ${key}`
[ $? -ne 0 ] && errors_keys=1
done
fi
# Job definitions
if [ -z "${exclude_jobs}" ];then
/sbin/service ${RUNDECK_SERVICE} status > /dev/null
[ $? -ne 0 ] && [ -z ${force} ] && areyousure "Rundeck service is not running, so jobs can't be restored. Do you want to start rundeck? (y/N) "
/sbin/service ${RUNDECK_SERVICE} start
sleep 60
/sbin/service ${RUNDECK_SERVICE} status > /dev/null
[ $? -ne 0 ] && echo "Rundeck could not start. Aborting..."
for project in projects/*;do rd-jobs load -f jobs/`basename ${project}`.xml -p `basename ${project}`> /dev/null
[ $? -ne 0 ] && errors_jobs=1;done
fi
# known_hosts
if [ -z "${exclude_hosts}" ];then
cp known_hosts `getent passwd ${RUNDECK_USER}|cut -d":" -f6`/.ssh/known_hosts
[ $? -ne 0 ] && errors_hosts=1
fi
# execution logs
if [ -n "${include_logs}" ];then
cp -a logs/* `grep ^framework.logs.dir ${RUNDECK_CONFIG_DIR}/framework.properties |cut -d"=" -f 2`
[ $? -ne 0 ] && [ -n "${include_logs}" ] && errors_logs=1
fi
rm -rf ${BACKUPDIR}
}
args=`getopt -o hlc:fu:s: --long help,exclude-config,exclude-projects,exclude-keys,exclude-jobs,exclude-hosts,include-logs,configdir:,force,user:,service: -n $0 -- "$@"`
[ $? != 0 ] && echo "$0: Could not parse arguments" && usage && exit 1
eval set -- "$args"
while true ; do
case "$1" in
--exclude-config) exclude_config=1;shift;;
--exclude-projects) exclude_projects=1;shift;;
--exclude-keys) exclude_keys=1;shift;;
--exclude-jobs) exclude_jobs=1;shift;;
--exclude-hosts) exclude_hosts=1;shift;;
-l|--include-logs) include_logs=1;shift;;
-c|--configdir) RUNDECK_CONFIG_DIR="$2";shift 2;;
-u|--user) RUNDECK_USER="$2";shift 2;;
-s|--service) RUNDECK_SERVICE="$2";shift 2;;
-f|--force) force=1;shift;;
-h|--help) echo "rundeck_backup - v1.00"
echo "Copyleft (c) 2013 Tomàs Núñez Lirola <[email protected]> under GPL License"
echo "This script deals with rundeck backup/recovery."
echo ""
usage
echo ""
echo "Options:"
echo "-h | --help"
echo " Print detailed help"
echo "--exclude-config"
echo " Don't backup / restore config files"
echo "--exclude-projects"
echo " Don't backup / restore project definitions"
echo "--exclude-keys"
echo " Don't backup / restore ssh key files"
echo "--exclude-jobs"
echo " Don't backup / restore job definitions"
echo "--exclude-hosts"
echo " Don't backup / restore .ssh/known_hosts file"
echo "--include-logs"
echo " Include execution logs in the backup / restore procedure (they are excluded by default)"
echo "-c <directory> | --configdir <directory>"
echo " Change default rundeck config directory (/etc/rundeck)"
echo "-u <user> | --user <user>"
echo " Change default rundeck user (rundeck)"
echo "-s <service> | --service <service"
echo " Change default rundeck service (rundeckd)"
echo "-f | --force"
echo " Assume 'yes' to all questions"
echo ""
echo "This plugin will backup or restore a rundeck instance, copying files and exporting job definitions with rd-jobs tool. "
echo "Examples:"
echo " $0 backup rundeck-201303.tar.gz"
echo " $0 restore --exclude-jobs rundeck-201303.tar.gz"
echo ""
exit;;
--) shift; break;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
[ $# -lt 1 ] && echo "Error! Missing arguments" && usage && exit 1
action=$1
backup_file="${2:-$DEFAULT_BACKUP_FILE}"
backup_file=`readlink -m "$backup_file"`
[ -n "${exclude_config}" ] && [ -n "${exclude_projects}" ] && [ -n "${exclude_keys}" ] && [ -n "${exclude_jobs}" ] && [ -n "${exclude_hosts}" ] && [ -z "${include_logs}" ] && echo "Error! If everything is excluded, no action will be taken" && exit 1
ID=${RANDOM}
BACKUPDIR=/${TMPDIR}/rundeck-backup-$ID
if [ ${action} == "backup" ];then
backup ${backup_file}
elif [ ${action} == "restore" ];then
restore ${backup_file}
else
echo "Value $1 not recognized. Accepted values: backup, restore" && usage && exit 1
fi
[ -n "${errors_config}" ] && echo "Something happened when copying the config files. Backup may not be complete"
[ -n "${errors_projects}" ] && echo "Something happened when copying the project definitions. Backup may not be complete"
[ -n "${errors_keys}" ] && echo "Something happened when copying ssh key files. Backup may not be complete"
[ -n "${errors_jobs}" ] && echo "Something happened when copying job definitions. Backup may not be complete"
[ -n "${errors_hosts}" ] && echo "Something happened with the known_hosts file. Backup may not be complete"
[ -n "${errors_logs}" ] && echo "Something happened with the execution log files. Backup may not be complete"
[ -n "${errors_config}" ] || [ -n "${errors_projects}" ] || [ -n "${errors_keys}" ] || [ -n "${errors_jobs}" ] || [ -n "${errors_hosts}" ] || [ -n "${errors_logs}" ] && exit 2
echo "OK - ${action} finished successfully using ${backup_file}"