-
Notifications
You must be signed in to change notification settings - Fork 0
/
rollback
112 lines (80 loc) · 1.75 KB
/
rollback
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
#!/bin/bash
set -u
set -e
_ROLLBACKS=()
_doRoll()
{
set +e
local WHAT=("$@")
for ((i=${#WHAT[@]}-1; i >= 0; i--));
do
CMD=${WHAT[i]}
eval "$CMD;"
if [ $? -ne 0 ];
then
>&2 echo "Command failed: $CMD"
>&2 echo "# Rollback commands:"
for ((k=${#_ROLLBACKS[@]}-1; k >= 0; k--));
do
eval 'local R=("${'"${_ROLLBACKS[k]}"'_ROLLBACK[@]-"# none"}")'
>&2 echo "# ${_ROLLBACKS[k]}"
for ((j=${#R[@]}-1; j >= 0; j--));
do
>&2 echo "${R[j]}"
done
done
>&2 echo "# Teardown commands:"
for ((k=${#_ROLLBACKS[@]}-1; k >= 0; k--));
do
eval 'local R=("${'"${_ROLLBACKS[k]}"'_TEARDOWN[@]-"# none"}")'
>&2 echo "# teardown: ${_ROLLBACKS[k]}"
for ((j=${#R[@]}-1; j >= 0; j--));
do
>&2 echo "${R[j]}"
done
done
exit 1
fi
done
}
_saveTeardown()
{
local NAME=$1
local WHERE=$2
shift 2
local WHAT=("$@")
echo "Saving $NAME teardown commands to $WHERE"
cat <<EOF > $WHERE
#!/bin/bash
set -u
set -e
EOF
for ((i=${#WHAT[@]}-1; i >= 0; i--));
do
cat <<< "${WHAT[i]}" >> $WHERE
done
chmod +x $WHERE
}
createRollback()
{
NAME=$1
_ROLLBACKS+=("$NAME")
eval "${NAME}_ROLLBACK=()"
eval "${NAME}_TEARDOWN=()"
eval "${NAME}_STATUS=0"
eval "$2"'() { '"$NAME"'_ROLLBACK+=("$*"); }'
if [ -n "$4" ];
then
eval "$4"'() { '"$NAME"'_TEARDOWN+=("$*"); }'
if [ -n "$5" ];
then
eval "$5"'() { '"$2"' "$*"; '"$4"' "$*"; }'
fi
fi
eval "$NAME"'() { >&2 echo "Encountered an error in '"$NAME"', rolling back"; _doRoll "${'"$NAME"'_ROLLBACK[@]}"; '"$NAME"'_STATUS=1; }'
eval "$3"'() { echo "Finished in '"$NAME"', running teardown"; _doRoll "${'"$NAME"'_TEARDOWN[@]}"; }'
if [ -n "$6" ];
then
eval "$6"'() { _saveTeardown "'"$NAME"'" "$1" "${'"$NAME"'_TEARDOWN[@]}"; }'
fi
}