Skip to content

fog-agent updates: modes, update rings, a minimum version, and a server copy of each release - #1759

Merged
fog-workflows[bot] merged 4 commits into
working-1.6from
feat/agent-update-rings
Sep 11, 2026
Merged

fog-agent updates: modes, update rings, a minimum version, and a server copy of each release#1759
fog-workflows[bot] merged 4 commits into
working-1.6from
feat/agent-update-rings

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

Summary

fog-agent updates get three modes, update rings, a minimum version, and a server-side copy of every release. Agents take the manifest and the file from this server instead of from GitHub.

This is the server half of design 0015 as changed on 2026-09-11. The agent half is FOGProject/fog-agent#17.

What changed

Modes (FOG_AGENT_UPDATE_MODE). Off, Pinned or Latest. Before this, an empty FOG_AGENT_DESIRED_VERSION meant off, and there was no way to follow the newest release. Schema 438 sets Pinned on a server that already named a version and Off on every other server, so an upgrade starts no updates. A host's own Desired Agent Version still wins over every mode.

Latest is resolved on the server. The agent still receives an exact version, so agents already in the field follow Latest with no change. The newest release is chosen from the signed manifest that the new daemon downloads. A host is never moved below the version it runs, unless that version was withdrawn from the manifest.

Update rings (FOG_AGENT_UPDATE_RINGS, host agentUpdateRing). The rings are delays in days, default 0,3,7, counted from when this server first saw a release. The ring is a host column, set on the host form or by mass edit (ADR 0038 decision 1). A blank ring is the last ring, so a new host is never among the first to update.

Minimum version (FOG_AGENT_MIN_VERSION). It is a floor in every mode. A pinned version, a host override or a ring delay below it is raised to it. A host that runs a release below it is raised to it even in Off mode. A lab build (0.1.7-2-gabc) is left alone, because PHP's version_compare() and the agent's semver order it differently. The settings page and the host form refuse to save a pin or an override below the minimum. The minimum must be a version in the manifest once one has synced.

Server copy of releases (FOGAgentReleaseSync, agentReleaseArtifacts). A new non-root daemon downloads the manifest and its signature. It indexes every file and downloads the files that enrolled hosts need into /opt/fog/agent/versions/<version>/. It keeps each version a host runs or is told to run, plus the newest FOG_AGENT_KEEP_VERSIONS (default 3). It stays idle while the mode is Off, no host has an override, and no minimum is set. The update block now carries manifest, signature and artifact. GET /agent/v1/payload/update/{id} serves only the file of the version the host is told to run.

The server does not verify the signature. Every agent verifies the signature and each file's hash against the root compiled into it. The server checks each file's size and sha256 before it records the file, so it does not serve junk.

Settings grouping. Every setting that only fog-agent reads moves to FOG Agent. Directory placement moves to FOG Agent - Directory Placement. FOG_GRACE_TIMEOUT and FOG_TASK_FORCE_REBOOT are read by both clients. They stay where they are, and their text says the agent reads them. One setting cannot render in two panels, because the settings form names each input by the setting, and the second copy overwrites the edit.

Corrected text. FOG_AGENT_UPDATE_MANIFEST_URL said a mirror serves a site with no internet access. It did not: each file comes from the address inside the signed manifest.

Verification

