diff --git a/audit/internal/platform/runtime.go b/audit/internal/platform/runtime.go index 6fb2df3..4318ca4 100644 --- a/audit/internal/platform/runtime.go +++ b/audit/internal/platform/runtime.go @@ -55,7 +55,6 @@ func (s *System) CollectRuntimeHealth(exportDir string) (schema.RuntimeHealth, e if err == nil { health.Interfaces = make([]schema.RuntimeInterface, 0, len(interfaces)) hasIPv4 := false - missingIPv4 := false for _, iface := range interfaces { outcome := "no_offer" if len(iface.IPv4) > 0 { @@ -63,8 +62,6 @@ func (s *System) CollectRuntimeHealth(exportDir string) (schema.RuntimeHealth, e hasIPv4 = true } else if strings.EqualFold(iface.State, "DOWN") { outcome = "link_down" - } else { - missingIPv4 = true } health.Interfaces = append(health.Interfaces, schema.RuntimeInterface{ Name: iface.Name, @@ -73,17 +70,9 @@ func (s *System) CollectRuntimeHealth(exportDir string) (schema.RuntimeHealth, e Outcome: outcome, }) } - switch { - case hasIPv4 && !missingIPv4: + if hasIPv4 { health.NetworkStatus = "OK" - case hasIPv4: - health.NetworkStatus = "PARTIAL" - health.Issues = append(health.Issues, schema.RuntimeIssue{ - Code: "dhcp_partial", - Severity: "warning", - Description: "At least one interface did not obtain IPv4 connectivity.", - }) - default: + } else { health.NetworkStatus = "FAILED" health.Issues = append(health.Issues, schema.RuntimeIssue{ Code: "dhcp_failed", diff --git a/audit/internal/webui/pages.go b/audit/internal/webui/pages.go index 470d4ec..8c9b686 100644 --- a/audit/internal/webui/pages.go +++ b/audit/internal/webui/pages.go @@ -647,7 +647,7 @@ func buildRuntimeNetworkRow(health schema.RuntimeHealth) runtimeHealthRow { if status == "" { status = "UNKNOWN" } - issue := runtimeIssueDescriptions(health.Issues, "dhcp_partial", "dhcp_failed") + issue := runtimeIssueDescriptions(health.Issues, "dhcp_failed") return runtimeHealthRow{Title: "Network", Status: status, Source: "ListInterfaces / DHCP", Issue: issue} } @@ -705,12 +705,12 @@ func buildRuntimeServicesRow(health schema.RuntimeHealth) runtimeHealthRow { nonActive := make([]string, 0) for _, svc := range health.Services { state := strings.TrimSpace(strings.ToLower(svc.Status)) - // "activating" and "deactivating" are transient states for oneshot services - // (RemainAfterExit=yes) — the service is running normally, not failed. - // Only "failed" and "inactive" (after services should be running) are problems. + // "inactive" is OK for oneshot services that have completed successfully + // (bee-sshsetup, bee-preflight, bee-audit, bee-network, etc.). + // Only "failed" is a genuine problem. switch state { - case "active", "activating", "deactivating", "reloading": - // OK — service is running or transitioning normally + case "active", "activating", "deactivating", "reloading", "inactive": + // OK — service is running, transitioning normally, or completed successfully default: nonActive = append(nonActive, svc.Name+"="+svc.Status) } diff --git a/iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot b/iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot index 3e4c738..7e2ba00 100755 --- a/iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot +++ b/iso/builder/config/hooks/normal/9000-bee-setup.hook.chroot @@ -69,6 +69,7 @@ chmod +x /usr/local/bin/bee-boot-status 2>/dev/null || true chmod +x /usr/local/bin/bee-install 2>/dev/null || true chmod +x /usr/local/bin/bee-gui-gate 2>/dev/null || true chmod +x /usr/local/bin/bee-remount-medium 2>/dev/null || true +chmod +x /usr/local/bin/bee-check-nvswitch 2>/dev/null || true if [ "$GPU_VENDOR" = "nvidia" ]; then chmod +x /usr/local/bin/bee-nvidia-load 2>/dev/null || true chmod +x /usr/local/bin/bee-gpu-burn 2>/dev/null || true diff --git a/iso/overlay/etc/systemd/system/bee-nvidia.service b/iso/overlay/etc/systemd/system/bee-nvidia.service index 8d31ea1..4b85f4f 100644 --- a/iso/overlay/etc/systemd/system/bee-nvidia.service +++ b/iso/overlay/etc/systemd/system/bee-nvidia.service @@ -2,6 +2,8 @@ Description=Bee: load NVIDIA kernel modules and create device nodes After=local-fs.target udev.service bee-blackbox.service Before=bee-audit.service +# Skip silently if bee-nvidia-load is absent (non-nvidia builds). +ConditionPathExists=/usr/local/bin/bee-nvidia-load [Service] Type=oneshot diff --git a/iso/overlay/etc/systemd/system/nvidia-fabricmanager.service.d/bee-nvswitch-check.conf b/iso/overlay/etc/systemd/system/nvidia-fabricmanager.service.d/bee-nvswitch-check.conf new file mode 100644 index 0000000..219e2d1 --- /dev/null +++ b/iso/overlay/etc/systemd/system/nvidia-fabricmanager.service.d/bee-nvswitch-check.conf @@ -0,0 +1,4 @@ +[Service] +# Skip fabricmanager on systems without NVSwitch hardware. +# ExecCondition exits 1-254 → unit is silently skipped (inactive, not failed). +ExecCondition=/usr/local/bin/bee-check-nvswitch diff --git a/iso/overlay/usr/local/bin/bee-boot-status b/iso/overlay/usr/local/bin/bee-boot-status index 702c41b..9438bc2 100644 --- a/iso/overlay/usr/local/bin/bee-boot-status +++ b/iso/overlay/usr/local/bin/bee-boot-status @@ -3,8 +3,14 @@ # Shows live service status until all bee services are done or failed, # then exits so getty can show the login prompt. -CRITICAL="bee-preflight bee-nvidia bee-audit" -ALL="bee-sshsetup ssh bee-network bee-nvidia bee-preflight bee-audit bee-web" +GPU_VENDOR="$(cat /etc/bee-gpu-vendor 2>/dev/null || echo nvidia)" +if [ "$GPU_VENDOR" = "nvidia" ]; then + CRITICAL="bee-preflight bee-nvidia bee-audit" + ALL="bee-sshsetup ssh bee-network bee-nvidia bee-preflight bee-audit bee-web" +else + CRITICAL="bee-preflight bee-audit" + ALL="bee-sshsetup ssh bee-network bee-preflight bee-audit bee-web" +fi svc_state() { systemctl is-active "$1.service" 2>/dev/null || echo "inactive"; } diff --git a/iso/overlay/usr/local/bin/bee-check-nvswitch b/iso/overlay/usr/local/bin/bee-check-nvswitch new file mode 100644 index 0000000..f662ce1 --- /dev/null +++ b/iso/overlay/usr/local/bin/bee-check-nvswitch @@ -0,0 +1,4 @@ +#!/bin/sh +# Exit 0 if NVSwitch hardware is detected; exit 1 to skip fabricmanager on non-NVSwitch systems. +# NVSwitch appears in lspci as vendor 10de, class 0680 (Bridge, Other). +lspci -Dn 2>/dev/null | awk '$2 == "0680:" && $3 ~ /^10de:/ { found=1; exit } END { exit(found ? 0 : 1) }'