Compare commits

...

84 Commits

Author SHA1 Message Date
pedro 23f277231a pxe: more on customize pxe menus, give example 2024-09-27 23:18:56 -03:00
pedro d2e5b1f824 pxe: allow personalization of boot menus 2024-09-27 23:18:56 -03:00
pedro 5dbb4a58f3 pxe: more sudo cmds to fix 2024-09-27 23:18:56 -03:00
pedro 2df34e4b23 pxe: a lot of improvements 2024-09-27 23:18:56 -03:00
pedro bd52916b06 pxe: finally this is the thing for nfs
cleanup old deps
2024-09-27 23:18:56 -03:00
pedro 2e57351e1a pxe: ensure systemd is aware of mounts 2024-09-27 23:18:56 -03:00
pedro 97b8de7fd3 pxe: nfs-common dep was in the wrong place 2024-09-27 23:18:56 -03:00
pedro f617526c34 workbench-script: improve err msg for HTTP POST 2024-09-27 23:18:56 -03:00
pedro e527ba611d pxe: improve error msgs in wb-script 2024-09-27 23:18:56 -03:00
pedro abfe9a5ceb pxe: improve autostart script 2024-09-27 23:18:56 -03:00
pedro ddb9b4a105 pxe: add nfs-common 2024-09-27 23:18:56 -03:00
pedro 349e0eb480 pxe: improve autostart 2024-09-27 23:18:56 -03:00
pedro b2e82e7bb9 pxe: trying to fix autostart script 2024-09-27 23:18:56 -03:00
pedro 2a7af1ddab Revert "pxe: we know the server host, is in the config"
This reverts commit 5399d544ee.
2024-09-27 23:18:56 -03:00
pedro 7d16cb8bd4 pxe: fix autostart script 2024-09-27 23:18:56 -03:00
pedro 93a86a8b11 pxe: we know the server host, is in the config 2024-09-27 23:18:56 -03:00
pedro 2fd0d2fdb9 pxe: add ref to dhcp proxy 2024-09-27 23:18:56 -03:00
pedro 6c513cb5d3 bugfix wrong try/except 2024-09-27 23:18:56 -03:00
pedro 103f2f8e79 workbench-script: improve autostart script 2024-09-27 23:18:56 -03:00
pedro c845249a81 pxe: bugfix wrong try 2024-09-27 23:18:56 -03:00
pedro 6ffa9a9304 deploy-workbench: no debug mode when script ended 2024-09-27 23:18:56 -03:00
pedro 19957c608d pxe: add try-exception for writing fallback path 2024-09-27 23:18:56 -03:00
pedro b380450bd4 pxe: snapshot nfs dir, ensure exists 2024-09-27 23:18:56 -03:00
pedro 80edd9e748 add empty readme in english 2024-09-27 23:18:56 -03:00
pedro 9de317adbf pxe: fix snapshot nfs logic 2024-09-27 23:18:56 -03:00
pedro e4b844713e pxe settings.ini: migrate to localhost domain 2024-09-27 23:18:56 -03:00
pedro 21942f26af settings.ini: move to using domain 2024-09-27 23:18:56 -03:00
pedro da026ad0c3 workbench-script: warn when not root 2024-09-27 23:18:56 -03:00
pedro fa4758fdf6 improve docs 2024-09-27 23:18:56 -03:00
pedro ecb9b1649b pxe: do the trick for rw snapshots dir 2024-09-27 23:18:56 -03:00
pedro 52e99064c6 workbench-script: remove ntplib
- it was not being used
- let's delegate this to Operating System
2024-09-27 23:18:56 -03:00
pedro d2c06b760f pxe: move README to spanish 2024-09-27 23:18:56 -03:00
pedro 66a744d108 pxe: fix wrong default path 2024-09-27 23:18:56 -03:00
pedro ab778a881d pxe: more useful warning error 2024-09-27 23:18:56 -03:00
pedro 51af4d3a9b pxe: simplify and avoid error 2024-09-27 23:18:56 -03:00
pedro b99c729125 pxe: simplify with cp 2024-09-27 23:18:56 -03:00
pedro 4fcdcc8955 deploy-workbench: detect nfs env 2024-09-27 23:18:56 -03:00
pedro a70179223a pxe: rsync to copy squashfs 2024-09-27 23:18:56 -03:00
pedro 9e96ae52d0 pxe: change initrd location in tftp 2024-09-27 23:18:56 -03:00
pedro d2431bead7 pxe: come back to the previous directory 2024-09-27 23:18:56 -03:00
pedro 8d54a4c157 pxe: see if squashfs can be a symlink 2024-09-27 23:18:56 -03:00
pedro f0b5b91ccd pxe: force cp 2024-09-27 23:18:56 -03:00
pedro 5aa938f195 pxe: change symlink to cp 2024-09-27 23:18:56 -03:00
pedro 5447aea9e2 pxe: fix directory pxelinux 2024-09-27 23:18:56 -03:00
pedro 95ae7b4144 pxe: bugfix to continue 2024-09-27 23:18:56 -03:00
pedro f8937a2559 pxe: fix netboot conditional 2024-09-27 23:18:56 -03:00
pedro 7bc3e4b69d pxe: recover netboot stuff
yes, finally this is needed too
2024-09-27 23:18:56 -03:00
pedro 5bf01202dc pxe: add missing directory 2024-09-27 23:18:56 -03:00
pedro 9243f55b37 pxe: fix initrd location 2024-09-27 23:18:56 -03:00
pedro f09e9306df pxe: fix symlinks live 2024-09-27 23:18:56 -03:00
pedro 06f1b2231f pxe: simplify a lot the extraction of live parts 2024-09-27 23:18:56 -03:00
pedro e80c58c16f pxe: bugfix wrong symlink 2024-09-27 23:18:56 -03:00
pedro df073d72e4 pxe: fix wrong path 2024-09-27 23:18:56 -03:00
pedro 23f1bc7717 change nfs persistency strategy
it is easier than you thought
2024-09-27 23:18:56 -03:00
pedro 47ea66f013 workbench-script: attempt to write to snapshot dir 2024-09-27 23:18:56 -03:00
pedro e6a3ffd060 no, nfs common is not needed 2024-09-27 23:18:56 -03:00
pedro 37975fc236 pxe: update README 2024-09-27 23:18:56 -03:00
pedro 1e18c84255 pxe: add comment 2024-09-27 23:18:56 -03:00
pedro 71dffb3074 pxe: prepare more the nfs part 2024-09-27 23:18:56 -03:00
pedro b8ffd19b6a deploy-workbench: add nfs as dependency 2024-09-27 23:18:56 -03:00
pedro e3dfe94955 deploy-workbench: protect shell vars 2024-09-27 23:18:56 -03:00
pedro 13b17dbcf7 pxe: fix wrong paths TFTP/PXE 2024-09-27 23:18:56 -03:00
pedro 5aae459ca4 pxe: fix wrong cp 2024-09-27 23:18:56 -03:00
pedro 086d0da3d6 pxe: path live iso 2024-09-27 23:18:56 -03:00
pedro 3113a3f9c2 pxe: fix logic on tftp live parts 2024-09-27 23:18:56 -03:00
pedro 2a0f9371e1 pxe: bugfix FORCE env var 2024-09-27 23:18:56 -03:00
pedro f51f38d677 pxe: probably last details 2024-09-27 23:18:56 -03:00
pedro cc070c2cce pxe: add FORCE for netboot 2024-09-27 23:18:56 -03:00
pedro 0d8dd533ed pxe: try fixing kernel and initrd 2024-09-27 23:18:56 -03:00
pedro 3725f4d42c pxe: fix path of linux and initrd 2024-09-27 23:18:56 -03:00
pedro e4fb74c59c pxe: create dir for nfs 2024-09-27 23:18:56 -03:00
pedro 0e153cec68 pxe: clarify when pxe is finished 2024-09-27 23:18:56 -03:00
pedro 8a5942a287 pxe: dnsmasq: fix tftp path 2024-09-27 23:18:56 -03:00
pedro 2b902f3a5a pxe: better msgs 2024-09-27 23:18:56 -03:00
pedro a7bc751ccd pxe: bugfix wrong cat for nfs 2024-09-27 23:18:56 -03:00
pedro 887cf162c5 pxe: facilitate run 2024-09-27 23:18:56 -03:00
pedro 748a2255eb deploy workbench: bugfix copy of settings.ini 2024-09-27 23:18:56 -03:00
pedro 91b8fa3a4e pxe: improve installation msg 2024-09-27 23:18:56 -03:00
pedro 221b232ba1 bugfix bad netboot config 2024-09-27 23:18:56 -03:00
pedro f888eb39f9 add dnsmasq config 2024-09-27 23:18:56 -03:00
pedro 44be896bb2 deploy-workbench: fixes: mkfs.vfat not found 2024-09-27 23:18:56 -03:00
pedro 65a0137f86 bugfix env location 2024-09-27 23:18:56 -03:00
pedro a60a6e6539 PXE WIP 2024-09-27 23:18:56 -03:00
pedro 8e4186d9d4 Merge pull request 'contribuciones en estancia con ekoa' (#1) from ekoa into main
Reviewed-on: #1
2024-09-28 02:16:27 +00:00
15 changed files with 340 additions and 46 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
iso iso
settings.ini settings.ini
# ignore all possible snapshots in this dir # ignore all possible snapshots in this repo
*.json *.json

View File

@ -54,3 +54,9 @@ OPCIONES
## Enfoque ## Enfoque
workbench-script trata de ser simple y minimalista, una función principal y funciones de soporte la lectura de las diferentes funcionalidades. 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
Para generar la iso y preparar un usb que arranque con workbench necesitas generarte una workbench de este, con tu configuración específica
Ejecuta `./deploy-workbench.sh`

View File

@ -34,12 +34,12 @@ END
create_iso() { create_iso() {
# Copy kernel and initramfs # Copy kernel and initramfs
vmlinuz="$(ls -1v ${ISO_PATH}/chroot/boot/vmlinuz-* | tail -n 1)" vmlinuz="$(ls -1v "${ISO_PATH}"/chroot/boot/vmlinuz-* | tail -n 1)"
initrd="$(ls -1v ${ISO_PATH}/chroot/boot/initrd.img-* | tail -n 1)" initrd="$(ls -1v "${ISO_PATH}"/chroot/boot/initrd.img-* | tail -n 1)"
${SUDO} cp ${vmlinuz} ${ISO_PATH}/staging/live/vmlinuz ${SUDO} cp ${vmlinuz} "${ISO_PATH}"/staging/live/vmlinuz
${SUDO} cp ${initrd} ${ISO_PATH}/staging/live/initrd ${SUDO} cp ${initrd} "${ISO_PATH}"/staging/live/initrd
# Creating ISO # Creating ISO
iso_path="${ISO_PATH}/${iso_name}.iso" iso_path=""${ISO_PATH}"/${iso_name}.iso"
# 0x14 is FAT16 Hidden FAT16 <32, this is the only format detected in windows10 automatically when using a persistent volume of 10 MB # 0x14 is FAT16 Hidden FAT16 <32, this is the only format detected in windows10 automatically when using a persistent volume of 10 MB
${SUDO} xorrisofs \ ${SUDO} xorrisofs \
@ -59,7 +59,7 @@ create_iso() {
-e /EFI/boot/efiboot.img \ -e /EFI/boot/efiboot.img \
-no-emul-boot \ -no-emul-boot \
-isohybrid-gpt-basdat \ -isohybrid-gpt-basdat \
-append_partition 2 0xef ${ISO_PATH}/staging/EFI/boot/efiboot.img \ -append_partition 2 0xef "${ISO_PATH}"/staging/EFI/boot/efiboot.img \
-append_partition 3 0x14 "${rw_img_path}" \ -append_partition 3 0x14 "${rw_img_path}" \
"${ISO_PATH}/staging" "${ISO_PATH}/staging"
@ -138,7 +138,7 @@ EOF
${SUDO} grub-mkstandalone \ ${SUDO} grub-mkstandalone \
--format=x86_64-efi \ --format=x86_64-efi \
--output=${ISO_PATH}/tmp/bootx64.efi \ --output="${ISO_PATH}"/tmp/bootx64.efi \
--locales="" \ --locales="" \
--fonts="" \ --fonts="" \
"boot/grub/grub.cfg=${ISO_PATH}/tmp/grub-standalone.cfg" "boot/grub/grub.cfg=${ISO_PATH}/tmp/grub-standalone.cfg"
@ -149,10 +149,10 @@ EOF
# grubx64 looks for a file in /EFI/debian/grub.cfg -> src src https://unix.stackexchange.com/questions/648089/uefi-grub-not-finding-config-file # grubx64 looks for a file in /EFI/debian/grub.cfg -> src src https://unix.stackexchange.com/questions/648089/uefi-grub-not-finding-config-file
${SUDO} cp /usr/lib/shim/shimx64.efi.signed /tmp/bootx64.efi ${SUDO} cp /usr/lib/shim/shimx64.efi.signed /tmp/bootx64.efi
${SUDO} cp /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed /tmp/grubx64.efi ${SUDO} cp /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed /tmp/grubx64.efi
${SUDO} cp ${ISO_PATH}/tmp/grub-standalone.cfg ${ISO_PATH}/staging/EFI/debian/grub.cfg ${SUDO} cp "${ISO_PATH}/tmp/grub-standalone.cfg" "${ISO_PATH}/staging/EFI/debian/grub.cfg"
( (
cd ${ISO_PATH}/staging/EFI/boot cd "${ISO_PATH}/staging/EFI/boot"
${SUDO} dd if=/dev/zero of=efiboot.img bs=1M count=20 ${SUDO} dd if=/dev/zero of=efiboot.img bs=1M count=20
${SUDO} mkfs.vfat efiboot.img ${SUDO} mkfs.vfat efiboot.img
${SUDO} mmd -i efiboot.img efi efi/boot ${SUDO} mmd -i efiboot.img efi efi/boot
@ -178,8 +178,8 @@ compress_chroot_dir() {
# why squashfs -> https://unix.stackexchange.com/questions/163190/why-do-liveusbs-use-squashfs-and-similar-file-systems # why squashfs -> https://unix.stackexchange.com/questions/163190/why-do-liveusbs-use-squashfs-and-similar-file-systems
# noappend option needed to avoid this situation -> https://unix.stackexchange.com/questions/80447/merging-preexisting-source-folders-in-mksquashfs # noappend option needed to avoid this situation -> https://unix.stackexchange.com/questions/80447/merging-preexisting-source-folders-in-mksquashfs
${SUDO} mksquashfs \ ${SUDO} mksquashfs \
${ISO_PATH}/chroot \ "${ISO_PATH}/chroot" \
${ISO_PATH}/staging/live/filesystem.squashfs \ "${ISO_PATH}/staging/live/filesystem.squashfs" \
${DEBUG_SQUASHFS_ARGS:-} \ ${DEBUG_SQUASHFS_ARGS:-} \
-noappend -e boot -noappend -e boot
} }
@ -198,8 +198,13 @@ create_persistence_partition() {
${SUDO} umount -f -l "${tmp_rw_mount}" >/dev/null 2>&1 || true ${SUDO} umount -f -l "${tmp_rw_mount}" >/dev/null 2>&1 || true
mkdir -p "${tmp_rw_mount}" mkdir -p "${tmp_rw_mount}"
${SUDO} mount "$(pwd)/${rw_img_path}" "${tmp_rw_mount}" ${SUDO} mount "$(pwd)/${rw_img_path}" "${tmp_rw_mount}"
${SUDO} mkdir -p "${tmp_rw_mount}/settings" ${SUDO} mkdir -p "${tmp_rw_mount}"
${SUDO} cp -v settings.ini "${tmp_rw_mount}/settings/settings.ini" if [ -f "settings.ini" ]; then
${SUDO} cp -v settings.ini "${tmp_rw_mount}/settings.ini"
else
echo "ERROR: settings.ini does not exist yet, cannot read config from there. You can take inspiration with file settings.ini.example"
exit 1
fi
${SUDO} umount "${tmp_rw_mount}" ${SUDO} umount "${tmp_rw_mount}"
uuid="$(blkid "${rw_img_path}" | awk '{ print $3; }')" uuid="$(blkid "${rw_img_path}" | awk '{ print $3; }')"
@ -258,14 +263,32 @@ prepare_app() {
# startup script execution # startup script execution
cat > "${ISO_PATH}/chroot/root/.profile" <<END cat > "${ISO_PATH}/chroot/root/.profile" <<END
set -x if [ -f /tmp/workbench_lock ]; then
return 0
else
touch /tmp/workbench_lock
fi
set -x
stty -echo # Do not show what we type in terminal so it does not meddle with our nice output stty -echo # Do not show what we type in terminal so it does not meddle with our nice output
dmesg -n 1 # Do not report *useless* system messages to the terminal dmesg -n 1 # Do not report *useless* system messages to the terminal
# detect pxe env
nfs_host="\$(df -hT | grep nfs | cut -f1 -d: | head -n1)"
if [ "\${nfs_host}" ]; then
mount --bind /run/live/medium /mnt
# debian live nfs path is readonly, do a trick
# to make snapshots subdir readwrite
mount \${nfs_host}:/snapshots /run/live/medium/snapshots
# reload mounts on systemd
systemctl daemon-reload
fi
# clearly specify the right working directory, used in the python script as os.getcwd() # clearly specify the right working directory, used in the python script as os.getcwd()
cd /mnt cd /mnt
pipenv run python /opt/workbench/workbench-script.py --config "/mnt/settings/settings.ini" pipenv run python /opt/workbench/workbench-script.py --config /mnt/settings.ini
stty echo stty echo
set +x
END END
#TODO add some useful commands #TODO add some useful commands
cat > "${ISO_PATH}/chroot/root/.bash_history" <<END cat > "${ISO_PATH}/chroot/root/.bash_history" <<END
@ -280,9 +303,7 @@ echo 'Install requirements'
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
sudo \ sudo \
python3 python3-dev python3-pip pipenv \ python3 python3-dev python3-pip pipenv \
dmidecode smartmontools hwinfo pciutils lshw < /dev/null dmidecode smartmontools hwinfo pciutils lshw nfs-common < /dev/null
# Install python requirements using apt instead of pip
#python3-dateutils python3-decouple python3-colorlog
# Install lshw B02.19 utility using backports (DEPRECATED in Debian 12) # Install lshw B02.19 utility using backports (DEPRECATED in Debian 12)
#apt install -y -t ${VERSION_CODENAME}-backports lshw < /dev/null #apt install -y -t ${VERSION_CODENAME}-backports lshw < /dev/null
@ -405,7 +426,8 @@ install_requirements() {
image_deps='debootstrap image_deps='debootstrap
squashfs-tools squashfs-tools
xorriso xorriso
mtools' mtools
dosfstools'
# secureboot: # secureboot:
# -> extra src https://wiki.debian.org/SecureBoot/ # -> extra src https://wiki.debian.org/SecureBoot/
# -> extra src https://wiki.debian.org/SecureBoot/VirtualMachine # -> extra src https://wiki.debian.org/SecureBoot/VirtualMachine
@ -423,17 +445,17 @@ install_requirements() {
# thanks https://willhaley.com/blog/custom-debian-live-environment/ # thanks https://willhaley.com/blog/custom-debian-live-environment/
create_base_dirs() { create_base_dirs() {
mkdir -p ${ISO_PATH} mkdir -p "${ISO_PATH}"
mkdir -p ${ISO_PATH}/staging/EFI/boot mkdir -p "${ISO_PATH}/staging/EFI/boot"
mkdir -p ${ISO_PATH}/staging/boot/grub/x86_64-efi mkdir -p "${ISO_PATH}/staging/boot/grub/x86_64-efi"
mkdir -p ${ISO_PATH}/staging/isolinux mkdir -p "${ISO_PATH}/staging/isolinux"
mkdir -p ${ISO_PATH}/staging/live mkdir -p "${ISO_PATH}/staging/live"
mkdir -p ${ISO_PATH}/tmp mkdir -p "${ISO_PATH}/tmp"
# usb name # usb name
${SUDO} touch ${ISO_PATH}/staging/${iso_name} ${SUDO} touch "${ISO_PATH}/staging/${iso_name}"
# for uefi secure boot grub config file # for uefi secure boot grub config file
mkdir -p ${ISO_PATH}/staging/EFI/debian mkdir -p "${ISO_PATH}/staging/EFI/debian"
} }
# this function is used both in shell and chroot # this function is used both in shell and chroot

4
pxe/.env.example Normal file
View File

@ -0,0 +1,4 @@
server_ip=192.168.1.2
nfs_allowed_lan=192.168.1.0/24
tftp_path='/srv/pxe-tftp'
nfs_path='/srv/pxe-nfs'

2
pxe/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
pxe-menu.cfg

2
pxe/Makefile Normal file
View File

@ -0,0 +1,2 @@
test_pxe:
qemu-system-x86_64 -m 1G -boot n -netdev user,id=mynet0,tftp=/srv/pxe-tftp,bootfile=pxelinux.0 -device e1000,netdev=mynet0

1
pxe/README-en.md Normal file
View File

@ -0,0 +1 @@
TODO

55
pxe/README-es.md Normal file
View File

@ -0,0 +1,55 @@
# workbench via PXE
## Introducción
Permite arrancar workbench a través de la red en vez de por USB. Utiliza la misma imagen generada por el script [deploy-workbench.sh](../deploy-workbench.sh), pero en el formato compatible con el arranque por red en vez de la iso.
Ejecuta el siguiente script en un servidor debian estable que estará dedicado a la gestión del pxe server
```
./install-pxe.sh
```
Este servidor aporta un servicio de arranque por red tipo PXE, y no hace colisión con un servidor DHCP existente.
## Funcionamiento
El servidor PXE ofrece a la máquina que arranca un *debian live* a través de [NFS](https://es.wikipedia.org/wiki/Network_File_System). Una vez arrancado, ejecuta el `workbench-script.py` con la configuración remota del servidor PXE. Cuando ha terminado, también guarda en el mismo servidor PXE el snapshot resultante. También lo puede guardar en devicehub si se especifica en la variable `url` de la configuración `settings.ini`.
## Probarlo todo en localhost
Preparar configuración de `.env` tal como:
```
server_ip=10.0.2.2
nfs_allowed_lan=10.0.2.0/24
tftp_path='/srv/pxe-tftp'
nfs_path='/srv/pxe-nfs'
```
Red y host 10.0.2.2? Esta es la forma en que el programa *qemu* hace red en localhost, 10.0.2.2 es la dirección de localhost que saliendo de qemu es traducida como 127.0.0.1
Desplegar servidores TFTP y NFS en el mismo ordenador, para permitir nfs inseguro:
```
DEBUG=true ./install-pxe.sh
```
Los directorios inseguros contienen configuración y snapshots de workbench, nada importante supongo. Aún así, `DEBUG=true` no se recomienda para un entorno de producción para evitar sorpresas.
Y para terminar, probar el cliente PXE con el siguiente comando:
```
make test_pxe
```
## Recursos
El servicio PXE
- Originalmente inspirado en este artículo https://farga.exo.cat/exo/wiki/src/branch/master/howto/apu/apu-installer.md
- https://github.com/eReuse/workbench-live/blob/feature/pxe/docs/PXE-setup.md
- https://wiki.debian.org/PXEBootInstall
- https://wiki.debian.org/DebianInstaller/NetbootFirmware
- [In this presentation](https://people.debian.org/~andi/LiveNetboot.pdf), recomienda página 12 [4.6 Building a netboot image](https://live-team.pages.debian.net/live-manual/html/live-manual/the-basics.en.html#236) [4.7 Webbooting](https://live-team.pages.debian.net/live-manual/html/live-manual/the-basics.en.html#275)

5
pxe/README.md Normal file
View File

@ -0,0 +1,5 @@
# pxe
- [Español](./README-es.md)
- [English](./README-en.md)

158
pxe/install-pxe.sh Executable file
View File

@ -0,0 +1,158 @@
#!/bin/sh
# Copyright (c) 2024 Pedro <copyright@cas.cat>
# SPDX-License-Identifier: AGPL-3.0-or-later
set -e
set -u
# DEBUG
set -x
detect_user() {
userid="$(id -u)"
# detect non root user without sudo
if [ ! "${userid}" = 0 ] && id ${USER} | grep -qv sudo; then
echo "ERROR: this script needs root or sudo permissions (current user is not part of sudo group)"
exit 1
# detect user with sudo or already on sudo src https://serverfault.com/questions/568627/can-a-program-tell-it-is-being-run-under-sudo/568628#568628
elif [ ! "${userid}" = 0 ] || [ -n "${SUDO_USER}" ]; then
SUDO='sudo'
# jump to current dir where the script is so relative links work
cd "$(dirname "${0}")"
# working directory to build the iso
ISO_PATH="iso"
# detect pure root
elif [ "${userid}" = 0 ]; then
SUDO=''
ISO_PATH="/opt/workbench"
fi
}
install_dependencies() {
${SUDO} apt update
${SUDO} apt install -y wget dnsmasq nfs-kernel-server rsync syslinux
}
backup_file() {
target="${1}"
ts="$(date +'%Y-%m-%d_%H-%M-%S')"
if [ -f "${target}" ]; then
if ! grep -q 'we should do a backup' "${target}"; then
${SUDO} cp -a "${target}" "${target}-bak_${ts}"
fi
fi
}
install_nfs() {
# append live directory, which is expected by the debian live env
${SUDO} mkdir -p "${nfs_path}/live"
${SUDO} mkdir -p "${nfs_path}/snapshots"
# debian live nfs path is readonly, do a trick
# to make snapshots subdir readwrite
if ! grep -q "/snapshots" /proc/mounts; then
${SUDO} mkdir -p "/snapshots"
${SUDO} mount --bind "${nfs_path}/snapshots" "/snapshots"
fi
backup_file /etc/exports
if [ "${DEBUG:-}" ]; then
nfs_debug=' 127.0.0.1(rw,sync,no_subtree_check,no_root_squash,insecure)'
fi
${SUDO} tee /etc/exports <<END
${script_header}
# we assume that if you remove this line from the file, we should do a backup
${nfs_path} ${nfs_allowed_lan}(rw,sync,no_subtree_check,no_root_squash)${nfs_debug:-}
/snapshots ${nfs_allowed_lan}(rw,sync,no_subtree_check,no_root_squash)${nfs_debug:-}
END
# reload nfs exports
${SUDO} exportfs -vra
if [ ! -f "${nfs_path}/settings.ini" ]; then
if [ -f "settings.ini" ]; then
${SUDO} cp settings.ini "${nfs_path}/settings.ini"
else
echo "ERROR: $(pwd)/settings.ini does not exist yet, cannot read config from there. You can take inspiration with file $(pwd)/settings.ini.example"
exit 1
fi
fi
}
install_tftp() {
# from https://wiki.debian.org/PXEBootInstall#Simple_way_-_using_Dnsmasq
${SUDO} tee /etc/dnsmasq.d/pxe-tftp <<END
${script_header}
port=0
# info: https://wiki.archlinux.org/title/Dnsmasq#Proxy_DHCP
dhcp-range=${nfs_allowed_lan%/*},proxy
dhcp-boot=pxelinux.0
pxe-service=x86PC,"Network Boot",pxelinux
enable-tftp
tftp-root=${tftp_path}
END
}
install_netboot() {
# if you want to refresh install, remove or move dir
if [ ! -d "${tftp_path}" ] || [ "${FORCE:-}" ]; then
${SUDO} mkdir -p "${tftp_path}/pxelinux.cfg"
if [ ! -f "${tftp_path}/netboot.tar.gz" ]; then
url="http://ftp.debian.org/debian/dists/${VERSION_CODENAME}/main/installer-amd64/current/images/netboot/netboot.tar.gz"
${SUDO} wget -P "${tftp_path}" "${url}"
${SUDO} tar xvf "${tftp_path}/netboot.tar.gz" -C "${tftp_path}"
${SUDO} rm -rf "${tftp_path}/pxelinux.cfg"
${SUDO} mkdir -p "${tftp_path}/pxelinux.cfg"
fi
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/vmlinuz" "${tftp_path}/"
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/initrd" "${tftp_path}/"
${SUDO} cp /usr/lib/syslinux/memdisk "${tftp_path}/"
${SUDO} cp /usr/lib/syslinux/modules/bios/* "${tftp_path}/"
envsubst < ./pxe-menu.cfg | ${SUDO} tee "${tftp_path}/pxelinux.cfg/default"
fi
${SUDO} rsync -av "${PXE_DIR}/../iso/staging/live/filesystem.squashfs" "${nfs_path}/live/"
}
init_config() {
# get where the script is
cd "$(dirname "${0}")"
# this is what we put in the files we modity
script_header='# configuration done through workbench install-pxe script'
PXE_DIR="$(pwd)"
if [ -f ./.env ]; then
. ./.env
else
echo "PXE: WARNING: $(pwd)/.env does not exist yet, cannot read config from there. You can take inspiration with file $(pwd)/.env.example"
fi
VERSION_CODENAME="${VERSION_CODENAME:-bookworm}"
tftp_path="${tftp_path:-/srv/pxe-tftp}"
# vars used in envsubst require to be exported:
export server_ip="${server_ip}"
export nfs_path="${nfs_path:-/srv/pxe-nfs}"
}
main() {
detect_user
init_config
install_dependencies
install_tftp
install_nfs
install_netboot
echo "PXE: Installation finished"
}
main "${@}"
# written in emacs
# -*- mode: shell-script; -*-

12
pxe/pxe-menu.cfg.example Normal file
View File

@ -0,0 +1,12 @@
DEFAULT menu.c32
PROMPT 0
TIMEOUT 50
ONTIMEOUT wb
MENU TITLE PXE Boot Menu
LABEL wb
MENU LABEL Boot Workbench
KERNEL vmlinuz
INITRD initrd
APPEND ip=dhcp netboot=nfs nfsroot=${server_ip}:${nfs_path}/ boot=live text forcepae

6
pxe/settings.ini.example Normal file
View File

@ -0,0 +1,6 @@
[settings]
url = http://localhost:8000/api/snapshot/
token = '1234'
path = /mnt
# device = your_device_name
# # erase = basic

View File

@ -1,5 +1,5 @@
[settings] [settings]
url = http://127.0.0.1:8000/api/snapshot/ url = http://localhost:8000/api/snapshot/
token = '1234' token = '1234'
# path = /path/to/save # path = /path/to/save
# device = your_device_name # device = your_device_name

3
snapshots/README.md Normal file
View File

@ -0,0 +1,3 @@
This is the path by default used by workbench-script
You can change it in the configuration

View File

@ -7,7 +7,6 @@ import hashlib
import argparse import argparse
import configparser import configparser
import ntplib
import requests import requests
@ -228,6 +227,8 @@ def smartctl(all_disks, disk=None):
## End Command Functions ## ## End Command Functions ##
# TODO permitir selección
# TODO permitir que vaya más rápido
def get_data(all_disks): def get_data(all_disks):
lshw = 'sudo lshw -json' lshw = 'sudo lshw -json'
hwinfo = 'sudo hwinfo --reallyall' hwinfo = 'sudo hwinfo --reallyall'
@ -249,15 +250,33 @@ def gen_snapshot(all_disks):
def save_snapshot_in_disk(snapshot, path): def save_snapshot_in_disk(snapshot, path):
snapshot_path = os.path.join(path, 'snapshots')
filename = "{}/{}_{}.json".format( filename = "{}/{}_{}.json".format(
path, snapshot_path,
datetime.now().strftime("%Y%m%d-%H_%M_%S"), datetime.now().strftime("%Y%m%d-%H_%M_%S"),
snapshot['uuid'] snapshot['uuid'])
)
print(f"workbench: INFO: Snapshot written in path '{filename}'") try:
if not os.path.exists(snapshot_path):
os.makedirs(snapshot_path)
print(f"workbench: INFO: Created snapshots directory at '{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}'")
except Exception as e:
try:
print(f"workbench: WARNING: Attempting to save in actual path. Reason: Failed to write in snapshots directory:\n {e}.")
fallback_filename = "{}/{}_{}.json".format(
path,
datetime.now().strftime("%Y%m%d-%H_%M_%S"),
snapshot['uuid'])
with open(fallback_filename, "w") as f:
f.write(json.dumps(snapshot))
print(f"workbench: INFO: Snapshot written in fallback path '{fallback_filename}'")
except Exception as e:
print(f"workbench: ERROR: Could not save snapshot locally. Reason: Failed to write in fallback path:\n {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/'
@ -269,14 +288,8 @@ def send_snapshot_to_devicehub(snapshot, token, url):
try: try:
requests.post(url, data=json.dumps(snapshot), headers=headers) requests.post(url, data=json.dumps(snapshot), headers=headers)
print(f"workbench: INFO: Snapshot sent to '{url}'") print(f"workbench: INFO: Snapshot sent to '{url}'")
except: except Exception as e:
print(f"workbench: ERROR: Snapshot not remotely sent. URL '{url}' is unreachable. Do you have internet? Is your server up & running?") print(f"workbench: ERROR: Snapshot not remotely sent. URL '{url}' is unreachable. Do you have internet? Is your server up & running?\n {e}")
@logs
def sync_time():
# is neccessary?
ntplib.NTPClient()
response = client.request('pool.ntp.org')
def load_config(config_file="settings.ini"): def load_config(config_file="settings.ini"):
""" """
@ -333,6 +346,11 @@ def main():
config = load_config(config_file) config = load_config(config_file)
# 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 os.geteuid() != 0:
print("workbench: 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)