#!/bin/bash # ===================================================================== # Rename a machine, as far as anything is allowed to. # # owuivm-set-name # # Reads the wanted name from /var/lib/owuivm/incoming/.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"