Skip to content

Commit 2ca688e

Browse files
Kabuki94claude
andcommitted
update MOTD dashboard and fix cockpit in WSL2
motd (usr/libexec/mios/motd): - Bump version refs to v0.2.2 - Replace Unicode symbols (●○✓✗⚠) with ASCII ([OK]/[ ]/[!!]) - Fix IP detection: use 1.1.1.1 as routing target (was stale v0.2.0.1) - Add filled ASCII resource bars for CPU/Memory/Disk (/proc + df) - Add AI stack section: LocalAI endpoint + model from install.env, online/offline ping check via curl --max-time 2 - Show container count, Ollama status, virt type - Show update staged status via bootc status --json - Dual-run: fastfetch (hardware) then MiOS dashboard (services) - tty0/console safe: ANSI color only, no Unicode box chars profile.d/mios-motd.sh: - Bump version; run both fastfetch and motd (was fastfetch-or-motd) cockpit WSL2 fix: - cockpit.service.d/10-mios-wsl2.conf: After=systemd-logind.service and dbus-daemon-wsl.service; TimeoutStartSec=90 for TLS cert gen - cockpit.socket.d/10-mios-wsl2.conf: clear After=libvirtd.socket, replace with After=dbus-daemon-wsl.service to avoid activation delay Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5f95035 commit 2ca688e

4 files changed

Lines changed: 121 additions & 63 deletions

File tree

usr/lib/profile.d/mios-motd.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
# MiOS v0.2.0 — Terminal/TTY dashboard
2-
# Shows fastfetch services panel on interactive login.
3-
# Suppress with: export MIOS_NO_MOTD=1
4-
if [[ $- == *i* ]] && [ -z "${MIOS_NO_MOTD:-}" ]; then
1+
# MiOS v0.2.2 -- System dashboard on interactive login.
2+
# fastfetch for hardware overview, then MiOS service dashboard.
3+
# Suppress: export MIOS_NO_MOTD=1
4+
if [[ $- == *i* ]] && [[ -z "${MIOS_NO_MOTD:-}" ]]; then
55
if command -v fastfetch &>/dev/null; then
66
fastfetch 2>/dev/null || true
7-
elif [[ -x /usr/libexec/mios/motd ]]; then
7+
fi
8+
if [[ -x /usr/libexec/mios/motd ]]; then
89
/usr/libexec/mios/motd 2>/dev/null || true
910
fi
1011
fi
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[Unit]
2+
# cockpit-ws uses systemd-logind varlink for session management.
3+
# In WSL2, logind retries at boot -- wait for it to be fully active.
4+
After=systemd-logind.service dbus-daemon-wsl.service
5+
6+
[Service]
7+
# Give cockpit-ws extra time to initialize TLS certs on first run
8+
TimeoutStartSec=90
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[Unit]
2+
# In WSL2, remove the libvirtd.socket ordering -- libvirtd works fine
3+
# but the ordering causes an unnecessary delay on first connection.
4+
After=
5+
After=dbus-daemon-wsl.service

usr/libexec/mios/motd

Lines changed: 102 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,129 @@
11
#!/bin/bash
2-
# MiOS v0.2.0 — Enhanced MOTD Dashboard
3-
# Natively supports Role, MOK, and Update status (v0.2.0 baseline).
2+
# MiOS v0.2.2 -- System Dashboard (MOTD)
3+
# ASCII-safe, tty0/console compatible.
4+
# Suppress: export MIOS_NO_MOTD=1
45
[[ $- != *i* ]] && exit 0
5-
[[ -n "$MIOS_NO_MOTD" ]] && exit 0
6+
[[ -n "${MIOS_NO_MOTD:-}" ]] && exit 0
67

