Skip to Content
Sviluppo App IoTIronFlock CLIFlag, output e codici di uscita

Flag, output e codici di uscita

Queste regole valgono per ogni comando ironflock, e uno script può farci affidamento. La pagina di ciascun comando indica solo ciò che il comando aggiunge.

Una riga di comando ha una di queste due forme:

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

Il gruppo è il prodotto: agent per l’agente del dispositivo, appliance per l’IronFlock Appliance, os per IronFlockOS. Un verbo ha lo stesso significato in ogni gruppo. I comandi che riguardano la macchina nel suo insieme non hanno un gruppo. ironflock e ironflock <group> senza verbo stampano il loro aiuto. Nessun comando accetta argomenti posizionali, salvo dove la sua pagina lo indica; tutto il resto è un flag. login e device sono nomi riservati: rispondono che sono riservati, con il codice di uscita 2.

Flag globali

Ogni comando accetta questi flag. Tutti tranne --help possono stare prima o dopo il nome del comando: ironflock --json version e ironflock version --json sono equivalenti.

FlagSignificato
--download-base <url>URL di base dei download. Predefinito: il cloud IronFlock, https://instance-registry.ironflock.com/dl; per un dispositivo di un IronFlock Appliance, alcuni comandi usano prima il mirror dell’Appliance. Vedi Base di download.
--host [user@]machineEsegue il comando su quella macchina via SSH invece che qui. Indicalo più volte per più macchine. Vedi Macchine remote via SSH.
--hosts <file>Esegue il comando su ogni macchina indicata nel file, un [user@]machine per riga. Vedi Il file degli host.
--parallel <n>Elabora al massimo n macchine di --host e --hosts contemporaneamente. Predefinito 10, da 1 a 100.
--jsonScrive il risultato su stdout come un unico oggetto JSON e non chiede nulla.
--yesRisponde sì alla domanda del comando. Non annulla mai un rifiuto.
-h, --helpStampa l’aiuto del comando.

Flag con nomi fissi

Il nome di un flag ha lo stesso significato in ogni comando che lo prevede. -c e -d sono gli unici flag brevi oltre a -h.

FlagSignificatoComandi
-c, --config <file>il file .flock del dispositivoagent install, agent configure, doctor, os flash, os install, os reset
-d, --drive <drive>l’unità su cui scrive un comandoos flash
--disk <disk>il disco da cui si è avviato il sistema in esecuzione, che il comando sostituisceos install
--output <file>il file che un comando scrive al posto di un’unitàos flash
--http-proxy, --https-proxy, --no-proxyil proxy aziendaleagent install, agent configure, os install
--proxy-password-file <file>un file o una pipe la cui unica riga è la password dell’utente indicato negli URL del proxyagent install, agent configure, os install

Base di download e proxy

La base di download viene da --download-base, poi dalla variabile d’ambiente IRONFLOCK_DL_BASE, altrimenti è https://instance-registry.ironflock.com/dl. Senza nessuno dei due, agent install, doctor, os install e os update usano, prima del cloud, il mirror di download dell’Appliance indicato dal file .flock del dispositivo (Dispositivi di un IronFlock Appliance).

Il proxy viene dai flag, poi da HTTP_PROXY, HTTPS_PROXY e NO_PROXY (o dalle loro forme in minuscolo). agent configure fa eccezione: modifica il proxy del dispositivo solo con i propri flag, e l’ambiente del comando lì non cambia nulla. Un URL di proxy ha la forma http://proxy.example.com:3128; funzionano anche https:// e socks5://, e un URL senza schema vale come http://. Quando il proxy richiede un login, l’URL indica l’utente, come in http://[email protected]:3128, e --proxy-password-file fornisce la password (vedi Segreti). Per i dispositivi dietro un proxy, vedi Dietro un Proxy Aziendale.

Output e JSON

