Skip to Content

Device Agent Commands

The ironflock agent commands connect a Linux machine to IronFlock as a device and look after the device agent from then on. You use them to install the agent, to give it another device configuration or proxy, to update, stop and start it, to read its log, and to remove it again.

The Device Agent

The device agent is the program that connects a machine to IronFlock as a device and runs the apps of the device’s project in Docker. Which device a machine becomes is set by the device configuration file (.flock) that IronFlock Studio gives for each device (Connect Devices).

CommandWhat it doesAsks
agent installinstalls the agent and connects the machine to IronFlock as the device of a .flockyes
agent configuregives the installed agent another .flock or other proxy settingsbefore Docker restarts
agent updatelets the agent update itself to the release of its channel, and follows itbefore the restart
agent removeremoves the agent and undoes what its install changedyes, “No” preselected
agent restartrestarts the agent and checks that it runs againno
agent stopstops the agent until it is started againyes
agent startstarts the agent and checks that it runsno
agent logsshows the agent’s logno

Every agent command needs root and runs on Linux. Without root it ends with exit code 3 and does not call sudo itself (Root Privileges). On macOS the agent commands end with exit code 3 before they look at anything; run them on the Linux machine, or from the Mac with --host. On an IronFlockOS device the image brings the agent with its system: agent install and agent remove refuse there, and agent configure -c enrolls the device with another .flock.

Each command also takes the global flags --yes, --json, --download-base, --host, --hosts and --parallel (Global Flags). A question needs a terminal; without one, give --yes (Questions and Confirmation).

With --host, a command runs on another machine over SSH (Remote Machines over SSH). On several machines at once (--host more than once, or --hosts), agent restart, agent start and agent logs run as they are, but agent logs --follow not with --json. agent stop, agent update, agent configure and agent remove need --yes there, as nobody is asked, and agent configure takes no -c, as a .flock names one device. agent install runs on one machine at a time.

What an Installed Agent Looks Like

Path or unitWhat it is
/opt/ironflock/device-agentthe agent’s folder: the agent, its copy of the .flock (device-config.flock) and the state of its last self-update (update-state.json). When the install brought Docker, or Docker held nothing yet, Docker keeps its images and containers here as well
ironflock-device-agent.servicethe systemd service that runs the agent. It starts at every boot
/var/log/ironflock/device-agent.logthe agent’s log, readable by root alone. agent logs shows it
/opt/ironflock/device-init/installed.jsonthe record of everything the install changed. agent remove undoes exactly that
/etc/ironflock/proxy.envthe proxy settings of Docker and the agent, when there is a proxy. Only root reads it (mode 0600)

The agent also writes a few settings of the host by itself, at every start: the slice ironflock.slice it runs in, which keeps memory for it, the systemd watchdog, the kernel’s crash settings and a cap on the size of the journal.

A machine that an earlier IronFlock installer set up may still have the agent in the legacy layout /opt/reagent (service reagent.service, log /var/log/reagent.log), which the agent moves to /opt/ironflock/device-agent by itself; ironflock status shows which layout a machine has, and the refusals below name the cases where it matters.

ironflock agent install

Installs the device agent in /opt/ironflock/device-agent, Docker when it is missing, and the host defaults of a device, and connects the machine to IronFlock as the device of the .flock. The agent starts right away and updates itself from then on.

ironflock agent install -c <device.flock> [flags]

Runs on: Linux, Debian or Ubuntu based, with systemd; not on IronFlockOS. Root: required. Asks: before it installs the packages and Docker, and for each host default; --yes answers every question with its default.

The machine needs internet access, or the download server given with --download-base (Download Base), or the download mirror of the appliance that the .flock names (Where the Agent Comes From). The hosts a device must reach are listed in Network Requirements.

FlagMeaning
-c, --config <file>the device’s .flock file (required)
--disable-suspendmask the systemd sleep targets: a device that suspends drops off the network
--rebootreboot when the install is done (not needed: the agent starts right away)
--http-proxy <url>corporate HTTP proxy for the downloads, Docker and the agent, such as http://proxy:3128, or http://user@proxy:3128 without the password
--https-proxy <url>corporate HTTPS proxy for the downloads, Docker and the agent, in the same form
--no-proxy <hosts>comma-separated hosts that bypass the proxy; localhost is always added
--proxy-password-file <file>a file or a pipe (/dev/stdin) whose one line is the password of the user that --http-proxy and --https-proxy name

Where the Agent Comes From