7-
_ip() { ip -4 route get v0.2.0.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' | head -1; }
8-
IP=$(_ip); [[ -z "$IP" ]] && IP="v0.2.0.1"
9-
HN=$(hostname -s 2>/dev/null || echo "MiOS")
10-
_l() { printf '\e]8;;%s\e\\%s\e]8;;\e\\' "$1" "$2"; }
11-
C=$'\033[0;36m';W=$'\033[1;37m';G=$'\033[0;32m';Y=$'\033[0;33m';R=$'\033[0;31m';D=$'\033[0;90m';N=$'\033[0m'
8+
# ── Colors (ANSI basic -- safe for all TTYs) ─────────────────────────────────
9+
C=$'\033[0;36m' # cyan
10+
W=$'\033[1;37m' # bold white
11+
G=$'\033[0;32m' # green
12+
Y=$'\033[0;33m' # yellow
13+
R=$'\033[0;31m' # red
14+
D=$'\033[0;90m' # dark gray
15+
N=$'\033[0m' # reset
1216

13-
_s() {
17+
# ── Helpers ───────────────────────────────────────────────────────────────────
18+
_ip() {
19+
ip -4 route get 1.1.1.1 2>/dev/null \
20+
| awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' \
21+
| head -1
22+
}
23+
_svc() { # _svc <unit> -- prints [OK] or [ ] in color
1424
if systemctl is-active --quiet "$1" 2>/dev/null; then
15-
printf '%s' "${G}${N}"
25+
printf '%s[OK]%s' "$G" "$N"
1626
else
17-
printf '%s' "${D}${N}"
27+
printf '%s[ ]%s' "$D" "$N"
1828
fi
1929
}
30+
_cnt() { printf '%d' "$(systemctl is-active --quiet "$1" 2>/dev/null && echo 1 || echo 0)"; }
31+
_bar() { # _bar <used_pct> <width>
32+
local pct=$1 w=$2 filled empty
33+
filled=$(( pct * w / 100 ))
34+
empty=$(( w - filled ))
35+
printf '['; printf '%*s' "$filled" '' | tr ' ' '='; printf '%*s' "$empty" '' | tr ' ' '-'; printf '] %3d%%' "$pct"
36+
}
2037

21-
# ── Header ──────────────────────────────────────────────────────────────────
22-
echo ""
23-
printf '%s\n' "${C}════════════════════════════════════════════════════════════${N}"
24-
printf '%s\n' "${W} MiOS v0.2.0${N} ${D}${HN}${IP}${N}"
25-
printf '%s\n' "${C}════════════════════════════════════════════════════════════${N}"
38+
IP=$( _ip); [[ -z "$IP" ]] && IP="(no route)"
39+
HN=$( hostname -s 2>/dev/null || echo "mios")
40+
VIRT=$(systemd-detect-virt 2>/dev/null || echo "none")
2641

27-
# ── Status Row (Role, Update, MOK) ──────────────────────────────────────────
28-
ROLE=$(grep "^ROLE=" /var/lib/mios/role.active 2>/dev/null | cut -d= -f2 || echo "unknown")
29-
case "$ROLE" in
30-
desktop) ROLE_STR="${G}Desktop${N}" ;;
31-
headless) ROLE_STR="${W}Headless${N}" ;;
32-
k3s*) ROLE_STR="${C}K3s Master${N}" ;;
33-
*) ROLE_STR="${Y}${ROLE}${N}" ;;
34-
esac
42+
# ── Hardware stats ────────────────────────────────────────────────────────────
43+
CPU_PCT=$(top -bn1 2>/dev/null | awk '/^%Cpu/{printf "%.0f", 100-$8}' || echo "?")
44+
MEM_TOTAL=$(awk '/MemTotal/{print int($2/1024)}' /proc/meminfo 2>/dev/null || echo "?")
45+
MEM_AVAIL=$(awk '/MemAvailable/{print int($2/1024)}' /proc/meminfo 2>/dev/null || echo "?")
46+
MEM_USED=$(( MEM_TOTAL - MEM_AVAIL ))
47+
MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))
48+
DISK_PCT=$(df / 2>/dev/null | awk 'NR==2{sub(/%/,"",$5); print $5}' || echo "?")
49+
UPTIME=$(uptime -p 2>/dev/null | sed 's/^up //' || echo "?")
3550

