pxe: a lot of improvements
This commit is contained in:
parent
bd52916b06
commit
2df34e4b23
|
@ -198,9 +198,9 @@ 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}"
|
||||||
if [ -f "settings.ini" ]; then
|
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
|
else
|
||||||
echo "ERROR: settings.ini does not exist yet, cannot read config from there. You can take inspiration with file settings.ini.example"
|
echo "ERROR: settings.ini does not exist yet, cannot read config from there. You can take inspiration with file settings.ini.example"
|
||||||
exit 1
|
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
|
dmesg -n 1 # Do not report *useless* system messages to the terminal
|
||||||
|
|
||||||
# detect pxe env
|
# 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
|
mount --bind /run/live/medium /mnt
|
||||||
# debian live nfs path is readonly, do a trick
|
# debian live nfs path is readonly, do a trick
|
||||||
# to make snapshots subdir readwrite
|
# to make snapshots subdir readwrite
|
||||||
nfs_host="\$(df -hT | grep nfs | cut -f1 -d: | head -n1)"
|
|
||||||
mount \${nfs_host}:/snapshots /run/live/medium/snapshots
|
mount \${nfs_host}:/snapshots /run/live/medium/snapshots
|
||||||
# reload mounts on systemd
|
# reload mounts on systemd
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
2
pxe/Makefile
Normal file
2
pxe/Makefile
Normal 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
|
|
@ -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`.
|
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
|
## Recursos
|
||||||
|
|
||||||
El servicio PXE
|
El servicio PXE
|
||||||
|
|
|
@ -8,21 +8,46 @@ set -u
|
||||||
# DEBUG
|
# DEBUG
|
||||||
set -x
|
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() {
|
install_dependencies() {
|
||||||
apt update
|
${SUDO} apt update
|
||||||
apt install -y wget dnsmasq nfs-kernel-server rsync
|
${SUDO} apt install -y wget dnsmasq nfs-kernel-server rsync syslinux
|
||||||
}
|
}
|
||||||
|
|
||||||
backup_file() {
|
backup_file() {
|
||||||
target="${1}"
|
target="${1}"
|
||||||
ts="$(date +'%Y-%m-%d_%H-%M-%S')"
|
ts="$(date +'%Y-%m-%d_%H-%M-%S')"
|
||||||
|
|
||||||
if [ -f "${target}" ]; then
|
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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_nfs() {
|
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
|
# debian live nfs path is readonly, do a trick
|
||||||
# to make snapshots subdir readwrite
|
# to make snapshots subdir readwrite
|
||||||
|
@ -31,16 +56,21 @@ install_nfs() {
|
||||||
mount --bind "${nfs_path}/snapshots" "/snapshots"
|
mount --bind "${nfs_path}/snapshots" "/snapshots"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat > /etc/exports <<END
|
backup_file /etc/exports
|
||||||
${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)
|
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
|
END
|
||||||
# reload nfs exports
|
# 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 "${nfs_path}/settings.ini" ]; then
|
||||||
if [ -f "settings.ini" ]; then
|
if [ -f "settings.ini" ]; then
|
||||||
|
@ -55,7 +85,8 @@ END
|
||||||
install_tftp() {
|
install_tftp() {
|
||||||
|
|
||||||
# from https://wiki.debian.org/PXEBootInstall#Simple_way_-_using_Dnsmasq
|
# 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
|
port=0
|
||||||
# info: https://wiki.archlinux.org/title/Dnsmasq#Proxy_DHCP
|
# info: https://wiki.archlinux.org/title/Dnsmasq#Proxy_DHCP
|
||||||
dhcp-range=${nfs_allowed_lan%/*},proxy
|
dhcp-range=${nfs_allowed_lan%/*},proxy
|
||||||
|
@ -78,25 +109,39 @@ install_netboot() {
|
||||||
mkdir -p "${tftp_path}/pxelinux.cfg"
|
mkdir -p "${tftp_path}/pxelinux.cfg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp -fv "${PXE_DIR}/../iso/staging/live/vmlinuz" "${tftp_path}/"
|
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/vmlinuz" "${tftp_path}/"
|
||||||
cp -fv "${PXE_DIR}/../iso/staging/live/initrd" "${tftp_path}/"
|
${SUDO} cp -fv "${PXE_DIR}/../iso/staging/live/initrd" "${tftp_path}/"
|
||||||
rsync -av "${PXE_DIR}/../iso/staging/live/filesystem.squashfs" "${nfs_path}/live/"
|
|
||||||
|
|
||||||
cat > "${tftp_path}/pxelinux.cfg/default" <<END
|
${SUDO} cp /usr/lib/syslinux/memdisk "${tftp_path}/"
|
||||||
default wb
|
${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
|
KERNEL vmlinuz
|
||||||
INITRD initrd
|
INITRD initrd
|
||||||
APPEND ip=dhcp netboot=nfs nfsroot=${server_ip}:${nfs_path}/ boot=live text forcepae
|
APPEND ip=dhcp netboot=nfs nfsroot=${server_ip}:${nfs_path}/ boot=live text forcepae
|
||||||
END
|
END
|
||||||
cd -
|
cd -
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rsync -av "${PXE_DIR}/../iso/staging/live/filesystem.squashfs" "${nfs_path}/live/"
|
||||||
}
|
}
|
||||||
|
|
||||||
init_config() {
|
init_config() {
|
||||||
|
|
||||||
# get where the script is
|
# get where the script is
|
||||||
cd "$(dirname "${0}")"
|
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)"
|
PXE_DIR="$(pwd)"
|
||||||
|
|
||||||
if [ -f ./.env ]; then
|
if [ -f ./.env ]; then
|
||||||
|
@ -111,6 +156,7 @@ init_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
detect_user
|
||||||
init_config
|
init_config
|
||||||
install_dependencies
|
install_dependencies
|
||||||
install_tftp
|
install_tftp
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[settings]
|
[settings]
|
||||||
url = http://localhost:8000/api/snapshot/
|
url = http://localhost:8000/api/snapshot/
|
||||||
token = '1234'
|
token = '1234'
|
||||||
path = /run/live/medium
|
path = /mnt
|
||||||
# device = your_device_name
|
# device = your_device_name
|
||||||
# # erase = basic
|
# # erase = basic
|
||||||
|
|
Loading…
Reference in a new issue