From 6758f4bd07eb86fd9c32adbe1107cdc1b11919e1 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Sun, 21 May 2023 12:25:28 +0200 Subject: Add top subcommand --- CHANGELOG.md | 3 ++ lib/main.bash | 2 + lib/subcommands/top.bash | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 lib/subcommands/top.bash diff --git a/CHANGELOG.md b/CHANGELOG.md index 976c578..2fa3655 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 which in turn should make re-using playbooks easier. - A convenience function has been introduced, `playbook_path()`, which can give you the absolute path to the playbook's base or data directory. +- A `top` subcommand has been added to give some generic information of all + nodes known to Bashtard. It uses information from the `sysinfo` subcommand, + which it will pull in through an `ssh` invocation. ### Changed diff --git a/lib/main.bash b/lib/main.bash index db5832e..57f1559 100644 --- a/lib/main.bash +++ b/lib/main.bash @@ -86,6 +86,7 @@ Usage: $BASHTARD_NAME ssh $BASHTARD_NAME sync [playbook] $BASHTARD_NAME sysinfo + $BASHTARD_NAME top $BASHTARD_NAME var [-p ] $BASHTARD_NAME var [-s] @@ -102,6 +103,7 @@ Commands: sync Pull latest changes through git, and synchronize all added playbooks. sysinfo Show gathered information about this system. + top Show resource information about all known hosts. var Show or set the value of a given configuration key. EOF diff --git a/lib/subcommands/top.bash b/lib/subcommands/top.bash new file mode 100644 index 0000000..bef8bca --- /dev/null +++ b/lib/subcommands/top.bash @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2023 Patrick Spek +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +subcommand() +{ + local results + local widths + + declare -A results + declare -A widths=( + [node]=0 + [memory]=0 + [load]=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")") + 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_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_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[uptime] < width_uptime )) + then + widths[uptime]=$width_uptime + fi + done + + printstr="%-${widths[node]}s %${widths[load]}s %${widths[memory]}s %${widths[uptime]}s\n" + + # Print results + printf "$printstr" \ + "Node" \ + "Load" \ + "Memory" \ + "Uptime" + + for node in "${!results[@]}" + do + printf "$printstr" \ + "$node" \ + "$(grep '^load' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" \ + "$(grep '^memory' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" \ + "$(grep '^uptime' <<< "${results["$node"]}" | sed 's/[^ ]* *//')" + done +} -- cgit v1.1