diff options
Diffstat (limited to 'lib/subcommands')
-rw-r--r-- | lib/subcommands/backup.bash | 4 | ||||
-rw-r--r-- | lib/subcommands/del.bash | 6 | ||||
-rw-r--r-- | lib/subcommands/pull.bash | 2 | ||||
-rw-r--r-- | lib/subcommands/sysinfo.bash | 69 | ||||
-rw-r--r-- | lib/subcommands/top.bash | 113 | ||||
-rw-r--r-- | lib/subcommands/zap.bash | 37 |
6 files changed, 226 insertions, 5 deletions
diff --git a/lib/subcommands/backup.bash b/lib/subcommands/backup.bash index 8048053..3d56539 100644 --- a/lib/subcommands/backup.bash +++ b/lib/subcommands/backup.bash @@ -72,7 +72,7 @@ backup_filesystem() { "--keep-weekly" "$(config "bashtard.backup.keep.weekly")" "--keep-monthly" "$(config "bashtard.backup.keep.monthly")" "--keep-yearly" "$(config "bashtard.backup.keep.yearly")" - "--prefix" "{fqdn}-" + "--glob-archives" "${BASHTARD_PLATFORM[fqdn]}-" "--remote-path" "$remote" "$repo/hostfs" ) @@ -144,7 +144,7 @@ backup_database_postgresql() { "--keep-weekly" "$(config "bashtard.backup.keep.weekly")" "--keep-monthly" "$(config "bashtard.backup.keep.monthly")" "--keep-yearly" "$(config "bashtard.backup.keep.yearly")" - "--prefix" "$database-" + "--glob-archives" "$database-" "--remote-path" "$remote" "$repo/postgresql-$database" ) diff --git a/lib/subcommands/del.bash b/lib/subcommands/del.bash index 3649e69..293e401 100644 --- a/lib/subcommands/del.bash +++ b/lib/subcommands/del.bash @@ -24,7 +24,7 @@ subcommand() # Make sure we only run add if the playbook is not in the registry yet if ! grep -Fqx "$BASHTARD_PLAYBOOK" "$playbook_registry" then - crit "bashtard/add" "'$BASHTARD_PLAYBOOK' is not registered for ${BASHTARD_PLATFORM[fqdn]}" + crit "bashtard/del" "'$BASHTARD_PLAYBOOK' is not registered for ${BASHTARD_PLATFORM[fqdn]}" return 3 fi @@ -32,13 +32,13 @@ subcommand() if [[ ! -d "$playbook_base" ]] then - emerg "bashtard/sync" "No such directory: $playbook_base" + emerg "bashtard/del" "No such directory: $playbook_base" return 1 fi if [[ ! -f "$playbook_base/playbook.bash" ]] then - emerg "bashtard/sync" "No such file: $playbook_base/playbook.bash" + emerg "bashtard/del" "No such file: $playbook_base/playbook.bash" return 1 fi diff --git a/lib/subcommands/pull.bash b/lib/subcommands/pull.bash index 4f2ae99..8dfb48b 100644 --- a/lib/subcommands/pull.bash +++ b/lib/subcommands/pull.bash @@ -19,4 +19,6 @@ subcommand() git -C "$BASHTARD_ETCDIR" pull origin master || return 4 git -C "$BASHTARD_ETCDIR" submodule update --init --recursive || return 4 [[ -n $dirty ]] && git -C "$BASHTARD_ETCDIR" stash pop + + return 0 } diff --git a/lib/subcommands/sysinfo.bash b/lib/subcommands/sysinfo.bash index 8aa237e..4bceb42 100644 --- a/lib/subcommands/sysinfo.bash +++ b/lib/subcommands/sysinfo.bash @@ -5,12 +5,81 @@ # SPDX-License-Identifier: AGPL-3.0-or-later subcommand() { + local load_1 + local load_5 + local load_15 + local memory_free + local memory_total + local memory_used + local storage_free + local storage_total + local storage_used + local uptime + + # Set the variables which are compatible on every POSIX-compliant system + storage_used="$(df | awk '/[0-9]+/ { sum += $3 } END { print sum }')" + storage_free="$(df | awk '/[0-9]+/ { sum += $4 } END { print sum }')" + storage_total=$(( storage_used + storage_free )) + + # And do platform-specific magic + case "${BASHTARD_PLATFORM[os]}" in + freebsd) + load_1="$(uptime | awk -F' *,? *' '{ print $(NF-2) }')" + load_5="$(uptime | awk -F' *,? *' '{ print $(NF-1) }')" + load_15="$(uptime | awk -F' *,? *' '{ print $NF }')" + memory_total=$(( $(sysctl -n hw.physmem) / 1024 )) + memory_used=$(( ( $(sysctl -n vm.stats.vm.v_active_count) * $(sysctl -n hw.pagesize) ) / 1024 )) + memory_free=$(( memory_total - memory_used)) + uptime=$(( "$(date +%s)" - "$(sysctl -a | awk '/^kern.boottime/ { print substr($5, 0, length($5)-1) }')" )) + ;; + *) + load_1="$(awk '{ print $1 }' < /proc/loadavg)" + load_5="$(awk '{ print $2 }' < /proc/loadavg)" + load_15="$(awk '{ print $3 }' < /proc/loadavg)" + memory_total="$(awk '/MemTotal/ { print $2 }' < /proc/meminfo)" + memory_free="$(awk '/MemAvailable/ { print $2 }' < /proc/meminfo)" + memory_used=$(( memory_total - memory_free )) + uptime="$(awk -F. '{ print $1 }' < /proc/uptime)" + ;; + esac + + # For any value that isn't set, just default to 0 to avoid all sorts of errors + [[ -z "$load_1" ]] && load_1=0 + [[ -z "$load_5" ]] && load_5=0 + [[ -z "$load_15" ]] && load_15=0 + [[ -z "$memory_free" ]] && memory_free=0 + [[ -z "$memory_total" ]] && memory_total=0 + [[ -z "$memory_used" ]] && memory_used=0 + [[ -z "$storage_free" ]] && storage_free=0 + [[ -z "$storage_total" ]] && storage_total=0 + [[ -z "$storage_used" ]] && storage_used=0 + [[ -z "$uptime" ]] && uptime=0 + + # Print the values that can be set by package maintainers printf "%-15s %s\n" "etcdir" "$BASHTARD_ETCDIR" printf "%-15s %s\n" "libdir" "$BASHTARD_LIBDIR" printf "%-15s %s\n" "sharedir" "$BASHTARD_SHAREDIR" + # Print all the discovered platform information for key in "${!BASHTARD_PLATFORM[@]}" do printf "%-15s %s\n" "$key" "${BASHTARD_PLATFORM[$key]}" done + + # Print fun little extras + printf "%-15s %0.1fGi / %0.1fGi\n" "memory" \ + "$(awk '{ print($1 / 1024 / 1024) }' <<< "$memory_used")" \ + "$(awk '{ print($1 / 1024 / 1024) }' <<< "$memory_total")" + printf "%-15s %0.1fGb / %0.1fGb\n" "storage" \ + "$(awk '{ print($1 / 1024 / 1024) }' <<< "$storage_used")" \ + "$(awk '{ print($1 / 1024 / 1024) }' <<< "$storage_total")" + printf "%-15s %0.2f %0.2f %0.2f\n" "load" \ + "$load_1" \ + "$load_5" \ + "$load_15" + printf "%-15s %dd %02dh %02dm %02ds\n" "uptime" \ + "$(( uptime / 60 / 60 / 24 ))" \ + "$(( uptime / 60 / 60 % 24 ))" \ + "$(( uptime / 60 % 60 ))" \ + "$(( uptime % 60 ))" } diff --git a/lib/subcommands/top.bash b/lib/subcommands/top.bash new file mode 100644 index 0000000..d4a9b3f --- /dev/null +++ b/lib/subcommands/top.bash @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 Patrick Spek <p.spek@tyil.nl> +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +subcommand() +{ + local results + local widths + + declare -A results + declare -A widths=( + [load]=0 + [memory]=0 + [node]=0 + [storage]=0 + [uptime]=0 + ) + + if [[ ! -d "$BASHTARD_ETCDIR/hosts.d" ]] + then + crit "$BASHTARD_NAME/ssh" "Could not find hosts file at $BASHTARD_ETCDIR/hosts.d" + return 3 + fi + + chgdir "$BASHTARD_ETCDIR/hosts.d" + + for node in * + do + local user + local host + + user="$(config_for "$node" "bashtard.ssh.user" "$USER")" + host="$(config_for "$node" "bashtard.ssh.host")" + + if [[ -z "$host" ]] + then + crit "$BASHTARD_NAME/ssh" "bashtard.ssh.host is not configured for $node" + continue + fi + + if [[ "$node" == "${BASHTARD_PLATFORM[fqdn]}" ]] + then + results+=(["$node"]="$("$BASHTARD_BIN" sysinfo)") + else + debug "$BASHTARD_NAME/ssh" "$user@$node ($host) > bashtard sysinfo" + # shellcheck disable=SC2029 + results+=(["$node"]="$(ssh "$user@$host" "bashtard sysinfo" 2>/dev/null)") + fi + + unset user + unset host + done + + # Check widths + for node in "${!results[@]}" + do + node_load="$(grep '^load' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + node_memory="$(grep '^memory' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + node_storage="$(grep '^storage' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + node_uptime="$(grep '^uptime' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + + width_load="$(wc -c <<< "$node_load")" + width_memory="$(wc -c <<< "$node_memory")" + width_node="$(wc -c <<< "$node")" + width_storage="$(wc -c <<< "$node_storage")" + width_uptime="$(wc -c <<< "$node_uptime")" + + if (( widths[load] < width_load )) + then + widths[load]=$width_load + fi + + if (( widths[memory] < width_memory )) + then + widths[memory]=$width_memory + fi + + if (( widths[node] < width_node )) + then + widths[node]=$width_node + fi + + if (( widths[storage] < width_storage )) + then + widths[storage]=$width_storage + fi + + if (( widths[uptime] < width_uptime )) + then + widths[uptime]=$width_uptime + fi + done + + # Print results + printf "$(tput bold)%-${widths[node]}s %-${widths[load]}s %-${widths[memory]}s %-${widths[storage]}s %-${widths[uptime]}s$(tput sgr0)\n" \ + "Node" \ + "Load" \ + "Memory" \ + "Storage" \ + "Uptime" + + for node in "${!results[@]}" + do + printf "%-${widths[node]}s %${widths[load]}s %${widths[memory]}s %${widths[storage]}s %${widths[uptime]}s\n" \ + "$node" \ + "$(grep '^load' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" \ + "$(grep '^memory' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" \ + "$(grep '^storage' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" \ + "$(grep '^uptime' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + done | sort +} diff --git a/lib/subcommands/zap.bash b/lib/subcommands/zap.bash new file mode 100644 index 0000000..dcefffd --- /dev/null +++ b/lib/subcommands/zap.bash @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 Patrick Spek <p.spek@tyil.nl> +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +subcommand() +{ + local buffer + local playbook_registry + + export BASHTARD_PLAYBOOK="$1" ; shift + + if [[ -z "$BASHTARD_PLAYBOOK" ]] + then + crit "bashtard/zap" "No playbook name specified" + return + fi + + playbook_registry="$BASHTARD_ETCDIR/registry.d/${BASHTARD_PLATFORM[fqdn]}" + + # Make sure we only run add if the playbook is not in the registry yet + if ! grep -Fqx "$BASHTARD_PLAYBOOK" "$playbook_registry" + then + crit "bashtard/zap" "'$BASHTARD_PLAYBOOK' is not registered for ${BASHTARD_PLATFORM[fqdn]}" + return 3 + fi + + notice "bashtard/zap" "Removing playbook '$BASHTARD_PLAYBOOK' from '${BASHTARD_PLATFORM[fqdn]}'" + + buffer="$(tmpfile)" + + # Remove the playbook from the registry + cp -- "$playbook_registry" "$buffer" + grep -Fvx "$BASHTARD_PLAYBOOK" "$buffer" \ + | sort > "$playbook_registry" +} |