#!/bin/sh # bee-boot-status — boot progress display on tty1. # Shows live service status until all bee services are done or failed, # then exits so getty can show the login prompt. # GUI (lightdm) starts independently without waiting for this. # Services to wait for before handing off to login prompt. CRITICAL="bee-preflight bee-nvidia bee-audit" # Services shown with details. ALL="bee-sshsetup ssh bee-network bee-nvidia bee-preflight bee-audit bee-web" svc_state() { systemctl is-active "$1.service" 2>/dev/null || echo "inactive" } svc_icon() { case "$(svc_state "$1")" in active) printf '\033[32m[ OK ]\033[0m' ;; failed) printf '\033[31m[ FAIL ]\033[0m' ;; activating) printf '\033[33m[ .. ]\033[0m' ;; deactivating) printf '\033[33m[ stop ]\033[0m' ;; inactive) printf '\033[90m[ ]\033[0m' ;; *) printf '\033[90m[ ? ]\033[0m' ;; esac } svc_detail() { local svc="$1" local state state="$(svc_state "$svc")" case "$state" in failed) # Show why it failed local msg msg="$(systemctl show -p Result "$svc.service" 2>/dev/null | cut -d= -f2)" [ -n "$msg" ] && [ "$msg" != "success" ] && printf ' \033[31m(%s)\033[0m' "$msg" ;; activating) # Show last journal line local line line="$(journalctl -u "$svc.service" -n 1 --no-pager --output=cat 2>/dev/null | head -c 60)" [ -n "$line" ] && printf ' \033[90m%s\033[0m' "$line" ;; esac } get_ips() { ip -4 addr show scope global 2>/dev/null \ | awk '/inet /{printf " %s\t%s\n", $NF, $2}' } all_critical_done() { for svc in $CRITICAL; do case "$(svc_state "$svc")" in active|failed|inactive) ;; *) return 1 ;; esac done return 0 } while true; do # Build frame in a variable to reduce flicker out="" out="${out}$(printf '\033[H\033[2J')" out="${out}$(printf '\n')" out="${out}$(printf ' \033[33m███████╗ █████╗ ███████╗██╗ ██╗ ██████╗ ███████╗███████╗\033[0m\n')" out="${out}$(printf ' \033[33m██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝ ██╔══██╗██╔════╝██╔════╝\033[0m\n')" out="${out}$(printf ' \033[33m█████╗ ███████║███████╗ ╚████╔╝ █████╗██████╔╝█████╗ █████╗\033[0m\n')" out="${out}$(printf ' \033[33m██╔══╝ ██╔══██║╚════██║ ╚██╔╝ ╚════╝██╔══██╗██╔══╝ ██╔══╝\033[0m\n')" out="${out}$(printf ' \033[33m███████╗██║ ██║███████║ ██║ ██████╔╝███████╗███████╗\033[0m\n')" out="${out}$(printf ' \033[33m╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝\033[0m\n')" out="${out}$(printf ' Hardware Audit LiveCD\n')" out="${out}$(printf '\n')" # Services for svc in $ALL; do out="${out}$(printf ' %s %-20s%s\n' "$(svc_icon "$svc")" "$svc" "$(svc_detail "$svc")")" done out="${out}$(printf '\n')" # Network ips="$(get_ips)" if [ -n "$ips" ]; then out="${out}$(printf ' \033[1mNetwork:\033[0m\n')" out="${out}$(printf '%s\n' "$ips")" out="${out}$(printf '\n')" fi # Status line if all_critical_done; then out="${out}$(printf ' \033[1mSystem ready.\033[0m Audit is running in the background.\n')" if [ -n "$ips" ]; then first_ip="$(echo "$ips" | awk '{print $2}' | cut -d/ -f1 | head -1)" out="${out}$(printf ' Web UI: \033[1mhttp://%s/\033[0m\n' "$first_ip")" fi printf '%s\n' "$out" sleep 3 break else out="${out}$(printf ' \033[90mStarting up...\033[0m\n')" fi printf '%s' "$out" sleep 3 done