chore: bootstrap lean sysadmin-chronicles repo
Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q001-prep.sh — Workstation baseline: SSH key missing
|
||||
#
|
||||
# Prepares the workstation VM for Q001 "Welcome Aboard".
|
||||
# The player's SSH key was never added during provisioning.
|
||||
#
|
||||
# What this does:
|
||||
# - Ensures the player account exists
|
||||
# - Removes /home/player/.ssh/authorized_keys (key not provisioned)
|
||||
# - Leaves /var/log/auth.log with a "Permission denied (publickey)" entry
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
# AGENT RULES: Never run against a live player session.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-workstation}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_USER="${SSH_USER:-opsbridge}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
|
||||
VM_IP="$(get_vm_ip "$DOMAIN")"
|
||||
SSH="ssh $SSH_OPTS $SSH_USER@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
$SSH "sudo $*"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q001-prep: Preparing $DOMAIN for 'Welcome Aboard'..."
|
||||
|
||||
run_in_vm "bash -lc 'mkdir -p /home/player/.ssh; touch /var/log/auth.log; ts=\$(date +\"%b %d %H:%M:%S\"); echo \"\$ts ares sshd[1234]: Failed publickey for player from 10.42.0.1 port 22 ssh2\" >> /var/log/auth.log; rm -f /home/player/.ssh/authorized_keys; echo Q001-prep: authorized_keys removed'"
|
||||
|
||||
echo "Q001-prep: Done."
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q002-prep.sh — hermes baseline: nginx config syntax error
|
||||
#
|
||||
# Prepares sc-web-server for Q002 "Syntax Error in Aisle Four".
|
||||
# Introduces a deliberate nginx config syntax error that breaks the service.
|
||||
#
|
||||
# What this does:
|
||||
# - Installs nginx if not present
|
||||
# - Writes a broken /etc/nginx/sites-enabled/axiomworks.conf
|
||||
# (missing semicolon on the server_name line)
|
||||
# - Stops nginx so the player finds it down
|
||||
# - Adds error log evidence
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-web-server}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
VM_IP=$(get_vm_ip "$DOMAIN")
|
||||
SSH="ssh $SSH_OPTS player@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
printf '%s\n' "$*" | $SSH "sudo bash -se"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q002-prep: Preparing $DOMAIN for 'Syntax Error in Aisle Four'..."
|
||||
|
||||
run_in_vm "mkdir -p /etc/nginx/sites-enabled /etc/nginx/sites-available"
|
||||
|
||||
# Write broken nginx config (missing semicolon after server_name)
|
||||
run_in_vm "cat > /etc/nginx/sites-enabled/axiomworks.conf <<'NGINX_CONF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name axiomworks.internal # <-- MISSING SEMICOLON: this is the bug
|
||||
root /var/www/axiomworks;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ =404;
|
||||
}
|
||||
}
|
||||
NGINX_CONF"
|
||||
|
||||
# Disable the default site to make this the only relevant config
|
||||
run_in_vm "rm -f /etc/nginx/sites-enabled/default"
|
||||
|
||||
# Stop nginx (it fails to start with bad config)
|
||||
run_in_vm "systemctl stop nginx || true"
|
||||
|
||||
# Populate nginx error log with the kind of evidence a player would find
|
||||
run_in_vm "mkdir -p /var/log/nginx && echo '[emerg] unexpected \";\" in /etc/nginx/sites-enabled/axiomworks.conf:3' >> /var/log/nginx/error.log"
|
||||
|
||||
# Create the web root (nginx would serve from here if config were valid)
|
||||
run_in_vm "mkdir -p /var/www/axiomworks && echo '<h1>Axiom Works</h1>' > /var/www/axiomworks/index.html"
|
||||
|
||||
echo "Q002-prep: Done. nginx is stopped with broken config on $DOMAIN."
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q003-prep.sh — hermes baseline: logrotate missing, nginx access log ballooning
|
||||
#
|
||||
# Prepares sc-web-server for Q003 "The Log That Ate the Disk".
|
||||
# Assumes Q002 is already resolved (nginx is running, config is clean).
|
||||
#
|
||||
# What this does:
|
||||
# - Removes /etc/logrotate.d/nginx (log rotation not configured)
|
||||
# - Grows /var/log/nginx/access.log to ~80% disk pressure
|
||||
# - Disk usage should read >85% on /var so player sees the pressure
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-web-server}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
VM_IP=$(get_vm_ip "$DOMAIN")
|
||||
SSH="ssh $SSH_OPTS player@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
printf '%s\n' "$*" | $SSH "sudo bash -se"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q003-prep: Preparing $DOMAIN for 'The Log That Ate the Disk'..."
|
||||
|
||||
# Remove logrotate config for nginx
|
||||
run_in_vm "rm -f /etc/logrotate.d/nginx"
|
||||
|
||||
# Generate a large access log (~500MB of fake log entries, enough to fill a 6GB VM)
|
||||
# Use truncate for speed rather than generating real content
|
||||
run_in_vm "mkdir -p /var/log/nginx"
|
||||
run_in_vm "truncate -s 500M /var/log/nginx/access.log"
|
||||
|
||||
# Write real-looking last few lines so tail shows something plausible
|
||||
run_in_vm "echo '10.42.0.1 - - [\$(date +\"%d/%b/%Y:%H:%M:%S +0000\")] \"GET / HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0\"' >> /var/log/nginx/access.log"
|
||||
|
||||
echo "Q003-prep: Done. /var/log/nginx/access.log inflated on $DOMAIN."
|
||||
echo " Check disk pressure with: df -h (on the VM)"
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q004-prep.sh — hermes baseline: web root owned by root, deploy script in place
|
||||
#
|
||||
# Prepares sc-web-server for Q004 "Not My Files".
|
||||
# A bad deploy re-ran as root and chowned the web root to root.
|
||||
# The deploy script itself is in /opt/deploy/deploy.sh.
|
||||
#
|
||||
# What this does:
|
||||
# - Chowns /var/www/axiomworks and all contents to root:root
|
||||
# - Places a deploy script at /opt/deploy/deploy.sh (chowned player:player)
|
||||
# - Ensures nginx is running (deploy will fail but nginx serves stale content)
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-web-server}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
VM_IP=$(get_vm_ip "$DOMAIN")
|
||||
SSH="ssh $SSH_OPTS player@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
printf '%s\n' "$*" | $SSH "sudo bash -se"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q004-prep: Preparing $DOMAIN for 'Not My Files'..."
|
||||
|
||||
# Ensure web root exists and is owned by root (the bug)
|
||||
run_in_vm "mkdir -p /var/www/axiomworks && chown -R root:root /var/www/axiomworks"
|
||||
|
||||
# Create the deploy script as player:player (this is correct — player runs it)
|
||||
run_in_vm "mkdir -p /opt/deploy"
|
||||
run_in_vm "cat > /opt/deploy/deploy.sh <<'DEPLOY_SCRIPT'
|
||||
#!/usr/bin/env bash
|
||||
# deploy.sh — Axiom Works web deploy
|
||||
# Copies build artifacts to /var/www/axiomworks/
|
||||
set -e
|
||||
SRC=\"\${1:-/home/player/build/dist}\"
|
||||
rsync -av \"\$SRC/\" /var/www/axiomworks/
|
||||
echo 'Deploy complete.'
|
||||
DEPLOY_SCRIPT"
|
||||
run_in_vm "chown player:player /opt/deploy/deploy.sh && chmod 755 /opt/deploy/deploy.sh"
|
||||
|
||||
# Ensure nginx is running (serves stale content with root-owned files)
|
||||
run_in_vm "systemctl start nginx || true"
|
||||
|
||||
echo "Q004-prep: Done. /var/www/axiomworks is owned by root on $DOMAIN."
|
||||
echo " Player must: sudo chown -R player:player /var/www/axiomworks"
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q006-post-clean.sh — vulcan clean branch state after Q006
|
||||
#
|
||||
# Applies the authored clean outcome of Q006 so seed-vms.sh can materialize
|
||||
# baseline.post-q006 for later quests.
|
||||
#
|
||||
# What this does:
|
||||
# - Enables and starts systemd-timesyncd
|
||||
# - Verifies archlinux-keyring is installed
|
||||
# - Replaces pacman.log failure evidence with a healthy update trail
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-build-machine}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
VM_IP="$(get_vm_ip "$DOMAIN")"
|
||||
SSH="ssh $SSH_OPTS player@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
printf '%s\n' "$*" | $SSH "sudo bash -se"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q006-post-clean: Applying clean Q006 outcome on $DOMAIN..."
|
||||
|
||||
run_in_vm "pacman -Q archlinux-keyring >/dev/null"
|
||||
run_in_vm "timedatectl set-ntp true || true"
|
||||
run_in_vm "systemctl enable --now systemd-timesyncd"
|
||||
|
||||
run_in_vm "cat > /var/log/pacman.log <<'PACMAN_LOG'
|
||||
[2026-04-23T09:02:14-0400] [PACMAN] synchronizing package lists
|
||||
[2026-04-23T09:02:19-0400] [ALPM] transaction started
|
||||
[2026-04-23T09:02:19-0400] [ALPM] upgraded archlinux-keyring (20260401-1 -> 20260420-1)
|
||||
[2026-04-23T09:02:20-0400] [ALPM] transaction completed
|
||||
PACMAN_LOG"
|
||||
|
||||
run_in_vm "cat > /var/log/axiomworks/time-drift.note <<'NOTE'
|
||||
Time sync restored.
|
||||
systemd-timesyncd is enabled and active.
|
||||
archlinux-keyring is present and package operations are healthy.
|
||||
NOTE"
|
||||
|
||||
echo "Q006-post-clean: Done. systemd-timesyncd is active and baseline.post-q006 is ready on $DOMAIN."
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# Q006-prep.sh — vulcan baseline: time sync disabled, pacman signature errors logged
|
||||
#
|
||||
# Prepares sc-build-machine for Q006 "Time Is A Flat Circle".
|
||||
# The machine clock is drifting because time sync was disabled, which surfaces
|
||||
# as pacman signature verification failures.
|
||||
#
|
||||
# What this does:
|
||||
# - Disables and stops common NTP services
|
||||
# - Seeds pacman.log with realistic signature failure evidence
|
||||
# - Leaves a small operator note pointing at time drift symptoms
|
||||
#
|
||||
# Idempotent: safe to run multiple times.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
||||
|
||||
DOMAIN="${1:-sc-build-machine}"
|
||||
DRY_RUN=false
|
||||
[[ "${2:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
get_vm_ip() {
|
||||
local domain="$1"
|
||||
local addr=""
|
||||
addr="$(virsh domifaddr "$domain" --source agent 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
if [ -n "$addr" ]; then
|
||||
printf '%s\n' "$addr"
|
||||
return 0
|
||||
fi
|
||||
local mac=""
|
||||
mac="$(virsh dumpxml "$domain" 2>/dev/null | sed -n "s/.*<mac address='\\([^']*\\)'.*/\\1/p" | head -n1)"
|
||||
[ -n "$mac" ] || return 1
|
||||
addr="$(virsh net-dhcp-leases sc-internal 2>/dev/null | awk -v mac="$mac" '$0 ~ mac {print $5}' | cut -d/ -f1 | grep -v '^127\.' | head -n1 || true)"
|
||||
[ -n "$addr" ] || return 1
|
||||
printf '%s\n' "$addr"
|
||||
}
|
||||
|
||||
SC_SSH_KEY="${SC_SSH_KEY:-${HOME}/.ssh/sc_host_key}"
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=10 -o LogLevel=ERROR -i $SC_SSH_KEY"
|
||||
VM_IP="$(get_vm_ip "$DOMAIN")"
|
||||
SSH="ssh $SSH_OPTS player@$VM_IP"
|
||||
|
||||
run_in_vm() {
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " [DRY-RUN in $DOMAIN] $*"
|
||||
else
|
||||
printf '%s\n' "$*" | $SSH "sudo bash -se"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Q006-prep: Preparing $DOMAIN for 'Time Is A Flat Circle'..."
|
||||
|
||||
run_in_vm "timedatectl set-ntp false || true"
|
||||
run_in_vm "systemctl stop systemd-timesyncd ntpd chronyd 2>/dev/null || true"
|
||||
run_in_vm "systemctl disable systemd-timesyncd ntpd chronyd 2>/dev/null || true"
|
||||
run_in_vm "mkdir -p /var/log/axiomworks /srv/repo /srv/builds"
|
||||
|
||||
run_in_vm "cat > /var/log/pacman.log <<'PACMAN_LOG'
|
||||
[2026-04-23T08:10:51-0400] [PACMAN] synchronizing package lists
|
||||
[2026-04-23T08:10:57-0400] [ALPM] transaction started
|
||||
[2026-04-23T08:10:58-0400] [ALPM] warning: Public keyring not found; have you run 'pacman-key --init'?
|
||||
[2026-04-23T08:10:58-0400] [ALPM] error: archlinux-keyring: signature from \"Arch Linux Master Key\" is invalid
|
||||
[2026-04-23T08:10:58-0400] [ALPM] error: failed to commit transaction (invalid or corrupted package (PGP signature))
|
||||
[2026-04-23T08:10:58-0400] [ALPM] transaction failed
|
||||
PACMAN_LOG"
|
||||
|
||||
run_in_vm "cat > /var/log/axiomworks/time-drift.note <<'NOTE'
|
||||
Builds started failing after the machine clock fell behind.
|
||||
Symptoms:
|
||||
- pacman reports invalid or corrupted package (PGP signature)
|
||||
- signed packages appear to come from the future
|
||||
- timedatectl shows NTP inactive
|
||||
NOTE"
|
||||
|
||||
echo "Q006-prep: Done. NTP is disabled and pacman signature failures are seeded on $DOMAIN."
|
||||
Reference in New Issue
Block a user