stdout contiene il risultato e nient’altro. Si tratta di un breve testo per una persona oppure, con --json, esattamente un oggetto JSON su una riga. Anche --help va su stdout. L’unica eccezione è agent logs, il cui risultato è il log: con --json scrive un oggetto JSON per ogni riga del log.

stderr contiene tutto il resto: avanzamento, output degli strumenti che un comando esegue (apt, l’installer di Docker), avvisi, domande ed errori.

Così un reindirizzamento o una sostituzione di comando ottiene solo il risultato, e uno script che non vuole messaggi reindirizza stderr:

# Il risultato come testo in un file; avanzamento e avvisi restano visibili sul terminale ironflock status > result.txt # Il risultato come JSON in una variabile della shell, senza i messaggi su stderr result=$(ironflock status --json 2>/dev/null)

I nomi dei campi JSON sono in snake_case. Un risultato ha il campo action quando il comando ha modificato qualcosa, ad esempio "installed", "configured" o "removed". Nel tempo si aggiungono campi, e nessuno viene rinominato o rimosso all’interno di una versione major. Un programma che legge un risultato ignora i campi che non conosce. Con più macchine, --json scrive invece una riga per macchina (vedi Macchine remote via SSH).

Avanzamento

Un passo lungo mostra su stderr a che punto è: una barra su un terminale, altrimenti una riga a ogni 10%. Con --json, stdout riceve comunque esattamente un oggetto JSON, il risultato, e stderr riceve l’avanzamento come eventi, un oggetto JSON per riga:

{"event":"progress","phase":"writing","done":104857600,"total":412345678}
CampoSignificato
eventprogress
phasedownloading: download di un file immagine o di una release; checking: verifica del suo SHA-256 rispetto al catalogo; preparing: preparazione della scrittura di os install dall’immagine; writing: scrittura sull’unità (o nel file di --output); verifying: verifica dell’unità (o del file) tramite rilettura; installing: installazione di una release nell’altro slot (os update)
done, totalByte: del file immagine per downloading, checking, preparing e writing, dell’immagine scritta per verifying. Per installing, percentuale: total è 100.

os install legge il file immagine due volte prima del riavvio: checking confronta il suo SHA-256 con il catalogo firmato, e preparing decomprime l’immagine una volta per trovarne la partizione IRONFLOCKOS, inserirvi il file .flock del dispositivo e le impostazioni di rete, e calcolare i checksum di ciò che la scrittura mette sul disco. Su un terminale compaiono come Checking e Preparing.

Un evento arriva quando una fase inizia (done è 0), ogni volta che cambia la percentuale intera e quando la fase è completa (done è uguale a total). Un download che riprende salta ai byte che ha già. Le altre righe su stderr, tra cui gli avvisi, sono testo per una persona: un programma prende le righe che si possono interpretare come oggetti JSON e ignora le altre.

Domande e conferma

Un comando che modifica la macchina dice prima cosa farà, poi chiede:

  • Un comando che rimuove o sovrascrive qualcosa dice prima cosa va perso. Un comando che installa dice prima cosa installerà. agent stop dice prima che cosa si interrompe quando l’agente si arresta.
  • --yes risponde sì a ogni domanda del comando e sceglie il valore predefinito dove il comando offre una scelta.
  • Al terminale, una domanda ha «Yes» preselezionato, quindi basta premere Invio per proseguire. Tre domande hanno «No» preselezionato, quindi Invio da solo non cancella e non rimuove nulla: os flash prima di cancellare un’unità, os flash prima di sostituire il file di --output, e agent remove.
  • os reset ti chiede di digitare il nome del dispositivo, e os install il nome host della macchina. Qualsiasi altra cosa, anche Invio da solo, vale come no.
  • Ciò che hai digitato prima che comparisse una domanda viene scartato. Si risponde a una domanda dopo aver letto ciò che il comando dice.
  • Esc risponde no: il comando non modifica nulla e termina con il codice di uscita 4. Ctrl-C a una domanda non dà alcuna risposta, nemmeno quella preselezionata: il comando non modifica nulla e termina con il codice di uscita 130.

Una domanda richiede un terminale sia su stdin sia su stderr. Senza terminale (una pipe, la CI, uno script cloud-init), il comando non attende e non tira a indovinare: termina con il codice di uscita 4 e dice che --yes conferma. Lo stesso vale con --json, che non chiede nulla. Per questo gli script indicano --yes insieme a --json.

--yes non annulla mai un rifiuto. Quando un comando rifiuta (codice di uscita 3, o un controllo fallito), nessun flag lo fa proseguire. La pagina di ciascun comando elenca ciò che rifiuta. L’unica eccezione è un disco interno, che os flash --allow-internal scrive quando --drive lo indica.

Con --host, le domande ti raggiungono quando esegui il comando a un terminale. Su più macchine contemporaneamente non viene chiesto nulla a nessuno, quindi un comando che pone domande viene eseguito lì solo con --yes (vedi Macchine remote via SSH).

Privilegi di root

Un comando che modifica il sistema richiede root. Senza root termina con il codice di uscita 3 e lo dice. Non chiama sudo da solo; lo fa solo --host, sull’altra macchina. In quel caso os flash indica la riga di comando da digitare, con sudo davanti.

ComandiRoot
version, completion, os images, os drives, ogni --helpnon necessario
status, doctornon necessario. Senza root, status indica unknown (needs root) per ciò che non riesce a leggere, e doctor segna questi controlli come skipped. Con sudo leggono anche questo.
agent install, agent configure, agent update, agent remove, agent restart, agent stop, agent startnecessario
agent logsnecessario: legge soltanto, ma ciò che legge è accessibile solo a root
os flashnecessario per scrivere un’unità. Non necessario con --output. Su macOS, un utente che può scrivere sul dispositivo raw dell’unità non ha bisogno di root.
os install, os update, os rollback, os resetnecessario
self-updateaccesso in scrittura alla cartella del binario, ed essere il proprietario del binario e membro del suo gruppo, oppure root. Per /usr/local/bin/ironflock significa root

Con --host, un comando che richiede root viene eseguito tramite sudo sull’altra macchina quando l’utente di login non è root.

Segreti

Nessun comando stampa un segreto: né il segreto di un file .flock, né una passphrase WiFi, né una password del proxy, né una chiave di licenza. Questo vale per stdout, stderr, --json e i messaggi di errore.

Un segreto non è mai il valore di un flag quando può contenerlo un file, perché le righe di comando compaiono in ps e nella cronologia della shell. Una password del proxy non fa eccezione:

  • Un URL di proxy in un flag indica l’utente senza la password: http://[email protected]:3128.
  • Un URL con password, come http://user:password@proxy:3128, è una riga di comando errata (codice di uscita 2). Viene rifiutato prima che venga eseguito qualsiasi cosa, e con --host prima che arrivi alla macchina. L’errore non lo ripete.
  • La password viene da --proxy-password-file: un file, o una pipe (/dev/stdin), di una sola riga.
  • Le variabili proxy dell’ambiente, a cui agent install ricorre in mancanza dei flag, possono contenere una password: non compaiono su una riga di comando.
# La password da un file sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt # La password tramite una pipe sudo ironflock agent configure --proxy-password-file /dev/stdin --yes < proxy-password.txt

Su un dispositivo configurato da agent install, la password del proxy si trova dove solo root può leggerla: in /etc/ironflock/proxy.env (modo 0600). I drop-in di docker.service e di ironflock-device-agent.service indicano quel file e non contengono impostazioni del proxy, quindi systemctl show rivela a ogni utente il nome del file e nulla del suo contenuto.

Con --host, un file .flock, un file con la passphrase WiFi o un file con la password del proxy indicato in un flag arriva all’altra macchina tramite la connessione SSH, mai su una riga di comando (vedi Macchine remote via SSH). Una base di download che contiene credenziali di login termina con il codice di uscita 2 prima che venga raggiunta qualsiasi macchina.

Codici di uscita

CodiceTipoSignificato
0completato
1failedil comando è partito e non è riuscito a terminare
2usagela riga di comando è errata: un comando o un flag sconosciuto, un flag mancante, un nome riservato. Non è stato toccato nulla.
3preconditionla macchina non è nello stato richiesto dal comando: non root, nessun agente installato, un agente già installato, un sistema su cui il comando non funziona. Non è stato toccato nulla.
4declinedalla domanda è stato risposto no, oppure non è stato possibile porla e --yes non era indicato
130interruptedinterrotto (Ctrl-C) prima che il comando terminasse; con --host anche un comando sull’altra macchina terminato per un hangup, un’interruzione o un segnale di terminazione
255sshla connessione SSH di --host non è riuscita: la macchina non è stata raggiunta, o la connessione si è interrotta

Un errore è una riga su stderr, Error: seguito dal messaggio. Un errore di utilizzo è seguito da una riga che indica il --help da leggere. Con --json l’errore è il risultato: stdout riceve un oggetto errore, e stderr non riceve alcuna riga di errore. kind è uno dei tipi della tabella.

{"error":{"kind":"precondition","message":"the agent is not installed on this machine"}}

Due comandi scrivono il loro risultato e terminano comunque con il codice di uscita 1. agent update lo fa quando l’agente resta alla sua versione: il risultato dice perché, e stderr riceve la riga Error:. doctor lo fa quando un controllo è fallito: il risultato dice quale, e non segue alcuna riga di errore. Con --json, in questi casi nessuno dei due scrive un oggetto errore: stdout contiene il risultato.

Con --help, un comando sconosciuto non è un errore: ironflock os nosuch --help stampa l’aiuto di ironflock os, con il codice di uscita 0. Su più macchine, il comando termina con il codice di uscita peggiore tra quelli delle macchine (vedi Macchine remote via SSH).

Interruzioni

Ctrl-C, SIGTERM e SIGHUP (quando il terminale o la sessione SSH scompare) terminano subito la maggior parte dei comandi, come terminano qualsiasi programma, senza una riga di errore; la shell vede 130 (143 dopo SIGTERM, 129 dopo SIGHUP). Alcuni passi li gestiscono:

  • os flash mentre scarica, scrive o rilegge un’immagine, e os update mentre scarica e verifica un bundle, si fermano al blocco successivo. Dicono cosa hanno lasciato, come errore di tipo interrupted, e terminano con 130; in questo caso os update non installa nulla. Quando os flash ha riletto l’ultimo blocco, completa i passi finali e termina con 0. Un secondo Ctrl-C termina subito il processo; con --output può restare il file .part.
  • agent logs --follow segue il log fino a un segnale di questo tipo, poi termina con 0.
  • agent update smette di seguire l’aggiornamento con 130; l’agente prosegue da solo.
  • os reset, mentre scrive la sua richiesta, la ritira, termina con 130 e il dispositivo non si riavvia.
  • agent configure, una volta iniziata la modifica della macchina, non si ferma più per un terminale o una sessione SSH persi. Ctrl-C e SIGTERM lo terminano comunque subito.
  • os install si comporta diversamente prima e dopo la sua domanda; vedi ironflock os install.

Codici di uscita in uno script

Uno script indica --yes affinché il comando non si fermi alla sua domanda, --json per un risultato leggibile, e controlla il codice di uscita:

#!/bin/sh # Fa aggiornare l'agente da solo; conserva il risultato JSON, scarta l'avanzamento su 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" ;; esac

Con il codice di uscita 0, $result contiene il risultato, il cui outcome è updated o current. Con il codice di uscita 1, contiene il risultato, il cui outcome e reason dicono perché l’agente resta alla sua versione, oppure un oggetto errore. Con il codice di uscita 3, contiene l’oggetto errore.

Last updated on