Flags, salida y códigos de salida
Estas reglas valen para todos los comandos ironflock, y un script puede confiar en ellas. La página de cada comando indica solo lo que el comando añade.
Una línea de comandos tiene una de estas dos formas:
ironflock <group> <verb> [flags] ironflock agent install -c device.flock
ironflock <verb> [flags] ironflock versionEl grupo es el producto: agent para el agente del dispositivo, appliance para el appliance de IronFlock, os para IronFlockOS. Un verbo significa lo mismo en todos los grupos. Los comandos que afectan a la máquina en su conjunto no tienen grupo. ironflock y ironflock <group> sin verbo imprimen su ayuda. Ningún comando acepta argumentos posicionales, salvo que su página lo indique; todo lo demás es un flag. login y device son nombres reservados: responden que están reservados, con el código de salida 2.
Flags globales
Todos los comandos aceptan estos flags. Todos salvo --help pueden ir antes o después del nombre del comando: ironflock --json version y ironflock version --json son lo mismo.
| Flag | Significado |
|---|---|
--download-base <url> | URL base de las descargas. Por defecto: la nube de IronFlock, https://instance-registry.ironflock.com/dl; para un dispositivo de un appliance de IronFlock, algunos comandos toman primero la réplica del appliance. Consulta Base de descarga. |
--host [user@]machine | Ejecuta el comando en esa máquina por SSH en lugar de aquí. Indícalo más de una vez para varias máquinas. Consulta Máquinas remotas por SSH. |
--hosts <file> | Ejecuta el comando en cada máquina que indica el archivo, una [user@]machine por línea. Consulta El archivo de hosts. |
--parallel <n> | Ejecuta a la vez como máximo n de las máquinas de --host y --hosts. Por defecto 10, de 1 a 100. |
--json | Escribe el resultado en stdout como un único objeto JSON, y no pregunta nada. |
--yes | Responde sí a la pregunta del comando. Nunca anula un rechazo. |
-h, --help | Imprime la ayuda del comando. |
Flags con nombres fijos
El nombre de un flag significa lo mismo en todos los comandos que lo tienen. -c y -d son los únicos flags cortos, además de -h.
| Flag | Significado | Comandos |
|---|---|---|
-c, --config <file> | el archivo .flock del dispositivo | agent install, agent configure, doctor, os flash, os install, os reset |
-d, --drive <drive> | la unidad en la que escribe un comando | os flash |
--disk <disk> | el disco desde el que arrancó el sistema en ejecución, que el comando reemplaza | os install |
--output <file> | el archivo que escribe un comando en lugar de una unidad | os flash |
--http-proxy, --https-proxy, --no-proxy | el proxy corporativo | agent install, agent configure, os install |
--proxy-password-file <file> | un archivo o una tubería cuya única línea es la contraseña del usuario de las URL de proxy | agent install, agent configure, os install |
Base de descarga y proxy
La base de descarga se toma de --download-base, después de la variable de entorno IRONFLOCK_DL_BASE y, si no hay ninguna, es https://instance-registry.ironflock.com/dl. Sin ninguna de las dos, agent install, doctor, os install y os update toman, antes que la nube, la réplica de descargas del appliance que indica el archivo .flock del dispositivo (Dispositivos de un appliance de IronFlock).
El proxy se toma de los flags y después de HTTP_PROXY, HTTPS_PROXY y NO_PROXY (o de sus formas en minúsculas). agent configure es la excepción: cambia el proxy del dispositivo solo con sus flags, y el entorno del comando no cambia nada ahí. Una URL de proxy tiene la forma http://proxy.example.com:3128; https:// y socks5:// también funcionan, y una URL sin esquema es http://. Cuando el proxy pide inicio de sesión, la URL indica el usuario, como en http://[email protected]:3128, y --proxy-password-file da la contraseña (consulta Secretos). Para dispositivos detrás de un proxy, consulta Detrás de un proxy corporativo.
Salida y JSON
stdout lleva el resultado y nada más. Es un texto breve para una persona o, con --json, exactamente un objeto JSON en una línea. --help también va a stdout. La única excepción es agent logs, cuyo resultado es el registro: con --json escribe un objeto JSON por cada línea del registro.
stderr lleva todo lo demás: el progreso, la salida de las herramientas que ejecuta un comando (apt, el instalador de Docker), las advertencias, las preguntas y los errores.
Así, una redirección o una sustitución de comandos obtiene solo el resultado, y un script que quiere silencio redirige stderr:
# El resultado como texto en un archivo; el progreso y las advertencias siguen apareciendo en la terminal
ironflock status > result.txt
# El resultado como JSON en una variable del shell, sin los mensajes de stderr
result=$(ironflock status --json 2>/dev/null)Los nombres de los campos JSON van en snake_case. Un resultado tiene el campo action cuando el comando cambió algo, por ejemplo "installed", "configured" o "removed". Con el tiempo se añaden campos, y ninguno se renombra ni se elimina dentro de una versión mayor. Un programa que lee un resultado ignora los campos que no conoce. Con varias máquinas, --json escribe en su lugar una línea por máquina (consulta Máquinas remotas por SSH).
Progreso
Un paso largo muestra en stderr cuánto ha avanzado: una barra en una terminal y, si no, una línea en cada décima parte. Con --json, stdout sigue recibiendo exactamente un objeto JSON, el resultado, y stderr recibe el progreso como eventos, un objeto JSON por línea:
{"event":"progress","phase":"writing","done":104857600,"total":412345678}| Campo | Significado |
|---|---|
event | progress |
phase | downloading: descarga de un archivo de imagen o de un release; checking: comprobación de su SHA-256 con el catálogo; preparing: preparación de la escritura de os install a partir de la imagen; writing: escritura en la unidad (o en el archivo de --output); verifying: verificación de la unidad (o del archivo) mediante relectura; installing: instalación de un release en el otro slot (os update) |
done, total | Bytes: del archivo de imagen para downloading, checking, preparing y writing, de la imagen escrita para verifying. Para installing, porcentaje: total es 100. |
os install lee el archivo de imagen dos veces antes del reinicio: checking compara su SHA-256 con el catálogo firmado, y preparing descomprime la imagen una vez para encontrar su partición IRONFLOCKOS, colocar en ella el archivo .flock del dispositivo y los ajustes de red, y calcular las sumas de comprobación de lo que la escritura pone en el disco. En una terminal aparecen como Checking y Preparing.
Un evento llega cuando empieza una fase (done es 0), cada vez que cambia el porcentaje entero y cuando la fase termina (done es igual a total). Una descarga que se reanuda salta a los bytes que ya tiene. Las demás líneas de stderr, entre ellas las advertencias, son texto para una persona: un programa toma las líneas que se pueden analizar como objetos JSON y omite el resto.
Preguntas y confirmación
Un comando que cambia la máquina dice primero lo que va a hacer y después pregunta:
- Un comando que elimina o sobrescribe algo dice primero qué desaparece. Un comando que instala dice primero qué va a instalar.
agent stopdice primero qué termina al detener el agente. --yesresponde sí a todas las preguntas del comando, y toma el valor por defecto donde el comando ofrece una elección.- En la terminal, una pregunta tiene preseleccionado «Yes», así que basta con Enter para continuar. Tres preguntas tienen preseleccionado «No», así que Enter solo no borra ni elimina nada:
os flashantes de borrar una unidad,os flashantes de reemplazar el archivo de--output, yagent remove. os resette pide que escribas el nombre del dispositivo, yos install, el nombre de host de la máquina. Cualquier otra cosa, también Enter solo, responde no.- Lo que escribiste antes de que apareciera una pregunta se descarta. Una pregunta se responde después de haber leído lo que dice el comando.
- Esc responde no: el comando no cambia nada y termina con el código de salida 4. Ctrl-C en una pregunta no da ninguna respuesta, ni siquiera la preseleccionada: el comando no cambia nada y termina con el código de salida 130.
Una pregunta necesita una terminal tanto en stdin como en stderr. Sin ella (una tubería, CI, un script de cloud-init), el comando no espera ni adivina: termina con el código de salida 4 e indica que --yes confirma. Lo mismo ocurre con --json, que no pregunta nada. Por eso los scripts indican --yes junto con --json.
--yes nunca anula un rechazo. Cuando un comando se niega (código de salida 3, o una comprobación que falló), ningún flag hace que continúe. La página de cada comando enumera lo que rechaza. La única excepción es un disco interno, que os flash --allow-internal escribe cuando --drive lo indica.
Con --host, las preguntas te llegan cuando ejecutas el comando en una terminal. En varias máquinas a la vez no se pregunta a nadie, así que un comando que pregunta solo se ejecuta allí con --yes (consulta Máquinas remotas por SSH).
Privilegios de root
Un comando que cambia el sistema necesita root. Sin root termina con el código de salida 3 y lo indica. No llama a sudo por sí mismo; solo lo hace --host, en la otra máquina. os flash indica entonces la línea de comandos que hay que escribir, con sudo delante.
| Comandos | Root |
|---|---|
version, completion, os images, os drives, todos los --help | no es necesario |
status, doctor | no es necesario. Sin root, status dice unknown (needs root) para lo que no puede leer, y doctor marca esas comprobaciones como skipped. Con sudo lo leen. |
agent install, agent configure, agent update, agent remove, agent restart, agent stop, agent start | necesario |
agent logs | necesario: solo lee, pero lo que lee es exclusivo de root |
os flash | necesario para escribir una unidad. No es necesario con --output. En macOS, un usuario que puede escribir en el dispositivo raw de la unidad no necesita root. |
os install, os update, os rollback, os reset | necesario |
self-update | permiso de escritura en la carpeta del binario, y ser el propietario del binario y miembro de su grupo, o root. Para /usr/local/bin/ironflock, eso es root |
Con --host, un comando que necesita root se ejecuta mediante sudo en la otra máquina cuando la cuenta de acceso no es root.
Secretos
Ningún comando imprime un secreto: ni el secreto de un archivo .flock, ni una frase de contraseña de WiFi, ni una contraseña de proxy, ni una clave de licencia. Esto vale para stdout, stderr, --json y los mensajes de error.
Un secreto nunca es el valor de un flag cuando un archivo puede contenerlo, porque las líneas de comandos aparecen en ps y en el historial del shell. Una contraseña de proxy no es una excepción:
- Una URL de proxy en un flag indica el usuario sin la contraseña:
http://[email protected]:3128. - Una URL con contraseña, como
http://user:password@proxy:3128, es una línea de comandos incorrecta (código de salida 2). Se rechaza antes de que se ejecute nada y, con--host, antes de que llegue a la máquina. El error no la repite. - La contraseña viene de
--proxy-password-file: un archivo, o una tubería (/dev/stdin), de una línea. - Las variables de proxy del entorno, a las que recurre
agent install, pueden llevar una contraseña: no están en una línea de comandos.
# La contraseña desde un archivo
sudo ironflock agent configure --https-proxy http://[email protected]:3128 --proxy-password-file proxy-password.txt
# La contraseña por una tubería
sudo ironflock agent configure --proxy-password-file /dev/stdin --yes < proxy-password.txtEn un dispositivo que configuró agent install, la contraseña del proxy está donde solo root la lee: en /etc/ironflock/proxy.env (modo 0600). Los drop-ins de docker.service y de ironflock-device-agent.service nombran ese archivo y no contienen ningún ajuste de proxy, así que systemctl show muestra a cualquier usuario el nombre del archivo y nada de su contenido.
Con --host, un archivo .flock, un archivo de frase de contraseña de WiFi o un archivo de contraseña de proxy indicado en un flag llega a la otra máquina por la conexión SSH, nunca en una línea de comandos (consulta Máquinas remotas por SSH). Una base de descarga con credenciales termina con el código de salida 2 antes de llegar a ninguna máquina.
Códigos de salida
| Código | Tipo | Significado |
|---|---|---|
| 0 | hecho | |
| 1 | failed | el comando empezó y no pudo terminar |
| 2 | usage | la línea de comandos es incorrecta: un comando o un flag desconocido, un flag que falta, un nombre reservado. No se tocó nada. |
| 3 | precondition | la máquina no está en el estado que necesita el comando: sin root, sin agente instalado, con un agente ya instalado, un sistema en el que el comando no se ejecuta. No se tocó nada. |
| 4 | declined | se respondió no a la pregunta, o no se pudo hacer y no se indicó --yes |
| 130 | interrupted | interrumpido (Ctrl-C) antes de que el comando terminara; con --host, también un comando en la otra máquina que terminó por una desconexión (SIGHUP), una interrupción o una señal de terminación |
| 255 | ssh | falló la conexión SSH de --host: no se alcanzó la máquina, o la conexión se cortó |
Un error es una línea en stderr, Error: seguido del mensaje. A un error de uso le sigue una línea que indica qué --help leer. Con --json, el error es el resultado: stdout recibe un objeto de error, y stderr no recibe ninguna línea de error. kind es uno de los tipos de la tabla.
{"error":{"kind":"precondition","message":"the agent is not installed on this machine"}}Dos comandos escriben su resultado y aun así terminan con el código de salida 1. agent update lo hace cuando el agente se queda en su versión: el resultado dice por qué, y stderr recibe la línea Error:. doctor lo hace cuando falló una comprobación: el resultado dice cuál, y no sigue ninguna línea de error. Con --json, ninguno de los dos escribe entonces un objeto de error: stdout tiene el resultado.
Con --help, un comando desconocido no es un error: ironflock os nosuch --help imprime la ayuda de ironflock os, con el código de salida 0. En varias máquinas, el comando termina con el peor código de salida de las máquinas (consulta Máquinas remotas por SSH).
Interrupciones
Ctrl-C, SIGTERM y SIGHUP (cuando desaparece la terminal o la sesión SSH) terminan la mayoría de los comandos de inmediato, como terminan cualquier programa, sin línea de error; el shell ve 130 (143 tras SIGTERM, 129 tras SIGHUP). Algunos pasos los gestionan:
os flashmientras descarga, escribe o relee una imagen, yos updatemientras descarga y comprueba un paquete, se detienen en el siguiente bloque. Indican lo que dejaron, como un error del tipointerrupted, y terminan con 130;os updateno instala nada entonces. Una vez queos flashha releído el último bloque, sus pasos finales se completan y termina con 0. Un segundo Ctrl-C termina el proceso de inmediato; con--outputpuede quedar el archivo.part.agent logs --followsigue el registro hasta recibir una de estas señales, y entonces termina con 0.agent updatedeja de seguir la actualización con 130; el agente continúa por sí solo.os reset, mientras escribe su solicitud, la retira, termina con 130 y el dispositivo no se reinicia.agent configure, una vez que ha empezado a cambiar la máquina, ya no se detiene si se pierde la terminal o la sesión SSH. Ctrl-C y SIGTERM siguen terminándolo de inmediato.os installse comporta de forma distinta antes y después de su pregunta; consultaironflock os install.
Códigos de salida en un script
Un script indica --yes para que el comando no se detenga en su pregunta, --json para obtener un resultado que pueda leer, y comprueba el código de salida:
#!/bin/sh
# Hacer que el agente se actualice; conservar el resultado JSON y descartar el progreso de 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" ;;
esacCon el código de salida 0, $result contiene el resultado, cuyo outcome es updated o current. Con el código de salida 1, contiene o bien el resultado, cuyos outcome y reason dicen por qué el agente se queda en su versión, o bien un objeto de error. Con el código de salida 3, contiene el objeto de error.