Flags, saída e códigos de saída
Estas regras valem para todos os comandos ironflock, e um script pode contar com elas. A página de cada comando indica apenas o que o comando acrescenta.
Uma linha de comando tem uma de duas formas:
ironflock <group> <verb> [flags] ironflock agent install -c device.flock
ironflock <verb> [flags] ironflock versionO grupo é o produto: agent para o agente do dispositivo, appliance para o appliance IronFlock, os para o IronFlockOS. Um verbo significa o mesmo em todos os grupos. Comandos que tratam da máquina como um todo não têm grupo. ironflock e ironflock <group> sem verbo imprimem a sua ajuda. Nenhum comando aceita argumentos posicionais, a menos que a sua página diga o contrário; todo o resto é flag. login e device são nomes reservados: eles respondem que são reservados, com o código de saída 2.
Flags globais
Todo comando aceita estas flags. Todas, exceto --help, podem vir antes ou depois do nome do comando: ironflock --json version e ironflock version --json são a mesma coisa.
| Flag | Significado |
|---|---|
--download-base <url> | URL base dos downloads. Padrão: a nuvem IronFlock, https://instance-registry.ironflock.com/dl; para um dispositivo de um appliance IronFlock, alguns comandos usam primeiro o espelho do appliance. Veja Base de download. |
--host [user@]machine | Executa o comando nessa máquina via SSH em vez de aqui. Informe-a mais de uma vez para várias máquinas. Veja Máquinas remotas via SSH. |
--hosts <file> | Executa o comando em cada máquina indicada no arquivo, uma [user@]machine por linha. Veja O arquivo de hosts. |
--parallel <n> | Executa no máximo n das máquinas de --host e --hosts ao mesmo tempo. Padrão 10, de 1 a 100. |
--json | Escreve o resultado no stdout como um único objeto JSON, e não pergunta nada. |
--yes | Responde sim à pergunta do comando. Nunca anula uma recusa. |
-h, --help | Imprime a ajuda do comando. |
Flags com nomes fixos
Um nome de flag significa o mesmo em todos os comandos que a têm. -c e -d são as únicas flags curtas além de -h.
| Flag | Significado | Comandos |
|---|---|---|
-c, --config <file> | o arquivo .flock do dispositivo | agent install, agent configure, doctor, os flash, os install, os reset |
-d, --drive <drive> | a unidade em que um comando grava | os flash |
--disk <disk> | o disco a partir do qual o sistema em execução iniciou, e que o comando substitui | os install |
--output <file> | o arquivo que um comando grava no lugar de uma unidade | os flash |
--http-proxy, --https-proxy, --no-proxy | o proxy corporativo | agent install, agent configure, os install |
--proxy-password-file <file> | um arquivo ou um pipe cuja única linha é a senha do usuário nas URLs de proxy | agent install, agent configure, os install |
Base de download e proxy
A base de download vem de --download-base, depois da variável de ambiente IRONFLOCK_DL_BASE; caso contrário, é https://instance-registry.ironflock.com/dl. Sem nenhuma das duas, o agent install, o doctor, o os install e o os update usam, antes da nuvem, o espelho de downloads do appliance que o arquivo .flock do dispositivo indica (Dispositivos de um appliance IronFlock).
O proxy vem das flags, depois de HTTP_PROXY, HTTPS_PROXY e NO_PROXY (ou das suas formas em minúsculas). O agent configure é a exceção: ele altera o proxy do dispositivo apenas com as suas flags, e o ambiente do comando não muda nada ali. Uma URL de proxy tem a forma http://proxy.example.com:3128; https:// e socks5:// também funcionam, e uma URL sem esquema é tratada como http://. Quando o proxy exige login, a URL indica o usuário, como em http://[email protected]:3128, e --proxy-password-file fornece a senha (veja Segredos). Para dispositivos atrás de um proxy, veja Atrás de um Proxy Corporativo.
Saída e JSON
O stdout traz o resultado e nada mais. Ele é um texto curto para uma pessoa ou, com --json, exatamente um objeto JSON em uma linha. O --help também vai para o stdout. A única exceção é o agent logs, cujo resultado é o log: com --json, ele escreve um objeto JSON por linha do log.
O stderr traz todo o resto: o progresso, a saída das ferramentas que um comando executa (apt, o instalador do Docker), avisos, perguntas e erros.
Assim, um redirecionamento ou uma substituição de comando recebe apenas o resultado, e um script que quer silêncio redireciona o stderr:
# O resultado como texto em um arquivo; o progresso e os avisos continuam aparecendo no terminal
ironflock status > result.txt
# O resultado como JSON em uma variável do shell, sem as mensagens do stderr
result=$(ironflock status --json 2>/dev/null)Os nomes de campo no JSON são snake_case. Um resultado tem o campo action quando o comando alterou algo, por exemplo "installed", "configured" ou "removed". Campos são adicionados com o tempo, e nenhum é renomeado ou removido dentro de uma versão principal. Um programa que lê um resultado ignora os campos que não conhece. Com várias máquinas, o --json escreve uma linha por máquina (veja Máquinas remotas via SSH).
Progresso
Uma etapa longa mostra no stderr quanto já avançou: uma barra em um terminal, caso contrário uma linha a cada décimo. Com --json, o stdout continua recebendo exatamente um objeto JSON, o resultado, e o stderr recebe o progresso como eventos, um objeto JSON por linha:
{"event":"progress","phase":"writing","done":104857600,"total":412345678}| Campo | Significado |
|---|---|
event | progress |
phase | downloading: baixando um arquivo de imagem ou uma release; checking: verificando o SHA-256 dele com o catálogo; preparing: preparando a gravação do os install a partir da imagem; writing: gravando-o na unidade (ou no arquivo de --output); verifying: verificando a unidade (ou o arquivo) por releitura; installing: instalando uma release no outro slot (os update) |
done, total | Bytes: do arquivo de imagem para downloading, checking, preparing e writing, da imagem gravada para verifying. Para installing, porcentagem: total é 100. |
O os install lê o arquivo de imagem duas vezes antes da reinicialização: checking compara o SHA-256 dele com o catálogo assinado, e preparing descompacta a imagem uma vez para encontrar a sua partição IRONFLOCKOS, colocar nela o arquivo .flock do dispositivo e as configurações de rede, e calcular os checksums do que a gravação coloca no disco. Em um terminal, elas aparecem como Checking e Preparing.
Um evento é emitido quando uma fase começa (done é 0), sempre que a porcentagem inteira muda e quando a fase termina (done igual a total). Um download retomado salta para os bytes que já tem. As outras linhas do stderr, entre elas os avisos, são texto para uma pessoa: um programa pega as linhas que podem ser lidas como objetos JSON e ignora o resto.
Perguntas e confirmação
Um comando que altera a máquina diz primeiro o que vai fazer e depois pergunta:
- Um comando que remove ou sobrescreve algo diz primeiro o que será perdido. Um comando que instala diz primeiro o que vai instalar. O
agent stopdiz primeiro o que a parada do agente encerra. --yesresponde sim a todas as perguntas do comando e usa o padrão onde o comando oferece uma escolha.- No terminal, uma pergunta vem com “Yes” pré-selecionado, então Enter sozinho prossegue. Três perguntas vêm com “No” pré-selecionado, então Enter sozinho não apaga nem remove nada:
os flashantes de apagar uma unidade,os flashantes de substituir o arquivo de--output, eagent remove. - O
os resetpede que você digite o nome do dispositivo, e oos install, o nome de host da máquina. Qualquer outra coisa, inclusive Enter sozinho, responde não. - O que você digitou antes de uma pergunta aparecer é descartado. Uma pergunta é respondida depois que você leu o que o comando diz.
- Esc responde não: o comando não altera nada e termina com o código de saída 4. Ctrl-C em uma pergunta não dá resposta nenhuma, nem mesmo a pré-selecionada: o comando não altera nada e termina com o código de saída 130.
Uma pergunta precisa de um terminal tanto no stdin quanto no stderr. Sem ele (um pipe, CI, um script cloud-init), o comando não espera e não adivinha: termina com o código de saída 4 e diz que --yes confirma. O mesmo vale com --json, que não pergunta nada. Por isso, scripts usam --yes junto com --json.
--yes nunca anula uma recusa. Quando um comando recusa (código de saída 3, ou uma verificação que falhou), nenhuma flag o faz prosseguir. A página de cada comando lista o que ele recusa. A única exceção é um disco interno, que o os flash --allow-internal grava quando --drive o indica.
Com --host, as perguntas chegam até você quando você executa o comando em um terminal. Em várias máquinas ao mesmo tempo ninguém é perguntado, então um comando que pergunta só roda ali com --yes (veja Máquinas remotas via SSH).
Privilégios de root
Um comando que altera o sistema precisa de root. Sem root, ele termina com o código de saída 3 e diz isso. Ele não chama o sudo por conta própria; só o --host faz isso, na outra máquina. O os flash indica então a linha de comando a digitar, com sudo na frente.
| Comandos | Root |
|---|---|
version, completion, os images, os drives, todo --help | não necessário |
status, doctor | não necessário. Sem root, o status diz unknown (needs root) para o que não consegue ler, e o doctor marca essas verificações como skipped. Com sudo, eles leem essas informações. |
agent install, agent configure, agent update, agent remove, agent restart, agent stop, agent start | necessário |
agent logs | necessário: ele apenas lê, mas o que lê pertence só ao root |
os flash | necessário para gravar uma unidade. Não necessário com --output. No macOS, um usuário que pode gravar no dispositivo raw da unidade não precisa de root. |
os install, os update, os rollback, os reset | necessário |
self-update | acesso de escrita à pasta do binário, e ser o dono do binário e membro do seu grupo, ou root. Para /usr/local/bin/ironflock, isso é root |
Com --host, um comando que precisa de root roda via sudo na outra máquina quando o usuário de login não é root.
Segredos
Nenhum comando imprime um segredo: nem o segredo de um arquivo .flock, nem uma senha de WiFi, nem uma senha de proxy, nem uma chave de licença. Isso vale para stdout, stderr, --json e mensagens de erro.
Um segredo nunca é o valor de uma flag quando um arquivo pode contê-lo, porque linhas de comando aparecem no ps e no histórico do shell. Uma senha de proxy não é exceção:
- Uma URL de proxy em uma flag indica o usuário sem a senha:
http://[email protected]:3128. - Uma URL com senha, como
http://user:password@proxy:3128, é uma linha de comando incorreta (código de saída 2). Ela é recusada antes que qualquer coisa rode e, com--host, antes de ir para a máquina. O erro não a repete. - A senha vem de
--proxy-password-file: um arquivo, ou um pipe (/dev/stdin), de uma linha. - As variáveis de proxy do ambiente, que o
agent installusa quando faltam as flags, podem conter uma senha: elas não ficam em uma linha de comando.
# A senha a partir de um arquivo
sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt
# A senha por um pipe
sudo ironflock agent configure --proxy-password-file /dev/stdin --yes < proxy-password.txtEm um dispositivo configurado pelo agent install, a senha do proxy fica onde só o root a lê: em /etc/ironflock/proxy.env (modo 0600). Os drop-ins de docker.service e de ironflock-device-agent.service indicam esse arquivo e não contêm nenhuma configuração de proxy, de modo que o systemctl show mostra a todos os usuários o nome do arquivo e nada do que ele contém.
Com --host, um arquivo .flock, um arquivo de senha de WiFi ou um arquivo de senha de proxy indicado em uma flag vai para a outra máquina pela conexão SSH, nunca em uma linha de comando (veja Máquinas remotas via SSH). Uma base de download com credenciais termina com o código de saída 2 antes que qualquer máquina seja alcançada.
Códigos de saída
| Código | Tipo | Significado |
|---|---|---|
| 0 | concluído | |
| 1 | failed | o comando começou e não conseguiu terminar |
| 2 | usage | a linha de comando está incorreta: um comando ou uma flag desconhecidos, uma flag ausente, um nome reservado. Nada foi tocado. |
| 3 | precondition | a máquina não está no estado de que o comando precisa: sem root, nenhum agente instalado, um agente já instalado, um sistema em que o comando não roda. Nada foi tocado. |
| 4 | declined | a pergunta foi respondida com não, ou não pôde ser feita e --yes não foi informado |
| 130 | interrupted | interrompido (Ctrl-C) antes de o comando terminar; com --host, também um comando na outra máquina que terminou com um hangup, uma interrupção ou um sinal de término |
| 255 | ssh | a conexão SSH do --host falhou: a máquina não foi alcançada, ou a conexão caiu |
Um erro é uma linha no stderr, Error: seguido da mensagem. Um erro de uso é seguido de uma linha que indica o --help a ler. Com --json, o erro é o resultado: o stdout recebe um objeto de erro, e o stderr não recebe linha de erro. kind é um dos tipos da tabela.
{"error":{"kind":"precondition","message":"the agent is not installed on this machine"}}Dois comandos escrevem o seu resultado e mesmo assim terminam com o código de saída 1. O agent update faz isso quando o agente permanece na sua versão: o resultado diz por quê, e o stderr recebe a linha Error:. O doctor faz isso quando uma verificação falhou: o resultado diz qual, e nenhuma linha de erro vem depois. Com --json, nenhum dos dois escreve um objeto de erro nesse caso: o stdout tem o resultado.
Com --help, um comando desconhecido não é erro: ironflock os nosuch --help imprime a ajuda de ironflock os, com o código de saída 0. Em várias máquinas, o comando termina com o pior código de saída entre as máquinas (veja Máquinas remotas via SSH).
Interrupções
Ctrl-C, SIGTERM e SIGHUP (quando o terminal ou a sessão SSH desaparece) encerram a maioria dos comandos imediatamente, como encerram qualquer programa, sem linha de erro; o shell vê 130 (143 depois de SIGTERM, 129 depois de SIGHUP). Algumas etapas os tratam:
os flash, enquanto baixa, grava ou relê uma imagem, eos update, enquanto baixa e verifica um pacote de atualização, param no próximo bloco. Eles dizem o que deixaram, como um erro do tipointerrupted, e terminam com 130; oos updateentão não instala nada. Quando oos flashjá releu o último bloco, as suas etapas finais são concluídas e ele termina com 0. Um segundo Ctrl-C encerra o processo imediatamente; com--output, ele pode deixar para trás o arquivo.part.agent logs --followacompanha o log até receber um desses sinais e então termina com 0.agent updatepara de acompanhar a atualização com 130; o agente continua sozinho.os reset, enquanto escreve a sua solicitação, retira a solicitação e termina com 130, e o dispositivo não reinicia.agent configure, depois que começou a alterar a máquina, não para mais quando o terminal ou a sessão SSH se perde. Ctrl-C e SIGTERM ainda o encerram imediatamente.os installse comporta de forma diferente antes e depois da sua pergunta; vejaironflock os install.
Códigos de saída em um script
Um script usa --yes para que o comando não pare na pergunta, --json para obter um resultado que consiga ler, e verifica o código de saída:
#!/bin/sh
# Deixar o agente se atualizar; guardar o resultado JSON, descartar o progresso no 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" ;;
esacCom o código de saída 0, $result contém o resultado, cujo outcome é updated ou current. Com o código de saída 1, contém o resultado, cujo outcome e reason dizem por que o agente permanece na sua versão, ou um objeto de erro. Com o código de saída 3, contém o objeto de erro.