36-
MOK_STATUS="${R}✗ Unverified${N}"
37-
if command -v mokutil &>/dev/null; then
38-
if mokutil --sb-state 2>/dev/null | grep -q "enabled"; then
39-
MOK_STATUS="${G}✓ Secure Boot${N}"
51+
# ── MiOS-specific state ───────────────────────────────────────────────────────
52+
ROLE=$( grep -m1 "^ROLE=" /var/lib/mios/role.active 2>/dev/null | cut -d= -f2 || echo "default")
53+
IMG_REF=$(bootc status --json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('booted',{}).get('image',{}).get('image',{}).get('image',''))" 2>/dev/null || echo "")
54+
[[ -z "$IMG_REF" ]] && IMG_REF=$(cat /usr/lib/os-release 2>/dev/null | grep PRETTY | cut -d= -f2 | tr -d '"' || echo "MiOS $MiosVersion")
55+
56+
UPDATE_STR="${D}[ ] current${N}"
57+
if command -v bootc &>/dev/null; then
58+
STAGED=$(bootc status --json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('staged') or '')" 2>/dev/null)
59+
if [[ -n "$STAGED" && "$STAGED" != "None" ]]; then
60+
UPDATE_STR="${Y}[!!] update staged${N}"
4061
else
41-
MOK_STATUS="${Y}○ SB Disabled${N}"
62+
UPDATE_STR="${G}[OK] up-to-date${N}"
4263
fi
4364
fi
4465

45-
UP_STATUS="${D}Check with 'mios update'${N}"
46-
if command -v bootc &>/dev/null; then
47-
STAGED=$(bootc status --json 2>/dev/null | jq -r '.staged.image.image.repository' 2>/dev/null)
48-
if [[ "$STAGED" != "null" && -n "$STAGED" ]]; then
49-
UP_STATUS="${Y}⚠ Update Staged${N}"
66+
BOOT_STR="${D}[ ] standard${N}"
67+
if command -v mokutil &>/dev/null; then
68+
if mokutil --sb-state 2>/dev/null | grep -q "enabled"; then
69+
BOOT_STR="${G}[OK] Secure Boot${N}"
5070
else
51-
UP_STATUS="${G}✓ Up-to-date${N}"
71+
BOOT_STR="${Y}[ ] SB off${N}"
5272
fi
5373
fi
5474

55-
printf ' Role: %-15s Update: %-15s Boot: %s\n' "$ROLE_STR" "$UP_STATUS" "$MOK_STATUS"
56-
echo ""
57-
58-
# ── Management ──────────────────────────────────────────────────────────────
59-
printf '%s\n' "${W} Management Interfaces${N}"
60-
printf '%s\n' " $(_s cockpit.socket) Cockpit $(_l "https://${IP}:9090" "https://${IP}:9090")"
61-
printf '%s\n' " $(_s sshd) SSH $(_l "ssh://${IP}" "${IP}:22")"
62-
63-
if systemctl is-active --quiet gnome-remote-desktop 2>/dev/null; then
64-
printf '%s\n' " ${G}${N} Remote Login $(_l "rdp://${IP}:3389" "${IP}:3389") ${D}(GRD)${N}"
75+
# ── AI stack ──────────────────────────────────────────────────────────────────
76+
AI_EP=$(grep -m1 "^endpoint" /etc/mios/ai/config.json 2>/dev/null | grep -oP 'http[^"]+' || echo "http://localhost:8080/v1")
77+
AI_MODEL=$(grep -m1 "^MIOS_AI_MODEL" /etc/mios/install.env 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "qwen2.5-coder:7b")
78+
AI_PING="${D}[ ] offline${N}"
79+
if curl -sf --max-time 2 "${AI_EP}/models" &>/dev/null; then
80+
AI_PING="${G}[OK] online${N}"
6581
fi
6682

67-
if podman ps --format '{{.Names}}' 2>/dev/null | grep -q mios-guacamole; then
68-
printf '%s\n' " ${G}${N} Browser Desktop $(_l "http://${IP}:8080/guacamole/" "http://${IP}:8080/guacamole/")"
69-
fi
83+
CONTAINERS=$(podman ps -q 2>/dev/null | wc -l)
84+
85+
# ── Draw ──────────────────────────────────────────────────────────────────────
86+
W60="============================================================"
87+
S60="------------------------------------------------------------"
7088

