70 lines
2.9 KiB
Bash
Executable File
70 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# =====================================================================
|
|
# Rename a machine, as far as anything is allowed to.
|
|
#
|
|
# owuivm-set-name <machine-id>
|
|
#
|
|
# Reads the wanted name from /var/lib/owuivm/incoming/<id>.name, which
|
|
# the desktop tool wrote as the operator, and records it in the override
|
|
# file. Same staging trick as owuivm-insert-media, and for the same
|
|
# reason: a systemd unit instance carries one string, and that string is
|
|
# the machine id.
|
|
#
|
|
# WHY AN OVERRIDE FILE AND NOT AN EDIT TO configs/vms.toml
|
|
#
|
|
# Because that file is mostly comments, and they are the useful part of
|
|
# it - what an id is, why the ISO glob is not `*.iso`, what the prompt
|
|
# fields do. No TOML writer preserves comments, so a program that edits
|
|
# the registry in place is a program that deletes its own documentation
|
|
# the first time someone presses Rename.
|
|
#
|
|
# So the registry stays exactly as shipped and this writes a separate,
|
|
# tiny file that readers merge over the top. Only `name` is overridable,
|
|
# which is also the only field that is safe to change: `id` is identity
|
|
# and the rest is prompt text.
|
|
# =====================================================================
|
|
set -euo pipefail
|
|
|
|
INCOMING=${OWUIVM_INCOMING_DIR:-/var/lib/owuivm/incoming}
|
|
OVERRIDES=${OWUIVM_NAME_OVERRIDES:-/var/lib/owuivm/registry/vm-names.toml}
|
|
REGISTRY=${OWUIVM_REGISTRY:-/var/lib/owuivm/registry/vms.toml}
|
|
|
|
id="${1:-}"
|
|
[[ "$id" =~ ^[a-z0-9][a-z0-9-]{0,30}$ ]] || { echo "bad machine id '$id'" >&2; exit 64; }
|
|
|
|
if [ -r "$REGISTRY" ]; then
|
|
grep -qE "^[[:space:]]*id[[:space:]]*=[[:space:]]*\"$id\"" "$REGISTRY" \
|
|
|| { echo "no machine '$id' in $REGISTRY" >&2; exit 64; }
|
|
fi
|
|
|
|
src="$INCOMING/$id.name"
|
|
[ -f "$src" ] || { echo "no name staged for $id" >&2; exit 65; }
|
|
[ ! -h "$src" ] || { echo "$src is a symlink; refusing" >&2; exit 65; }
|
|
|
|
# First line only, trimmed. A name is a label in a window title and in a
|
|
# report; a newline in it would be a second line of a TOML file.
|
|
wanted=$(head -c 200 "$src" | head -1 | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
rm -f -- "$src"
|
|
[ -n "$wanted" ] || { echo "the name was empty" >&2; exit 64; }
|
|
# Printable, and nothing that would need escaping in a TOML basic string.
|
|
printf '%s' "$wanted" | grep -qP '^[^\x00-\x1f"\\]{1,40}$' \
|
|
|| { echo "a name must be 1-40 printable characters and no quotes or backslashes" >&2; exit 64; }
|
|
|
|
tmp=$(mktemp "${OVERRIDES}.XXXXXX")
|
|
trap 'rm -f "$tmp"' EXIT
|
|
{
|
|
echo '# Machine display names, set from the Tool Server VM Maintenance app.'
|
|
echo '# Merged over the `name` field in vms.toml. Delete a line to go back'
|
|
echo '# to the shipped name; delete the file to reset all of them.'
|
|
echo '[names]'
|
|
# Every other machine's current override, kept.
|
|
if [ -r "$OVERRIDES" ]; then
|
|
grep -E '^[a-z0-9-]+[[:space:]]*=' "$OVERRIDES" | grep -vE "^$id[[:space:]]*=" || true
|
|
fi
|
|
printf '%s = "%s"\n' "$id" "$wanted"
|
|
} > "$tmp"
|
|
chmod 0644 "$tmp"
|
|
mv -f "$tmp" "$OVERRIDES"
|
|
trap - EXIT
|
|
echo "$id is now called $wanted"
|