Installation
One line installs ironflock on Linux or macOS. It needs root, because it writes to /usr/local/bin. Later, ironflock self-update brings it to the newest release, and ironflock version --check tells you whether a newer one is out.
curl -fsSL https://instance-registry.ironflock.com/dl/cli/install.sh | sudo bashWhat the Install Line Does
- It finds the system (Linux or macOS) and the architecture of the machine: amd64, arm64 or 32-bit ARM (v5 to v7) on Linux, Apple silicon or Intel on macOS. On Apple silicon, a shell that runs under Rosetta 2 gets the Apple silicon build as well.
- It downloads
version.txtand theironflockof that version for this machine fromhttps://instance-registry.ironflock.com/dl/cli/. - It checks both against the IronFlock release key that the script carries. On Linux it checks the OpenPGP signature (
.asc) withsqvorgpgv. On macOS it checks the plain RSA signature of the same key (.sig) with the system’s/usr/bin/openssl, so that nothing has to be installed first. - It installs the binary as
/usr/local/bin/ironflock, in place of one that is there. The new file is copied next to the old one and renamed over it, so anironflockthat runs at that moment keeps the binary it started from. On a Mac without/usr/local/bin, the script makes the folder. - It runs
ironflockwith the arguments given afterbash -s --. Without arguments it only installs and names the next step.
On a Linux machine with an amd64 CPU, the output looks like this:
Download base: https://instance-registry.ironflock.com/dl
Downloading ironflock 2.0.2 (linux/amd64)...
Signature verified (key F6C94D96CE315377ACA7C8EA4990543373212788).
Installed ironflock 2.0.2 as /usr/local/bin/ironflock.
Connect this machine to IronFlock with:
sudo ironflock agent install -c /path/to/device.flock
All commands: ironflock --help
Tab completion in your shell: ironflock completion --helpOn a Mac, the next step it names is ironflock os flash, which writes IronFlockOS for a device onto a USB stick or an SD card. When it replaces an ironflock that was there, the Installed line ends with , in place of the one that was there.
Requirements
- Root — the script writes to
/usr/local/bin. Run it withsudo bash. curlorwget— for the downloads.- On Linux,
base64andsqvorgpgv— for the signature check. apt depends on one ofsqvandgpgv, so every Debian and Ubuntu has one. Without both, the script stops and namesapt install gpgv. - On macOS, nothing that does not come with the system.
A POSIX shell runs the script: bash, sh, dash or BusyBox ash.
A Missing or Wrong Signature
A missing or wrong signature stops the script before it installs anything, and an ironflock installed before stays as it was. The script ends with exit code 1 and one line on stderr, for example:
install.sh: https://instance-registry.ironflock.com/dl/cli/linux/amd64/2.0.2/ironflock is not signed by IronFlock: not installing itA download that fails stops the script the same way: nothing is installed.
Install and Run a Command in One Line
The arguments after bash -s -- go to ironflock once it is installed. This line installs ironflock and connects the machine to IronFlock as the device of the device configuration file (.flock) device.flock:
curl -fsSL https://instance-registry.ironflock.com/dl/cli/install.sh | sudo bash -s -- agent install -c device.flockUnder curl ... | bash, the standard input of the script is the script itself. The script therefore lets ironflock read from your terminal, so the command’s questions still reach you and you answer them as usual. Without a terminal (a cloud-init script, CI), ironflock gets no input: a command that asks ends with exit code 4 unless you add --yes. The script ends with the exit code of ironflock. ironflock agent install describes the command.
Update
sudo ironflock self-update replaces ironflock with the newest release, after the same checks against the IronFlock release key (ironflock self-update). ironflock version --check shows the version you have and whether a newer release is out (ironflock version).
The install line at the top of this page updates as well: run it again, and it replaces /usr/local/bin/ironflock with the current release.
On an IronFlockOS device, ironflock comes with the system, and ironflock os update updates it with the system.
Verify the Install Script First
To check install.sh itself before it runs as root, download it with its signature, import the release key and verify the signature with gpg:
curl -fsSLO https://instance-registry.ironflock.com/dl/cli/install.sh
curl -fsSLO https://instance-registry.ironflock.com/dl/cli/install.sh.asc
curl -fsSL https://instance-registry.ironflock.com/dl/cli/ironflock-bootstrap.asc | gpg --import
gpg --verify install.sh.asc install.shgpg has to report a good signature by the key with the fingerprint F6C9 4D96 CE31 5377 ACA7 C8EA 4990 5433 7321 2788. Compare it with the IronFlock Bootstrap key on Signing Keys. Then run the verified script, without arguments or with the arguments for ironflock:
sudo bash install.sh
sudo bash install.sh agent install -c device.flockDownload Base
ironflock and the install script download from the IronFlock cloud, https://instance-registry.ironflock.com/dl. A different download base, such as a mirror on your network, is named in one of two ways. For a device of an IronFlock appliance, a few commands find the appliance’s download mirror by themselves:
| Setting | Read by | Order |
|---|---|---|
--download-base <url> | every ironflock command | first |
the environment variable IRONFLOCK_DL_BASE | install.sh and every ironflock command | second |
the download mirror of the appliance that the device’s .flock file names | agent install, doctor, os install, os update | third |
| the IronFlock cloud | every command | last |
Below the download base, the install script reads cli/version.txt and cli/<system>/<arch>/<version>/ironflock, each with its .asc and .sig signature. It checks them against the release key it carries, whatever the download base is, so a mirror serves IronFlock’s signed files unchanged. ironflock reads the IronFlockOS catalog and images below ironflockos/, the device agent below device-agent/, and below cli/ the newest release (version.txt, for self-update and version --check) and the ironflock binaries (for self-update, and for --host those of other platforms).
By default, sudo does not pass the variables of your shell on. Set the variable after sudo, or give the flag:
# Install ironflock from a mirror
curl -fsSL https://mirror.example.com/dl/cli/install.sh | sudo IRONFLOCK_DL_BASE=https://mirror.example.com/dl bash
# Connect this machine with the agent from the mirror
sudo ironflock agent install -c device.flock --download-base https://mirror.example.com/dlTwo commands use the download base differently. agent update lets the agent update from its own update server, the update_url of its .flock file, and the download base does not change it. os update takes the flag, then the variable, then the update_url of the agent’s .flock file. Over --host, the download base goes along to the other machine; one with a login in it (https://user:[email protected]/dl) ends with exit code 2 before any machine is reached.
Devices of an IronFlock Appliance
The .flock file that an IronFlock appliance issues names the appliance’s download mirror as the agent’s update server (update_url), for example http://10.0.0.5:15002/dl, or https://registry.<domain>/dl when the appliance runs with a domain. When neither --download-base nor IRONFLOCK_DL_BASE is set, agent install, doctor and os install take their files from that mirror, so a machine that reaches the appliance but not ironflock.com can be connected or converted. A .flock file of the IronFlock cloud names a host of the cloud and takes the cloud.
- What the mirror does not give comes from the same path below the IronFlock cloud’s download base, with a warning: for
agent installaWarning:line on stderr and an entry ofwarningsin the--jsonresult, foros installa warning in the plan, fordoctorawarningof the checkdownload_tree.agent installandos installfail only when neither the mirror nor the cloud gives a file, and their error then names both. agent installandos installreach the mirror directly, and the cloud through the proxy, when there is one.- An HTTPS mirror with a certificate of the appliance’s own CA works only where the machine’s system trusts that CA.
Some downloads still come from elsewhere:
install.shand theironflockbinary come from ironflock.com. With--host, the binary goes from your computer to the machine (Remote Machines over SSH).agent installtakes the distribution’s packages and Docker from their own servers.self-updateandversion --checkread the flag, then the variable, else the IronFlock cloud, not the appliance’s mirror.
After the install, the agent takes its updates from the appliance. See Edge Devices.
Tab Completion
ironflock completion prints the script that lets your shell complete ironflock command lines when you press Tab.
ironflock completion <shell>The shell is bash, zsh or fish. Runs on Linux and macOS. No root. Asks nothing. The command has no flags of its own; the global flags apply.
Run the line for your shell to complete in the shell you type in. Add the line to the file in the third column to complete in every new shell:
| Shell | Line | File |
|---|---|---|
| bash | eval "$(ironflock completion bash)" | ~/.bashrc; needs the package bash-completion |
| zsh | source <(ironflock completion zsh) | ~/.zshrc, after compinit |
| fish | ironflock completion fish | source | ~/.config/fish/config.fish |
The script completes:
- the commands and their flags;
- the values of the flags that take one of a few:
--channel,--variantand--kernelofos images,--channelofos update, and--installer-confirm,--installer-afterand--installer-allow-usbofos flash; - a
.flockfile for-c; - the shell’s file names for
--hosts,--proxy-password-file,--wifi-password-file,--image-file,--output,--driveand--disk.
Other flags and the arguments of other commands complete nothing. To complete, the script asks ironflock for the words that fit, and ironflock answers from its own list of commands: completing runs no command, lists no drive, downloads nothing and reaches no other machine, also when the line holds --host. With --host or --hosts, ironflock completion is answered on this machine, as --help is.
# Complete in the bash you type in
eval "$(ironflock completion bash)"
# Complete in every new bash
echo 'eval "$(ironflock completion bash)"' >> ~/.bashrc$ eval "$(ironflock completion bash)"
$ ironflock os images --kernel <Tab>
rt stdWith --json, the result is the script in a JSON object:
{"shell":"bash","script":"..."}A missing or unknown shell, or more than one, is a wrong command line: exit code 2, and the error names the shells it accepts.
ironflock version
Prints the version of the ironflock binary and the platform it was built for. With --check, it also asks the download server whether a newer release is out.
ironflock version [flags]Runs on Linux and macOS. No root. Asks nothing. The global flags apply.
| Flag | Meaning |
|---|---|
--check | Ask the download server whether a newer release is out |
# The version of ironflock on this machine
ironflock version
# The same as JSON
ironflock version --json
# The binary that runs on another machine over SSH: same version, that machine's platform
ironflock --host pi@device-17 version
# Is a newer release out?
ironflock version --checkironflock 2.0.2 linux/amd64{"version":"2.0.2","os":"linux","arch":"amd64"}Over --host, the platform is the other machine’s, for example ironflock 2.0.2 linux/arm64: the other machine runs a binary of the same version for its own platform.
A development build names its commit: 2.0.0-23-g5b38681 is the build of commit 5b38681, 23 commits after release 2.0.0.
Is a Newer Release Out?
--check reads cli/version.txt of the download base (--download-base, else IRONFLOCK_DL_BASE, else the IronFlock cloud) and checks it against its signature (.asc) with the IronFlock release key that the binary carries. It asks through the proxy that agent configure set (/etc/ironflock/proxy.env), else through the proxy of the environment. Only root reads that file, so without root it takes the environment’s. version --check and self-update are the only commands that ask for the newest release; no command does it by itself.
A second line on stdout says what it found, and what installs a newer release: self-update, or on IronFlockOS os update.
$ ironflock version --check
ironflock 2.0.3 linux/amd64
ironflock 2.1.0 is out at https://instance-registry.ironflock.com/dl. 'sudo ironflock self-update' installs it.When version.txt names the version of this binary, the second line is This is the newest release. When this binary is newer, a development build after the release, the line says so. A development build x.y.z-N-g<commit> counts as newer than release x.y.z and older than the next one; with N = 0 it stands with x.y.z, and the line says that no newer release is out.
With --json, the object has two more fields: latest_version, what version.txt names, and newer, whether that is newer than this binary.
{"version":"2.0.3","os":"linux","arch":"amd64","latest_version":"2.1.0","newer":true}The exit code is 0 whether a newer release is out or not. It is 1 when the server does not answer, has no version.txt, or has one that is not signed by the key. Over --host, the first line names the binary of this build, as version does, and the other machine asks the server.
ironflock self-update
Replaces the ironflock binary that runs with the newest release, or with the release --version names, an older one too. The release is checked against the IronFlock release key before anything on the disk changes.
ironflock self-update [flags]Runs on: Linux and macOS; not on IronFlockOS. Root: needed for /usr/local/bin/ironflock (Who May Replace the Binary). Asks: yes, after it has said which release replaces which; --yes answers.
| Flag | Meaning |
|---|---|
--version <x.y.z> | The release to install instead of the newest, such as 2.0.3; an older one too |
# Update ironflock to the newest release; the command asks first
sudo ironflock self-update
# Update without a question and read the result as JSON
sudo ironflock self-update --yes --json
# Go back to an older release
sudo ironflock self-update --version 2.0.3
# Update the ironflock installed on another machine
ironflock --host pi@device-17 self-update --yesWhat It Replaces, and with What
- The file. The binary that runs, every symbolic link resolved: the file a link leads to is replaced, and the link stays. The command names the file before anything else. The folder
/opt/ironflock/device-initof an agent’s install holds that install’s record, noironflock, and the command does not touch it. - The release. Without
--version, the newest: whatcli/version.txtof the download base names (--download-base, elseIRONFLOCK_DL_BASE, else the IronFlock cloud), the file the install line reads. The binary of a release iscli/<system>/<arch>/<version>/ironflock. There are no channels: another tree is another download base, such as a mirror. - The proxy. The downloads go through the proxy that
agent configureset (/etc/ironflock/proxy.env), else throughHTTP_PROXY,HTTPS_PROXYandNO_PROXYof the environment.sudoand a command over--hosthave no proxy in their environment. The file is root’s, so a run without root takes the environment’s proxy and says so. The command says when it takes the file’s. - Nothing to do. When the binary is that release already, or newer than it (a development build after it), the command says so and ends with exit code 0, without a question and without a download; the result’s
outcomeiscurrent. Without--versionit never goes back to an older release.
The Checks
Before the binary is replaced:
version.txtis checked against its signature by the IronFlock release key that the running binary carries.- The new binary is checked against its signature by the same key, and against its build information: the program
ironflock, for this platform, from an unmodified source tree. - It is written next to the old one, in the same folder, with the old one’s mode, owner and group, and run once (
version --json). It has to say that it is the release asked for, on this platform. A signature binds no version, so an older signed binary served in place of the newest is refused here. - Only then is it renamed over the old one, in one step.
No sqv or gpgv is needed: ironflock checks the signatures itself.
A file that fails a check never replaces the binary, and the new file next to it is removed again. A run that fails, is declined or is interrupted leaves the old binary as it was. A command of ironflock that runs while the file is replaced goes on with the file it started from. A second Ctrl-C, or a power loss, between the write and the rename can leave the new file (.ironflock.new-* next to the binary) behind; remove it by hand.
Who May Replace the Binary
The command needs write access to the folder of the binary, and has to run as the binary’s owner and a member of its group, or as root, so that the new file keeps the owner and the group. For /usr/local/bin/ironflock, where the install line puts it, that is root. Otherwise the command ends with exit code 3 before anything is downloaded, names the owner or the group, and names the command line with sudo.
IronFlockOS and Other Machines
- IronFlockOS brings
ironflockwith its system, and every OS update replaces the system as a whole. There the command ends with exit code 3 before it looks at anything, and namesos update. On the IronFlockOS installer stick it refuses as theagentcommands do. - Over
--host, the binary that runs is the run’s copy, which is removed when the command ends. So the command updates/usr/local/bin/ironflockof the machine instead. Without that file it ends with exit code 3 and names the install line. An installedironflockthat does not run, or does not say its version, ends it with exit code 3 too, before anything is downloaded: the install line installsironflockanew. - On several machines (
--hostmore than once,--hosts), with--yes, each machine updates its/usr/local/bin/ironflock.
Result
$ sudo ironflock self-update
This ironflock is 2.0.3, at /usr/local/bin/ironflock.
Download base: https://instance-registry.ironflock.com/dl (from default)
The downloads go through the proxy of the install's record (/etc/ironflock/proxy.env).
The newest release at https://instance-registry.ironflock.com/dl is ironflock 2.1.0 (its version.txt is signed by key F6C94D96CE315377ACA7C8EA4990543373212788).
ironflock 2.1.0 replaces 2.0.3 at /usr/local/bin/ironflock.
A command of ironflock that runs now goes on with 2.0.3; the next one runs 2.1.0.
? Install ironflock 2.1.0? Yes
Downloading ironflock 2.1.0 for linux/amd64 from https://instance-registry.ironflock.com/dl.
Signature verified (key F6C94D96CE315377ACA7C8EA4990543373212788): the program ironflock for linux/amd64.
The new file says it is ironflock 2.1.0 linux/amd64; it is in place.
ironflock at /usr/local/bin/ironflock is updated from 2.0.3 to 2.1.0.The binary is downloaded after the answer. Without a terminal, or with --json, the command needs --yes. With --json, for a binary that is the newest release already:
{"outcome":"current","path":"/usr/local/bin/ironflock","version":"2.1.0","latest_version":"2.1.0"}| Field | Values |
|---|---|
action | updated when the binary was replaced; absent otherwise |
outcome | updated (a newer release, or with --version another build of the same standing), downgraded (an older release, as --version asked), current (nothing to do) |
path | the file that was replaced, or would have been |
version | the version of that file now |
previous_version | when the file was replaced: the version before |
latest_version | what version.txt names; absent with --version, which does not read it |
Exit Codes
| Code | Means |
|---|---|
| 0 | updated, or nothing to do |
| 1 | the download failed, a check failed, the download tree has no binary of the newest release for this platform, or the replacement failed. The binary is as it was |
| 2 | wrong command line, also a --version that is no version, or that the download tree does not have for this platform |
| 3 | on IronFlockOS, without the right to replace the file, and over --host without /usr/local/bin/ironflock or with one that does not say its version |
| 4 | the question was answered with no, or could not be asked and --yes was not given |
| 130 | interrupted; the binary is as it was |