Edgeweir
Guides

Node upgrades

Staged node upgrades: canary, promotion, signature checks and automatic rollback on the node, and node capabilities.

Concepts

TermDefinition
Canary groupThe node group upgraded first. Other nodes stay Waiting for canary until promotion.
Release sourceThe base URL of node release artifacts, with one v<version>/ directory per version.
Supervisoredgeweir-node supervise --manage-nginx, which downloads, verifies, switches, and rolls back.
Node capabilityA feature flag a node reports. When the cluster configuration needs a capability a node lacks, Clusters & nodes shows Upgrade required.

Prerequisites

ItemRequirement
Cluster nodesEvery enabled node of the cluster: heartbeat within 45 seconds, healthy data plane, current cluster revision applied, Linux, architecture (amd64 or arm64) present in the release, reports self-upgrade-v1
CountAt most 1000 enabled nodes per cluster
ConcurrencyNo other upgrade is in progress on the cluster's nodes
SupervisorThe node runs supervise --manage-nginx (the default of the node image and systemd unit) and finds cosign; when EDGEWEIR_UPGRADE_PUBLIC_KEY is set, that file exists
ArtifactsThe release source's v<version>/ directory holds checksums.txt, checksums.txt.sigstore.json, and the edgeweir-node_<version>_linux_<arch>.tar.gz archives listed in checksums.txt

Nodes that do not meet the supervisor conditions do not report self-upgrade-v1. An install with --allow-unsigned does not install cosign; a host without cosign cannot be upgraded remotely. Node installation is covered in Adding nodes.

Upgrade nodes

  1. Open Clusters & nodes and select the cluster.
  2. In Node upgrades, click New upgrade.
  3. Enter Target version, for example 0.1.0 (the tag v0.1.0 works too), and select Canary node group.
  4. Click Start canary. While the dialog lists Nodes not ready, it cannot start: deal with those nodes first (see below).
  5. Wait until the canary nodes show Succeeded and stay healthy for 30 seconds.
  6. Click Promote remaining nodes. The rest are upgraded in batches: at most a quarter of them at a time (at least one, by node name); when a node succeeds the next one is released.
  7. Verify: the upgrade shows Succeeded; the Agent / engine column of the Nodes list shows the target version.

An upgrade restarts the node's agent. OpenResty runs under the supervisor (node images and packages of this version and later): it keeps serving during an upgrade and reloads the configuration, and bans, CC state and rate-limit counters survive; a rollback to an older version restarts it. An upgrade is not guaranteed to be hitless; choose a canary group whose traffic other nodes can absorb.

The dialog

