this derivation will be built: /nix/store/cqacgripk9fihi6lq6ag17x9yqjhp2cn-treefmt-check.drv building '/nix/store/cqacgripk9fihi6lq6ag17x9yqjhp2cn-treefmt-check.drv' treefmt-check> treefmt v2.5.0traversed 396 files treefmt-check> emitted 361 files for processing treefmt-check> formatted 361 files (11 changed) in 878ms treefmt-check> M docs/gen-ssh-config.sh treefmt-check> M docs/generate-host-info.sh treefmt-check> M docs/generate-lldp-graph.sh treefmt-check> M docs/get-lldp-neighbors.sh treefmt-check> M docs/hosts/README.md treefmt-check> M docs/hosts/eta.md treefmt-check> M docs/hosts/psi.md treefmt-check> M docs/hosts/rho.md treefmt-check> M docs/hosts/tau.md treefmt-check> M tasks.py treefmt-check> M tests/test_generate_network_topology.py treefmt-check> diff --git a/docs/gen-ssh-config.sh b/docs/gen-ssh-config.sh treefmt-check> index 7d7300d..575c5a6 100755 treefmt-check> --- a/docs/gen-ssh-config.sh treefmt-check> +++ b/docs/gen-ssh-config.sh treefmt-check> @@ -3,10 +3,10 @@ set -euo pipefail treefmt-check> treefmt-check> user=${1:-} treefmt-check> treefmt-check> -if [[ -z "$user" ]]; then treefmt-check> - echo "Missing username" treefmt-check> - echo "Usage: $(basename "$0") username" treefmt-check> - exit 1 treefmt-check> +if [[ -z $user ]]; then treefmt-check> + echo "Missing username" treefmt-check> + echo "Usage: $(basename "$0") username" treefmt-check> + exit 1 treefmt-check> fi treefmt-check> treefmt-check> # GitHub directory pages change independently of this script; use the stable API. treefmt-check> @@ -28,20 +28,20 @@ Host eta treefmt-check> EOF treefmt-check> treefmt-check> curl -fsSL \ treefmt-check> - -H 'Accept: application/vnd.github+json' \ treefmt-check> - -H 'X-GitHub-Api-Version: 2022-11-28' \ treefmt-check> - 'https://api.github.com/repos/SBEE-Lab/infra/contents/hosts?ref=main' \ treefmt-check> - > "$tempfile" treefmt-check> -machines=$(grep -oE '"name"[[:space:]]*:[[:space:]]*"[^"]+\.nix"' "$tempfile" \ treefmt-check> - | sed -E 's/.*"([^"]+)\.nix"/\1/' \ treefmt-check> - | sort -u) treefmt-check> + -H 'Accept: application/vnd.github+json' \ treefmt-check> + -H 'X-GitHub-Api-Version: 2022-11-28' \ treefmt-check> + 'https://api.github.com/repos/SBEE-Lab/infra/contents/hosts?ref=main' \ treefmt-check> + >"$tempfile" treefmt-check> +machines=$(grep -oE '"name"[[:space:]]*:[[:space:]]*"[^"]+\.nix"' "$tempfile" | treefmt-check> + sed -E 's/.*"([^"]+)\.nix"/\1/' | treefmt-check> + sort -u) treefmt-check> treefmt-check> while read -r machine; do treefmt-check> - if [[ -z "$machine" || "$machine" == "eta" ]]; then treefmt-check> - continue treefmt-check> - fi treefmt-check> + if [[ -z $machine || $machine == "eta" ]]; then treefmt-check> + continue treefmt-check> + fi treefmt-check> treefmt-check> - cat < + cat < Host $machine treefmt-check> HostName $machine.sjanglab.org treefmt-check> User $user treefmt-check> @@ -50,4 +50,4 @@ Host $machine treefmt-check> ProxyJump eta treefmt-check> treefmt-check> EOF treefmt-check> -done <<< "$machines" treefmt-check> +done <<<"$machines" treefmt-check> diff --git a/docs/generate-host-info.sh b/docs/generate-host-info.sh treefmt-check> index c213cd5..3e61dcd 100755 treefmt-check> --- a/docs/generate-host-info.sh treefmt-check> +++ b/docs/generate-host-info.sh treefmt-check> @@ -1,9 +1,9 @@ treefmt-check> #!/usr/bin/env bash treefmt-check> set -euo pipefail treefmt-check> treefmt-check> -if [[ -z "${1:-}" ]]; then treefmt-check> - echo "Usage: $(basename "$0") host" >&2 treefmt-check> - exit 1 treefmt-check> +if [[ -z ${1:-} ]]; then treefmt-check> + echo "Usage: $(basename "$0") host" >&2 treefmt-check> + exit 1 treefmt-check> fi treefmt-check> treefmt-check> target=$1 treefmt-check> @@ -13,15 +13,15 @@ lstopo="$hostname.lstopo.svg" treefmt-check> printf '# %s treefmt-check> treefmt-check> ``` treefmt-check> -' "$hostname" > "$report" treefmt-check> -ssh "$target" -- "nix-shell -p 'inxi.override { withRecommends = true; }' --run 'sudo inxi -F -a -i --slots -xxx -c0 -z -m'" >> "$report" treefmt-check> +' "$hostname" >"$report" treefmt-check> +ssh "$target" -- "nix-shell -p 'inxi.override { withRecommends = true; }' --run 'sudo inxi -F -a -i --slots -xxx -c0 -z -m'" >>"$report" treefmt-check> tempfile=$(mktemp -t sbee-host-info.XXXXXX) treefmt-check> -sed -E 's/(uuid: )[^ ]+/\1/g' "$report" > "$tempfile" treefmt-check> +sed -E 's/(uuid: )[^ ]+/\1/g' "$report" >"$tempfile" treefmt-check> mv "$tempfile" "$report" treefmt-check> ssh "$target" -- "nix-shell -p hwloc -p dmidecode --run 'sudo lstopo /tmp/$hostname.lstopo.svg'" treefmt-check> scp "$target:/tmp/$hostname.lstopo.svg" "$lstopo" treefmt-check> ssh "$target" -- "sudo rm /tmp/$hostname.lstopo.svg" treefmt-check> printf '``` treefmt-check> ![hardware topology](%s) treefmt-check> -' "$lstopo" >> "$report" treefmt-check> +' "$lstopo" >>"$report" treefmt-check> echo "wrote $report" >&2 treefmt-check> diff --git a/docs/generate-lldp-graph.sh b/docs/generate-lldp-graph.sh treefmt-check> index facbd2f..7fbaa06 100755 treefmt-check> --- a/docs/generate-lldp-graph.sh treefmt-check> +++ b/docs/generate-lldp-graph.sh treefmt-check> @@ -1,9 +1,9 @@ treefmt-check> #!/usr/bin/env bash treefmt-check> set -euo pipefail treefmt-check> treefmt-check> -if (( BASH_VERSINFO[0] < 4 )); then treefmt-check> - echo "$(basename "$0") requires Bash 4 or newer" >&2 treefmt-check> - exit 1 treefmt-check> +if ((BASH_VERSINFO[0] < 4)); then treefmt-check> + echo "$(basename "$0") requires Bash 4 or newer" >&2 treefmt-check> + exit 1 treefmt-check> fi treefmt-check> treefmt-check> report="../graph.md" treefmt-check> @@ -11,60 +11,60 @@ url="https://github.com/SBEE-Lab/infra/blob/main/docs/hosts" treefmt-check> declare -A interfaces treefmt-check> treefmt-check> { treefmt-check> - echo '```mermaid' treefmt-check> - echo ' graph TD' treefmt-check> + echo '```mermaid' treefmt-check> + echo ' graph TD' treefmt-check> treefmt-check> - for host_file in *; do treefmt-check> - [[ -f "$host_file" ]] || continue treefmt-check> - while read -r neighbor; do treefmt-check> - [[ -z "$neighbor" ]] && continue treefmt-check> - host_interface=$(echo "$neighbor" | cut -d' ' -f1) treefmt-check> - link_speed=$(echo "$neighbor" | cut -d' ' -f2) treefmt-check> - neighbor_interface=$(echo "$neighbor" | cut -d' ' -f3 | tr -cd '[:alnum:]._-') treefmt-check> - neighbor_name=$(echo "$neighbor" | cut -d' ' -f4 | tr -cd '[:alnum:]._-') treefmt-check> + for host_file in *; do treefmt-check> + [[ -f $host_file ]] || continue treefmt-check> + while read -r neighbor; do treefmt-check> + [[ -z $neighbor ]] && continue treefmt-check> + host_interface=$(echo "$neighbor" | cut -d' ' -f1) treefmt-check> + link_speed=$(echo "$neighbor" | cut -d' ' -f2) treefmt-check> + neighbor_interface=$(echo "$neighbor" | cut -d' ' -f3 | tr -cd '[:alnum:]._-') treefmt-check> + neighbor_name=$(echo "$neighbor" | cut -d' ' -f4 | tr -cd '[:alnum:]._-') treefmt-check> treefmt-check> - interfaces[$host_file]+=" $host_interface" treefmt-check> - interfaces[$neighbor_name]+=" $neighbor_interface" treefmt-check> + interfaces[$host_file]+=" $host_interface" treefmt-check> + interfaces[$neighbor_name]+=" $neighbor_interface" treefmt-check> treefmt-check> - echo " ${host_file}.${host_interface}[\"$host_interface\"]-- $link_speed ---${neighbor_name}.${neighbor_interface}[\"$neighbor_interface\"]" treefmt-check> - done < "$host_file" treefmt-check> - done treefmt-check> + echo " ${host_file}.${host_interface}[\"$host_interface\"]-- $link_speed ---${neighbor_name}.${neighbor_interface}[\"$neighbor_interface\"]" treefmt-check> + done <"$host_file" treefmt-check> + done treefmt-check> treefmt-check> - for host in "${!interfaces[@]}"; do treefmt-check> - interfaces[$host]=$(xargs -n 1 <<< "${interfaces[$host]}" | sort -u | xargs) treefmt-check> - echo " subgraph $host" treefmt-check> - for interface in ${interfaces[$host]}; do treefmt-check> - echo " ${host}.${interface}[\"$interface\"]" treefmt-check> - done treefmt-check> - echo " end" treefmt-check> + for host in "${!interfaces[@]}"; do treefmt-check> + interfaces[$host]=$(xargs -n 1 <<<"${interfaces[$host]}" | sort -u | xargs) treefmt-check> + echo " subgraph $host" treefmt-check> + for interface in ${interfaces[$host]}; do treefmt-check> + echo " ${host}.${interface}[\"$interface\"]" treefmt-check> done treefmt-check> + echo " end" treefmt-check> + done treefmt-check> treefmt-check> - for host in "${!interfaces[@]}"; do treefmt-check> - [[ -f "../$host.md" ]] || continue treefmt-check> - for interface in ${interfaces[$host]}; do treefmt-check> - echo " click ${host}.${interface} \"$url/$host.md\" \"$host\"" treefmt-check> - done treefmt-check> + for host in "${!interfaces[@]}"; do treefmt-check> + [[ -f "../$host.md" ]] || continue treefmt-check> + for interface in ${interfaces[$host]}; do treefmt-check> + echo " click ${host}.${interface} \"$url/$host.md\" \"$host\"" treefmt-check> done treefmt-check> + done treefmt-check> treefmt-check> - echo '```' treefmt-check> -} > "$report" treefmt-check> + echo '```' treefmt-check> +} >"$report" treefmt-check> treefmt-check> # Remove inverse duplicate links. treefmt-check> while true; do treefmt-check> - duplicate="" treefmt-check> - while read -r link; do treefmt-check> - interface_1=$(awk '{print $1}' <<< "$link" | rev | cut -c 3- | rev) treefmt-check> - link_speed=$(awk '{print $2}' <<< "$link") treefmt-check> - interface_2=$(awk '{print $3}' <<< "$link" | cut -c 4-) treefmt-check> - candidate="$interface_2-- $link_speed ---$interface_1" treefmt-check> - if grep -q -F "$candidate" "$report"; then treefmt-check> - duplicate=$candidate treefmt-check> - break treefmt-check> - fi treefmt-check> - done < <(grep -E -- '-- [[:digit:]]+[GM] ---' "$report") treefmt-check> + duplicate="" treefmt-check> + while read -r link; do treefmt-check> + interface_1=$(awk '{print $1}' <<<"$link" | rev | cut -c 3- | rev) treefmt-check> + link_speed=$(awk '{print $2}' <<<"$link") treefmt-check> + interface_2=$(awk '{print $3}' <<<"$link" | cut -c 4-) treefmt-check> + candidate="$interface_2-- $link_speed ---$interface_1" treefmt-check> + if grep -q -F "$candidate" "$report"; then treefmt-check> + duplicate=$candidate treefmt-check> + break treefmt-check> + fi treefmt-check> + done < <(grep -E -- '-- [[:digit:]]+[GM] ---' "$report") treefmt-check> treefmt-check> - [[ -n "$duplicate" ]] || break treefmt-check> - tempfile=$(mktemp -t sbee-lldp-graph.XXXXXX) treefmt-check> - awk -v pattern="$duplicate" 'index($0, pattern) == 0' "$report" > "$tempfile" treefmt-check> - mv "$tempfile" "$report" treefmt-check> + [[ -n $duplicate ]] || break treefmt-check> + tempfile=$(mktemp -t sbee-lldp-graph.XXXXXX) treefmt-check> + awk -v pattern="$duplicate" 'index($0, pattern) == 0' "$report" >"$tempfile" treefmt-check> + mv "$tempfile" "$report" treefmt-check> done treefmt-check> diff --git a/docs/get-lldp-neighbors.sh b/docs/get-lldp-neighbors.sh treefmt-check> index 01f8d12..1396412 100755 treefmt-check> --- a/docs/get-lldp-neighbors.sh treefmt-check> +++ b/docs/get-lldp-neighbors.sh treefmt-check> @@ -1,9 +1,9 @@ treefmt-check> #!/usr/bin/env bash treefmt-check> set -euo pipefail treefmt-check> treefmt-check> -if [[ -z "${1:-}" ]]; then treefmt-check> - echo "Usage: $(basename "$0") host" >&2 treefmt-check> - exit 1 treefmt-check> +if [[ -z ${1:-} ]]; then treefmt-check> + echo "Usage: $(basename "$0") host" >&2 treefmt-check> + exit 1 treefmt-check> fi treefmt-check> treefmt-check> target=$1 treefmt-check> @@ -12,17 +12,17 @@ report="$hostname" treefmt-check> lldp=$(ssh "$target" -- networkctl lldp --json=short) treefmt-check> treefmt-check> while IFS=$' ' read -r interface neighbor_interface neighbor_name; do treefmt-check> - [[ -z "$interface" ]] && continue treefmt-check> - link_speed=$(ssh "$target" -- cat "/sys/class/net/$interface/speed" < /dev/null) treefmt-check> + [[ -z $interface ]] && continue treefmt-check> + link_speed=$(ssh "$target" -- cat "/sys/class/net/$interface/speed" treefmt-check> - if (( link_speed >= 1000 )); then treefmt-check> - speed="$((link_speed / 1000))G" treefmt-check> - else treefmt-check> - speed="${link_speed}M" treefmt-check> - fi treefmt-check> - echo "$interface $speed $neighbor_interface $neighbor_name" treefmt-check> + if ((link_speed >= 1000)); then treefmt-check> + speed="$((link_speed / 1000))G" treefmt-check> + else treefmt-check> + speed="${link_speed}M" treefmt-check> + fi treefmt-check> + echo "$interface $speed $neighbor_interface $neighbor_name" treefmt-check> done < <( treefmt-check> - python3 -c ' treefmt-check> + python3 -c ' treefmt-check> import json treefmt-check> import sys treefmt-check> treefmt-check> @@ -37,7 +37,7 @@ for interface in data.get("Neighbors", []): treefmt-check> ) treefmt-check> remote_name = neighbor.get("SystemName") or neighbor.get("ChassisID") treefmt-check> print(name, remote_interface, remote_name, sep="\t") treefmt-check> -' <<< "$lldp" treefmt-check> -) > "$report" treefmt-check> +' <<<"$lldp" treefmt-check> +) >"$report" treefmt-check> treefmt-check> echo "wrote $report" >&2 treefmt-check> diff --git a/docs/hosts/README.md b/docs/hosts/README.md treefmt-check> index 388bc1b..2d07aaf 100644 treefmt-check> --- a/docs/hosts/README.md treefmt-check> +++ b/docs/hosts/README.md treefmt-check> @@ -10,7 +10,7 @@ treefmt-check> treefmt-check> ## 하드웨어 보고서 treefmt-check> treefmt-check> -저장소 devShell에서 전체 inventory를 갱신합니다. 대상은 [공용 SSH 설정](../dev/ssh-access.md#공용-ssh-설정)에 등록되어 있어야 하며 원격 `sudo` 권한이 필요합니다. treefmt-check> +저장소 devShell에서 전체 inventory를 갱신합니다. 대상은 [공용 SSH 설정](../dev/ssh-access.md#%EA%B3%B5%EC%9A%A9-ssh-%EC%84%A4%EC%A0%95)에 등록되어 있어야 하며 원격 `sudo` 권한이 필요합니다. treefmt-check> treefmt-check> ```bash treefmt-check> nix develop treefmt-check> diff --git a/docs/hosts/eta.md b/docs/hosts/eta.md treefmt-check> index ee45ad6..94c55e3 100644 treefmt-check> --- a/docs/hosts/eta.md treefmt-check> +++ b/docs/hosts/eta.md treefmt-check> @@ -98,4 +98,5 @@ Info: treefmt-check> Packages: pm: nix-default pkgs: 0 pm: nix-sys pkgs: 588 libs: 58 pm: nix-usr pkgs: 0 Compilers: treefmt-check> gcc: 15.3.0 Client: Sudo v: 1.9.17p2 inxi: 3.3.41 treefmt-check> ``` treefmt-check> + treefmt-check> ![hardware topology](eta.lstopo.svg) treefmt-check> diff --git a/docs/hosts/psi.md b/docs/hosts/psi.md treefmt-check> index 8756e00..945eec5 100644 treefmt-check> --- a/docs/hosts/psi.md treefmt-check> +++ b/docs/hosts/psi.md treefmt-check> @@ -187,4 +187,5 @@ Info: treefmt-check> Packages: pm: nix-default pkgs: 0 pm: nix-sys pkgs: 557 libs: 86 pm: nix-usr pkgs: 0 Compilers: treefmt-check> gcc: 15.3.0 Client: Sudo v: 1.9.17p2 inxi: 3.3.41 treefmt-check> ``` treefmt-check> + treefmt-check> ![hardware topology](psi.lstopo.svg) treefmt-check> diff --git a/docs/hosts/rho.md b/docs/hosts/rho.md treefmt-check> index 9bb6663..2f011ab 100644 treefmt-check> --- a/docs/hosts/rho.md treefmt-check> +++ b/docs/hosts/rho.md treefmt-check> @@ -130,4 +130,5 @@ Info: treefmt-check> Packages: pm: nix-default pkgs: 0 pm: nix-sys pkgs: 438 libs: 54 pm: nix-usr pkgs: 0 Compilers: treefmt-check> gcc: 15.3.0 Client: Sudo v: 1.9.17p2 inxi: 3.3.41 treefmt-check> ``` treefmt-check> + treefmt-check> ![hardware topology](rho.lstopo.svg) treefmt-check> diff --git a/docs/hosts/tau.md b/docs/hosts/tau.md treefmt-check> index 22e4222..4894ab2 100644 treefmt-check> --- a/docs/hosts/tau.md treefmt-check> +++ b/docs/hosts/tau.md treefmt-check> @@ -130,4 +130,5 @@ Info: treefmt-check> Packages: pm: nix-default pkgs: 0 pm: nix-sys pkgs: 555 libs: 84 pm: nix-usr pkgs: 0 Compilers: treefmt-check> gcc: 15.3.0 Client: Sudo v: 1.9.17p2 inxi: 3.3.41 treefmt-check> ``` treefmt-check> + treefmt-check> ![hardware topology](tau.lstopo.svg) treefmt-check> diff --git a/tasks.py b/tasks.py treefmt-check> index de1b8a0..a8a9250 100755 treefmt-check> --- a/tasks.py treefmt-check> +++ b/tasks.py treefmt-check> @@ -187,11 +187,10 @@ def update_lldp_info(c: Any, hosts: str = "") -> None: treefmt-check> graph_script = ROOT / "docs" / "generate-lldp-graph.sh" treefmt-check> output_dir.mkdir(parents=True, exist_ok=True) treefmt-check> treefmt-check> - with TemporaryDirectory(prefix="lldp-", dir=output_dir) as lldp_dir: treefmt-check> - with c.cd(lldp_dir): treefmt-check> - for host in inventory_hostnames(hosts): treefmt-check> - c.run(f"{shlex.quote(str(collect_script))} {shlex.quote(host)}") treefmt-check> - c.run(shlex.quote(str(graph_script))) treefmt-check> + with TemporaryDirectory(prefix="lldp-", dir=output_dir) as lldp_dir, c.cd(lldp_dir): treefmt-check> + for host in inventory_hostnames(hosts): treefmt-check> + c.run(f"{shlex.quote(str(collect_script))} {shlex.quote(host)}") treefmt-check> + c.run(shlex.quote(str(graph_script))) treefmt-check> treefmt-check> treefmt-check> @task treefmt-check> diff --git a/tests/test_generate_network_topology.py b/tests/test_generate_network_topology.py treefmt-check> index 67c98fa..5aee91a 100644 treefmt-check> --- a/tests/test_generate_network_topology.py treefmt-check> +++ b/tests/test_generate_network_topology.py treefmt-check> @@ -2,7 +2,6 @@ import importlib.util treefmt-check> import unittest treefmt-check> from pathlib import Path treefmt-check> treefmt-check> - treefmt-check> SCRIPT = Path(__file__).parents[1] / "docs" / "generate-network-topology.py" treefmt-check> treefmt-check> error: Cannot build '/nix/store/cqacgripk9fihi6lq6ag17x9yqjhp2cn-treefmt-check.drv'. Reason: builder failed with exit code 1. Output paths: /nix/store/3wwwl2jgvbb6rnxqnqvr99zp2r3nqfnh-treefmt-check Last 25 log lines: > > - with TemporaryDirectory(prefix="lldp-", dir=output_dir) as lldp_dir: > - with c.cd(lldp_dir): > - for host in inventory_hostnames(hosts): > - c.run(f"{shlex.quote(str(collect_script))} {shlex.quote(host)}") > - c.run(shlex.quote(str(graph_script))) > + with TemporaryDirectory(prefix="lldp-", dir=output_dir) as lldp_dir, c.cd(lldp_dir): > + for host in inventory_hostnames(hosts): > + c.run(f"{shlex.quote(str(collect_script))} {shlex.quote(host)}") > + c.run(shlex.quote(str(graph_script))) > > > @task > diff --git a/tests/test_generate_network_topology.py b/tests/test_generate_network_topology.py > index 67c98fa..5aee91a 100644 > --- a/tests/test_generate_network_topology.py > +++ b/tests/test_generate_network_topology.py > @@ -2,7 +2,6 @@ import importlib.util > import unittest > from pathlib import Path > > - > SCRIPT = Path(__file__).parents[1] / "docs" / "generate-network-topology.py" > > For full logs, run: nix log /nix/store/cqacgripk9fihi6lq6ag17x9yqjhp2cn-treefmt-check.drv