fix: authenticate unwatched hosts during the status probe (#1337)

With metrics enabled, the status probe left SSH authentication to the
metrics poll - which only runs while someone is viewing the host. An
unwatched host therefore never left "reachable", while a host with
metrics disabled (whose probe always authenticates) showed online. The
probe now authenticates whenever no metrics poll will.
This commit is contained in:
ZacharyZcR
2026-08-25 02:14:51 +08:00
committed by GitHub
parent 404608867f
commit c17134a2a4
3 changed files with 28 additions and 1 deletions
@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import {
needsStatusPollAuthentication,
statusAfterAuthentication,
statusAfterReachabilityCheck,
} from "./host-status.js";
@@ -21,4 +22,11 @@ describe("host availability status", () => {
expect(statusAfterAuthentication(false, "online")).toBe("reachable");
expect(statusAfterAuthentication(false, "offline")).toBe("offline");
});
it("authenticates in the status probe unless a metrics poll will do it", () => {
expect(needsStatusPollAuthentication(false, false)).toBe(true);
expect(needsStatusPollAuthentication(false, true)).toBe(true);
expect(needsStatusPollAuthentication(true, false)).toBe(true);
expect(needsStatusPollAuthentication(true, true)).toBe(false);
});
});
+15
View File
@@ -15,3 +15,18 @@ export function statusAfterAuthentication(
if (authenticated) return "online";
return current === "offline" ? "offline" : "reachable";
}
/**
* Whether the cheap status probe must also authenticate over SSH.
*
* "online" means authenticated, and normally the metrics poll proves that.
* That poll only runs while someone is viewing the host, so an unwatched host
* with metrics enabled would otherwise never leave "reachable" - while a host
* with metrics disabled, whose probe always authenticates, shows online.
*/
export function needsStatusPollAuthentication(
metricsEnabled: boolean,
hasViewers: boolean,
): boolean {
return !metricsEnabled || !hasViewers;
}
+5 -1
View File
@@ -71,6 +71,7 @@ import {
} from "./helpers.js";
import {
type HostStatus,
needsStatusPollAuthentication,
statusAfterAuthentication,
statusAfterReachabilityCheck,
} from "./host-status.js";
@@ -581,7 +582,10 @@ class PollingManager {
if (
isOnline &&
supportsMetrics(refreshedHost) &&
!config?.statsConfig.metricsEnabled
needsStatusPollAuthentication(
!!config?.statsConfig.metricsEnabled,
this.activeViewers.has(refreshedHost.id),
)
) {
try {
await withSshConnection(refreshedHost, async () => undefined);