-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.sh
195 lines (172 loc) · 6.16 KB
/
utils.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
# -------------------------------------------------------------------------------------
# Common utilities for logging, terminating script execution and Hipchat integration.
# -------------------------------------------------------------------------------------
# Terminate script execution with error message
function bail {
error "$*"
print_stack_trace
exit 99
}
# Test for the presence of the specified command and terminate script execution if not found
function check_command {
type -P "$1" &> /dev/null || bail "Unable to find $1, please install it and run this script again"
}
# Log an debug message to the console if BITBUCKET_VERBOSE_BACKUP=true
function debug {
if [ "${BITBUCKET_VERBOSE_BACKUP}" = "true" ]; then
print "$(script_ctx)[$(hostname)] DEBUG: $*"
fi
}
# Log an error message to the console and publish it to Hipchat
function error {
# Set the following to have log statements print contextual information
echo "$(script_ctx)[$(hostname)] ERROR: $*" 1>&2
hc_announce "[$(hostname)] ERROR: $*" "red" 1
}
# Log an info message to the console and publish it to Hipchat
function info {
# Set the following to have log statements print contextual information
print "$(script_ctx)[$(hostname)] INFO: $*"
hc_announce "[$(hostname)] INFO: $*" "gray"
}
# Checks if a variable is zero length, if so it prints the supplied error message and bails
function check_config_var {
local conf_var_name="$1"
local conf_error_message="$2"
local conf_bail_message="$3"
if [ -z "${conf_error_message}" ]; then
conf_error_message="The configuration var '${conf_var_name}' is required, please update '${BACKUP_VARS_FILE}'."
fi
if [ -z "${conf_bail_message}" ]; then
conf_bail_message="See bitbucket.diy-backup.vars.sh.example for the defaults and instructions."
fi
check_var "${conf_var_name}" "${conf_error_message}" "${conf_bail_message}"
}
# Similar to check_config_var but does does not print the extra message about consulting the vars file
function check_var {
local set_var_name="$1"
local set_error_message="$2"
local set_bail_message="$3"
if [ -z "${!set_var_name}" ]; then
if [ -z "${set_error_message}" ]; then
set_error_message="Fatal error '${set_var_name}' has not been set"
fi
if [ -z "${set_bail_message}" ]; then
bail "${set_error_message}"
else
error "${set_error_message}"
bail "${set_bail_message}"
fi
fi
}
# Checks that the directory is empty - ignoring dot files and linux's lost+found directory
function ensure_empty_directory {
local dir="$1"
if [ -n "$(ls "${dir}" | grep -v "lost+found")" ]; then
bail "Cannot restore over existing contents of '${dir}'. Please rename/delete the folder or delete its contents."
fi
}
# A function with no side effects. Normally called when a callback does not need to do any work
function no_op {
echo > /dev/null
}
# Log a message to the console without adding standard logging markup
function print {
echo "$@"
}
function script_ctx {
if [ -n "${BASH_VERSION}" ]; then
local depth=0
for func in ${FUNCNAME[@]}; do
case "${func}" in
debug|info|error|bail|check_config_var|check_var|run|script_ctx|print_stack_trace)
depth=$((${depth}+1))
;;
esac
done
echo "[$(basename ${BASH_SOURCE[${depth}]}):${BASH_LINENO[${depth}]} -> ${FUNCNAME[${depth}]}]"
fi
}
function print_stack_trace {
if [ -n "${BASH_VERSION}" ]; then
local idx=0
local depth=" "
echo "Stack trace:" 1>&2
for func in ${FUNCNAME[@]}; do
case "${func}" in
debug|info|error|bail|check_config_var|check_var|run|script_ctx|print_stack_trace)
;;
*)
echo "${depth}[${BASH_SOURCE[${idx}]}:${BASH_LINENO[${idx}]} -> ${FUNCNAME[${idx}]}]" 1>&2
;;
esac
depth="${depth} "
idx=$((${idx}+1))
done
fi
}
# Log then execute the provided command
function run {
if [ "${BITBUCKET_VERBOSE_BACKUP}" = "true" ]; then
local cmdline=
for arg in "$@"; do
case "${arg}" in
*\ * | *\"*)
cmdline="${cmdline} '${arg}'"
;;
*)
cmdline="${cmdline} ${arg}"
;;
esac
done
case "${cmdline}" in
*curl*)
cmdline=$(echo "${cmdline}" | sed -e 's/-u .* /-u ******:****** /g')
;;
*PGPASSWORD=*)
cmdline=$(echo "${cmdline}" | sed -e 's/PGPASSWORD=".*" /PGPASSWORD="**********" /g')
;;
esac
debug "Running${cmdline}" 1>&2
fi
"$@"
}
# Log a success message to the console and publish it to Hipchat
function success {
print "[$(hostname)] SUCC: $*"
hc_announce "[$(hostname)] SUCC: $*" "green"
}
# -------------------------------------------------------------------------------------
# Internal methods
# -------------------------------------------------------------------------------------
# Publish a message to Hipchat using the REST API
#
# $1: string: message
# $2: string: color (yellow/green/red/purple/gray/random)
# $3: integer: notify (0/1)
#
function hc_announce {
if [ -z "${HIPCHAT_ROOM}" ]; then
return 0
fi
if [ -z "${HIPCHAT_TOKEN}" ]; then
return 0
fi
if [ -z "$1" ]; then
print "ERROR: HipChat notification message is missing."
return 1
fi
local hc_color="gray"
if [ -n "$2" ]; then
hc_color=$2
fi
local hc_notify="false"
if [ "1" = "$3" ]; then
hc_notify="true"
fi
local hc_message=$(echo "$1" | sed -e 's|"|\\\"|g')
local hipchat_payload="{\"message\":\"${hc_message}\",\"color\":\"${hc_color}\",\"notify\":\"${hc_notify}\"}"
local hipchat_url="${HIPCHAT_URL}/v2/room/${HIPCHAT_ROOM}/notification?auth_token=${HIPCHAT_TOKEN}"
! curl ${CURL_OPTIONS} -X POST -H "Content-Type: application/json" -d "${hipchat_payload}" "${hipchat_url}"
true
}