@crvouga/dev-fleet 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -7
- package/agents/audit.md +18 -18
- package/ansible/agents/agents.yml +134 -0
- package/ansible/agents/templates/antigravity.settings.json.j2 +3 -0
- package/ansible/agents/templates/claude.settings.json.j2 +3 -0
- package/ansible/agents/templates/codex.config.toml.j2 +11 -0
- package/ansible/agents/templates/gemini.settings.json.j2 +14 -0
- package/ansible/agents/templates/grok.config.toml.j2 +19 -0
- package/ansible/agents/templates/opencode.json.j2 +24 -0
- package/ansible/agents/templates/receipt.json.j2 +10 -0
- package/ansible/ansible.cfg +14 -0
- package/ansible/github/git.yml +82 -0
- package/ansible/macos/manager-privilege.yml +83 -0
- package/ansible/macos/manager.yml +164 -9
- package/ansible/macos/policy.json +13 -0
- package/ansible/macos/t3-policy.yml +5 -3
- package/ansible/macos/vault-renew.yml +85 -0
- package/ansible/macos/worker-host-key.yml +33 -0
- package/ansible/monitoring/agent-darwin.yml +3 -0
- package/ansible/monitoring/agent.yml +2 -0
- package/ansible/monitoring/hub-darwin.yml +3 -0
- package/ansible/monitoring/hub-route-darwin.yml +1 -0
- package/ansible/net/remote-probe.sh +4 -1
- package/ansible/platforms.json +2 -2
- package/ansible/pyproject.toml +5 -0
- package/ansible/ubuntu/baseline.yml +39 -13
- package/ansible/ubuntu/disk-gc.py +6 -2
- package/ansible/ubuntu/firewall.nft.j2 +50 -0
- package/ansible/ubuntu/policy.json +125 -6
- package/ansible/ubuntu/reboot.yml +89 -0
- package/ansible/ubuntu/recovery.yml +13 -3
- package/ansible/ubuntu/t3/policy.json +3 -0
- package/ansible/ubuntu/t3-desktop.yml +23 -2
- package/ansible/ubuntu/t3-headless.yml +128 -0
- package/ansible/ubuntu/t3-health.sh +24 -10
- package/ansible/ubuntu/t3-idle.py +37 -2
- package/ansible/ubuntu/t3-policy.yml +4 -1
- package/ansible/ubuntu/t3-route.yml +1 -0
- package/ansible/ubuntu/tailscale.yml +54 -8
- package/ansible/ubuntu/tasks/browser.yml +3 -0
- package/ansible/ubuntu/tasks/containers-off.yml +43 -0
- package/ansible/ubuntu/tasks/docker.yml +53 -6
- package/ansible/ubuntu/tasks/dpkg.yml +4 -0
- package/ansible/ubuntu/tasks/features.yml +22 -0
- package/ansible/ubuntu/tasks/firewall.yml +172 -0
- package/ansible/ubuntu/tasks/install.yml +2 -1
- package/ansible/ubuntu/tasks/packages.yml +4 -2
- package/ansible/ubuntu/tasks/release.yml +6 -0
- package/ansible/ubuntu/tasks/resources.yml +6 -4
- package/ansible/ubuntu/tasks/services.yml +2 -2
- package/ansible/ubuntu/tasks/sizing.yml +49 -0
- package/ansible/ubuntu/tasks/snapshot.yml +14 -3
- package/ansible/ubuntu/tasks/ssh.yml +61 -4
- package/ansible/ubuntu/tasks/t3-restart.yml +3 -1
- package/ansible/ubuntu/tasks/user.yml +1 -0
- package/ansible/ubuntu/worker-account.yml +117 -0
- package/ansible/uv.lock +265 -0
- package/bin/devfleet.mjs +42 -4
- package/bootstrap/fleet-remote-bootstrap.sh +91 -25
- package/bootstrap/global-config.ts +29 -3
- package/bootstrap/package-smoke.ts +127 -0
- package/bootstrap/pins.ts +189 -0
- package/bootstrap/release-notes.ts +88 -0
- package/bootstrap/release-version.ts +41 -7
- package/bootstrap/worker-features.ts +114 -0
- package/bootstrap/worker-seed.yaml +65 -0
- package/bootstrap/worker-tools.ts +39 -9
- package/cliproxy/README.md +1 -1
- package/cliproxy/docs/health-workflow.example.yml +20 -143
- package/docs/authentication.md +21 -11
- package/docs/consumer-setup.md +74 -58
- package/docs/convergence.md +67 -0
- package/docs/declared.md +61 -34
- package/docs/machine-setup.md +73 -7
- package/docs/manager-setup.md +34 -0
- package/docs/operations.md +64 -9
- package/docs/releasing.md +49 -1
- package/docs/runbooks.md +112 -7
- package/docs/state.md +23 -11
- package/docs/support-matrix.md +40 -4
- package/docs/topology.md +82 -12
- package/docs/ubuntu-sync.md +98 -42
- package/docs/worker-contract.md +122 -19
- package/docs/worker-requirements.md +107 -0
- package/examples/fleet.json +1 -0
- package/examples/workers-from-infrastructure/main.tf +132 -0
- package/examples/workers-from-infrastructure/worker-records.json +14 -0
- package/llms.txt +3 -1
- package/mise.lock +29 -0
- package/mise.toml +5 -3
- package/package.json +2 -2
- package/schema/check-ids.json +1991 -162
- package/schema/check-ids.schema.json +34 -0
- package/schema/fleet.schema.json +349 -10
- package/schema/output/check.schema.json +1 -1
- package/schema/output/fleet-state-definition.schema.json +14 -0
- package/schema/output/fleet-sync-schedule.schema.json +26 -0
- package/schema/output/fleet-sync.schema.json +18 -0
- package/schema/output/report.schema.json +3 -2
- package/schema/worker-record.schema.json +76 -0
- package/src/agents/converge.ts +140 -24
- package/src/agents/files.ts +2 -32
- package/src/agents/native-verify.ts +34 -3
- package/src/agents/secrets.ts +39 -4
- package/src/check-owners.ts +62 -2
- package/src/check-registry.ts +630 -0
- package/src/cli/agent-guide.ts +3 -3
- package/src/cli/cli.ts +4 -0
- package/src/cli/fleet-manifest.ts +108 -0
- package/src/cli/fleet-node-lifecycle.ts +704 -0
- package/src/cli/fleet-node-park.ts +238 -0
- package/src/cli/fleet-node-seed.ts +167 -0
- package/src/cli/fleet-state.ts +2 -1
- package/src/cli/fleet-sync-checkout.ts +7 -0
- package/src/cli/fleet-sync-enrollment.ts +193 -32
- package/src/cli/fleet-sync-forward.ts +6 -0
- package/src/cli/fleet-sync-manager.ts +123 -8
- package/src/cli/fleet-sync-output.ts +31 -11
- package/src/cli/fleet-sync-plan.ts +65 -9
- package/src/cli/fleet-sync-records.ts +113 -0
- package/src/cli/fleet-sync-remote.ts +172 -15
- package/src/cli/fleet-sync-schedule.ts +14 -4
- package/src/cli/fleet-sync-state.ts +31 -10
- package/src/cli/fleet-sync-vault.ts +152 -26
- package/src/cli/fleet-sync-worker.ts +214 -0
- package/src/cli/fleet-sync.ts +172 -21
- package/src/cli/fleet-validate.ts +277 -0
- package/src/cli/fleet-watch.ts +7 -1
- package/src/cli/fleet.ts +87 -5
- package/src/cli/managed-health.ts +25 -1
- package/src/cli/register-fleet.ts +251 -4
- package/src/cli/registry.ts +47 -0
- package/src/cli/tailnet.ts +43 -10
- package/src/cli/ui-data.ts +3 -1
- package/src/cli/worker-usage-report.ts +63 -0
- package/src/clock.ts +42 -0
- package/src/definition.ts +762 -232
- package/src/diagnostics.ts +5 -2
- package/src/exposure.ts +102 -0
- package/src/fleet-config.ts +3 -1
- package/src/git-identity.ts +76 -3
- package/src/ide/ide.ts +5 -0
- package/src/ide/t3.ts +12 -2
- package/src/input-hashes.ts +6 -0
- package/src/machine/machine-class.ts +59 -0
- package/src/machine/platform.ts +90 -11
- package/src/machine/state.ts +70 -16
- package/src/machine/support-matrix.ts +11 -9
- package/src/machine-health.ts +28 -5
- package/src/manager-health.ts +148 -2
- package/src/manager-sync.ts +89 -8
- package/src/monitoring/beszel.ts +8 -8
- package/src/monitoring/enroll.ts +8 -1
- package/src/monitoring/hub-access.ts +10 -4
- package/src/monitoring/systems.ts +138 -0
- package/src/network-definition.ts +13 -4
- package/src/node-converge-linux.ts +136 -27
- package/src/node-converge.ts +13 -3
- package/src/platform/ansible-receipt.ts +17 -2
- package/src/platform/ansible.ts +40 -4
- package/src/platform/manager-host.ts +25 -8
- package/src/platform/resource-verify.ts +18 -7
- package/src/platform/t3-policy.ts +24 -10
- package/src/platform/t3-service.ts +109 -34
- package/src/platform/ubuntu-release.ts +24 -0
- package/src/platform/ubuntu-verify.ts +31 -3
- package/src/platform/ubuntu-worker.ts +58 -0
- package/src/platform/worker-platform.ts +72 -0
- package/src/protocol.ts +1 -1
- package/src/public-reachability.ts +186 -0
- package/src/remote-bootstrap.ts +50 -12
- package/src/remote-operation.ts +18 -4
- package/src/repair-plan.ts +23 -12
- package/src/report.ts +2 -1
- package/src/schedule-check.ts +21 -2
- package/src/secrets.ts +7 -0
- package/src/service-auth.ts +55 -48
- package/src/ssh-connection.ts +141 -0
- package/src/ssh.ts +63 -24
- package/src/state/store.ts +4 -2
- package/src/state/sync.ts +35 -6
- package/src/state/workers.ts +140 -0
- package/src/t3/pairing.ts +59 -0
- package/src/t3/peer-link.ts +333 -0
- package/src/t3/version.ts +1 -1
- package/src/tailnet-cleanup.ts +185 -0
- package/src/tailnet-control.ts +346 -0
- package/src/tailscale.ts +1 -1
- package/src/toolchain-checks.ts +11 -1
- package/src/types.ts +4 -2
- package/src/worker-account.ts +63 -0
- package/src/worker-activity.ts +303 -0
- package/src/worker-capacity.ts +31 -0
- package/src/worker-credentials.ts +201 -0
- package/src/worker-exposure.ts +388 -0
- package/src/worker-features.ts +201 -0
- package/src/worker-host-checks.ts +71 -20
- package/src/worker-manifest.ts +224 -0
- package/src/worker-parking.ts +70 -0
- package/src/worker-policy.ts +38 -36
- package/src/worker-readiness.ts +15 -3
- package/src/worker-reboot.ts +129 -0
- package/src/worker-records.ts +305 -0
- package/src/worker-seed.ts +143 -0
- package/src/worker-sizing.ts +76 -0
- package/src/cli/schedule-logs.ts +0 -36
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { fleet } from '../fleet-config';
|
|
2
|
+
import { readParked } from '../state/workers';
|
|
3
|
+
import type { TailnetComputer } from '../tailscale';
|
|
4
|
+
import type { FleetNode, NodeReport, Runner } from '../types';
|
|
5
|
+
import { fleetUsage, usageSummary, type WorkerUsage } from '../worker-activity';
|
|
6
|
+
import { parkedCheck, parkedOnline } from '../worker-parking';
|
|
7
|
+
|
|
8
|
+
/** The workers fleet-status contacts: every one that is not parked. */
|
|
9
|
+
export function activeNodes(nodes: FleetNode[]): FleetNode[] {
|
|
10
|
+
const parked = readParked();
|
|
11
|
+
return nodes.filter((node) => !parked[node.id]);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function reportOf(reports: NodeReport[], id: string): NodeReport {
|
|
15
|
+
const worker = fleet.workers.find((entry) => entry.id === id);
|
|
16
|
+
const found = reports.find(
|
|
17
|
+
(entry) =>
|
|
18
|
+
entry.node === id ||
|
|
19
|
+
(worker?.network && entry.node === worker.network.tailscaleName)
|
|
20
|
+
);
|
|
21
|
+
if (found) return found;
|
|
22
|
+
const added: NodeReport = { node: id, checks: [] };
|
|
23
|
+
reports.push(added);
|
|
24
|
+
return added;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Adds to fleet-status what it says about each worker beyond its health:
|
|
28
|
+
* parked workers as parked (and a warning when one is online anyway), and
|
|
29
|
+
* for every active worker it reaches its uptime, agent turns, last agent
|
|
30
|
+
* activity and `worker:idle`. Returns the `workers` of the JSON output and
|
|
31
|
+
* its `usage` summary.
|
|
32
|
+
*/
|
|
33
|
+
export async function appendUsage(
|
|
34
|
+
reports: NodeReport[],
|
|
35
|
+
nodes: FleetNode[],
|
|
36
|
+
{
|
|
37
|
+
run,
|
|
38
|
+
computers = [],
|
|
39
|
+
now = new Date(),
|
|
40
|
+
}: { run: Runner; computers?: TailnetComputer[]; now?: Date }
|
|
41
|
+
): Promise<{ workers: WorkerUsage[]; usage: ReturnType<typeof usageSummary> }> {
|
|
42
|
+
const parked = readParked();
|
|
43
|
+
for (const worker of fleet.workers) {
|
|
44
|
+
const at = parked[worker.id];
|
|
45
|
+
if (!at) continue;
|
|
46
|
+
const report = reportOf(reports, worker.id);
|
|
47
|
+
report.checks.push(parkedCheck(worker.id, at, now));
|
|
48
|
+
const online = parkedOnline(
|
|
49
|
+
worker.id,
|
|
50
|
+
worker.network?.tailscaleName,
|
|
51
|
+
computers
|
|
52
|
+
);
|
|
53
|
+
if (online) report.checks.push(online);
|
|
54
|
+
}
|
|
55
|
+
const { workers, checks } = await fleetUsage(fleet, {
|
|
56
|
+
nodes: nodes.filter((node) => !parked[node.id]),
|
|
57
|
+
parked,
|
|
58
|
+
run,
|
|
59
|
+
now,
|
|
60
|
+
});
|
|
61
|
+
for (const [id, check] of checks) reportOf(reports, id).checks.push(check);
|
|
62
|
+
return { workers, usage: usageSummary(workers) };
|
|
63
|
+
}
|
package/src/clock.ts
CHANGED
|
@@ -53,6 +53,48 @@ export function clockCheck(
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/** The offset of a worker's clock from the manager's, measured by the
|
|
57
|
+
* manager around one SSH round trip: the worker read its clock between
|
|
58
|
+
* `sentAt` and `receivedAt` (milliseconds on the manager's clock), so the
|
|
59
|
+
* offset is only known to lie in that window. The check judges the smallest
|
|
60
|
+
* offset the window allows, so a slow link never reads as a skewed clock.
|
|
61
|
+
*/
|
|
62
|
+
export function clockOffsetCheck(
|
|
63
|
+
remoteSeconds: number,
|
|
64
|
+
sentAt: number,
|
|
65
|
+
receivedAt: number
|
|
66
|
+
): Check {
|
|
67
|
+
const remote = remoteSeconds * 1000;
|
|
68
|
+
const least =
|
|
69
|
+
remote > receivedAt
|
|
70
|
+
? (remote - receivedAt) / 1000
|
|
71
|
+
: remote < sentAt
|
|
72
|
+
? (sentAt - remote) / 1000
|
|
73
|
+
: 0;
|
|
74
|
+
const direction = remote > receivedAt ? 'ahead of' : 'behind';
|
|
75
|
+
const measured = `${least.toFixed(1)} s ${direction} the manager`;
|
|
76
|
+
const remedy = clockRemedy(undefined);
|
|
77
|
+
if (least > failOffsetSeconds)
|
|
78
|
+
return {
|
|
79
|
+
id: 'worker:clock-offset',
|
|
80
|
+
status: 'fail',
|
|
81
|
+
summary: `CLOCK_SKEWED ${measured}`,
|
|
82
|
+
remedy,
|
|
83
|
+
};
|
|
84
|
+
if (least > warnOffsetSeconds)
|
|
85
|
+
return {
|
|
86
|
+
id: 'worker:clock-offset',
|
|
87
|
+
status: 'warn',
|
|
88
|
+
summary: `CLOCK_DRIFTING ${measured}`,
|
|
89
|
+
remedy,
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
id: 'worker:clock-offset',
|
|
93
|
+
status: 'pass',
|
|
94
|
+
summary: `The clock is within ${warnOffsetSeconds} s of the manager's.`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
56
98
|
function clockRemedy(timeService: number | undefined): { action: string } {
|
|
57
99
|
return {
|
|
58
100
|
action:
|