Lab run on the 1.6 lab server, against the real signed manifest at fogproject.org. The lab VM (host 239) ran a fog-agent#17 build stamped v0.1.7-2-gf344ed3.

  • Deploy applied schema 438. The FOG_AGENT_* settings moved to FOG Agent, and FOG_AGENT_UPDATE_MODE came out off because the pinned version was empty.
  • With host 239's own desired version set to 0.1.7, one sync indexed 48 files. It downloaded 0.1.7 for linux/amd64 and windows/amd64, the two platforms of the enrolled hosts. The stored linux file hashed to the manifest's sha256 (5b257450…), and the web user owns every file.
  • The poll's update block carried manifest, signature and artifact: 43. nginx logged GET /fog/agent/v1/payload/update/43 200 7032994, which is the manifest's size for that file. The agent journal logged update: applied (v0.1.7-2-gf344ed3 -> 0.1.7, restarting), then probation, then 0.1.7 polled successfully. The VM's binary now hashes to the manifest's sha256, and host 239 shows ok.
  • Resolved against the real first-seen times: Latest ring 0 → 0.1.7, rings 1, 2 and blank → stay on 0.1.6. Off with minimum 0.1.7 → a 0.1.5 host gets 0.1.7, and the lab build is left alone. Pinned 0.1.5 with minimum 0.1.6 → 0.1.6.
  • FOGAgentReleaseSync, run as the web user for one pass, logged Agent releases are current (48 files in the manifest).

Not run on the lab: the settings-page and host-form refusals, and the mass-edit ring picker. The browser session sits behind OIDC sign-in. The pure checks cover their logic, and phpstan covers the pages.

  • tests/agent-update-rings.test.php: 45 checks. Each of 16 defects was put back one at a time, and the test went red each time.
  • sh tests/run-all.sh: 357 passed, 0 failed before the merge of working-1.6 (Let mass edit set the rest of a host's General tab #1758). CI runs the merged tree.
  • phpstan, source and tests: clean before the merge. It first reported four $set might not be defined in the new settings cases, fixed at the cause rather than baselined.

🤖 Generated with Claude Code

https://claude.ai/code/session_013Sbto9eLVhLiCPyGERUZ27

mastacontrola and others added 2 commits September 11, 2026 06:41
…er copy of each release

FOG_AGENT_UPDATE_MODE is Off, Pinned or Latest. Before this, an empty
FOG_AGENT_DESIRED_VERSION meant off, and no setting followed the newest
release. Schema 438 sets Pinned on a server that named a version and Off
on every other server, so an upgrade starts no updates.

The server resolves Latest, so the agent still receives an exact version.
Update rings are delays in days (FOG_AGENT_UPDATE_RINGS, default 0,3,7),
counted from when this server first saw a release. The ring is a host
column, set on the host form or by mass edit. A blank ring is the last
ring. A host never moves below the version it runs, unless that version
left the manifest.

FOG_AGENT_MIN_VERSION is a floor in every mode. It raises a pin, an
override or a ring delay below it, and it raises a host below it even in
Off mode. The settings page and the host form refuse a pin or an
override below it.

FOGAgentReleaseSync downloads the signed manifest and the files enrolled
hosts need into /opt/fog/agent/versions/<version>/, and keeps the newest
FOG_AGENT_KEEP_VERSIONS (default 3) plus every version a host needs. The
update block carries the manifest, the signature and a payload id, and
GET /agent/v1/payload/update/{id} serves the file. Every agent still
verifies the signature and the hash itself.

Every setting only fog-agent reads moves to the FOG Agent category.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Sbto9eLVhLiCPyGERUZ27
…ate-rings

# Conflicts:
#	tests/mass-edit-form.test.php
@fog-workflows
fog-workflows Bot enabled auto-merge September 11, 2026 11:47
fog-workflows Bot and others added 2 commits September 11, 2026 11:48
…ipts executable

The suite on the merged tree failed two checks:

- psr4-layout: Releases extends FOGBase, so no rule places it. It goes in
  TABLE under Agent, beside Update, which it serves.
- alpine-openrc-services W: installInitScript copies with cp -f, which keeps
  the source mode. The new init scripts were committed 0644, so OpenRC could
  not run the Alpine one. All three are now 0755.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Sbto9eLVhLiCPyGERUZ27
@fog-workflows
fog-workflows Bot added this pull request to the merge queue Sep 11, 2026
Merged via the queue into working-1.6 with commit 3b7a8fa Sep 11, 2026
10 checks passed
@fog-workflows
fog-workflows Bot deleted the feat/agent-update-rings branch September 11, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant