Options, sortie et codes de sortie
Ces règles valent pour chaque commande ironflock, et un script peut s’y fier. La page de chaque commande ne mentionne que ce que la commande y ajoute.
Une ligne de commande a l’une de ces deux formes :
ironflock <group> <verb> [flags] ironflock agent install -c device.flock
ironflock <verb> [flags] ironflock versionLe groupe est le produit : agent pour l’agent de l’appareil, appliance pour l’IronFlock Appliance, os pour IronFlockOS. Un verbe a le même sens dans chaque groupe. Les commandes qui concernent la machine dans son ensemble n’ont pas de groupe. ironflock et ironflock <group> sans verbe affichent leur aide. Aucune commande n’accepte d’arguments positionnels, sauf si sa page l’indique ; tout le reste est une option. login et device sont des noms réservés : ils répondent qu’ils sont réservés, avec le code de sortie 2.
Options globales
Chaque commande accepte ces options. Toutes, sauf --help, peuvent se placer avant ou après le nom de la commande : ironflock --json version et ironflock version --json sont équivalents.
| Option | Signification |
|---|---|
--download-base <url> | URL de base des téléchargements. Par défaut : le cloud IronFlock, https://instance-registry.ironflock.com/dl ; pour un appareil d’une IronFlock Appliance, certaines commandes prennent d’abord le miroir de l’appliance. Voir Base de téléchargement. |
--host [user@]machine | Exécuter la commande sur cette machine via SSH au lieu d’ici. À donner plusieurs fois pour plusieurs machines. Voir Machines distantes via SSH. |
--hosts <file> | Exécuter la commande sur chaque machine que nomme le fichier, un [user@]machine par ligne. Voir Le fichier d’hôtes. |
--parallel <n> | Traiter au plus n des machines de --host et --hosts en même temps. Par défaut 10, de 1 à 100. |
--json | Écrire le résultat sur stdout sous la forme d’un seul objet JSON, et ne poser aucune question. |
--yes | Répondre oui à la question de la commande. Ne lève jamais un refus. |
-h, --help | Afficher l’aide de la commande. |
Options à nom fixe
Un nom d’option a le même sens dans chaque commande qui possède cette option. -c et -d sont les seules options courtes en dehors de -h.
| Option | Signification | Commandes |
|---|---|---|
-c, --config <file> | le fichier .flock de l’appareil | agent install, agent configure, doctor, os flash, os install, os reset |
-d, --drive <drive> | le lecteur sur lequel une commande écrit | os flash |
--disk <disk> | le disque à partir duquel le système en cours d’exécution a démarré, et que la commande remplace | os install |
--output <file> | le fichier qu’une commande écrit au lieu d’un lecteur | os flash |
--http-proxy, --https-proxy, --no-proxy | le proxy d’entreprise | agent install, agent configure, os install |
--proxy-password-file <file> | un fichier ou un pipe dont l’unique ligne est le mot de passe de l’utilisateur indiqué dans les URL de proxy | agent install, agent configure, os install |
Base de téléchargement et proxy
La base de téléchargement provient de --download-base, puis de la variable d’environnement IRONFLOCK_DL_BASE ; à défaut, c’est https://instance-registry.ironflock.com/dl. Sans l’une ni l’autre, agent install, doctor, os install et os update prennent le miroir de téléchargement de l’appliance que nomme le fichier .flock de l’appareil, avant le cloud (Appareils d’une IronFlock Appliance).
Le proxy provient des options, puis de HTTP_PROXY, HTTPS_PROXY et NO_PROXY (ou de leurs formes en minuscules). agent configure fait exception : il modifie le proxy de l’appareil uniquement avec ses options, et l’environnement de la commande n’y change rien. Une URL de proxy ressemble à http://proxy.example.com:3128 ; https:// et socks5:// fonctionnent aussi, et une URL sans schéma est en http://. Lorsque le proxy exige une authentification, l’URL indique l’utilisateur, comme dans http://[email protected]:3128, et --proxy-password-file fournit le mot de passe (voir Secrets). Pour les appareils derrière un proxy, voir Derrière un proxy d’entreprise.
Sortie et JSON
stdout transporte le résultat et rien d’autre. C’est soit un court texte destiné à une personne, soit, avec --json, exactement un objet JSON sur une ligne. --help va aussi sur stdout. La seule exception est agent logs, dont le résultat est le journal : avec --json, la commande écrit un objet JSON par ligne du journal.
stderr transporte tout le reste : la progression, la sortie des outils qu’une commande exécute (apt, l’installateur de Docker), les avertissements, les questions et les erreurs.
Une redirection ou une substitution de commande obtient donc le résultat seul, et un script qui veut le silence redirige stderr :
# Le résultat en texte dans un fichier ; la progression et les avertissements restent affichés dans le terminal
ironflock status > result.txt
# Le résultat en JSON dans une variable du shell, sans les messages de stderr
result=$(ironflock status --json 2>/dev/null)Les noms de champs JSON sont en snake_case. Un résultat comporte le champ action lorsque la commande a modifié quelque chose, par exemple "installed", "configured" ou "removed". Des champs s’ajoutent avec le temps, et aucun n’est renommé ni supprimé au sein d’une version majeure. Un programme qui lit un résultat ignore les champs qu’il ne connaît pas. Avec plusieurs machines, --json écrit à la place une ligne par machine (voir Machines distantes via SSH).
Progression
Une étape longue indique sur stderr où elle en est : une barre dans un terminal, sinon une ligne à chaque dixième. Avec --json, stdout reçoit toujours exactement un objet JSON, le résultat, et stderr reçoit la progression sous forme d’événements, un objet JSON par ligne :
{"event":"progress","phase":"writing","done":104857600,"total":412345678}| Champ | Signification |
|---|---|
event | progress |
phase | downloading : téléchargement d’un fichier image ou d’une version ; checking : vérification de son SHA-256 par rapport au catalogue ; preparing : préparation de l’écriture de os install à partir de l’image ; writing : écriture sur le lecteur (ou dans le fichier de --output) ; verifying : vérification du lecteur (ou du fichier) par relecture ; installing : installation d’une version dans l’autre slot (os update) |
done, total | Octets : du fichier image pour downloading, checking, preparing et writing, de l’image écrite pour verifying. Pour installing, un pourcentage : total vaut 100. |
os install lit le fichier image deux fois avant le redémarrage : checking compare son SHA-256 avec le catalogue signé, et preparing décompresse l’image une fois pour trouver sa partition IRONFLOCKOS, y placer le fichier .flock de l’appareil et les paramètres réseau, et calculer les sommes de contrôle de ce que l’écriture met sur le disque. Dans un terminal, elles s’affichent comme Checking et Preparing.
Un événement arrive au début d’une phase (done vaut 0), à chaque changement de pourcentage entier, et à la fin de la phase (done égale total). Un téléchargement qui reprend saute directement aux octets déjà présents. Les autres lignes de stderr, dont les avertissements, sont du texte destiné à une personne : un programme prend les lignes qui s’analysent comme des objets JSON et ignore le reste.
Questions et confirmation
Une commande qui modifie la machine dit d’abord ce qu’elle va faire, puis pose une question :
- Une commande qui supprime ou écrase quelque chose dit d’abord ce qui disparaît. Une commande qui installe dit d’abord ce qu’elle va installer.
agent stopdit d’abord ce à quoi l’arrêt de l’agent met fin. --yesrépond oui à chaque question de la commande et prend la valeur par défaut là où la commande propose un choix.- Dans un terminal, une question présélectionne « Yes » : Entrée suffit pour continuer. Trois questions présélectionnent « No », si bien qu’Entrée seule n’efface et ne supprime rien :
os flashavant d’effacer un lecteur,os flashavant de remplacer le fichier de--output, etagent remove. os resetvous demande de taper le nom de l’appareil, etos installle nom d’hôte de la machine. Toute autre saisie, Entrée seule comprise, vaut un non.- Ce que vous avez tapé avant l’apparition d’une question est ignoré. Une question reçoit sa réponse après que vous avez lu ce que dit la commande.
- Échap répond non : la commande ne modifie rien et se termine avec le code de sortie 4. Ctrl-C à une question ne donne aucune réponse, pas même celle qui est présélectionnée : la commande ne modifie rien et se termine avec le code de sortie 130.
Une question nécessite un terminal à la fois sur stdin et sur stderr. Sans terminal (un pipe, la CI, un script cloud-init), la commande n’attend pas et ne devine pas : elle se termine avec le code de sortie 4 et indique que --yes confirme. Il en va de même avec --json, qui ne pose aucune question. Les scripts passent donc --yes en même temps que --json.
--yes ne lève jamais un refus. Lorsqu’une commande refuse (code de sortie 3, ou une vérification qui a échoué), aucune option ne la fait continuer. La page de chaque commande liste ce qu’elle refuse. La seule exception est un disque interne, sur lequel os flash --allow-internal écrit lorsque --drive le désigne.
Via --host, les questions vous parviennent lorsque vous exécutez la commande dans un terminal. Sur plusieurs machines à la fois, personne n’est interrogé : une commande qui pose une question ne s’y exécute donc qu’avec --yes (voir Machines distantes via SSH).
Privilèges root
Une commande qui modifie le système nécessite root. Sans root, elle se termine avec le code de sortie 3 et le dit. Elle n’appelle pas sudo elle-même ; seul --host le fait, sur l’autre machine. os flash indique alors la ligne de commande à taper, précédée de sudo.
| Commandes | Root |
|---|---|
version, completion, os images, os drives, chaque --help | non requis |
status, doctor | non requis. Sans root, status indique unknown (needs root) pour ce qu’il ne peut pas lire, et doctor marque ces vérifications comme skipped. Avec sudo, ils le lisent. |
agent install, agent configure, agent update, agent remove, agent restart, agent stop, agent start | requis |
agent logs | requis : la commande ne fait que lire, mais ce qu’elle lit n’est accessible qu’à root |
os flash | requis pour écrire sur un lecteur. Non requis avec --output. Sous macOS, un utilisateur autorisé à écrire sur le périphérique brut du lecteur n’a pas besoin de root. |
os install, os update, os rollback, os reset | requis |
self-update | un accès en écriture au dossier du binaire, et être le propriétaire du binaire et membre de son groupe, ou root. Pour /usr/local/bin/ironflock, c’est root |
Via --host, une commande qui nécessite root passe par sudo sur l’autre machine lorsque le compte de connexion n’est pas root.
Secrets
Aucune commande n’affiche de secret : ni le secret d’un fichier .flock, ni une phrase secrète WiFi, ni un mot de passe de proxy, ni une clé de licence. Cela vaut pour stdout, stderr, --json et les messages d’erreur.
Un secret n’est jamais la valeur d’une option là où un fichier peut le contenir, car les lignes de commande apparaissent dans ps et dans l’historique du shell. Un mot de passe de proxy ne fait pas exception :
- Une URL de proxy dans une option indique l’utilisateur sans le mot de passe :
http://[email protected]:3128. - Une URL avec mot de passe, comme
http://user:password@proxy:3128, est une ligne de commande erronée (code de sortie 2). Elle est refusée avant toute exécution, et avec--hostavant d’être envoyée à la machine. L’erreur ne la répète pas. - Le mot de passe provient de
--proxy-password-file: un fichier, ou un pipe (/dev/stdin), d’une seule ligne. - Les variables de proxy de l’environnement, sur lesquelles
agent installse rabat, peuvent contenir un mot de passe : elles ne figurent pas sur une ligne de commande.
# Le mot de passe depuis un fichier
sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt
# Le mot de passe via un pipe
sudo ironflock agent configure --proxy-password-file /dev/stdin --yes < proxy-password.txtSur un appareil configuré par agent install, le mot de passe du proxy se trouve là où seul root peut le lire : dans /etc/ironflock/proxy.env (mode 0600). Les drop-ins de docker.service et de ironflock-device-agent.service nomment ce fichier et ne contiennent aucun paramètre de proxy : systemctl show révèle donc à chaque utilisateur le nom du fichier, et rien de son contenu.
Via --host, un fichier .flock, un fichier de phrase secrète WiFi ou un fichier de mot de passe de proxy désigné dans une option est transmis à l’autre machine par la connexion SSH, jamais sur une ligne de commande (voir Machines distantes via SSH). Avec une base de téléchargement qui contient des identifiants, la commande se termine avec le code de sortie 2 avant qu’aucune machine ne soit jointe.
Codes de sortie
| Code | Type | Signification |
|---|---|---|
| 0 | terminé | |
| 1 | failed | la commande a démarré et n’a pas pu aller au bout |
| 2 | usage | la ligne de commande est erronée : une commande ou une option inconnue, une option manquante, un nom réservé. Rien n’a été touché. |
| 3 | precondition | la machine n’est pas dans l’état dont la commande a besoin : pas root, aucun agent installé, un agent déjà installé, un système sur lequel la commande ne s’exécute pas. Rien n’a été touché. |
| 4 | declined | la question a reçu la réponse non, ou elle n’a pas pu être posée et --yes n’a pas été donné |
| 130 | interrupted | interruption (Ctrl-C) avant la fin de la commande ; avec --host, aussi une commande sur l’autre machine qui s’est terminée par un signal de raccrochage (hangup), d’interruption ou de terminaison |
| 255 | ssh | la connexion SSH de --host a échoué : la machine n’a pas été jointe, ou la connexion a été coupée |
Une erreur est une ligne sur stderr, Error: suivi du message. Une erreur d’utilisation est suivie d’une ligne qui indique le --help à lire. Avec --json, l’erreur est le résultat : stdout reçoit un objet d’erreur, et stderr ne reçoit aucune ligne d’erreur. kind est l’un des types du tableau.
{"error":{"kind":"precondition","message":"the agent is not installed on this machine"}}Deux commandes écrivent leur résultat et se terminent malgré tout avec le code de sortie 1. agent update le fait lorsque l’agent reste à sa version : le résultat dit pourquoi, et stderr reçoit la ligne Error:. doctor le fait lorsqu’une vérification a échoué : le résultat dit laquelle, et aucune ligne d’erreur ne suit. Avec --json, aucune des deux n’écrit alors d’objet d’erreur : stdout contient le résultat.
Avec --help, une commande inconnue n’est pas une erreur : ironflock os nosuch --help affiche l’aide de ironflock os, avec le code de sortie 0. Sur plusieurs machines, la commande se termine avec le pire code de sortie des machines (voir Machines distantes via SSH).
Interruptions
Ctrl-C, SIGTERM et SIGHUP (lorsque le terminal ou la session SSH disparaît) mettent fin immédiatement à la plupart des commandes, comme à n’importe quel programme, sans ligne d’erreur ; le shell voit 130 (143 après SIGTERM, 129 après SIGHUP). Certaines étapes les traitent :
os flashpendant qu’il télécharge, écrit ou relit une image, etos updatependant qu’il télécharge et vérifie un bundle, s’arrêtent au bloc suivant. Ils indiquent ce qu’ils laissent derrière eux, sous la forme d’une erreur de typeinterrupted, et se terminent avec 130 ;os updaten’installe alors rien. Une fois queos flasha relu le dernier bloc, ses étapes finales s’achèvent et il se termine avec 0. Un second Ctrl-C met fin au processus immédiatement ; avec--output, il peut laisser derrière lui le fichier.part.agent logs --followsuit le journal jusqu’à un tel signal, puis se termine avec 0.agent updatecesse de suivre la mise à jour avec 130 ; l’agent continue de lui-même.os reset, pendant qu’il écrit sa demande, retire la demande, se termine avec 130, et l’appareil ne redémarre pas.agent configure, une fois qu’il a commencé à modifier la machine, ne s’arrête plus pour un terminal ou une session SSH perdus. Ctrl-C et SIGTERM y mettent toujours fin immédiatement.os installse comporte différemment avant et après sa question ; voirironflock os install.
Codes de sortie dans un script
Un script passe --yes pour que la commande ne s’arrête pas à sa question, --json pour obtenir un résultat qu’il peut lire, et vérifie le code de sortie :
#!/bin/sh
# Laisser l'agent se mettre à jour ; garder le résultat JSON, écarter la progression sur stderr.
result=$(sudo ironflock agent update --yes --json 2>/dev/null)
code=$?
case $code in
0) echo "agent is current: $result" ;;
1) echo "agent update failed: $result" ;;
3) echo "agent update refused on this machine: $result" ;;
*) echo "agent update ended with exit code $code: $result" ;;
esacAvec le code de sortie 0, $result contient le résultat, dont l’outcome vaut updated ou current. Avec le code de sortie 1, il contient soit le résultat, dont l’outcome et la reason disent pourquoi l’agent reste à sa version, soit un objet d’erreur. Avec le code de sortie 3, il contient l’objet d’erreur.