blob: 227512ac945361ab7568889641248fa57dc8e02d (
plain)
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
|
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2022 Patrick Spek <p.spek@tyil.nl>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# shellcheck source=lib/util.bash
source "$(dirname "${BASH_SOURCE[0]}")/util.bash"
# shellcheck source=lib/logging.bash
source "$(dirname "${BASH_SOURCE[0]}")/logging.bash"
main() {
debug "$BASHTARD_NAME/main" "Running from $BASHTARD_LIBDIR"
debug "$BASHTARD_NAME/main" "Configuration dir is at $BASHTARD_ETCDIR"
debug "$BASHTARD_NAME/main" "> $0 $*"
[[ -z $1 ]] && usage && exit 2
export BASHTARD_COMMAND="$1" ; shift
debug "$BASHTARD_NAME/main" "Handling subcommand '$BASHTARD_COMMAND'"
subcommand_src="$BASHTARD_LIBDIR/subcommands/$BASHTARD_COMMAND.bash"
debug "$BASHTARD_NAME/main" "Checking $subcommand_src"
if [[ ! -f $subcommand_src ]]
then
debug "$BASHTARD_NAME/main" "No script found to handle action, showing usage"
usage
exit 2
fi
# Declare some global variables
declare -A BASHTARD_PLATFORM
# Figure out system details
debug "$BASHTARD_NAME/main" "Discovering system information"
discover_system
# Export BASHTARD_ variables
export BASHTARD_PLATFORM
# Source the file defining the subcommand.
debug "$BASHTARD_NAME/main" "Sourcing $subcommand_src"
source "$subcommand_src"
# Maintain our own tempdir
export TMPDIR="$BASEDIR/tmp/$RANDOM"
mkdir -p -- "$TMPDIR"
debug "$BASHTARD_NAME/main" "\$TMPDIR set to $TMPDIR"
# Actually perform the subcommand
debug "$BASHTARD_NAME/main" "Running subcommand '$BASHTARD_COMMAND'"
subcommand "$@"
local subcommand_exit=$?
# Clean up if necessary
if [[ -z $BASHTARD_MESSY ]]
then
debug "$BASHTARD_NAME/main" "Cleaning up tempfiles at $TMPDIR"
rm -rf -- "$TMPDIR"
fi
## Use the subcommand's exit code
exit $subcommand_exit
}
usage() {
local playbooks
local playbook_length
local playbook_longest=0
cat <<EOF
Usage:
$BASHTARD_NAME -h
$BASHTARD_NAME add <playbook>
$BASHTARD_NAME bootstrap
$BASHTARD_NAME del <playbook>
$BASHTARD_NAME ssh <command>
$BASHTARD_NAME sync [playbook]
$BASHTARD_NAME sysinfo
Perform maintenance on your infra.
Commands:
add Add a configuration playbook to this machine.
bootstrap Bootstrap the $BASHTARD_NAME configuration system.
del Remove a configuration playbook from this machine.
ssh Run a given command on all known hosts.
sync Pull latest changes through git, and synchronize all added
playbooks.
sysinfo Show gathered information about this system.
Playbooks:
EOF
# Find all playbooks
mapfile -t playbooks < <(find \
"$BASHTARD_ETCDIR/playbooks.d"/* \
-maxdepth 0 \
-type d \
)
# Find longest playbook name
for playbook in "${playbooks[@]}"
do
playbook_length="$(printf "%s" "$(basename "$playbook")" | wc -c)"
if (( playbook_longest < playbook_length ))
then
playbook_longest=$playbook_length
fi
done
# Render playbook descriptions
for playbook in "${playbooks[@]}"
do
printf "\t%-${playbook_longest}s %s\n" \
"$(basename "$playbook")" \
"$(cat "$playbook/description.txt")"
done
}
# Discover information about the system. If any bugs are reported and you want
# more information about the system the user is running on, additional checks
# can be added here, and the user will simply have to include the output of the
# sysinfo command in their message to you.
discover_system() {
BASHTARD_PLATFORM["os"]="$(discover_system_os)"
BASHTARD_PLATFORM["arch"]="$(discover_system_arch)"
BASHTARD_PLATFORM["version"]="$(discover_system_version)"
BASHTARD_PLATFORM["term"]="$TERM"
BASHTARD_PLATFORM["fqdn"]="$(hostname -f)"
# When on a Linux-using OS, check for the specific distribution in use.
if [[ ${BASHTARD_PLATFORM[os]} == *"linux"* ]]
then
BASHTARD_PLATFORM["distro"]="$(discover_system_distro)"
fi
BASHTARD_PLATFORM[key]="$(discover_system_key)"
}
discover_system_arch() {
uname -m
}
discover_system_distro() {
if [[ -f /etc/os-release ]]
then
(
source /etc/os-release
printf "%s" "$NAME" \
| awk '{print tolower($0)}' \
| sed 's@[/+ ]@_@g'
)
return
fi
crit "No /etc/os-release found. Are you sure you're on a sane GNU+Linux distribution?"
if command -v pacman > /dev/null
then
warn "$BASHTARD_NAME/main" "Found pacman, assuming Archlinux as distro."
printf "%s" "archlinux"
return
fi
}
discover_system_version() {
printf "%s" "$(uname -r | awk '{print tolower($0)}')"
}
discover_system_key() {
key+="${BASHTARD_PLATFORM[os]}"
if [[ ${BASHTARD_PLATFORM[distro]} ]]
then
key+="-${BASHTARD_PLATFORM[distro]}"
fi
printf "%s" "$key"
}
discover_system_os() {
if command -v uname > /dev/null
then
printf "%s" "$(uname -s | awk '{print tolower($0)}' | sed 's@[/+ ]@_@g')"
return
fi
}
main "$@"
|