Files
infix/utils/ixll
Joachim Wiberg e2c29cb1a7 utils: add fleet management commands to ixll
Introduce libfleet.sh and a new 'fleet' subcommand to ixll for managing
and operating enrolled Infix devices via RESTCONF.

Device configuration is stored in ~/.config/infix/config.json
(chmod 600): and organised by profile, allowing bulk operations across
groups of devices (e.g. all aarch64 targets).

New commands:

  ixll fleet enroll [-d] [-p profile] [-u user] [-w password] <name> <address>
  ixll fleet list
  ixll fleet upgrade <name|profile> <url>
  ixll fleet backup  [-o dir] <name|profile>
  ixll fleet reboot  <name|profile>

Upgrade runs in parallel across a fleet and shows a live per-device
progress bar by polling the infix-system:install-bundle RPC and the
installer state from the YANG operational data store.

The global -A flag (admin/admin) is honoured as a credential fallback
for devices enrolled without an explicit password.

Also fix a pre-existing typo: ">2" → ">&2" in the error path.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-09 19:24:36 +01:00

143 lines
3.4 KiB
Bash
Executable File

#!/bin/sh
set -e
. $(dirname $(readlink -f "$0"))/libll.sh
. $(dirname $(readlink -f "$0"))/libfleet.sh
usage()
{
local me="$(basename $0)"
cat <<EOF
usage: $me [-A] <command> [<args>]
Wrap various existing network facilities such that an interface name
may be supplied in places where a hostname is otherwise expected.
Also provides fleet management and upgrade of enrolled Infix devices.
Options:
-A
For commands requiring authentication, use password
authentication with username "admin" and password "admin".
Link-local commands:
scan [-a] [<iface>]
Discover Infix devices on the LAN using mDNS-SD (avahi-browse).
Use -a to show all mDNS devices, not just Infix. Falls back to
IPv6 link-local multicast ping if avahi-browse is not installed
and <iface> is specified.
peer <iface>
Return the address of the first IPv6 neighbor to respond on
<iface>'s local LAN.
ping <iface>
Send ping to all-hosts group, with link-local scope, on <iface>,
suppressing loopbacked packets.
ssh <iface> [<ssh-arguments>]
ssh(1) to the neighboring host on <iface>.
scp <src> <dst>
scp(1) from <src> to <dst>, but any host specified in either
<src> or <dst> is assumed to be an interface name, which is
expanded to a neighboring host on that interface.
Fleet commands (RESTCONF, config in ~/.config/infix/config.json):
fleet enroll [-p <profile>] [-u <user>] [-w <password>] <name> <address>
Enroll a device. Profile groups devices for bulk operations.
Password may be omitted if -A is always used.
fleet enroll -d <name>
Remove an enrolled device.
fleet list
List all enrolled devices.
fleet upgrade <name|profile> <url>
Install a software bundle from <url> on one device or all devices
in a profile, in parallel, with a live per-device progress display.
fleet backup [-o <dir>] <name|profile>
Save the startup-config from one device or all devices in a profile.
Single device: saved to the current directory.
Profile: saved to ~/.config/infix/<profile>/<name>/.
fleet reboot <name|profile>
Reboot one device or all devices in a profile.
help
Display this message.
Examples:
Start interactive ssh(1) session to the neighbor on eth0
$me ssh eth0
Copy /etc/hostname from the neighbor on eth0, using admin/admin
$me -A scp eth0:/etc/hostname /tmp/hostname
Enroll two devices into the "aarch64" fleet
$me fleet enroll -p aarch64 -w secret gw-1 192.168.1.10
$me fleet enroll -p aarch64 -w secret gw-2 192.168.1.11
Upgrade the entire aarch64 fleet
$me fleet upgrade aarch64 ftp://build-server/infix-aarch64-26.02.pkg
Backup a single device's startup-config to the current directory
$me -A fleet backup gw-1
EOF
}
while getopts "A" opt; do
case ${opt} in
A)
LLSSH_USER=admin
LLSSH_PASS=admin
LLSSH_OPTS="$LLSSH_OPTS -oStrictHostKeyChecking=no"
LLSSH_OPTS="$LLSSH_OPTS -oUserKnownHostsFile=/dev/null"
;;
esac
done
shift $((OPTIND - 1))
if [ $# -lt 1 ]; then
usage && exit 1
fi
cmd="$1"
shift
case "$cmd" in
help)
usage && exit 0
;;
scan)
llscan "$@"
;;
peer)
llpeer "$@"
;;
ping)
llping "$@"
;;
scp)
llscp "$@"
;;
ssh)
llssh "$@"
;;
fleet)
fleet_main "$@"
;;
*)
echo "Unknown command \"$cmd\"" >&2
exit 1
;;
esac