#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2022 Patrick Spek
#
# 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 <
$BASHTARD_NAME del
$BASHTARD_NAME init [repository]
$BASHTARD_NAME ssh
$BASHTARD_NAME sync [playbook]
$BASHTARD_NAME sysinfo
Perform maintenance on your infra.
Commands:
add Add a configuration playbook to this machine.
init Initialize 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() {
local 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 "$@"