clawdie-iso/live/operator-session/clawdie-live-seed

134 lines
4 KiB
Text
Raw Normal View History

#!/bin/sh
# Clawdie operator USB live seed importer.
# Reads operator-provided files from the FAT32 CLAWDIESEED partition
# (mountable on Linux pre-flash) and installs them into the live system
# at every boot. Idempotent by design: editing the seed and rebooting
# re-applies it. Failure is never fatal — missing/empty/unmountable seed
# logs and continues so the operator can still log in via SDDM.
#
# Runs before LOGIN so sshd sees the imported authorized_keys on first
# attach. See live/operator-session/clawdie-live-seed.README.txt for the
# allowlisted file contract written to the FAT at build time.
# PROVIDE: clawdie_live_seed
# REQUIRE: FILESYSTEMS devfs
# BEFORE: LOGIN
# KEYWORD: nojail
. /etc/rc.subr
name="clawdie_live_seed"
rcvar="${name}_enable"
start_cmd="${name}_start"
stop_cmd=":"
# This service is one-shot/idempotent, not a daemon — the default
# rc.subr status check looks for a pidfile and would say "not running"
# even after a successful import, which is actively misleading. Override
# with a log-tail report so `service clawdie_live_seed status` answers
# the question the operator is actually asking ("did the import run?").
status_cmd="${name}_status"
extra_commands="status"
SEED_LABEL="CLAWDIESEED"
SEED_MOUNT="/mnt/clawdie-seed"
SEED_LOG="/var/log/clawdie-live-seed.log"
SEED_USER="clawdie"
SEED_USER_HOME="/home/clawdie"
_seed_log() {
printf '%s %s\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$1" >>"${SEED_LOG}" 2>/dev/null || true
}
_seed_find_partition() {
for _candidate in \
"/dev/msdosfs/${SEED_LABEL}" \
"/dev/gpt/${SEED_LABEL}" \
"/dev/label/${SEED_LABEL}"
do
if [ -e "${_candidate}" ]; then
echo "${_candidate}"
return 0
fi
done
if command -v gpart >/dev/null 2>&1; then
gpart show -lp 2>/dev/null \
| awk -v label="${SEED_LABEL}" '
$0 ~ label {
for (i = 1; i <= NF; i++) {
if ($i ~ "^/dev/") { print $i; exit }
}
}
'
fi
return 0
}
_seed_install_authorized_keys() {
_src="$1"
_ssh_dir="${SEED_USER_HOME}/.ssh"
_dst="${_ssh_dir}/authorized_keys"
mkdir -p "${_ssh_dir}"
chown "${SEED_USER}:${SEED_USER}" "${_ssh_dir}" 2>/dev/null || true
chmod 0700 "${_ssh_dir}"
# Strip CRLF so keys created on Windows/Linux editors don't get rejected
# by sshd for trailing whitespace.
tr -d '\r' <"${_src}" >"${_dst}.new"
mv -f "${_dst}.new" "${_dst}"
chown "${SEED_USER}:${SEED_USER}" "${_dst}" 2>/dev/null || true
chmod 0600 "${_dst}"
_seed_log "installed authorized_keys from ${_src} -> ${_dst}"
}
clawdie_live_seed_start() {
: >>"${SEED_LOG}" 2>/dev/null || true
_dev=$(_seed_find_partition)
if [ -z "${_dev:-}" ]; then
_seed_log "no ${SEED_LABEL} partition found — skipping import"
return 0
fi
mkdir -p "${SEED_MOUNT}"
if ! mount -t msdosfs -o ro "${_dev}" "${SEED_MOUNT}" 2>>"${SEED_LOG}"; then
_seed_log "mount failed on ${_dev} — skipping import"
return 0
fi
# Allowlist: /ssh/authorized_keys takes precedence over /authorized_keys.
# Any other file on the partition is ignored on purpose.
_imported=0
if [ -f "${SEED_MOUNT}/ssh/authorized_keys" ]; then
_seed_install_authorized_keys "${SEED_MOUNT}/ssh/authorized_keys"
_imported=1
elif [ -f "${SEED_MOUNT}/authorized_keys" ]; then
_seed_install_authorized_keys "${SEED_MOUNT}/authorized_keys"
_imported=1
fi
if [ "${_imported}" -eq 0 ]; then
_seed_log "no allowlisted files on ${_dev} — nothing to import"
fi
umount "${SEED_MOUNT}" 2>/dev/null || true
return 0
}
clawdie_live_seed_status() {
if [ -s "${SEED_LOG}" ]; then
echo "${name}: one-shot importer; last run log tail:"
tail -n 5 "${SEED_LOG}"
return 0
fi
echo "${name}: not yet run this boot (no log at ${SEED_LOG})"
return 1
}
load_rc_config "$name"
: "${clawdie_live_seed_enable:=YES}"
run_rc_command "$1"