#!/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
$BASHTARD_NAME var [-p ]
$BASHTARD_NAME var [-s]
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.
var Show or set the value of a given configuration key.
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 "$@"