Files
Michael Chus a38c35ce2d docs: add three LiveCD/embedded patterns from bee project
- alpine-livecd: mkimage profile rules, apkovl mechanics, workdir caching,
  squashfs compression, NIC firmware, long build survival via screen
- vendor-installer-verification: checksum-before-download, cache validation,
  version URL verification before writing build scripts
- unattended-boot-services: OpenRC invariants for headless environments,
  network-independent SSH, persistent DHCP, graceful degradation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 18:18:22 +03:00

4.0 KiB

Contract: Unattended Boot Services (OpenRC)

Version: 1.0

Purpose

Rules for OpenRC services that run in unattended environments: LiveCDs, kiosks, embedded systems. No user is present. No TTY prompts. Every failure path must have a silent fallback.


Core Invariants

  • Never block boot. A service failure must not prevent other services from starting.
  • Never prompt. No read, no pause, no interactive input of any kind.
  • Always exit 0. Use eend 0 at the end of start() regardless of the operation result.
  • Log everything. Write results to /var/log/ so SSH inspection is possible after boot.
  • Fail silently, degrade gracefully. Missing tool → skip that collector. No network → skip network-dependent steps.

Service Dependencies

Use the minimum necessary dependencies:

depend() {
    need localmount       # almost always needed
    after some-service    # ordering without hard dependency
    use logger            # optional soft dependency
    # DO NOT add: need net, need networking, need network-online
}

Never use need net or need networking unless the service is genuinely useless without network and you want it to fail loudly when no cable is connected. For services that work with or without network, use after instead.


Network-Independent SSH

Dropbear (and any SSH server) must start without network being available. Common mistake: installing dropbear-openrc which adds need net in its default init.

Override with a custom init:

#!/sbin/openrc-run
description="SSH server"

depend() {
    need localmount
    after bee-sshsetup    # key/user setup, not networking
    use logger
    # NO need net
}

start() {
    check_config || return 1
    ebegin "Starting dropbear"
    /usr/sbin/dropbear ${DROPBEAR_OPTS}
    eend $?
}

Place this file in the overlay at etc/init.d/dropbear — it overrides the package-installed version.


Persistent DHCP

Do not use blocking DHCP (-n flag exits if no offer). Use background mode so the client retries automatically when a cable is connected after boot:

# Wrong — exits immediately if no DHCP offer
udhcpc -i "$iface" -t 3 -T 5 -n -q

# Correct — background daemon, retries indefinitely
udhcpc -i "$iface" -b -t 0 -T 3 -q

The network service itself should complete immediately (exit 0) — udhcpc daemons run in background.


Service Start Order (typical LiveCD)

localmount
  └── sshsetup    (user creation, key injection — before dropbear)
        └── dropbear    (SSH — independent of network)
  └── network     (DHCP on all interfaces — does not block anything)
        └── nvidia      (or other hardware init — after network in case firmware needs it)
              └── audit   (main workload — after all hardware ready)

Services at the same level can start in parallel. Use after not need for ordering without hard dependency.


Error Handling in start()

start() {
    ebegin "Running audit"
    /usr/local/bin/audit --output /var/log/audit.json >> /var/log/audit.log 2>&1
    local rc=$?
    if [ $rc -eq 0 ]; then
        einfo "Audit complete"
    else
        ewarn "Audit finished with errors — check /var/log/audit.log"
    fi
    eend 0   # always 0 — never fail the runlevel
}
  • Capture exit code into a local variable.
  • Log the result with einfo or ewarn.
  • Always eend 0 — a failed audit is not a reason to block the boot runlevel.
  • The exception: services whose failure makes SSH impossible (e.g. key setup) may return 1.

Rules

  • Every start() ends with eend 0 unless failure makes the entire environment unusable.
  • Network is always best-effort. Test for it, don't depend on it.
  • Proprietary drivers (NVIDIA, etc.): load failure → log warning → continue without enrichment.
  • External tools (ipmitool, smartctl, etc.): not-found → skip that data source → do not abort.
  • Timeout all external commands: timeout 30 smartctl ... prevents infinite hangs.
  • Write all output to /var/log/ — TTY output is secondary.