pxe: a lot of improvements

This commit is contained in:
pedro 2024-09-27 17:27:12 -03:00
parent bd52916b06
commit 2df34e4b23
5 changed files with 99 additions and 23 deletions

View file

@ -198,9 +198,9 @@ create_persistence_partition() {
${SUDO} umount -f -l "${tmp_rw_mount}" >/dev/null 2>&1 || true
mkdir -p "${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}"
if [ -f "settings.ini" ]; then
${SUDO} cp -v settings.ini "${tmp_rw_mount}/settings/settings.ini"
${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
@ -274,11 +274,11 @@ stty -echo # Do not show what we type in terminal so it does not meddle with our
dmesg -n 1 # Do not report *useless* system messages to the terminal
# detect pxe env
if [ -d /run/live/medium ]; then
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
nfs_host="\$(df -hT | grep nfs | cut -f1 -d: | head -n1)"
mount \${nfs_host}:/snapshots /run/live/medium/snapshots
# reload mounts on systemd
systemctl daemon-reload

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

View file

@ -16,6 +16,34 @@ Este servidor aporta un servicio de arranque por red tipo PXE, y no hace colisi
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

View file

@ -8,21 +8,46 @@ 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() {
apt update
apt install -y wget dnsmasq nfs-kernel-server rsync
${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
cp -a "${target}" "${target}_bak_${ts}"
if ! grep -q 'we should do a backup' "${target}"; then
${SUDO} cp -a "${target}" "${target}-bak_${ts}"
fi
fi
}
install_nfs() {
backup_file /etc/exports
# append live directory, which is expected by the debian live env
mkdir -p "${nfs_path}/live"
mkdir -p "${nfs_path}/snapshots"
# debian live nfs path is readonly, do a trick
# to make snapshots subdir readwrite
@ -31,16 +56,21 @@ install_nfs() {
mount --bind "${nfs_path}/snapshots" "/snapshots"
fi
cat > /etc/exports <<END
${nfs_path} ${nfs_allowed_lan}(rw,sync,no_subtree_check,no_root_squash)
/snapshots ${nfs_allowed_lan}(rw,sync,no_subtree_check,no_root_squash)
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
exportfs -vra
${SUDO} exportfs -vra
# append live directory, which is expected by the debian live env
mkdir -p "${nfs_path}/live"
mkdir -p "${nfs_path}/snapshots"
if [ ! -f "${nfs_path}/settings.ini" ]; then
if [ -f "settings.ini" ]; then
@ -55,7 +85,8 @@ END
install_tftp() {
# from https://wiki.debian.org/PXEBootInstall#Simple_way_-_using_Dnsmasq
cat > /etc/dnsmasq.d/pxe-tftp <<END
${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
@ -78,25 +109,39 @@ install_netboot() {
mkdir -p "${tftp_path}/pxelinux.cfg"
fi
cp -fv "${PXE_DIR}/../iso/staging/live/vmlinuz" "${tftp_path}/"
cp -fv "${PXE_DIR}/../iso/staging/live/initrd" "${tftp_path}/"
rsync -av "${PXE_DIR}/../iso/staging/live/filesystem.squashfs" "${nfs_path}/live/"
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/vmlinuz" "${tftp_path}/"
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/initrd" "${tftp_path}/"
cat > "${tftp_path}/pxelinux.cfg/default" <<END
default wb
${SUDO} cp /usr/lib/syslinux/memdisk "${tftp_path}/"
${SUDO} cp /usr/lib/syslinux/modules/bios/* "${tftp_path}/"
${SUDO} tee "${tftp_path}/pxelinux.cfg/default" <<END
DEFAULT menu.c32
PROMPT 0
TIMEOUT 50
ONTIMEOUT wb
label 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
END
cd -
fi
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
@ -111,6 +156,7 @@ init_config() {
}
main() {
detect_user
init_config
install_dependencies
install_tftp

View file

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