Compare commits
3 commits
9954f70e6c
...
f946a566a2
Author | SHA1 | Date | |
---|---|---|---|
f946a566a2 | |||
a3644afc2b | |||
a2e33d2b13 |
12
Makefile
12
Makefile
|
@ -43,3 +43,15 @@ boot_iso_uefi_secureboot:
|
||||||
-enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \
|
-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=deploy/iso/workbench_debug.iso,cache=none,if=virtio,format=raw,index=0,media=disk \
|
||||||
-boot menu=on
|
-boot menu=on
|
||||||
|
|
||||||
|
es_gen_po:
|
||||||
|
cp locale/es/LC_MESSAGES/messages.po locale/es/LC_MESSAGES/messages.pot.bak
|
||||||
|
pygettext3 -p locale/es/LC_MESSAGES/ workbench-script.py
|
||||||
|
# src https://stackoverflow.com/questions/7496156/gettext-how-to-update-po-and-pot-files-after-the-source-is-modified
|
||||||
|
msgmerge -N locale/es/LC_MESSAGES/messages.pot.bak locale/es/LC_MESSAGES/messages.pot > locale/es/LC_MESSAGES/messages.po
|
||||||
|
rm locale/es/LC_MESSAGES/messages.pot.bak
|
||||||
|
rm locale/es/LC_MESSAGES/messages.pot
|
||||||
|
|
||||||
|
|
||||||
|
es_gen_mo:
|
||||||
|
msgfmt locale/es/LC_MESSAGES/messages.po -o locale/es/LC_MESSAGES/messages.mo
|
||||||
|
|
21
README-es.md
21
README-es.md
|
@ -30,26 +30,11 @@ Comentarios sobre el borrado:
|
||||||
|
|
||||||
## Uso del script
|
## Uso del script
|
||||||
|
|
||||||
Detalles del uso del script para los técnicos
|
Detalles del uso del script para técnicos
|
||||||
|
|
||||||
```
|
El script está diseñado para funcionar por defecto de forma intuitiva y sin configuración previa
|
||||||
workbench.py [-h] -p PATH [-u URL] [-t TOKEN] [-d DEVICE] [-e {basic,baseline,enhanced}]
|
|
||||||
|
|
||||||
OPCIONES
|
Se puede especificar un fichero de configuración con el argumento `--config`, y en `settings.ini.example` se puede encontrar un ejemplo de configuración
|
||||||
|
|
||||||
El -p es el unico que es obligatorio el resto son opcionales. Si no pones -e no borra.
|
|
||||||
|
|
||||||
-p path
|
|
||||||
deja el snapshot en el dir path (tal como /mnt)
|
|
||||||
|
|
||||||
-e tipo-borrado
|
|
||||||
tipo de borrado de disco: basic, baseline, enhanced. Nota: bueno si pones -e tampoco borra porque hay que cambiar el script pero es descomentar unas lineas y ya.
|
|
||||||
|
|
||||||
-d device
|
|
||||||
le dices que device quieres borrar y depende de -e que defines el tipo de borrado. Nota: si no le dices -d y solo usas -e borrara todo lo que pille, menos el de boot como dijimos (no probado)
|
|
||||||
|
|
||||||
-u tiene que ir con -t y se usa para enviar a una direccion con su token (no probado)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Enfoque
|
## Enfoque
|
||||||
|
|
||||||
|
|
|
@ -255,11 +255,10 @@ END
|
||||||
|
|
||||||
prepare_app() {
|
prepare_app() {
|
||||||
# prepare app during prepare_chroot_env
|
# prepare app during prepare_chroot_env
|
||||||
# Install hardware_metadata module
|
|
||||||
workbench_dir="${ISO_PATH}/chroot/opt/workbench"
|
workbench_dir="${ISO_PATH}/chroot/opt/workbench"
|
||||||
${SUDO} mkdir -p "${workbench_dir}"
|
${SUDO} mkdir -p "${workbench_dir}"
|
||||||
${SUDO} cp workbench-script.py "${workbench_dir}/"
|
${SUDO} cp workbench-script.py "${workbench_dir}/"
|
||||||
${SUDO} cp requirements.txt "${workbench_dir}/"
|
${SUDO} cp -arp locale "${workbench_dir}/"
|
||||||
|
|
||||||
# startup script execution
|
# startup script execution
|
||||||
cat > "${ISO_PATH}/chroot/root/.profile" <<END
|
cat > "${ISO_PATH}/chroot/root/.profile" <<END
|
||||||
|
@ -301,7 +300,7 @@ echo 'Install requirements'
|
||||||
|
|
||||||
# Install debian requirements
|
# Install debian requirements
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
sudo \
|
sudo locales \
|
||||||
python3 python3-dev python3-pip pipenv \
|
python3 python3-dev python3-pip pipenv \
|
||||||
dmidecode smartmontools hwinfo pciutils lshw nfs-common < /dev/null
|
dmidecode smartmontools hwinfo pciutils lshw nfs-common < /dev/null
|
||||||
|
|
||||||
|
@ -355,6 +354,13 @@ apt-get install -y --no-install-recommends \
|
||||||
# Install app
|
# Install app
|
||||||
${install_app_str}
|
${install_app_str}
|
||||||
|
|
||||||
|
# thanks src https://serverfault.com/questions/362903/how-do-you-set-a-locale-non-interactively-on-debian-ubuntu
|
||||||
|
export LANG=${LANG}
|
||||||
|
export LC_ALL=${LANG}
|
||||||
|
# this is a high level command that does locale-gen and update-locale altogether
|
||||||
|
dpkg-reconfigure --frontend=noninteractive locales
|
||||||
|
locale -a
|
||||||
|
|
||||||
# Autologin root user
|
# Autologin root user
|
||||||
# src https://wiki.archlinux.org/title/getty#Automatic_login_to_virtual_console
|
# src https://wiki.archlinux.org/title/getty#Automatic_login_to_virtual_console
|
||||||
mkdir -p /etc/systemd/system/getty@tty1.service.d/
|
mkdir -p /etc/systemd/system/getty@tty1.service.d/
|
||||||
|
@ -396,6 +402,7 @@ CHROOT
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_chroot_env() {
|
prepare_chroot_env() {
|
||||||
|
LANG="${CUSTOM_LANG:-es_ES.UTF-8}"
|
||||||
# version of debian the bootstrap is going to build
|
# version of debian the bootstrap is going to build
|
||||||
# if no VERSION_CODENAME is specified we assume that the bootstrap is going to
|
# if no VERSION_CODENAME is specified we assume that the bootstrap is going to
|
||||||
# be build with the same version of debian being executed because some files
|
# be build with the same version of debian being executed because some files
|
||||||
|
|
18
install-dependencies.sh
Executable file
18
install-dependencies.sh
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (c) 2024 Pedro <copyright@cas.cat>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
# DEBUG
|
||||||
|
set -x
|
||||||
|
|
||||||
|
main() {
|
||||||
|
sudo apt install smartmontools lshw hwinfo dmidecode
|
||||||
|
}
|
||||||
|
|
||||||
|
main "${@}"
|
||||||
|
|
||||||
|
# written in emacs
|
||||||
|
# -*- mode: shell-script; -*-
|
BIN
locale/es/LC_MESSAGES/messages.mo
Normal file
BIN
locale/es/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
107
locale/es/LC_MESSAGES/messages.po
Normal file
107
locale/es/LC_MESSAGES/messages.po
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2024-10-15 21:15+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: workbench-script.py:48 workbench-script.py:53
|
||||||
|
msgid "Running command `%s`"
|
||||||
|
msgstr "Ejecutando comando `%s`"
|
||||||
|
|
||||||
|
#: workbench-script.py:284
|
||||||
|
msgid "Created snapshots directory at '%s'"
|
||||||
|
msgstr "Creado directorio de snapshots en '%s'"
|
||||||
|
|
||||||
|
#: workbench-script.py:287
|
||||||
|
msgid "Snapshot written in path '%s'"
|
||||||
|
msgstr "Snapshot escrito en ruta '%s'"
|
||||||
|
|
||||||
|
#: workbench-script.py:290
|
||||||
|
msgid ""
|
||||||
|
"Attempting to save file in actual path. Reason: Failed to write in snapshots "
|
||||||
|
"directory:\n"
|
||||||
|
" %s."
|
||||||
|
msgstr ""
|
||||||
|
"Probando de guardar el fichero en la ruta actual. Motivo: Fallo al intentar "
|
||||||
|
"escribir en el directorio de snapshots:\n"
|
||||||
|
" %s."
|
||||||
|
|
||||||
|
#: workbench-script.py:297
|
||||||
|
msgid "Snapshot written in fallback path '%s'"
|
||||||
|
msgstr "Snapshot escrito en ruta alternativa '%s'"
|
||||||
|
|
||||||
|
#: workbench-script.py:299
|
||||||
|
msgid ""
|
||||||
|
"Could not save snapshot locally. Reason: Failed to write in fallback path:\n"
|
||||||
|
" %s"
|
||||||
|
msgstr ""
|
||||||
|
"No pude guardar snapshots localmente. Motivo: Fallo al escribir en la ruta "
|
||||||
|
"alternativa:\n"
|
||||||
|
" %s"
|
||||||
|
|
||||||
|
#: workbench-script.py:316
|
||||||
|
msgid "Snapshot successfully sent to '%s'"
|
||||||
|
msgstr "Snapshot enviado con éxito a '%s'"
|
||||||
|
|
||||||
|
#: workbench-script.py:331
|
||||||
|
msgid ""
|
||||||
|
"Snapshot not remotely sent to URL '%s'. Do you have internet? Is your server "
|
||||||
|
"up & running? Is the url token authorized?\n"
|
||||||
|
" %s"
|
||||||
|
msgstr ""
|
||||||
|
"Snapshot no enviado remotamente a la URL '%s'. Tienes internet? Está el "
|
||||||
|
"servidor en marcha? Está autorizado el url token?\n"
|
||||||
|
" %s"
|
||||||
|
|
||||||
|
#: workbench-script.py:342
|
||||||
|
msgid "Found config file in path: %s."
|
||||||
|
msgstr "Encontrado fichero de configuración en ruta: %s."
|
||||||
|
|
||||||
|
#: workbench-script.py:353
|
||||||
|
msgid "Config file '%s' not found. Using default values."
|
||||||
|
msgstr ""
|
||||||
|
"Fichero de configuración '%s' no encontrado. Utilizando valores por defecto."
|
||||||
|
|
||||||
|
#: workbench-script.py:373
|
||||||
|
msgid "workbench-script.py [-h] [--config CONFIG]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: workbench-script.py:374
|
||||||
|
msgid "Optional config loader for workbench."
|
||||||
|
msgstr "Cargador opcional de configuración para workbench"
|
||||||
|
|
||||||
|
#: workbench-script.py:377
|
||||||
|
msgid ""
|
||||||
|
"path to the config file. Defaults to 'settings.ini' in the current directory."
|
||||||
|
msgstr ""
|
||||||
|
"ruta al fichero de configuración. Por defecto es 'settings.ini' en el "
|
||||||
|
"directorio actual"
|
||||||
|
|
||||||
|
#: workbench-script.py:410
|
||||||
|
msgid "START"
|
||||||
|
msgstr "INICIO"
|
||||||
|
|
||||||
|
#: workbench-script.py:423
|
||||||
|
msgid ""
|
||||||
|
"This script must be run as root. Collected data will be incomplete or "
|
||||||
|
"unusable"
|
||||||
|
msgstr ""
|
||||||
|
"Es conveniente que este script sea ejecutado como administrador (root). Los "
|
||||||
|
"datos recopilados serán incompletos o no usables."
|
||||||
|
|
||||||
|
#: workbench-script.py:441
|
||||||
|
msgid "END"
|
||||||
|
msgstr "FIN"
|
|
@ -1,2 +0,0 @@
|
||||||
ntplib
|
|
||||||
requests
|
|
|
@ -8,6 +8,10 @@ import argparse
|
||||||
import configparser
|
import configparser
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
import locale
|
||||||
|
import logging
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +37,7 @@ def logs(f):
|
||||||
try:
|
try:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(err)
|
logger.error(err)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
@ -41,12 +45,12 @@ def logs(f):
|
||||||
|
|
||||||
@logs
|
@logs
|
||||||
def exec_cmd(cmd):
|
def exec_cmd(cmd):
|
||||||
print(f'workbench: INFO: running command `{cmd}`')
|
logger.info(_('Running command `%s`'), cmd)
|
||||||
return os.popen(cmd).read()
|
return os.popen(cmd).read()
|
||||||
|
|
||||||
@logs
|
@logs
|
||||||
def exec_cmd_erase(cmd):
|
def exec_cmd_erase(cmd):
|
||||||
print(cmd)
|
logger.info(_('Running command `%s`'), cmd)
|
||||||
return ''
|
return ''
|
||||||
# return os.popen(cmd).read()
|
# return os.popen(cmd).read()
|
||||||
|
|
||||||
|
@ -277,23 +281,22 @@ def save_snapshot_in_disk(snapshot, path):
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(snapshot_path):
|
if not os.path.exists(snapshot_path):
|
||||||
os.makedirs(snapshot_path)
|
os.makedirs(snapshot_path)
|
||||||
print(f"workbench: INFO: Created snapshots directory at '{snapshot_path}'")
|
logger.info(_("Created snapshots directory at '%s'"), snapshot_path)
|
||||||
|
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
f.write(json.dumps(snapshot))
|
f.write(json.dumps(snapshot))
|
||||||
print(f"workbench: INFO: Snapshot written in path '{filename}'")
|
logger.info(_("Snapshot written in path '%s'"), filename)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
try:
|
try:
|
||||||
print(f"workbench: WARNING: Attempting to save in actual path. Reason: Failed to write in snapshots directory:\n {e}.")
|
logger.warning(_("Attempting to save file in actual path. Reason: Failed to write in snapshots directory:\n %s."), e)
|
||||||
fallback_filename = "{}/{}_{}.json".format(
|
fallback_filename = "{}/{}_{}.json".format(
|
||||||
path,
|
path,
|
||||||
datetime.now().strftime("%Y%m%d-%H_%M_%S"),
|
datetime.now().strftime("%Y%m%d-%H_%M_%S"),
|
||||||
snapshot['uuid'])
|
snapshot['uuid'])
|
||||||
with open(fallback_filename, "w") as f:
|
with open(fallback_filename, "w") as f:
|
||||||
f.write(json.dumps(snapshot))
|
f.write(json.dumps(snapshot))
|
||||||
print(f"workbench: INFO: Snapshot written in fallback path '{fallback_filename}'")
|
logger.warning(_("Snapshot written in fallback path '%s'"), fallback_filename)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"workbench: ERROR: Could not save snapshot locally. Reason: Failed to write in fallback path:\n {e}")
|
logger.error(_("Could not save snapshot locally. Reason: Failed to write in fallback path:\n %s"), e)
|
||||||
|
|
||||||
# TODO sanitize url, if url is like this, it fails
|
# TODO sanitize url, if url is like this, it fails
|
||||||
# url = 'http://127.0.0.1:8000/api/snapshot/'
|
# url = 'http://127.0.0.1:8000/api/snapshot/'
|
||||||
|
@ -310,13 +313,7 @@ def send_snapshot_to_devicehub(snapshot, token, url):
|
||||||
response_text = response.read().decode('utf-8')
|
response_text = response.read().decode('utf-8')
|
||||||
|
|
||||||
if 200 <= status_code < 300:
|
if 200 <= status_code < 300:
|
||||||
print(f"workbench: INFO: Snapshot successfully sent to '{url}'")
|
logger.info(_("Snapshot successfully sent to '%s'"), url)
|
||||||
else:
|
|
||||||
txt = "workbench: ERROR: Failed to send snapshot. HTTP {}: {}".format(
|
|
||||||
status_code,
|
|
||||||
response_text
|
|
||||||
)
|
|
||||||
raise Exception(txt)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = json.loads(response_text)
|
response = json.loads(response_text)
|
||||||
|
@ -328,10 +325,10 @@ def send_snapshot_to_devicehub(snapshot, token, url):
|
||||||
if response.get("dhid"):
|
if response.get("dhid"):
|
||||||
print("dhid: {}".format(response['dhid']))
|
print("dhid: {}".format(response['dhid']))
|
||||||
except Exception:
|
except Exception:
|
||||||
print(response_text)
|
logger.error(response_text)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"workbench: ERROR: Snapshot not remotely sent to URL '{url}'. Do you have internet? Is your server up & running? Is the url token authorized?\n {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)
|
||||||
|
|
||||||
def load_config(config_file="settings.ini"):
|
def load_config(config_file="settings.ini"):
|
||||||
"""
|
"""
|
||||||
|
@ -342,7 +339,7 @@ def load_config(config_file="settings.ini"):
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
# If config file exists, read from it
|
# If config file exists, read from it
|
||||||
|
|
||||||
print(f"workbench: INFO: Found config file in path: '{config_file}'.")
|
logger.info(_("Found config file in path: %s."), config_file)
|
||||||
config.read(config_file)
|
config.read(config_file)
|
||||||
path = config.get('settings', 'path', fallback=os.getcwd())
|
path = config.get('settings', 'path', fallback=os.getcwd())
|
||||||
# TODO validate that has http:// start
|
# TODO validate that has http:// start
|
||||||
|
@ -353,7 +350,7 @@ def load_config(config_file="settings.ini"):
|
||||||
erase = config.get('settings', 'erase', fallback=None)
|
erase = config.get('settings', 'erase', fallback=None)
|
||||||
legacy = config.get('settings', 'legacy', fallback=None)
|
legacy = config.get('settings', 'legacy', fallback=None)
|
||||||
else:
|
else:
|
||||||
print(f"workbench: ERROR: Config file '{config_file}' not found. Using default values.")
|
logger.error(_("Config file '%s' not found. Using default values."), config_file)
|
||||||
path = os.path.join(os.getcwd())
|
path = os.path.join(os.getcwd())
|
||||||
url, token, device, erase, legacy = None, None, None, None, None
|
url, token, device, erase, legacy = None, None, None, None, None
|
||||||
|
|
||||||
|
@ -370,17 +367,45 @@ def parse_args():
|
||||||
"""
|
"""
|
||||||
Parse config argument, if available
|
Parse config argument, if available
|
||||||
"""
|
"""
|
||||||
parser = argparse.ArgumentParser(description="Optional config loader for workbench.")
|
parser = argparse.ArgumentParser(
|
||||||
|
usage=_("workbench-script.py [-h] [--config CONFIG]"),
|
||||||
|
description=_("Optional config loader for workbench."))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--config',
|
'--config',
|
||||||
help="Path to the config file. Defaults to 'settings.ini' in the current directory.",
|
help=_("path to the config file. Defaults to 'settings.ini' in the current directory."),
|
||||||
default="settings.ini" # Fallback to 'settings.ini' by default
|
default="settings.ini" # Fallback to 'settings.ini' by default
|
||||||
)
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def prepare_lang():
|
||||||
|
locale_path = os.path.join(os.path.dirname(__file__), 'locale')
|
||||||
|
domain = 'messages'
|
||||||
|
gettext.bindtextdomain(domain, locale_path)
|
||||||
|
gettext.textdomain(domain)
|
||||||
|
global _
|
||||||
|
# with LANG=es_ES.UTF-8, it detects spanish
|
||||||
|
_ = gettext.gettext
|
||||||
|
# # this would force it to spanish
|
||||||
|
# lang = gettext.translation(domain, localedir=locale_path, languages=['es'])
|
||||||
|
# lang.install()
|
||||||
|
# _ = lang.gettext
|
||||||
|
|
||||||
|
def prepare_logger():
|
||||||
|
global logger
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(logging.INFO)
|
||||||
|
formatter = logging.Formatter('[%(asctime)s] workbench: %(levelname)s: %(message)s')
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(console_handler)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
vline='\n___________\n\n'
|
prepare_lang()
|
||||||
print(f"{vline}workbench: START\n")
|
prepare_logger()
|
||||||
|
|
||||||
|
logger.info(_("START"))
|
||||||
|
|
||||||
# Parse the command-line arguments
|
# Parse the command-line arguments
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
@ -393,7 +418,7 @@ def main():
|
||||||
# TODO show warning if non root, means data is not complete
|
# TODO show warning if non root, means data is not complete
|
||||||
# if annotate as potentially invalid snapshot (pending the new API to be done)
|
# if annotate as potentially invalid snapshot (pending the new API to be done)
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
print("workbench: WARNING: This script must be run as root. Collected data will be incomplete or unusable")
|
logger.warning(_("This script must be run as root. Collected data will be incomplete or unusable"))
|
||||||
|
|
||||||
all_disks = get_disks()
|
all_disks = get_disks()
|
||||||
snapshot = gen_snapshot(all_disks)
|
snapshot = gen_snapshot(all_disks)
|
||||||
|
@ -411,7 +436,7 @@ def main():
|
||||||
if config['url']:
|
if config['url']:
|
||||||
send_snapshot_to_devicehub(snapshot, config['token'], config['url'])
|
send_snapshot_to_devicehub(snapshot, config['token'], config['url'])
|
||||||
|
|
||||||
print(f"\nworkbench: END{vline}")
|
logger.info(_("END"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in a new issue