The agent is its channel map, its binary, and the binary’s .sha256 and .sig. The command takes them from:

  1. --download-base, else IRONFLOCK_DL_BASE: that server alone.
  2. Else the download mirror of the IronFlock appliance that the .flock names as its update server (update_url), when its host is not one of the IronFlock cloud. A machine that reaches the appliance but not ironflock.com is installed this way. A .flock of the IronFlock cloud takes the cloud.
  3. Else the IronFlock cloud, https://instance-registry.ironflock.com/dl.

The command names the base on stderr: Download base: ... (from the device's .flock), else (from --download-base), (from IRONFLOCK_DL_BASE) or (from default).

With the appliance’s mirror, the files come from the mirror first, and from the same path below the IronFlock cloud’s download base where the mirror does not give them:

  • The channel map — when the mirror gives none now (no answer, none there, an error status), everything comes from the cloud, and the version is the one the cloud’s map names. A map that the mirror gives and that is refused (its signature, no version) fails the install, as from any server.
  • The binary, its .sha256 and its .sig — each one the mirror does not give comes from the cloud. When the mirror’s files do not pass the checks (checksum, signature), all three come from the cloud.

Each fallback is a line Warning: ... on stderr, with the mirror, the file and the reason, and with --json an entry of warnings in the result. When neither the mirror nor the cloud gives a file, the install fails with one error that names both sources and both reasons (neither the appliance's mirror ... nor the IronFlock cloud gives ...).

The mirror is the .flock’s update server, which bypasses the proxy (Proxy). An HTTPS mirror with a certificate of the appliance’s own CA works only where the machine’s system trusts that CA. The distribution’s packages and Docker still come from their own servers, and install.sh and ironflock from ironflock.com; with --host, ironflock goes from your computer to the machine.

Checks Before the Install

Before it changes anything, the command runs the checks of ironflock doctor that tell whether it can succeed: system, systemd, disk_space, clock, dns, proxy, download_tree, device_endpoint, docker_registry and update_server. They run for the .flock of -c, with the download base and the proxy flags of the install.

Four of them stop the install when they fail, because the install would then fail for certain or half way:

CheckFails whenWhy the install stops
systemthe machine is not Linux, or has no aptthe first step, apt, would fail
systemdsystemd does not run the systemthe install restarts Docker and starts the agent with systemctl, after it has recorded its first changes
disk_spaceless than 128 MiB are free in /optthe agent’s binary, about 50 MB, has to fit twice while the install runs
download_treethe download server gives no answer, has no agent for this architecture, or answers with something the install does not take; with the appliance’s mirror, neither the mirror nor the cloud has the agentthe install would fail at its third step, after apt and Docker

The message names the check, its finding and its hint. Every other finding is a warning on stderr, and the install goes on: the agent connects, updates and pulls its apps once the network lets it. A warning or skipped result never stops the install. Run ironflock doctor -c device.flock to see every check before you install.

Steps

  1. Names the packages it installs and asks. Installs them with apt.
  2. Installs Docker when the machine has none, and asks first.
  3. Downloads the agent of the production channel and verifies it against its checksum and its signature. An install that cannot get a verified agent stops here, before any of the following steps.
  4. Configures Docker: the proxy, when one is given, and, for a Docker that this install brought or that holds nothing yet, the data-root in the agent’s folder. A Docker that holds images or containers keeps its configuration and its data.
  5. Sets up the host defaults (table below). Each one is a choice at the terminal; --yes takes the default.
  6. Installs the agent in /opt/ironflock/device-agent and starts it.
Host defaultDefault
an SSH user for the project owner: login by key only, with sudoyes
the WiFi of the .flock, when it has oneyes
no suspend: the systemd sleep targets are maskedno; --disable-suspend makes it yes

The install also adds a login banner. Everything the install changes is written to /opt/ironflock/device-init/installed.json. When a step from step 4 on fails, the error says that the attempt is recorded and that the same command, run again, undoes it first. When the command finds such an earlier attempt, it undoes it once the checks have passed: it lists what it undoes, asks, and then installs again.

Proxy

The proxy flags set the corporate proxy for the downloads of the install, for Docker and for the agent. Each setting comes from its flag, else from the environment variables HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or their lower-case forms).

A proxy URL is http://proxy.example.com:3128; https:// and socks5:// work too, and a URL without a scheme is taken as http://. When the proxy wants a login, the URL names the user without the password, http://[email protected]:3128, and --proxy-password-file gives the password. The command puts the password into the URLs of the flags that name a user.

Warning: Never write the proxy password into the URL. Command lines show up in ps and in the shell history, so a URL with a password is refused as a wrong command line, and the error does not repeat it. Put the password on one line of a file, or pipe it in with --proxy-password-file /dev/stdin (Secrets).

Besides the hosts of --no-proxy, these bypass the proxy (NO_PROXY): localhost, 127.0.0.1 and ::1, and the download server and the update server of the .flock (its update_url) when they are not hosts of the IronFlock cloud, as an appliance or a mirror on the LAN. The hosts of the IronFlock cloud (ironflock.com, ironflock.dev and the hosts below them, and storage.googleapis.com) are on the internet and go through the proxy.

The install writes the proxy of Docker and the agent into /etc/ironflock/proxy.env, which only root reads (mode 0600), and Docker restarts to use it. The systemd drop-ins ironflock-proxy.conf of docker.service and of ironflock-device-agent.service name that file and hold no setting themselves, so systemctl show tells every user the file’s name and nothing of what it holds. A Docker drop-in of the host’s own (docker.service.d/http-proxy.conf) stays; IronFlock’s settings take precedence over its Environment= lines, and a warning names it. A daemon.json with proxies keeps them, as Docker takes those before any other.

To change the settings later, use agent configure. For the proxy of the whole site, see Behind a Corporate Proxy.

Examples

# Install the agent; the command asks before each step sudo ironflock agent install -c device.flock # Install without questions, and keep the device from suspending sudo ironflock agent install -c device.flock --yes --disable-suspend # Install behind a proxy that wants no login sudo ironflock agent install -c device.flock --https-proxy http://proxy.example.com:3128 # Install behind a proxy with a login; the password comes from a file sudo ironflock agent install -c device.flock --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt

Result

$ sudo ironflock agent install -c device.flock --yes Done: the IronFlock device agent runs (systemctl status ironflock-device-agent). The device appears online in IronFlock within a minute.
{"action":"installed","device":"demo-device","agent_version":"1.6.9"}

warnings is in the result only when a file came from the IronFlock cloud instead of the appliance’s mirror: one entry for each, as the Warning: lines say it.

Refuses When

A wrong command line ends with exit code 2 before anything runs: a proxy URL with a password; a proxy URL that names a user, without --proxy-password-file; --proxy-password-file without a proxy URL that names a user; a value that is not a proxy URL. A proxy variable of the environment that is not a proxy URL counts too; the error names the variable, not its value.

The command refuses with exit code 3, and changes nothing, when:

  • it does not run as root, or the machine is not Linux;
  • the machine runs IronFlockOS, before anything else, root or not. The image brings the agent and ironflock with its system, and every OS update replaces the system as a whole. The message says that the device enrolls with a .flock on its IRONFLOCKOS partition at its next start, and that agent configure -c enrolls it now. On the IronFlockOS installer stick it says that the stick is not a device;
  • an agent is installed already, also in the legacy layout /opt/reagent. The message names agent configure and agent remove;
  • the agent is moving the machine out of the legacy layout;
  • an earlier install stopped before the agent was set up, had moved Docker’s data-root, and Docker holds images or containers since: undoing that attempt would delete them;
  • one of the checks system, systemd, disk_space or download_tree fails. --yes changes nothing.

A question answered with no, or a question without a terminal and without --yes, ends the command with exit code 4. A step that fails ends it with exit code 1.

ironflock agent configure

Changes what the install set up: the device’s .flock, the corporate proxy of Docker and the agent, or both. Restarts what has to use the change.

ironflock agent configure [-c <device.flock>] [flags]

Runs on: Linux with an installed agent; on IronFlockOS with -c only. Root: required. Asks: before Docker restarts for new proxy settings; --yes answers.

FlagMeaning
-c, --config <file>the device’s new .flock file
--http-proxy <url>the HTTP proxy of Docker and the agent, instead of the one set
--https-proxy <url>the HTTPS proxy of Docker and the agent, instead of the one set
--no-proxy <hosts>the hosts that bypass the proxy, comma-separated, instead of those set; localhost is always added
--proxy-password-file <file>a file or a pipe (/dev/stdin) whose one line is the password of the user in the proxy URLs
--remove-proxyremove the proxy settings: Docker and the agent connect directly

Give -c, a proxy flag, or both. Without either there is nothing to change: a wrong command line (exit code 2).

Another .flock

With -c, the agent gets the .flock given and restarts: the machine becomes the device of that .flock. Apps and their data stay. When the install set up an SSH user, the SSH user follows the .flock:

  • Same project owner, another device key — the old key is no longer accepted, the new one is.
  • Another project owner — the new owner gets their SSH user, and the first owner’s SSH user goes as agent remove takes it: the sudo rule, the key, and the account with its home folder when the install created it.
  • A .flock without a device key — the SSH user goes, and none comes.

When the device changes hands, the first owner may be the one who runs the command, over SSH with the very account that goes, and removing an account ends its sessions. So the command works in this order: it sets up the new owner’s account (user, key, sudo rule), restarts the agent with the new .flock, and only then takes away the first owner’s sudo rule, sessions and account (or the old key alone, for the same owner). The device has a new way in, and is online, before the old way in goes. Before the sessions end, a line on stderr says so, for example Removing the account anna, ...: a session of anna ends here.

  • When the agent does not restart with the new .flock, the first owner keeps the access: somebody must be able to get in.
  • When only the new owner’s SSH user failed, the first owner’s access goes all the same: the device has changed hands and is online.
  • Whose access is still to go is recorded in /opt/ironflock/device-init/installed.json (users_to_remove). Every later agent configure -c and agent remove tries again.
  • An account that the new .flock sets up again is never removed (owner A, then B, then A).
  • From its first change on, a lost terminal or SSH session does not stop the command.

Over --host, the copy of the .flock on the machine is removed as soon as the command has read it. When the login of --host is an account that goes, the SSH session ends with the account: your run then ends with exit code 255, as after a lost connection, and the command on the machine goes on to its end. The run’s folder ironflock.XXXXXXXXXX with its binary then stays behind on the machine; in a temporary folder it stays until that is cleaned, in the account’s home it goes with the account.

On IronFlockOS

With -c, the command enrolls the device as IronFlockOS enrolls it on the first boot of every new root slot, on a device that has enrolled and on one that has not. The .flock given becomes the agent’s copy, /opt/ironflock/device-agent/device-config.flock on /data, and the device is set up from it in this order: the SSH user of the project owner, the WiFi, the hostname from the device name (unless /etc/ironflockos/enroll.conf says hostname-from-flock=no), the agent, restarted with the new .flock, and then the removal of the previous owner’s access.

The next OS update enrolls its new root slot from the same copy. The file you gave stays where it is. A step that fails does not keep the agent from restarting with the new .flock, but the first owner’s access goes only once the agent has restarted. The command then ends with exit code 1 and names each step that failed; run the same command again to repeat them.

The proxy flags are refused on IronFlockOS. IronFlockOS keeps the proxy of Docker, the agent and its clock in /etc/ironflockos/proxy.conf on /data, and a proxy.conf on its IRONFLOCKOS partition replaces it at the next start.

Proxy Settings

  • Each proxy flag given replaces its setting, and the others stay. --https-proxy alone changes the HTTPS proxy and keeps the HTTP proxy and the hosts that bypass them.
  • The password of --proxy-password-file goes into the URLs given that name a user. Without a URL given, it goes into the URLs of the device’s settings that name one, so a new password is set with the file alone.
  • --no-proxy, and the first proxy of a device that had none, also take localhost, 127.0.0.1, ::1 and the update server of the agent’s .flock when it is not a host of the IronFlock cloud (an appliance’s).
  • --remove-proxy removes the settings. It takes no other proxy flag.
  • The proxy variables of your environment change nothing here: only the flags count.

The list of hosts that bypass the proxy stays as the command finds it unless --no-proxy gives another. When that list names a host of the IronFlock cloud, a warning names it, with the agent configure --no-proxy that gives the list without it. A device that reaches the internet only through the proxy cannot update its agent while the cloud’s download server, instance-registry.ironflock.com, is on that list.

The settings are kept in /etc/ironflock/proxy.env, which only root reads, and named by the drop-ins ironflock-proxy.conf of docker.service and ironflock-device-agent.service. When the settings change, the command shows them before and after, without the password. Then Docker and the agent restart. Restarting Docker stops the apps of the device for a moment, so the command says so and asks; --yes answers. With the password on stdin there is no terminal to ask on: give --yes.

  • Docker does not restart, and nothing is asked, when Docker’s daemon.json sets proxies (Docker takes those before these settings), and when nothing changes.
  • A unit that only lacks its drop-in gets it, and only that unit restarts.
  • A Docker drop-in of the host’s own stays as it is. Another drop-in of the agent, or of Docker, that sets a proxy variable is named in a warning; IronFlock’s settings override it for each variable they set. A drop-in or daemon.json that holds a proxy password every user can read is named in a warning too.
  • When the restart of Docker fails, the agent restarts all the same, and the other way round. The error (exit code 1) names the units that still run with the old settings and the systemctl restart that applies them; a second run finds the settings in place and restarts nothing.
  • When the settings cannot be written, nothing restarts, and the error says to run the command again.

Proxy settings that an older install wrote into Environment= lines of http-proxy.conf drop-ins, where every user can read them with systemctl show, password and all, move to /etc/ironflock/proxy.env with any run of agent configure, also one with -c alone. No copy of the old files is kept. As a rule the move keeps the values, so it restarts nothing and asks nothing; where it changes the proxy a unit uses, the command says why, shows that unit’s proxy before and after, and asks. A value the settings file cannot hold (a single quote in the host or in the bypass list, a control character) does not move: a run without proxy flags leaves it, warns, and names the flag that gives the value anew.

Examples

# Make this machine the device of another .flock sudo ironflock agent configure -c new-device.flock # Set an HTTPS proxy with a login; the password comes from a file sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt # Set a new proxy password alone, read from stdin, without a question sudo ironflock agent configure --proxy-password-file /dev/stdin --yes < proxy-password.txt # Remove the proxy settings: Docker and the agent connect directly sudo ironflock agent configure --remove-proxy

Result

$ sudo ironflock agent configure -c new-device.flock Device configuration updated; the agent restarted. $ sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt The proxy settings of Docker and the agent change: HTTP proxy: none (unchanged) HTTPS proxy: none -> http://[email protected]:3128 (with a password) No proxy for: localhost,127.0.0.1,::1 Docker restarts for the new settings: the apps of the device stop for a moment and start again. ? Continue? Yes Proxy settings updated: HTTPS through http://[email protected]:3128 (with a password); not for localhost,127.0.0.1,::1. Restarted: docker.service, ironflock-device-agent.service.

On IronFlockOS, -c reports the enrolment:

Device configuration updated: this device enrolled as new-device, as IronFlockOS enrolls it at every new root slot; the agent restarted.
{"action":"configured","device":"new-device","restarted":["ironflock-device-agent.service"]}
{"action":"configured","proxy":{"password":false,"changed":true,"moved":false},"restarted":["docker.service","ironflock-device-agent.service"]}
FieldMeaning
actionconfigured when the command changed something; absent when nothing changed
devicethe device of the .flock of -c; absent without -c
proxywith a proxy flag, or when settings of the old form moved. http_proxy, https_proxy (without the password) and no_proxy as they are now, absent without a proxy; password: a URL has a password; changed: the settings differ from those before, or Docker or the agent takes them from now on or uses another proxy; moved: they were in the old form
restartedthe units the command restarted

Refuses When

A wrong command line ends with exit code 2: nothing to change; --remove-proxy with another proxy flag; a proxy URL with a password; a proxy URL that names a user, without --proxy-password-file; --proxy-password-file with URLs of which none names a user; a value that is not a proxy URL or a list of hosts.

The command refuses with exit code 3, and changes nothing, when:

  • no agent is installed (the message names agent install), except on IronFlockOS, where -c enrolls a device that has not enrolled yet;
  • the agent is moving the machine out of the legacy layout;
  • proxy flags are given and the agent still runs in the legacy layout /opt/reagent. Once the agent has moved it (ironflock status shows the layout), the same command works;
  • proxy flags are given on IronFlockOS, with -c or without;
  • --no-proxy or --proxy-password-file is given alone on a device without a proxy, or the password file alone when no proxy URL of the device names a user;
  • proxy flags keep a value of the old form that /etc/ironflock/proxy.env cannot hold; the message names the flag that gives it anew.

On IronFlockOS, -c is refused with exit code 3 when the enrolment would not keep the .flock:

  • a factory reset is requested and has not started yet (/boot/efi/factory-reset.conf, which os reset writes), or it has begun (/boot/efi/factory-reset.keep): the next start would erase what the command sets up;
  • a factory reset is open or gave up and holds the files that came with it (/run/ironflockos/factory-reset-hold; ironflock status says more);
  • /data could not be mounted, so the agent’s copy would land in the root slot. A .flock on the IRONFLOCKOS partition is the way then;
  • a .flock lies on the IRONFLOCKOS partition; the device enrolls with it at its next start, and the message names it;
  • the command runs on the IronFlockOS installer stick, which is not a device;
  • the system has no /usr/lib/ironflock/image.json, or an agent in the legacy layout.

ironflock agent update

Lets the agent update itself to the release of its channel, and follows what it does. The agent looks for a newer release at every start: the command restarts it and reports the outcome. The device is offline in IronFlock for a moment; its apps keep running.

ironflock agent update [flags]

Runs on: Linux, with an installed agent. Root: required. Asks: yes, after it has said what the restart does; --yes answers.

The command has no flags of its own and takes no version. The agent follows its channel (production, or test on IronFlock’s test platform), from its update server: the update_url of its .flock (an appliance’s mirror), else the IronFlock cloud. --download-base does not change it.

What the agent does, in this order:

  1. It reads the release of its channel. A release that failed on this device twice is not downloaded again until a newer one comes out.
  2. It downloads a newer release into its folder and checks its signature.
  3. It puts the new version in place and restarts into it, 10 seconds after the download. It holds the update back when it was last connected to IronFlock 12 minutes to a day ago: an update is activated from a version that is known to connect.
  4. The new version is on probation: it has to connect to IronFlock within 10 minutes of its start and stay up for 2 minutes. If it does not, or it stops three times before that, the agent goes back to the version before.
  5. After a rollback, the version before has to connect. Then the new version was at fault: it is tried once more at the next update, and after its second failure it is blocked until a newer release. When the version before cannot connect either within 10 minutes, the agent blames the network, and the new version is tried again at the next update.

The command follows this in update-state.json in the agent’s folder and in the agent’s log; it reads neither from before the restart. Its progress goes to stderr as lines of text, also with --json. A download shows once a minute how much it has so far.

outcomeMeansExit code
updatedthe new version passed its probation0
currentthe agent runs the release of its channel already0
rolled_backthe new version failed, and the agent runs the version before again1
blockedthe release of the channel failed on this device before; the agent did not try it1
not_updatedthe check, the download or the activation failed, or the agent held the update back1

With exit code 1 the result is written all the same, and stderr gets the Error: line. With --json no error object follows: stdout has the result.

Examples

# Update the agent; the command asks before the restart sudo ironflock agent update # Update without a question and read the outcome as JSON sudo ironflock agent update --yes --json

Result

$ sudo ironflock agent update --yes The agent 1.6.9 restarts now and looks for a newer release on its channel: the device is offline in IronFlock for a moment, its apps keep running. A newer release is downloaded and started. It has to connect to IronFlock within 10 minutes and stay up for 2, or the agent goes back to 1.6.9. The agent restarted; it looks for a newer release. Its channel offers 1.7.0: the agent downloads it. Activating 1.7.0: the agent restarts into it. 1.7.0 runs on probation: it has to connect to IronFlock within 10 minutes and stay up for 2. The agent was updated from 1.6.9 to 1.7.0: 1.7.0 connected to IronFlock and passed its probation.

An agent that is current, and one whose new version was rolled back:

{"outcome":"current","version":"1.7.0","channel_version":"1.7.0"}
{"outcome":"rolled_back","version":"1.6.9","channel_version":"1.7.0","failed_version":"1.7.0","reason":"did not connect within 10m0s","retry":"next_update"}
FieldValues
actionupdated when the agent runs a newer version now; absent otherwise
outcomeas in the table above
versionthe version that runs now
previous_versionwith updated: the version before
channel_versionthe release of the channel, as the agent read it; absent when it did not say
failed_versionwith rolled_back and blocked: the release that failed
reasonwhy it failed or was not updated, in the agent’s words
retrywith rolled_back and blocked: when the agent tries the failed release again: next_update, newer_release, or after_judgement (the version before has yet to connect)

Refuses When

The command refuses with exit code 3 when no agent is installed (the message names agent install), while the agent moves the machine out of the legacy layout, when the agent runs in the legacy layout (its updates keep no state that the command can follow), and with an agent older than 1.3.0, the first that updates itself under its unit.

It fails with exit code 1, and an error that says where to look, when the restart fails, and when the update does not move on within the agent’s periods: the agent’s check within 3 minutes of the restart, the download within 30 minutes, the activation within 3 minutes, each start of the new version on probation within 12 minutes, the agent’s judgement after a rollback within 12 minutes, and all of it within 84 minutes. The agent goes on by itself; ironflock status shows where it is.

Ctrl-C stops following, not the update, and ends the command with exit code 130.

ironflock agent remove

Removes the device agent and undoes what its install recorded. Docker itself and the packages stay installed.

ironflock agent remove [flags]

Runs on: Linux, with an installed agent; not on IronFlockOS. Root: required. Asks: yes, after it has listed what it removes. The question preselects “No”: Enter alone removes nothing.

The command has no flags of its own. It removes:

  • The agent — the agent, its database and /opt/ironflock/device-agent. The apps of the device and their data go with it when Docker keeps them in the agent’s folder.
  • The SSH user — the account only when the install created it. Of an account that existed before, only the device key goes from its authorized_keys, which stays the user’s. The access of an earlier project owner whose removal by agent configure -c had failed goes as well, listed with “(a removal that had failed)”.
  • The host defaults — the WiFi profile, the login banner and the masked sleep targets.
  • The files the install wrote or replaced — the originals come back, with their mode, owner and group.
  • The proxy settings — /etc/ironflock/proxy.env with the drop-ins that name it, and proxy settings that an older install left in http-proxy.conf drop-ins. Nothing comes back in their place: afterwards Docker has no proxy from IronFlock, and the command has written the proxy password nowhere. When Docker had a proxy from IronFlock, the list before the question says so.
  • The settings the agent wrote on the host by itself — the slice ironflock.slice with the drop-in 10-ironflock-resources.conf of its unit, the systemd watchdog (/etc/systemd/system.conf.d/10-ironflock-watchdog.conf), the kernel’s crash settings (/etc/sysctl.d/60-ironflock-crash-recovery.conf, which the kernel keeps until the next boot) and the cap of the journal (/etc/systemd/journald.conf.d/10-ironflock.conf).
  • The agent’s registry logins — once the agent has stopped, the command runs docker logout for the registry the .flock names (docker_registry_url) and, on a device of an appliance, for registry.<appliance_domain>. No other login in /root/.docker/config.json is touched. A Docker that is missing or fails does not stop the removal; a line says which login was not removed.

A Docker drop-in of the host’s own stays as it is. A Docker that does not restart for the removal (its data was not in the agent’s folder) uses the proxy it started with until its next restart.

The command lists on stderr what it removes, then asks. With --json the list is the field removed of the result. Once the command has begun to remove, a lost terminal or SSH session does not stop it: the SSH user that goes takes its sessions along, maybe the one that runs the command, and the removal goes on to its end.

Examples

# Remove the agent; the command lists what goes and asks sudo ironflock agent remove # Remove the agent without a question sudo ironflock agent remove --yes

Result

$ sudo ironflock agent remove --yes This removes: - the agent, its database and /opt/ironflock/device-agent (with Docker's images and containers) - the user operator and its home directory - /etc/profile.d/ironflock-motd.sh The IronFlock device agent was removed from this machine.
{"action":"removed","removed":["the agent, its database and /opt/ironflock/device-agent (with Docker's images and containers)","the user operator and its home directory","/etc/profile.d/ironflock-motd.sh"]}

Refuses When

The command refuses with exit code 3 when no agent is installed, and while the agent moves the machine out of the legacy layout. On IronFlockOS it refuses before anything else, root or not: the image brings the agent with its system, and every OS update and the next enrolment would set it up again. The message names ironflock os reset, which returns the device to a freshly written IronFlockOS without its identity at IronFlock. On the IronFlockOS installer stick it says that the stick is not a device.

The answer no, or a question without a terminal and without --yes, ends the command with exit code 4.

ironflock agent restart

Restarts the service of the agent and checks that the agent runs again: its unit has to run for five seconds with one process. The device is offline in IronFlock for those seconds; the apps keep running.

ironflock agent restart [flags]

Runs on: Linux, with an installed agent. Root: required. Asks: nothing.

The command has no flags of its own. The service is ironflock-device-agent.service. Run in a terminal that comes through the agent (the device’s terminal in IronFlock Studio, or SSH through IronFlock), the restart ends that session; the device is back within a minute.

# Restart the agent sudo ironflock agent restart # Restart it and read the new process as JSON sudo ironflock agent restart --json
$ sudo ironflock agent restart The agent restarted: ironflock-device-agent.service runs, with process 4242.
{"action":"restarted","unit":"ironflock-device-agent.service","state":"running","main_pid":4242}

state is the state of the unit afterwards, named as in ironflock status. main_pid is the agent’s process, a new one after every restart.

Refuses with exit code 3 when no agent is installed (the message names agent install -c <file>), while the agent moves the machine out of the legacy layout, and when systemd does not know the agent’s unit (the message names agent remove).

Fails with exit code 1 when the agent does not come up: systemd cannot start the unit, or its process ends within the five seconds. The error names the unit and where its last log lines are: the agent’s log (agent logs) and the journal (journalctl -u <unit>).

ironflock agent stop

Stops the service of the agent. The device goes offline in IronFlock, and the remote access through IronFlock goes with the agent: a session that came that way (the device’s terminal in IronFlock Studio, SSH through IronFlock) ends, and IronFlock cannot reach the device until the agent runs again. The apps keep running, as Docker runs them, not the agent.

ironflock agent stop [flags]

Runs on: Linux, with an installed agent. Root: required. Asks: yes, after it has said what stopping the agent ends; --yes answers.

The command has no flags of its own. agent start starts the agent again, and so does the next boot. A stopped agent cannot be started again through IronFlock. An agent that does not run has nothing to stop; then the command asks nothing, and the result has no action.

# Stop the agent; the command says what that ends and asks sudo ironflock agent stop # Stop it without a question sudo ironflock agent stop --yes
$ sudo ironflock agent stop --yes Stopping the agent (ironflock-device-agent.service) takes this device offline in IronFlock. The remote access through IronFlock goes with it: a session that came that way (the device's terminal in Studio, SSH through IronFlock) ends. The apps keep running. 'sudo ironflock agent start' starts the agent again, and so does the next boot. The agent is stopped (ironflock-device-agent.service): the device is offline in IronFlock, and its apps keep running. 'sudo ironflock agent start' starts the agent again.
{"action":"stopped","unit":"ironflock-device-agent.service","state":"stopped"}

Refuses with exit code 3 as agent restart does. The answer no, or a question without a terminal and without --yes, ends it with exit code 4.

ironflock agent start

Starts the service of the agent when it does not run, and checks that the agent comes up, as agent restart does: its unit has to run for five seconds with one process. An agent that runs already is left as it is, and the result then has no action.

ironflock agent start [flags]

Runs on: Linux, with an installed agent. Root: required. Asks: nothing. The command has no flags of its own.

# Start the agent sudo ironflock agent start # Start it and read its process as JSON sudo ironflock agent start --json
$ sudo ironflock agent start The agent started: ironflock-device-agent.service runs, with process 4242. The device appears online in IronFlock within a minute.

With --json, for an agent that runs already:

{"unit":"ironflock-device-agent.service","state":"running","main_pid":4242}

Refuses and fails as agent restart does: exit code 3 when no agent is installed, while the agent moves the machine out of the legacy layout, and when systemd does not know the agent’s unit; exit code 1 when the agent does not come up.

ironflock agent logs

Shows the log of the agent, /var/log/ironflock/device-agent.log, and the files the agent rotated it into. Changes nothing.

ironflock agent logs [flags]

Runs on: Linux, with an installed agent; it reads the files and needs no systemd. Root: required, as the agent writes its log for root alone (mode 0600). Asks: nothing.

FlagMeaning
--lines <n>the last n lines, or all. Default: 100; with --since, every line since then
--since <time>the lines from a time on: a duration back from now (90s, 10m, 2h, 1h30m, or whole days: 3d), or a time: 2026-11-10T09:00:00Z or with an offset, 2026-11-10 09:00, 2026-11-10 09:00:05, 2026-11-10 (its midnight), 09:00 (today). A time without a zone is in the machine’s time zone
--followafter the lines, show those the agent writes, until Ctrl-C

At 100 MB the agent renames its log to device-agent-<time>.log in the same folder and starts a new one; it keeps two. The command reads the log and these files.

The agent writes one JSON object per line: the time of the entry (to the second), its level, its message and more fields. The text form shows an entry as IronFlock Studio shows the agent’s log: the time in UTC, the level, the message and its error. A line that is no entry, such as the stack trace of a crash, is shown as it is. Control characters are escaped (\n, \x1b), so an entry is one line on the terminal and cannot steer it. With --json every line is one JSON object on stdout: the entry as the agent wrote it, with all its fields, or {"message":...} for a line that is no entry.

  • --since starts with the first entry of that time or later. The lines stay in the order the agent wrote them. A line without a time belongs to the entry before it.
  • With --follow, a line is shown once it is whole. When the agent starts a new file, the rest of the old one comes first, then the new one from its start. A log that does not exist yet is waited for. Ctrl-C ends the command with exit code 0; over --host, Ctrl-C ends the run with exit code 130.
  • When the agent has written no log yet, stderr says so, stdout stays empty, and the exit code is 0.

Examples

# The last 100 lines sudo ironflock agent logs # Everything of the last hour sudo ironflock agent logs --since 1h # The last 20 lines, then every new line until Ctrl-C sudo ironflock agent logs --follow --lines 20 # The last ten minutes as JSON, one object per line sudo ironflock agent logs --since 10m --json

Result

$ sudo ironflock agent logs --lines 3 2026-11-10T11:58:02Z INFO connected to IronFlock 2026-11-10T11:58:03Z INFO 3 apps running 2026-11-10T11:59:40Z ERROR pulling demo-app:1.2 failed: context deadline exceeded
{"level":"info","time":"2026-11-10T11:58:02Z","caller":"agent.go:212","message":"connected to IronFlock"}

Refuses When

A --since that is neither a duration nor a time, a negative duration, and a --lines that is neither a number nor all are wrong command lines (exit code 2). The command refuses with exit code 3 when it does not run as root, and when no agent is installed (the message names agent install -c <file>).

Last updated on