71-
# ── Infrastructure ──────────────────────────────────────────────────────────
7289
echo ""
73-
printf '%s\n' "${W} Infrastructure Status${N}"
74-
printf '%s\n' " $(_s firewalld) Firewall ${D}firewall-cmd --list-all${N}"
75-
printf '%s\n' " $(_s podman.socket) Podman ${D}$(podman ps -q 2>/dev/null | wc -l) containers${N}"
76-
printf '%s\n' " $(_s libvirtd.socket) Libvirt ${D}virt-manager / virsh${N}"
90+
printf '%s\n' "${C}+${W60}+${N}"
91+
printf '%s\n' "${W}| MiOS v0.2.2 -- ${HN}$(printf '%*s' $((42 - ${#HN})) '')${D}${IP}${N} ${W}|${N}"
92+
printf '%s\n' "${C}+${S60}+${N}"
93+
printf " %-12s %s\n" "Role:" "$ROLE"
94+
printf " %-12s %s\n" "Image:" "$IMG_REF"
95+
printf " %-12s %s %-12s %s\n" "Update:" "$UPDATE_STR" "Boot:" "$BOOT_STR"
96+
printf " %-12s %s\n" "Virt:" "$VIRT"
97+
printf '%s\n' "${C}+${S60}+${N}"
98+
echo ""
99+
printf ' %s\n' "${W}System Resources${N}"
100+
printf ' %-10s ' "CPU:"; _bar "${CPU_PCT:-0}" 30; echo ""
101+
printf ' %-10s ' "Memory:"; _bar "$MEM_PCT" 30; printf ' %dM / %dM\n' "$MEM_USED" "$MEM_TOTAL"
102+
printf ' %-10s ' "Disk /": _bar "${DISK_PCT:-0}" 30; echo " $(df -h / 2>/dev/null | awk 'NR==2{print $3"/"$2}')"
103+
printf ' %-10s %s\n' "Uptime:" "$UPTIME"
104+
echo ""
105+
printf '%s\n' "${C}+${S60}+${N}"
106+
printf ' %s\n' "${W}Services${N}"
107+
printf ' %s %-20s %s\n' "$(_svc cockpit.socket)" "Cockpit" "https://${IP}:9090"
108+
printf ' %s %-20s %s\n' "$(_svc sshd)" "SSH" "${IP}:22"
109+
printf ' %s %-20s %s\n' "$(_svc podman.socket)" "Podman" "${CONTAINERS} containers running"
110+
printf ' %s %-20s %s\n' "$(_svc firewalld)" "Firewall" "firewall-cmd --list-all"
111+
printf ' %s %-20s %s\n' "$(_svc libvirtd.socket)" "Libvirt" "virsh / virt-manager"
112+
printf ' %s %-20s %s\n' "$(_svc ollama.service)" "Ollama" "ollama list"
113+
printf ' %s %-20s %s\n' "$(_svc mios-ai.service)" "LocalAI" "$AI_EP model: $AI_MODEL"
77114

78-
# Optional
79-
if systemctl is-active --quiet k3s.service 2>/dev/null; then
80-
printf '%s\n' " ${G}${N} K3s API $(_l "https://${IP}:6443" "https://${IP}:6443")"
81-
fi
115+
# AI status
116+
printf ' %-24s %s\n' " AI endpoint:" "$AI_PING"
117+
118+
# Optional services
119+
systemctl is-active --quiet k3s.service 2>/dev/null && \
120+
printf ' %s %-20s %s\n' "${G}[OK]${N}" "K3s API" "https://${IP}:6443"
121+
122+
systemctl is-active --quiet gnome-remote-desktop 2>/dev/null && \
123+
printf ' %s %-20s %s\n' "${G}[OK]${N}" "Remote Desktop (GRD)" "${IP}:3389 (RDP)"
82124

83125
echo ""
84-
printf '%s\n' " ${D}Type 'mios' for management options. Output hidden via MIOS_NO_MOTD=1${N}"
126+
printf '%s\n' "${C}+${S60}+${N}"
127+
printf ' %s\n' "${D}Commands: mios | just build | bootc upgrade | MIOS_NO_MOTD=1 to suppress${N}"
128+
printf '%s\n' "${C}+${W60}+${N}"
85129
echo ""

0 commit comments

Comments
 (0)