-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpatch
executable file
·153 lines (138 loc) · 5.46 KB
/
patch
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
#!/usr/bin/env bash
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PREFIX=${PATCH_PREFIX-PIHERO_}
declare params_disabled=(PREFIX="$PREFIX")
# Sets variable with name $1 to the value of variable $PREFIX_$1 if it exists.
# If it doesn't, uses $2 as the default value or exits with an error message.
# Side effect: adds $PREFIX_$1=$value to the params_* arrays
p() {
local var=${1?var missing} && shift
local default=$1
local prefixed=$PREFIX$var
local resolved=${!prefixed}
if [ "$resolved" ]; then
printf -v "$var" '%s' "$resolved"
elif [ "$default" ]; then
printf -v "$var" '%s' "$default"
else
printf '\e[31mThe required parameter \e[3m%s\e[23m is missing.\e[0m\n' "$prefixed" >&2
printf 'Either use \e[3m%s\e[23m or run \e[3m%s\e[23m to provide it.\n' "export $prefixed=..." "$prefixed=... ${0##*/}"
exit 1
fi
local val=${!prefixed:-$default}
printf -v "$var" '%s' "$val"
if [ "$val" = 1 ]; then
params_disabled+=("$prefixed=0")
else
params_disabled+=("$prefixed=$val")
fi
}
# Ansible ad-hoc command wrapper which runs:
# ansible $HOST -v --become -m $1 -a "$2 $3 $4 ..."
m() {
local module=${1?module missing} && shift
local args="$*"
local host
# shellcheck disable=SC2153
for host in $HOST; do
ansible "$host" -v --become -m "$module" -a "$args"
done
}
# rsync command wrapper which runs:
# rsync --recursive --compress --delete --rsh='ssh -o ConnectTimeout=120' --rsync-path='sudo rsync' "${@:1:$#-1}" "$HOST:${*: -1}"
r() {
[ $# -ge 2 ] || {
printf '\e[31mAt least two parameters—the files to copy, and the destination—are required\n'
exit 1
}
local src=("${@:1:$#-1}")
local host
for host in $HOST; do
local dst="$host:${*: -1}"
printf "Copying \e[3m%s\e[23m to \e[3m%s\e[23m... " "${src[*]}" "$dst"
rsync --recursive --compress --delete --rsh='ssh -o ConnectTimeout=10' --rsync-path='sudo rsync' "${src[@]}" "$dst" || {
printf '\e[31Failed to copy \e[3m%s\e[23m to \e[3m%s\e[23m\n' "${src[*]}" "$dst"
exit 1
}
printf '\e[32;1m✔\e[0m\n'
done
}
# ssh command wrapper which runs:
# ssh -t $HOST "$@"
s() {
local host
# shellcheck disable=SC2153
for host in $HOST; do
ssh -t "$host" "$@"
done
}
# Runs this patch command with the same parameters as the current execution,
# but:
# - if parameter is 1, sets it to 0
# - given parameters, for example, CLI=1, overrides the corresponding parameter
continuous() {
local env_args=("${params_disabled[@]}") paths=()
while [ $# -gt 0 ]; do
case $1 in
*=*) env_args+=("${PREFIX}$1") && shift ;;
*) break ;;
esac
done
env_args+=("${PREFIX}CONTINUOUS=0")
paths=("$@")
local fswatch_args=(
--recursive # watch subdirectories
--exclude '~$' # ignore ~ suffix temp files
"${paths[@]}" # paths to watch
)
printf '\e[2mWatching \e[3m%s\e[22;23m\n' "${paths[*]}"
fswatch --print0 "${fswatch_args[@]}" | xargs -0 -n 1 -I {} env "${env_args[@]}" "$0"
}
deploy_cli() {
r "$CLI_FILES/bin/" /opt/pihero/bin/
r "$CLI_FILES/lib/" /opt/pihero/lib/
r "$CLI_FILES/"*.bash /opt/pihero
}
deploy_splash() {
r "$SPLASH_FILES/"*.bash /opt/pihero
r "$SPLASH_FILES/themes/"* /usr/share/plymouth/themes
}
deploy_hdmi() {
r "$HDMI_FILES/"*.bash /opt/pihero
}
main() {
# set params
p CONTINUOUS 0 # Whether to run the patch operations whenever a relevant file changes
p HOST # The host to patch
p CLI 1 # Whether to update the pihero CLI component
p CLI_FILES "$SCRIPT_DIR/roles/pihero/files" # The directory containing the pihero CLI component files
p SPLASH 1 # Whether to update the pihero splash component
p SPLASH_FILES "$SCRIPT_DIR/roles/splash/files" # The directory containing the splash component files
p HDMI 1 # Whether to update the HDMI component
p HDMI_FILES "$SCRIPT_DIR/roles/hdmi/files" # The directory containing the HDMI component files
if [ "$CLI" = 0 ] && [ "$SPLASH" = 0 ] && [ "$HDMI" = 0 ]; then
local params
printf -v params '\e[3m%s\e[23m ' "${PREFIX}HOST=foo.local" "$PREFIX...=..."
printf '\e[1mUsage: %s %s\e[0m\n' "$params" "${0##*/}"
printf ' Hints: Add -t / --continuous to run the corresponding patch operations whenever a relevant file changes.\n'
printf ' Type export %sto set a different host and the appropriate option or options for the remainder of your shell session.\n' "$params"
printf ' Check the source code for more options.\n'
exit 2
fi
if [ "$CONTINUOUS" = 0 ]; then
[ "$CLI" = 0 ] || deploy_cli
[ "$SPLASH" = 0 ] || deploy_splash
[ "$HDMI" = 0 ] || deploy_hdmi
else
command -v fswatch >/dev/null 2>&1 || HOMEBREW_NO_ENV_HINTS=TRUE brew install fswatch
trap "trap - SIGTERM && kill -- -"$$ SIGINT SIGTERM EXIT
printf 'Watching for changes... '
printf '\e[2m%s\e[22m' 'Press Ctrl+C to stop'
printf '\n'
[ "$CLI" = 0 ] || continuous CLI=1 "$CLI_FILES" &
[ "$SPLASH" = 0 ] || continuous SPLASH=1 "$SPLASH_FILES" &
[ "$HDMI" = 0 ] || continuous HDMI=1 "$HDMI_FILES" &
wait
fi
}
main "$@"