-
Notifications
You must be signed in to change notification settings - Fork 0
/
boilerplate.sh
147 lines (125 loc) · 3.81 KB
/
boilerplate.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
#!/bin/bash
#
# Add your copyright here !
#
# Note: requires BASH 4
# set -x
# usefull functions and variables
MYNAME="$(basename $0)"
DEBUG="true" # Set to false when deploying
NOOP="true" # Set to false when deploying
LOGFILE="/var/log/${MYNAME}.log"
function get_help {
cat <<EOF
Usage:
${MYNAME} [OPTIONS]
Options:
--debug <true/false> Run in debug mode and display all commands and outputs. Defaults to no.
--noop <true/false> Run in noop mode and output all commands without running them. Defaults to no.
--logfile <path to log file> Where to log the output. Defaults to /var/log/SCRIPT_NAME.log. Set to /dev/null to disable.
--help This message.
EOF
exit 1
}
function output () {
if [ "$NOOP" == 'true' ]; then
if [ "$DEBUG" == 'true' ]; then
echo "$1" |& tee -a $LOGFILE
else
echo "$1"
fi
else
if [ "$DEBUG" == 'true' ]; then
echo "Command: $1" |& tee -a $LOGFILE
eval "$1" |& tee -a $LOGFILE
else
eval "$1" >> $LOGFILE
fi
fi
}
# Arguments Check
gethelp=false
while [[ $# > 0 ]]
do
key="$1"
shift
case $key in
--noop)
NOOP="$1"
shift
;;
--debug)
DEBUG="$1"
shift
;;
--logfile)
LOGFILE="$1"
shift
;;
--help)
gethelp=true
;;
*)
output "echo \"Unknown option: $key\" >&2"
output "get_help >&2"
exit 1
;;
esac
done
# did we call --help?
$gethelp && output "get_help >&2"
# check for required args. Uncomment if you have required arguments.
# if [ -z ${tmpfolder+x} ] || [ -z ${dbtorestore+x} ]; then
# echo -e '\nERROR: Missing one or more required args'
# get_help
# fi
# Lock to ensure script is run only once at a time
#lock dirs/files
LOCKDIR="/tmp/${MYNAME}"
PIDFILE="${LOCKDIR}/PID"
# exit codes and text
ENO_SUCCESS=0; ETXT[0]="ENO_SUCCESS"
ENO_GENERAL=1; ETXT[1]="ENO_GENERAL"
ENO_LOCKFAIL=2; ETXT[2]="ENO_LOCKFAIL"
ENO_RECVSIG=3; ETXT[3]="ENO_RECVSIG"
###
### start locking attempt
###
trap 'ECODE=$?; echo "[${MYNAME}] Exit: ${ETXT[ECODE]}($ECODE)"' 0
output "echo -n [${MYNAME}] Locking:"
if mkdir "${LOCKDIR}" &>/dev/null; then
# lock succeeded, install signal handlers before storing the PID just in case
# storing the PID fails
trap 'ECODE=$?;
output "echo \"[${MYNAME}] Removing lock: Exit: ${ETXT[ECODE]}($ECODE)\""
rm -rf "${LOCKDIR}"' 0
echo "$$" >"${PIDFILE}"
# the following handler will exit the script upon receiving these signals
# the trap on "0" (EXIT) from above will be triggered by this trap's "exit" command!
trap 'output "echo \"[${MYNAME}] Killed by a signal.\" >&2"
exit ${ENO_RECVSIG}' 1 2 3 15
output "echo success, installed signal handlers"
else
# lock failed, check if the other PID is alive
OTHERPID="$(cat "${PIDFILE}")"
# if cat isn't able to read the file, another instance is probably
# about to remove the lock -- exit, we're *still* locked
# Thanks to Grzegorz Wierzowiecki for pointing out this race condition on
# http://wiki.grzegorz.wierzowiecki.pl/code:mutex-in-bash
if [ $? != 0 ]; then
output "echo \"lock failed, PID ${OTHERPID} is active\" >&2"
exit ${ENO_LOCKFAIL}
fi
if ! kill -0 $OTHERPID &>/dev/null; then
# lock is stale, remove it and restart
output "echo \"removing stale lock of nonexistant PID ${OTHERPID}\" >&2"
rm -rf "${LOCKDIR}"
output "echo \"[${MYNAME}] restarting myself\" >&2"
exec "$0" "$@"
else
# lock is valid and OTHERPID is active - exit, we're locked!
output "echo \"lock failed, PID ${OTHERPID} is active\" >&2"
exit ${ENO_LOCKFAIL}
fi
fi
exit 0