How Qawk is put together

Qawk has two halves. The bottom half is hawkBit's model, which you may already know and which cannot change without breaking every device. The top half is what Qawk adds, and it is built on the bottom half rather than beside it — which is why none of it requires anything new on a device.

The bottom half: hawkBit's model

Four nouns. Everything a device ever sees is made of them.

ThingWhat it is
Target A device. Identified by its controller id — the name it calls in with. Carries attributes it reports about itself and metadata you set from the outside.
Software module One installable thing with a version, holding one or more artifacts (the actual files). A module has a type: os, application, and whatever else you define.
Distribution set A named, versioned bundle of modules — app:1.2.0. This is the unit a device is given. You never assign a module; you assign a set.
Action One attempt to get one set onto one device. It is created when the set is assigned, it is active while the device works on it, and it ends finished or error when the device says so.

A device is in_sync when what it has installed is what it was assigned, pending while an action is open, and error when the last one failed.

Note

Everything reports through the device. Qawk never reaches into a machine. A device polls, is told what to do, does it, and says how it went. Every gate, every threshold, every rollback is driven by those reports — which is also why a device that stops calling in is simply a device Qawk knows nothing new about, rather than a failure.

The top half: what Qawk adds

hawkBit can put a set on a device. It has no opinion about which devices, in what order, under what conditions, or what to do when it goes wrong. That is the part Qawk is.

Channel (a fleet)

A set of devices that should all run the same release. A channel can have a rule — a query like attribute.ring==beta — and any device matching it that is in no channel yet joins by itself. So a device registering for the first time lands where it belongs, from what it says about itself, with nobody deciding.

Channels chain: beta names dev as its upstream, prod names beta. A release reaches a channel with an upstream only by promotion from it, and only through that channel's gate.

Centre

Where a device physically is — a shop, a site, a bowling centre. The device says so (attribute.centerid by default) and the centre is put in a channel. Every device of that centre follows.

This matters more than it sounds. Without it, moving a site from beta to prod means finding its forty machines and moving them one by one, and getting it wrong silently. With it, you move the place, and the lane computers, the terminals and the standalone machines all go together — because they belong to the place, not to a list someone maintains.

System

Devices that only make sense updated together. A lane computer and the two terminals bolted to it are one machine to the person using them; they are three targets to hawkBit.

A system type (Mender calls it a topology) says what components the system has and how a device declares which system it is in. A manifest says what each component should run, and in what order. The orchestrator applies the manifest to each system in turn: lower orders first, equal orders together, and if one device fails, the whole system goes back to what it was running.

Release

What a channel runs, and the history of what it was asked to run. A release carries a distribution set for the devices that stand alone and, when the channel has systems, a manifest for those — because a lane computer and the terminal under it cannot share one set.

How they fit together

The awkward question is: if a device is in a channel and a centre and a system, who decides what it runs? The answer is a single rule, and it is worth learning:

Good to know

A device that belongs to a system is updated by the orchestrator, never by its channel's set. Everything else in the channel gets the channel's set.

So the three layers do not fight:

  1. The centre decides the channel. If a device's centre is in a channel, that is the device's channel. You cannot move it elsewhere by hand — its centre would take it straight back — though you can lend it to a temporary channel.
  2. The channel decides the release. Which distribution set, and which manifest.
  3. Being in a system decides who delivers it. Standalone devices take the set from the channel. System members take their components' sets from the orchestrator, in the manifest's order.

And a release is only complete when both halves are done: the standalone devices are on the set and the orchestrator has finished with the systems. The next gate checks both, so a release cannot be promoted out of a channel whose systems it never actually reached.

The engine

None of this happens when you press a button. Pressing a button records an intention; a background loop makes it true, every ten seconds:

With several instances of Qawk on one database, exactly one runs that loop: they elect a leader through PostgreSQL, and another takes over within ten seconds if it stops. See Scaling.

Careful

A device with an action under way is waited for, never overtaken. A forced assignment cancels a running action — and a system half armed, or an application half live, would lose the deployment it belongs to. So the channel reaches a busy device on the next pass instead. This is why a wave sometimes appears to skip a machine and pick it up a minute later: it is deliberate.

Glossary

TermMeans
actionOne attempt to put one distribution set on one device.
artifactA file inside a software module. What actually downloads.
attributeSomething a device says about itself, in configData. attribute.ring, attribute.centerid.
centreWhere a device is. Put in a channel; its devices follow.
channel / fleetThe same thing. Devices that should run the same release. "Fleet" is the name in the API and the console; "channel" is the name in this documentation when the pipeline is the point.
componentOne role inside a system type — device1, device2 — with a query saying which devices fill it.
controller idA device's identity. What it calls in with.
DDIhawkBit's Direct Device Integration API: what devices speak.
distribution setA named, versioned bundle of software modules. The unit assigned to a device.
freezeA period in which no release reaches a channel.
gateWhat a channel's upstream must show before a release may be promoted in.
manifestWhat each component of a system type should run, and in what order.
metadataSomething you set on a device from the outside, as opposed to what it reports.
promotionMoving a release from one channel to the next, through the gate.
releaseWhat a channel runs: a set, optionally a manifest, and the history of both.
rollouthawkBit's own staged deployment, with groups and thresholds. A different tool from channels; Qawk has both.
runOne system inside a system deployment.
soft / forcedWhether the device may choose when to install, or is told to do it now.
systemDevices that work together and are updated as one.
system deploymentApplying a manifest to some systems, a few at a time.
targethawkBit's word for a device.
topologyMender's word for a system type.
waveA share of a channel's members given the release at a time.