ItemBehavior
Target versionPrefilled with the latest version of the release source: the latest GitHub release for the default source, a mirror's latest file otherwise (as install.sh reads it), cached by the console for 10 minutes; empty when it cannot be read. When every active node already runs that version or a newer one, the dialog says "Every node runs … or newer" and cannot start (nodes refuse downgrades)
Canary node groupDefaults to a canary node group (Canary turned on in the group's settings) with active nodes, else the non-default group with the fewest active nodes. Options show the active node count; when the chosen group holds every node (more than one), a note says none are left for the rollout
Nodes not readyActive nodes of the cluster that stop the upgrade, with the reason: Upgrade in progress, Offline, Not Linux, Unsupported architecture, No signed upgrades, Data plane unhealthy, Configuration not applied, Behind

Health window

ItemBehavior
ConditionThe canary node reports the target agent version, revision, and content hash, with a healthy data plane
DurationAt least 30 continuous seconds before promotion ("Promote after the canary group stays healthy for 30 seconds.")
RestartAn unhealthy report or a heartbeat gap over 45 seconds restarts the window

States

Upgrade stateMeaning
CanaryThe canary group is upgrading or under observation
RolloutThe remaining nodes are upgraded in batches
Succeeded / Failed / CancelledFinal result
Node stateMeaning
Waiting for canaryNot in the canary group; waits for promotion
QueuedPromoted; waits for the previous batch
PendingSent; the node has not started; shows the deadline
UpgradingThe node is downloading, verifying, or in its trial; shows the deadline
Succeeded / Failed / CancelledThe node's result; Diagnostics shows the details the node reported

Cancellation and expiry

ActionBehavior
Cancel queued workCancels node tasks that are Waiting for canary, Queued or Pending; completed nodes keep their current version; not possible while a node is Upgrading
ExpiryA node task not finished 30 minutes after it was sent shows "Upgrade task expired" and fails the upgrade; the canary group's tasks are sent when the upgrade is created, the others when their batch is released. Observing the canary before promotion has no time limit
Disabled or deleted nodeIts task shows "Node disabled or deleted; not upgraded" and the other nodes go on; with every canary node disabled or deleted the upgrade cannot be promoted: cancel it and start again

Checks on the node

A node accepts only its locally configured release source (--upgrade-source / EDGEWEIR_UPGRADE_SOURCE, default https://github.com/marvinli001/edgeweir-node/releases/download). URLs from the console must match the target version, the local Linux architecture, and the expected file names exactly.

  1. Downloads checksums.txt (up to 2 MiB), checksums.txt.sigstore.json (up to 4 MiB), and the archive (up to 128 MiB) with a 90-second HTTP timeout and at most 4 minutes for the whole staging. Redirects are allowed only to the same scheme and host, at most 5; with the default source, GitHub's download hosts are also allowed.
  2. Verifies checksums.txt with cosign: the certificate identity is fixed to https://github.com/marvinli001/edgeweir-node/.github/workflows/release.yml@refs/tags/v<version> and the issuer to https://token.actions.githubusercontent.com.
  3. Checks that the task's SHA-256 equals the signed manifest, then the archive's SHA-256.
  4. Refuses path traversal, links, special files, and duplicate entries when unpacking; at most 512 entries, 128 MiB per file, 256 MiB in total; checks the ELF architecture and the version printed by edgeweir-node version.
  5. Places the program and Lua in a private directory (0700) under the state directory (default /var/lib/edgeweir-node), persists the state, then switches.

The console cannot send shell commands, replace the key the node trusts, or skip signature checks. Plain-HTTP test mirrors are verified the same way.

Supervisor and rollback

ItemBehavior
ExclusionThe supervisor holds an exclusive lock in the state directory, so a second process never mistakes a running trial for an interrupted one; its private Unix socket has mode 0600
SuccessThe candidate completes mTLS, applies the desired configuration (applied, healthy data plane, revision equal to the console's latest), and stays healthy for at least 10 seconds within a 90-second trial; the agent tells the supervisor every 5 seconds, whatever the heartbeat interval
RollbackFailing within 90 seconds, exiting during the trial, or a supervisor restart restores the previous program, Lua, and configuration snapshot
DowngradeA version older than the node's current one is refused ("Version … was rejected; the previous version is kept") unless the node runs with --upgrade-allow-downgrade
ResultKept on disk until the console acknowledges it; a failed acknowledgment write does not lose it; download, verification, or persistence failures are never reported as success
No regressionIdentity keys, certificates, credentials, and analytics cursors do not roll back with the program
DiskOnly the current, previous, and staging version directories are kept
ComponentUpdate path
Agent program, LuaSigned self-upgrade
Supervisor, cosign, OpenRestyUpdate the node image or deb/rpm packages; security fixes in these components need a full image or package update

After a package or image update changes the installed base program and Lua, the supervisor prefers the new installation over an older self-upgraded version in the state directory; an unacknowledged upgrade task becomes "The task for version … was superseded by a local package update". The console shows the running agent version; running edgeweir-node version from the system path shows the base installation's version.

Private mirrors and own releases

ItemSetting
Console release sourceWhere the console reads release manifests, set in System settings → Node release source, see Node release source
Node release sourceThe node's EDGEWEIR_UPGRADE_SOURCE, pointing at the same base URL with v<version>/ directories
Mirror requirementsThe mirror serves the files directly; nodes refuse cross-origin redirects
Own signing keySet EDGEWEIR_UPGRADE_PUBLIC_KEY on the node to a public key deployed by the operator; the node verifies against that key without the public transparency log; changing the console database cannot change the key a node trusts
Plain-HTTP mirrorEDGEWEIR_UPGRADE_ALLOW_HTTP=true only for deliberately chosen local test or air-gapped mirrors; default false
/etc/default/edgeweir-node
EDGEWEIR_UPGRADE_SOURCE=https://mirror.example.com/edgeweir-node
EDGEWEIR_UPGRADE_PUBLIC_KEY=/etc/edgeweir-node/release.pub

Signing and verification are covered in the Sigstore documentation.

Node capabilities

CapabilityNeeded for
tls-v1Sites whose HTTPS tab has been saved
http01-v1ACME HTTP-01 validation
http3-v1Sites with HTTP/3 on
rules-v1Site rules, global rules, Allow or Block IP lists
rules-v2Rule engine extensions: functions and the new fields, expression targets and query parameter edits, origin overrides, compression rules, the new override settings, cache rule expression conditions and browser TTLs, bulk redirects, origin groups, see Rules
rules-v3Expression fields and header values: cookies and query parameters by name, new fields such as User-Agent and Referer, encoding and hash functions, substring, to_string, wildcard operators, expression values of request headers, response headers, and query parameters, response header append, redirect status 303, and {{time}} and {{path}} in error pages, see Rules
access-logs-v1Access log sampling
geoip-city-v1 / geoip-asn-v1Rules using GeoIP fields; reported only when the node has country / ASN data
geoip-subdivision-v1Rules using ip.geoip.subdivision; reported when the node has a City MMDB, checked by the console only; older nodes that do not report geoip-country-v1 count geoip-city-v1 instead
stats-sequence-v1Sequenced analytics reports; without it the node always shows Upgrade required
self-upgrade-v1Signed upgrades; reported when the supervisor runs and finds cosign
probe-health-v1The health endpoint /.edgeweir/health on the edge listeners; when every active node of a cluster has it, regional probes probe with HTTP / HTTPS, otherwise they only open TCP connections. Never shows Upgrade required
metrics-v1Host metrics in the heartbeat (CPU, load, memory, egress, active connections), reported by Linux nodes; without it node metrics and node-metric scheduling conditions show No data. Never shows Upgrade required
edge-ports-v1The cluster has extra listener ports, a site is bound to ports other than the defaults, or the HTTPS redirect uses a status, port or excluded domains other than the defaults, see HTTPS
client-ip-v1The cluster's client IP is not direct (or drops the client's X-Forwarded-For), or a rule reads ip.peer, see Client IP
l4-v2An L4 app uses a port range, origins on the arriving port or TLS termination, see Layer-4 forwarding
l4-v1The cluster has an enabled L4 app: layer-4 forwarding and L4 statistics. Without it the node refuses configurations with L4 apps, and the port pools tab, the L4 app list, and the dialog warn "Nodes {nodes} of {cluster} lack L4 forwarding and refuse configurations with L4 apps until upgraded"

When a node lacks a capability the cluster's current configuration needs, or lacks stats-sequence-v1, the node list in Clusters & nodes shows Upgrade required; the node keeps its last-known-good configuration and rejects configurations with unknown capabilities or enum values.

The console account (session or AccessKey) can publish a configuration that needs a new capability; nodes without it keep their configuration as above. Service accounts and background jobs that publish such a configuration get 409 NODE_CAPABILITY_REQUIRED.

API

ProcedureEndpointPurpose
upgrades.releaseGET /node-releases/{version}Reads a release manifest: archive, SHA-256, and signature URLs per architecture
upgrades.latestVersionGET /node-upgrades/latest-versionThe latest version of the release source; null when it cannot be told
upgrades.listGET /node-upgradesUpgrades with the state of every node; clusterId limits the list to one cluster
upgrades.createPOST /node-upgradesStarts an upgrade: version (a leading v is dropped), nodeGroupId (canary group)
upgrades.promotePOST /node-upgrades/{id}/promotePromotes the remaining nodes
upgrades.cancelPOST /node-upgrades/{id}/cancelCancels queued work

The endpoints are under /api/v1. Read-only AccessKeys can call the GET endpoints only; service accounts cannot call these procedures.

Limits

ItemDescription
InterruptionAn upgrade restarts the agent; OpenResty restarts only for a rollback to an older version or an update of the node image or package. It is not hitless
PlatformsLinux amd64 and arm64 only
ScopeSelf-upgrade updates only the agent program and Lua

Troubleshooting

SymptomCauseAction
"Use a version such as 0.2.0"Target version is not in major.minor.patch form (optionally with a pre-release suffix such as 1.0.0-rc.1)Correct the version
"These nodes must be online, healthy, in sync and support signed upgrades: …"The listed active nodes (at most 10, the rest as "+N") are offline, have not applied the current revision, have an unhealthy data plane, lack self-upgrade-v1, or have an architecture missing from the releaseFix or disable those nodes and retry
"The node group to upgrade first has no active nodes"The chosen node group has no active nodeChoose another node group
"An upgrade covers at most 1000 nodes"The cluster has more than 1000 active nodesSplit the cluster
"This release manifest is unavailable"The version does not exist, the release source is unreachable, or the manifest lists no Linux archiveCheck the version and the console release source
"The release source must use HTTPS and resolve to an allowed address"The release source saved in System settings → Node release source fails the outbound policySee Node release source
"These nodes already have an unfinished upgrade: …"The listed nodes have a task, or are Upgrading during cancellationWait for the current task to finish
"The upgrade has already finished"Cancelling an upgrade that ended—
"Canary nodes have not passed the health window"The canary group has been healthy for less than 30 secondsWait, then promote
"Version … was rejected; the previous version is kept"Download, signature, checksum, archive, or version check failedRead Diagnostics; check the node release source and public key
"Version … failed the health check and was rolled back"The candidate did not apply the configuration and stay healthy within 90 secondsRead the node logs
"Upgrade task expired"Not finished within 30 minutes after it was sentCheck node connectivity and start again
"The task for version … was superseded by a local package update"The node's package or image was updated before the upgrade was acknowledgedThe installed version applies; start again if needed
"Queued node upgrades were cancelled"Cancel queued work was clicked, or a node failed and the remaining queued tasks stoppedFix the failed node, then start again if needed
Edit on GitHub

On this page