From 96e9ddcf53934607eac9fd23b470c0211f65da22 Mon Sep 17 00:00:00 2001 From: sergio-gimenez Date: Sat, 15 Feb 2025 12:03:15 +0100 Subject: [PATCH 1/3] Specify user of the container to avoid crashing at first run --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 2fac0b3..2d35131 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,3 @@ - services: build-iso: init: true @@ -8,6 +7,7 @@ services: # uncomment next two lines to test this environment: - DEBUG=true + - USER=root volumes: - .:/opt/workbench-script:ro - ./iso:/opt/workbench-script/iso:rw -- 2.30.2 From ef17701a6898bbe46f904ce80d5900b5e5fb8751 Mon Sep 17 00:00:00 2001 From: sergio-gimenez Date: Sat, 15 Feb 2025 12:07:45 +0100 Subject: [PATCH 2/3] Add max retries between windows of 5 seconds --- workbench-script.py | 69 +++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/workbench-script.py b/workbench-script.py index 81c72ef..bdeb1f0 100644 --- a/workbench-script.py +++ b/workbench-script.py @@ -17,6 +17,7 @@ import locale import logging from datetime import datetime +import time SNAPSHOT_BASE = { @@ -31,7 +32,6 @@ SNAPSHOT_BASE = { } - ## Utility Functions ## def logs(f): def wrapper(*args, **kwargs): @@ -364,7 +364,7 @@ def generate_qr_code(url, disable_qr): # TODO sanitize url, if url is like this, it fails # url = 'http://127.0.0.1:8000/api/snapshot/' -def send_snapshot_to_devicehub(snapshot, token, url, ev_uuid, legacy, disable_qr): +def send_snapshot_to_devicehub(snapshot, token, url, ev_uuid, legacy, disable_qr, max_retries=5): url_components = urllib.parse.urlparse(url) ev_path = f"evidence/{ev_uuid}" components = (url_components.scheme, url_components.netloc, ev_path, '', '', '') @@ -374,35 +374,48 @@ def send_snapshot_to_devicehub(snapshot, token, url, ev_uuid, legacy, disable_qr "Authorization": f"Bearer {token}", "Content-Type": "application/json" } - try: - data = snapshot.encode('utf-8') - request = urllib.request.Request(url, data=data, headers=headers) - with urllib.request.urlopen(request) as response: - status_code = response.getcode() - response_text = response.read().decode('utf-8') - if 200 <= status_code < 300: - logger.info(_("Snapshot successfully sent to '%s'"), url) - if legacy: - try: - response = json.loads(response_text) - public_url = response.get('public_url') - dhid = response.get('dhid') - if public_url: - generate_qr_code(public_url, disable_qr) - print("url: {}".format(public_url)) - if dhid: - print("dhid: {}".format(dhid)) - except Exception: - logger.error(response_text) + retries = 0 + while retries < max_retries: + try: + data = snapshot.encode('utf-8') + request = urllib.request.Request(url, data=data, headers=headers) + with urllib.request.urlopen(request) as response: + status_code = response.getcode() + response_text = response.read().decode('utf-8') + + if 200 <= status_code < 300: + logger.info(_("Snapshot successfully sent to '%s'"), url) + if legacy: + try: + response = json.loads(response_text) + public_url = response.get('public_url') + dhid = response.get('dhid') + if public_url: + generate_qr_code(public_url, disable_qr) + print("url: {}".format(public_url)) + if dhid: + print("dhid: {}".format(dhid)) + except Exception: + logger.error(response_text) + else: + generate_qr_code(ev_url, disable_qr) + print("url: {}".format(ev_url)) + return else: - generate_qr_code(ev_url, disable_qr) - print("url: {}".format(ev_url)) - else: - logger.error(_("Snapshot %s not remotely sent to URL '%s'. Server responded with error:\n %s"), ev_uuid, url, response_text) + logger.error( + _("Snapshot %s not remotely sent to URL '%s'. Server responded with error:\n %s"), ev_uuid, url, response_text) + except Exception as e: + logger.error( + _("Snapshot not remotely sent to URL '%s'. Do you have internet? Is your server up & running? Is the url token authorized?\n %s"), url, e) - except Exception as e: - logger.error(_("Snapshot not remotely sent to URL '%s'. Do you have internet? Is your server up & running? Is the url token authorized?\n %s"), url, e) + retries += 1 + if retries < max_retries: + logger.info(_("Retrying... (%d/%d)"), retries, max_retries) + time.sleep(5) # TODO arbitrary number of seconds. + + logger.error( + _("Failed to send snapshot to URL '%s' after %d attempts"), url, max_retries) def load_config(config_file="settings.ini"): -- 2.30.2 From 0c2d669bb555b2b92336cc0d4fb6d0cdd97039c9 Mon Sep 17 00:00:00 2001 From: sergio-gimenez Date: Sat, 15 Feb 2025 12:44:54 +0100 Subject: [PATCH 3/3] Parametrise iso_file_name and document it --- Makefile | 14 +++++++---- README-es.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index b41a7c7..4300bd7 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,13 @@ install_dependencies: boot_iso: sudo qemu-system-x86_64 \ -enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \ - -drive format=raw,file=iso/workbench_production.iso,cache=none,if=virtio + -drive format=raw,file=$(ISO_FILE),cache=none,if=virtio + +boot_iso_from_usb: + sudo qemu-system-x86_64 \ + -enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \ + -drive format=raw,file=$(USB_DEVICE),cache=none,if=virtio + # src https://www.ubuntubuzz.com/2021/04/how-to-boot-uefi-on-qemu.html # needs `sudo apt-get install ovmf` @@ -30,18 +36,16 @@ boot_iso_uefi: sudo qemu-system-x86_64 \ -bios /usr/share/ovmf/OVMF.fd \ -enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \ - -drive format=raw,file=deploy/iso/WORKBENCH_debug.iso,cache=none,if=virtio + -drive format=raw,file=$(ISO_FILE),cache=none,if=virtio boot_iso_uefi_secureboot: - # For ovmf 2020.08-1, the change of boot order is usually necessary because the UEFI shell has the highest boot priority in OVMF_VARS*.ms.fd. sudo cp /usr/share/OVMF/OVMF_VARS_4M.ms.fd /tmp/efivars_4M.fd - # src https://wiki.debian.org/SecureBoot/VirtualMachine sudo qemu-system-x86_64 \ -machine q35,smm=on -global driver=cfi.pflash01,property=secure,value=on \ -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.secboot.fd,readonly=on \ -drive if=pflash,format=raw,unit=1,file=/tmp/efivars_4M.fd \ -enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \ - -drive file=deploy/iso/workbench_debug.iso,cache=none,if=virtio,format=raw,index=0,media=disk \ + -drive file=$(ISO_FILE),cache=none,if=virtio,format=raw,index=0,media=disk \ -boot menu=on # when you change something, you need to refresh it this way diff --git a/README-es.md b/README-es.md index 8393574..ba04073 100644 --- a/README-es.md +++ b/README-es.md @@ -40,8 +40,72 @@ Se puede especificar un fichero de configuración con el argumento `--config`, y workbench-script trata de ser simple y minimalista, una función principal y funciones de soporte la lectura de las diferentes funcionalidades. -## Generar ISO para el USB +## Generar una ISO para el USB -Para generar la iso y preparar un usb que arranque con workbench necesitas generarte una workbench de este, con tu configuración específica +Para crear una imagen ISO y preparar un USB que arranque con Workbench, primero debes generar una versión personalizada de Workbench con tu configuración específica. Como mínimo, necesitas un archivo `settings.ini` que contenga la URL de tu instancia de DeviceHub y el token de acceso. + +Existen dos métodos para generar la ISO: + +### 1. Usando Docker (Método recomendado) + +Este método es el más sencillo y compatible con cualquier sistema operativo (incluyendo Windows y macOS). Solo necesitas tener Docker instalado en tu máquina. + +Una vez instalado Docker, ejecuta el siguiente comando en la terminal: + +```bash +docker compose up +``` + +Este comando creará un contenedor de Docker con el script de Workbench y generará una ISO que incluirá tanto el script como el archivo `settings.ini` de tu directorio. La ISO resultante se guardará en: + +```bash +iso/workbench_debug.iso +``` + +### 2. Generando la ISO directamente en tu máquina + +Si prefieres generar la ISO sin Docker, puedes hacerlo manualmente ejecutando el script `deploy-workbench.sh`. Para ello, primero debes instalar las dependencias necesarias con el siguiente script: + +```bash +install-dependencies.sh +``` + +Luego, ejecuta: + +```bash +deploy-workbench.sh +``` + +Este proceso generará la ISO en el directorio `iso/workbench_debug.iso`. + +> [!NOTE] +> Se ha detectado que `deploy-workbench.sh` no funciona correctamente en distribuciones basadas en Ubuntu 24.04. + +## Testear la ISO Generada (Solo para linux) + +Para testear la ISO Generada, se proveé un Makefile. Este Makefile proporciona comandos para desplegar el sistema Workbench, gestionar dependencias y arrancar imágenes ISO con QEMU. + +Antes de usar el `Makefile`, instala las dependencias necesarias: + +```bash +make install_dependencies +``` + +### Arranque de Imágenes ISO + +```bash +make boot_iso ISO_FILE=iso/workbench_production.iso +``` + +O bien: + +```bash +make boot_iso ISO_FILE=iso/workbench_debug.iso +``` + +También es posible arrancar desde un live USB: + +```bash +make boot_iso_from_usb USB_DEVICE=/dev/sda +``` -Ejecuta `./deploy-workbench.sh` -- 2.30.2