From 094a2f005759c29eeb9b6bf0098f4c5daebfc143 Mon Sep 17 00:00:00 2001 From: Guido Berhoerster Date: Tue, 5 Sep 2023 09:15:11 +0200 Subject: Rename bin/debian-edu-faiinstall to bin/debian-edu-fai_install for consistency --- bin/debian-edu-fai_install | 428 +++++++++++++++++++++++++++++++++++++++++++++ bin/debian-edu-faiinstall | 428 --------------------------------------------- debian/install | 2 +- 3 files changed, 429 insertions(+), 429 deletions(-) create mode 100755 bin/debian-edu-fai_install delete mode 100755 bin/debian-edu-faiinstall diff --git a/bin/debian-edu-fai_install b/bin/debian-edu-fai_install new file mode 100755 index 0000000..fce3bf8 --- /dev/null +++ b/bin/debian-edu-fai_install @@ -0,0 +1,428 @@ +#!/bin/sh +# +# Prepare for FAI installation of Debian Edu. + +set -x + +LC_ALL=C +export LC_ALL + +## FIXME: Why is resolv.conf empty or missing? Because network +## was started in the chroot (target)? +## Try to find the DNS from the leases file, if that fails use +## default DNS: +if [ ! -s /etc/resolv.conf ] ; then + DNS="10.0.2.2" + LEASEDIR=/var/lib/dhcp/ + if [ -d $LEASEDIR ] ; then + LEASEFILE=$LEASEDIR`ls -tr -1 $LEASEDIR | tail -n 1` + if [ -r $LEASEFILE ] ; then + if DNSLEASE=`cat $LEASEFILE | grep domain-name-servers | \ + tail -n 1 | \ + grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"` ; then + DNS=$DNSLEASE + echo "info: Found leases file and domain-name-server: $DNS." + else + echo "info: Could not extract DNS from leases file." + fi + fi + fi + echo "info: Create temporary /etc/resolv.conf with DNS: $DNS." + cat >> /etc/resolv.conf < /etc/resolvconf/run/resolv.conf, i.e.: +## rm /etc/resolv.conf; ln -s /etc/resolvconf/run/resolv.conf /etc/resolv.conf +nameserver $DNS +search intern +EOF + fi + +# Make sure the created directories and files are readable by tfptd +# run as user nobody. +umask 022 + +# Fetch ftp_proxy and http_proxy if set globally +if [ -f /etc/environment ] ; then + . /etc/environment +fi + +### +### FAI Setup +### + +[ "$archs" ] || archs=$(command -V dpkg 1>/dev/null 2>/dev/null && dpkg --print-architecture || uname -m) +[ "$codenames" ] || codenames=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d "=" -f2) +[ "$http_proxy" ] || unset http_proxy +[ "$ftp_proxy" ] || unset ftp_proxy +[ "$mirrorurl" ] || mirrorurl=http://deb.debian.org/debian +[ "$rootpw" ] || rootpw="" +[ "$localuser" ] || localuser="" +[ "$localuserpw" ] || localuserpw="" +[ "$wifi_essid" ] || wifi_essid="" +[ "$wifi_passphrase" ] || wifi_passphrase="" +[ "$tftpdir" ] || tftpdir="/srv/tftp" +[ "$fai_logserver" ] || unset fai_logserver +[ "$fai_loguser" ] || unset fai_loguser +[ "$school_tag" ] || school_tag="SKOLE" + +# required for pre-selecting the default boot item in iPXE config +[ "$default_arch" ] || default_arch="$(echo ${archs} | cut -d " " -f1)" +[ "$default_codename" ] || default_codename=$(echo ${codenames} | cut -d " " -f1) + +# only set plymouth theme if known by the desktop-theme ... +if [ -e /etc/alternatives/desktop-theme/plymouth ]; then + [ "$theme" ] || theme="$(ls -L /etc/alternatives/desktop-theme/plymouth | grep script | cut -d'.' -f 1)" +fi + +# source Debian Edu's config file +if [ -f /etc/debian-edu/config ] ; then + . /etc/debian-edu/config +fi + +# source debian-edu-fai's config file +# Allow site specific overrides to the variables +if [ -f /etc/debian-edu/debian-edu-fai.conf ] ; then + . /etc/debian-edu/debian-edu-fai.conf +fi + +# keep a copy of /srv/tftp/ltsp if this is the first attempt to deploy +# debian-edu-fai on this system +if [ -d "${tftpdir}/debian-edu-fai" ] && [ ! -h "${tftpdir}/debian-edu-fai" ]; then + mv "${tftpdir}/ltsp" "${tftpdir}/ltsp.moved-aside-by-debian-edu-fai" +elif [ -h "${tftpdir}/debian-edu-fai" ]; then + rm "${tftpdir}/debian-edu-fai" +fi + +# For Debian Edu, we will create the FAI tftp boot dir in subfolder ltsp/. +mkdir -p "${tftpdir}/ltsp/" +# and symlink that to what really is inside... +ln -nsf "ltsp" "${tftpdir}/debian-edu-fai" + +# Start from a clean state after any configuration changes have been made. +rm -f $tftpdir/ltsp/fai-installers.cfg.~ +rm -f $tftpdir/ltsp/fai-menuitems.cfg.~ +rm -f $tftpdir/ltsp/debian-edu-fai.ipxe +rm -f $tftpdir/ltsp/ltsp.ipxe +rm -f $tftpdir/ltsp/memtest* +rm -f $tftpdir/ltsp/snponly.efi +rm -f $tftpdir/ltsp/undionly.kpxe + +# prepare menufile creation (always start fresh) +menuitems=${tftpdir}/debian-edu-fai/fai-menuitems.cfg +menuindex=1 +menufile=${tftpdir}/debian-edu-fai/fai-installers.cfg +if [ -e "${menuitems}" ]; then + mv "${menuitems}" "${menuitems}.~" +fi +if [ -e "${menufile}" ]; then + mv "${menufile}" "${menufile}.~" +fi +touch "${menuitems}" +touch "${menufile}" + +for codename in ${codenames}; do + + # skip codenames that don't sound like Debian suites... + if ! echo "bullseye bookworm sid unstable" | grep -q "${codename}"; then + echo "WARNING: The name '${codename}' is not a known and recent Debian distribution codename. Skipping..." + continue + fi + + # iterate over configured FAI client architectures... + for arch in ${archs}; do + + set +x + + echo + echo "###" + echo "### Creating/updating FAI server configuration" + echo "### (codename: ${codename}, architecture: ${arch})" + echo "###" + + set -x + + # create codename based fai base config + faiconfig="/etc/debian-edu/fai/debian-edu-fai.${arch}+${codename}" + if [ -d /etc/debian-edu/fai/debian-edu-fai.TEMPLATE ]; then + if [ -d "${faiconfig}" ]; then + rm -Rf "${faiconfig}" + fi + cp -a /etc/debian-edu/fai/debian-edu-fai.TEMPLATE "${faiconfig}" + touch "${faiconfig}/DONT_MODIFY_FILES_IN_THIS_DIRECTORY" + else + echo "ERROR: Failed to create FAI configuration in ${faiconfig}, no debian-edu-fai.TEMPLATE directory found" + exit 1 + fi + + # fill in placeholders (@rootpw@, @codename@ and @arch@) in nfsroot.conf.in + find "${faiconfig}" -name '*.in' | while read file_to_adapt; do + + cp ${file_to_adapt} ${file_to_adapt%.in} + + [ "$rootpw" ] && export rootpw && perl -p -e "s/\@rootpw\@/\$ENV{rootpw}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$mirrorurl" ] && export mirrorurl && perl -p -e "s/\@mirrorurl\@/\$ENV{mirrorurl}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$codename" ] && export codename && perl -p -e "s/\@codename\@/\$ENV{codename}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$arch" ] && export arch && perl -p -e "s/\@arch\@/\$ENV{arch}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + + # FIXME: also comment out variables that are not set (anymore) in /etc/debian-edu/faiinstall.cfg + + [ "$fai_logserver" ] && export fai_logserver && perl -p -e "s/^(#|)LOGSERVER=.{0,1}\@fai_logserver\@.{0,1}\s*\$/LOGSERVER=\'\$ENV{fai_logserver}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$fai_loguser" ] && export fai_loguser && perl -p -e "s/^(#|)LOGUSER=.{0,1}\@fai_loguser\@.{0,1}\s*\$/LOGUSER=\'\$ENV{fai_loguser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + + # hack for non-free-firmware repo area added since Debian 12 (aka bookworm) [we only support Debian 11 (aka bullseye) and upwards] + if [ "$codename" = "bullseye" ]; then + perl -p -e "s/ non-free-firmware//g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + fi + + chown root:root ${file_to_adapt%.in} + chmod 0600 ${file_to_adapt%.in} + rm ${file_to_adapt} + + done + + # source the NFS conf file... this might override our FAI_CONFIGDIR + # (but should not as recommended in our nfsroot.conf.in template) + if [ -f "$faiconfig/nfsroot.conf" ]; then + . $faiconfig/nfsroot.conf + else + echo "ERROR: No nfsroot.conf file found in $faiconfig/, can't continue..." + exit 1 + fi + + # hard-code some sensible defaults in case they have been commented out in $faiconfig/nfsroot.conf + [ "$FAI_DEBOOTSTRAP" ] || FAI_DEBOOTSTRAP="${codename} http://deb.debian.org/debian" + [ "$FAI_ROOTPW" ] || FAI_ROOTPW="${rootpw}" + [ "$NFSROOT" ] || NFSROOT="/srv/fai/nfsroot.debian-edu-fai/${arch}+${codename}" + [ "$TFTPROOT" ] || TFTPROOT="${tftpdir}/debian-edu-fai.${arch}+${codename}" + [ "$NFSROOT_HOOKS" ] || NFSROOT_HOOKS="/etc/debian-edu/fai/debian-edu-fai.${arch}+${codename}/" + [ "$FAI_DEBOOTSTRAP_OPTS" ] || FAI_DEBOOTSTRAP_OPTS="--arch=${arch}" + [ "$FAI_CONFIGDIR" ] || FAI_CONFIGDIR="/srv/fai/config" + + FAI_CONFIGDIR_REAL="${FAI_CONFIGDIR}" + # if FAI_CONFIGDIR is a symlink, we need to find the real location... + if [ -h ${FAI_CONFIGDIR} ]; then + FAI_CONFIGDIR_REAL="$(readlink ${FAI_CONFIGDIR})" + fi + + set +x + + echo + echo "###" + echo "### Installing/updating FAI config space (this takes some time)" + echo "### (codename: ${codename}, architecture: ${arch})" + echo "###" + debian-edu-fai_updateconfigspace "${FAI_CONFIGDIR_REAL}" + + set -x + + # Update variables to be customized in FAI config space + + # This code block might be executed on the same FAI_CONFIGDIR several times + # (once per arch and codename). + # This is a known issue and works as designed. People might have chosen to + # use difference FAI_CONFIGDIR values for different environments and with + # such a choice executing the below per arch and per codename makes sense. + + set +x + + echo + echo "###" + echo "### Tweaking FAI config space" + echo "### (codename: ${codename}, architecture: ${arch})" + echo "###" + + set -x + + find ${FAI_CONFIGDIR_REAL} -name '*.in' | while read file_to_adapt; do + + cp ${file_to_adapt} ${file_to_adapt%.in} + + # FIXME: also comment out variables that are not set (anymore) in /etc/debian-edu/faiinstall.cfg + + [ "$rootpw" ] && export rootpw && perl -p -e "s/^(#|)ROOTPW=.{0,1}\@rootpw\@.{0,1}\s*\$/ROOTPW=\'\$ENV{rootpw}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$localuser" ] && export localuser && perl -p -e "s/^(#|)username=.{0,1}\@localuser\@.{0,1}\s*\$/username=\'\$ENV{localuser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$localuserpw" ] && export localuserpw && perl -p -e "s/^(#|)USERPW=.{0,1}\@localuserpw\@.{0,1}\s*\$/USERPW=\'\$ENV{localuserpw}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$wifi_essid" ] && export wifi_essid && perl -p -e "s/^(#|)wifi_essid=.{0,1}\@wifi_essid\@.{0,1}\s*\$/wifi_essid=\'\$ENV{wifi_essid}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$wifi_passphrase" ] && export wifi_passphrase && perl -p -e "s/^(#|)wifi_passphrase=.{0,1}\@wifi_passphrase\@.{0,1}\s*\$/wifi_passphrase=\'\$ENV{wifi_passphrase}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$fai_logserver" ] && export fai_logserver && perl -p -e "s/^(#|)LOGSERVER=.{0,1}\@fai_logserver\@.{0,1}\s*\$/LOGSERVER=\'\$ENV{fai_logserver}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$fai_loguser" ] && export fai_loguser && perl -p -e "s/^(#|)LOGUSER=.{0,1}\@fai_loguser\@.{0,1}\s*\$/LOGUSER=\'\$ENV{fai_loguser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + [ "$school_tag" ] && export school_tag && perl -p -e "s/\@school_tag\@/\$ENV{school_tag}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" + + chown root:root ${file_to_adapt} + chmod 0600 ${file_to_adapt} + + done + + # set APTPROXY for use by fai-make-nfsroot... + if [ -n "${http_proxy}" ]; then + export APTPROXY="${http_proxy}" + export http_proxy + fi + + set +x + + echo + echo "###" + echo "### Creating FAI nfsroot installer environment" + echo "### (codename: ${codename}, architecture: ${arch})" + echo "###" + + # the NFSROOT variable we should have obtained from sourcing $faiconfig/nfsroot.conf + # (aka /etc/fai/nfsroot.conf) above... + if [ -n "${NFSROOT}" ] && [ -n "${codename}" ]; then + + # create nfs-root from scratch (if not present or not fully created in a previous run) + + # Create a ".DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" file at the end + # of fai-make-nfsroot and check for the presence of that file for detecting + # whether a fresh NFSROOT setup is required or just an NFSROOT update/upgrade. + if [ ! -f "${NFSROOT}/.DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" ]; then + + # enforce NFSROOT re-creation (or initial creation) + mkdir -p "${NFSROOT}/proc" + mount -t proc proc "${NFSROOT}/proc" + TMPDIR=/tmp fai-make-nfsroot -v -f -N -C ${faiconfig} + touch "${NFSROOT}/.DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" + else + mount -t proc proc "${NFSROOT}/proc" + # update packages (and clean old kernel images) in NFSROOT + TMPDIR=/tmp fai-make-nfsroot -v -k -N -C ${faiconfig} + # adjust nfsroot configuration (SSH pubkeys, rootpw, etc.) + TMPDIR=/tmp fai-make-nfsroot -v -a -C ${faiconfig} + + fi + [ -d "${NFSROOT}/proc/self" ] && umount "${NFSROOT}/proc" + [ -d "${NFSROOT}/sys/class" ] && umount "${NFSROOT}/sys" + + # Remove /srv/tftp/debian-edu-fai.ARCH+CODENAME after NFSROOT creation. + # We don't need that as we use our own iPXE boot config (instead + # of syslinux which is used by FAI by default). + if [ -d "${TFPTROOT}/" ]; then + rm -Rf "${TFTPROOT}/" + fi + + # symlink kernel and initrd files into + if [ -e "${NFSROOT}/vmlinuz" ] && [ -e "${NFSROOT}/initrd.img" ]; then + + # create kernel dir in tftp area + mkdir -p "${tftpdir}/debian-edu-fai/${arch}+${codename}/" + + # symlink vmlinuz / initrd in the NFSROOT + if [ -e "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" ]; then + rm "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" + fi + cp -a "${NFSROOT}/$(readlink "${NFSROOT}/vmlinuz")" "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" + if [ -e "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" ]; then + rm "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" + fi + cp -a "${NFSROOT}/$(readlink "${NFSROOT}/initrd.img")" "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" + + fi + fi + + cat >> "${menuitems}" <> "${menufile}" < "${tftpdir}/debian-edu-fai/ltsp.ipxe" +#!ipxe +# +# Configure iPXE for network installations + +# Set the default image (img) based on arch, or to root-path if it's not empty +#cpuid --ext 29 && set img amd64+${codename} || set img i386+${codename} + +# choose default boot entry (via configurable variables, see /etc/debian-edu/debian-edu-fai.conf) +set img ${default_arch}+${default_codename} + +goto start + +:start +# To completely hide the menu, set menu-timeout to -1 +isset \${menu-timeout} || set menu-timeout 5000 +iseq "\${menu-timeout}" "-1" && goto \${img} || +menu Debian Edu iPXE boot menu || goto \${img} +item +item --gap Debian Edu installation: +$(cat ${menuitems}) +item +item --gap Other options: +item --key m memtest Memory test +item --key c config Enter iPXE configuration +item --key s shell Drop to iPXE shell +item --key d disk Boot from the first local disk +item +item --key x exit Exit iPXE and continue BIOS boot +choose --timeout \${menu-timeout} --default \${img} img || goto cancel +goto \${img} + +:memtest +iseq \${platform} pcbios && kernel ${memtest_bios} || kernel ${memtest_efi} +# Boot "fails" on normal memtest exit with Esc, so show the menu again +boot || +goto start + +:config +config +goto start + +:shell +echo Type 'exit' to get the back to the menu +shell +goto start + +:disk +# Boot the first local HDD +sanboot --no-describe --drive 0x80 || goto failed + +:exit +exit 1 + +:cancel +echo You cancelled the menu, dropping to a shell +goto shell + +:failed +echo Booting failed, dropping to a shell +goto shell +EOF + +cat $menufile >> "${tftpdir}/debian-edu-fai/ltsp.ipxe" + +ln -sf ltsp.ipxe "${tftpdir}/debian-edu-fai/debian-edu-fai.ipxe" diff --git a/bin/debian-edu-faiinstall b/bin/debian-edu-faiinstall deleted file mode 100755 index fce3bf8..0000000 --- a/bin/debian-edu-faiinstall +++ /dev/null @@ -1,428 +0,0 @@ -#!/bin/sh -# -# Prepare for FAI installation of Debian Edu. - -set -x - -LC_ALL=C -export LC_ALL - -## FIXME: Why is resolv.conf empty or missing? Because network -## was started in the chroot (target)? -## Try to find the DNS from the leases file, if that fails use -## default DNS: -if [ ! -s /etc/resolv.conf ] ; then - DNS="10.0.2.2" - LEASEDIR=/var/lib/dhcp/ - if [ -d $LEASEDIR ] ; then - LEASEFILE=$LEASEDIR`ls -tr -1 $LEASEDIR | tail -n 1` - if [ -r $LEASEFILE ] ; then - if DNSLEASE=`cat $LEASEFILE | grep domain-name-servers | \ - tail -n 1 | \ - grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"` ; then - DNS=$DNSLEASE - echo "info: Found leases file and domain-name-server: $DNS." - else - echo "info: Could not extract DNS from leases file." - fi - fi - fi - echo "info: Create temporary /etc/resolv.conf with DNS: $DNS." - cat >> /etc/resolv.conf < /etc/resolvconf/run/resolv.conf, i.e.: -## rm /etc/resolv.conf; ln -s /etc/resolvconf/run/resolv.conf /etc/resolv.conf -nameserver $DNS -search intern -EOF - fi - -# Make sure the created directories and files are readable by tfptd -# run as user nobody. -umask 022 - -# Fetch ftp_proxy and http_proxy if set globally -if [ -f /etc/environment ] ; then - . /etc/environment -fi - -### -### FAI Setup -### - -[ "$archs" ] || archs=$(command -V dpkg 1>/dev/null 2>/dev/null && dpkg --print-architecture || uname -m) -[ "$codenames" ] || codenames=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d "=" -f2) -[ "$http_proxy" ] || unset http_proxy -[ "$ftp_proxy" ] || unset ftp_proxy -[ "$mirrorurl" ] || mirrorurl=http://deb.debian.org/debian -[ "$rootpw" ] || rootpw="" -[ "$localuser" ] || localuser="" -[ "$localuserpw" ] || localuserpw="" -[ "$wifi_essid" ] || wifi_essid="" -[ "$wifi_passphrase" ] || wifi_passphrase="" -[ "$tftpdir" ] || tftpdir="/srv/tftp" -[ "$fai_logserver" ] || unset fai_logserver -[ "$fai_loguser" ] || unset fai_loguser -[ "$school_tag" ] || school_tag="SKOLE" - -# required for pre-selecting the default boot item in iPXE config -[ "$default_arch" ] || default_arch="$(echo ${archs} | cut -d " " -f1)" -[ "$default_codename" ] || default_codename=$(echo ${codenames} | cut -d " " -f1) - -# only set plymouth theme if known by the desktop-theme ... -if [ -e /etc/alternatives/desktop-theme/plymouth ]; then - [ "$theme" ] || theme="$(ls -L /etc/alternatives/desktop-theme/plymouth | grep script | cut -d'.' -f 1)" -fi - -# source Debian Edu's config file -if [ -f /etc/debian-edu/config ] ; then - . /etc/debian-edu/config -fi - -# source debian-edu-fai's config file -# Allow site specific overrides to the variables -if [ -f /etc/debian-edu/debian-edu-fai.conf ] ; then - . /etc/debian-edu/debian-edu-fai.conf -fi - -# keep a copy of /srv/tftp/ltsp if this is the first attempt to deploy -# debian-edu-fai on this system -if [ -d "${tftpdir}/debian-edu-fai" ] && [ ! -h "${tftpdir}/debian-edu-fai" ]; then - mv "${tftpdir}/ltsp" "${tftpdir}/ltsp.moved-aside-by-debian-edu-fai" -elif [ -h "${tftpdir}/debian-edu-fai" ]; then - rm "${tftpdir}/debian-edu-fai" -fi - -# For Debian Edu, we will create the FAI tftp boot dir in subfolder ltsp/. -mkdir -p "${tftpdir}/ltsp/" -# and symlink that to what really is inside... -ln -nsf "ltsp" "${tftpdir}/debian-edu-fai" - -# Start from a clean state after any configuration changes have been made. -rm -f $tftpdir/ltsp/fai-installers.cfg.~ -rm -f $tftpdir/ltsp/fai-menuitems.cfg.~ -rm -f $tftpdir/ltsp/debian-edu-fai.ipxe -rm -f $tftpdir/ltsp/ltsp.ipxe -rm -f $tftpdir/ltsp/memtest* -rm -f $tftpdir/ltsp/snponly.efi -rm -f $tftpdir/ltsp/undionly.kpxe - -# prepare menufile creation (always start fresh) -menuitems=${tftpdir}/debian-edu-fai/fai-menuitems.cfg -menuindex=1 -menufile=${tftpdir}/debian-edu-fai/fai-installers.cfg -if [ -e "${menuitems}" ]; then - mv "${menuitems}" "${menuitems}.~" -fi -if [ -e "${menufile}" ]; then - mv "${menufile}" "${menufile}.~" -fi -touch "${menuitems}" -touch "${menufile}" - -for codename in ${codenames}; do - - # skip codenames that don't sound like Debian suites... - if ! echo "bullseye bookworm sid unstable" | grep -q "${codename}"; then - echo "WARNING: The name '${codename}' is not a known and recent Debian distribution codename. Skipping..." - continue - fi - - # iterate over configured FAI client architectures... - for arch in ${archs}; do - - set +x - - echo - echo "###" - echo "### Creating/updating FAI server configuration" - echo "### (codename: ${codename}, architecture: ${arch})" - echo "###" - - set -x - - # create codename based fai base config - faiconfig="/etc/debian-edu/fai/debian-edu-fai.${arch}+${codename}" - if [ -d /etc/debian-edu/fai/debian-edu-fai.TEMPLATE ]; then - if [ -d "${faiconfig}" ]; then - rm -Rf "${faiconfig}" - fi - cp -a /etc/debian-edu/fai/debian-edu-fai.TEMPLATE "${faiconfig}" - touch "${faiconfig}/DONT_MODIFY_FILES_IN_THIS_DIRECTORY" - else - echo "ERROR: Failed to create FAI configuration in ${faiconfig}, no debian-edu-fai.TEMPLATE directory found" - exit 1 - fi - - # fill in placeholders (@rootpw@, @codename@ and @arch@) in nfsroot.conf.in - find "${faiconfig}" -name '*.in' | while read file_to_adapt; do - - cp ${file_to_adapt} ${file_to_adapt%.in} - - [ "$rootpw" ] && export rootpw && perl -p -e "s/\@rootpw\@/\$ENV{rootpw}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$mirrorurl" ] && export mirrorurl && perl -p -e "s/\@mirrorurl\@/\$ENV{mirrorurl}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$codename" ] && export codename && perl -p -e "s/\@codename\@/\$ENV{codename}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$arch" ] && export arch && perl -p -e "s/\@arch\@/\$ENV{arch}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - - # FIXME: also comment out variables that are not set (anymore) in /etc/debian-edu/faiinstall.cfg - - [ "$fai_logserver" ] && export fai_logserver && perl -p -e "s/^(#|)LOGSERVER=.{0,1}\@fai_logserver\@.{0,1}\s*\$/LOGSERVER=\'\$ENV{fai_logserver}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$fai_loguser" ] && export fai_loguser && perl -p -e "s/^(#|)LOGUSER=.{0,1}\@fai_loguser\@.{0,1}\s*\$/LOGUSER=\'\$ENV{fai_loguser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - - # hack for non-free-firmware repo area added since Debian 12 (aka bookworm) [we only support Debian 11 (aka bullseye) and upwards] - if [ "$codename" = "bullseye" ]; then - perl -p -e "s/ non-free-firmware//g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - fi - - chown root:root ${file_to_adapt%.in} - chmod 0600 ${file_to_adapt%.in} - rm ${file_to_adapt} - - done - - # source the NFS conf file... this might override our FAI_CONFIGDIR - # (but should not as recommended in our nfsroot.conf.in template) - if [ -f "$faiconfig/nfsroot.conf" ]; then - . $faiconfig/nfsroot.conf - else - echo "ERROR: No nfsroot.conf file found in $faiconfig/, can't continue..." - exit 1 - fi - - # hard-code some sensible defaults in case they have been commented out in $faiconfig/nfsroot.conf - [ "$FAI_DEBOOTSTRAP" ] || FAI_DEBOOTSTRAP="${codename} http://deb.debian.org/debian" - [ "$FAI_ROOTPW" ] || FAI_ROOTPW="${rootpw}" - [ "$NFSROOT" ] || NFSROOT="/srv/fai/nfsroot.debian-edu-fai/${arch}+${codename}" - [ "$TFTPROOT" ] || TFTPROOT="${tftpdir}/debian-edu-fai.${arch}+${codename}" - [ "$NFSROOT_HOOKS" ] || NFSROOT_HOOKS="/etc/debian-edu/fai/debian-edu-fai.${arch}+${codename}/" - [ "$FAI_DEBOOTSTRAP_OPTS" ] || FAI_DEBOOTSTRAP_OPTS="--arch=${arch}" - [ "$FAI_CONFIGDIR" ] || FAI_CONFIGDIR="/srv/fai/config" - - FAI_CONFIGDIR_REAL="${FAI_CONFIGDIR}" - # if FAI_CONFIGDIR is a symlink, we need to find the real location... - if [ -h ${FAI_CONFIGDIR} ]; then - FAI_CONFIGDIR_REAL="$(readlink ${FAI_CONFIGDIR})" - fi - - set +x - - echo - echo "###" - echo "### Installing/updating FAI config space (this takes some time)" - echo "### (codename: ${codename}, architecture: ${arch})" - echo "###" - debian-edu-fai_updateconfigspace "${FAI_CONFIGDIR_REAL}" - - set -x - - # Update variables to be customized in FAI config space - - # This code block might be executed on the same FAI_CONFIGDIR several times - # (once per arch and codename). - # This is a known issue and works as designed. People might have chosen to - # use difference FAI_CONFIGDIR values for different environments and with - # such a choice executing the below per arch and per codename makes sense. - - set +x - - echo - echo "###" - echo "### Tweaking FAI config space" - echo "### (codename: ${codename}, architecture: ${arch})" - echo "###" - - set -x - - find ${FAI_CONFIGDIR_REAL} -name '*.in' | while read file_to_adapt; do - - cp ${file_to_adapt} ${file_to_adapt%.in} - - # FIXME: also comment out variables that are not set (anymore) in /etc/debian-edu/faiinstall.cfg - - [ "$rootpw" ] && export rootpw && perl -p -e "s/^(#|)ROOTPW=.{0,1}\@rootpw\@.{0,1}\s*\$/ROOTPW=\'\$ENV{rootpw}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$localuser" ] && export localuser && perl -p -e "s/^(#|)username=.{0,1}\@localuser\@.{0,1}\s*\$/username=\'\$ENV{localuser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$localuserpw" ] && export localuserpw && perl -p -e "s/^(#|)USERPW=.{0,1}\@localuserpw\@.{0,1}\s*\$/USERPW=\'\$ENV{localuserpw}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$wifi_essid" ] && export wifi_essid && perl -p -e "s/^(#|)wifi_essid=.{0,1}\@wifi_essid\@.{0,1}\s*\$/wifi_essid=\'\$ENV{wifi_essid}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$wifi_passphrase" ] && export wifi_passphrase && perl -p -e "s/^(#|)wifi_passphrase=.{0,1}\@wifi_passphrase\@.{0,1}\s*\$/wifi_passphrase=\'\$ENV{wifi_passphrase}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$fai_logserver" ] && export fai_logserver && perl -p -e "s/^(#|)LOGSERVER=.{0,1}\@fai_logserver\@.{0,1}\s*\$/LOGSERVER=\'\$ENV{fai_logserver}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$fai_loguser" ] && export fai_loguser && perl -p -e "s/^(#|)LOGUSER=.{0,1}\@fai_loguser\@.{0,1}\s*\$/LOGUSER=\'\$ENV{fai_loguser}\'\n/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - [ "$school_tag" ] && export school_tag && perl -p -e "s/\@school_tag\@/\$ENV{school_tag}/g" "${file_to_adapt%.in}" > "${file_to_adapt%.in}.new" && mv "${file_to_adapt%.in}.new" "${file_to_adapt%.in}" - - chown root:root ${file_to_adapt} - chmod 0600 ${file_to_adapt} - - done - - # set APTPROXY for use by fai-make-nfsroot... - if [ -n "${http_proxy}" ]; then - export APTPROXY="${http_proxy}" - export http_proxy - fi - - set +x - - echo - echo "###" - echo "### Creating FAI nfsroot installer environment" - echo "### (codename: ${codename}, architecture: ${arch})" - echo "###" - - # the NFSROOT variable we should have obtained from sourcing $faiconfig/nfsroot.conf - # (aka /etc/fai/nfsroot.conf) above... - if [ -n "${NFSROOT}" ] && [ -n "${codename}" ]; then - - # create nfs-root from scratch (if not present or not fully created in a previous run) - - # Create a ".DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" file at the end - # of fai-make-nfsroot and check for the presence of that file for detecting - # whether a fresh NFSROOT setup is required or just an NFSROOT update/upgrade. - if [ ! -f "${NFSROOT}/.DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" ]; then - - # enforce NFSROOT re-creation (or initial creation) - mkdir -p "${NFSROOT}/proc" - mount -t proc proc "${NFSROOT}/proc" - TMPDIR=/tmp fai-make-nfsroot -v -f -N -C ${faiconfig} - touch "${NFSROOT}/.DEBIAN_EDU_FAI_NFSROOT_INSTALLATION_COMPLETED" - else - mount -t proc proc "${NFSROOT}/proc" - # update packages (and clean old kernel images) in NFSROOT - TMPDIR=/tmp fai-make-nfsroot -v -k -N -C ${faiconfig} - # adjust nfsroot configuration (SSH pubkeys, rootpw, etc.) - TMPDIR=/tmp fai-make-nfsroot -v -a -C ${faiconfig} - - fi - [ -d "${NFSROOT}/proc/self" ] && umount "${NFSROOT}/proc" - [ -d "${NFSROOT}/sys/class" ] && umount "${NFSROOT}/sys" - - # Remove /srv/tftp/debian-edu-fai.ARCH+CODENAME after NFSROOT creation. - # We don't need that as we use our own iPXE boot config (instead - # of syslinux which is used by FAI by default). - if [ -d "${TFPTROOT}/" ]; then - rm -Rf "${TFTPROOT}/" - fi - - # symlink kernel and initrd files into - if [ -e "${NFSROOT}/vmlinuz" ] && [ -e "${NFSROOT}/initrd.img" ]; then - - # create kernel dir in tftp area - mkdir -p "${tftpdir}/debian-edu-fai/${arch}+${codename}/" - - # symlink vmlinuz / initrd in the NFSROOT - if [ -e "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" ]; then - rm "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" - fi - cp -a "${NFSROOT}/$(readlink "${NFSROOT}/vmlinuz")" "${tftpdir}/debian-edu-fai/${arch}+${codename}/vmlinuz" - if [ -e "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" ]; then - rm "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" - fi - cp -a "${NFSROOT}/$(readlink "${NFSROOT}/initrd.img")" "${tftpdir}/debian-edu-fai/${arch}+${codename}/initrd.img" - - fi - fi - - cat >> "${menuitems}" <> "${menufile}" < "${tftpdir}/debian-edu-fai/ltsp.ipxe" -#!ipxe -# -# Configure iPXE for network installations - -# Set the default image (img) based on arch, or to root-path if it's not empty -#cpuid --ext 29 && set img amd64+${codename} || set img i386+${codename} - -# choose default boot entry (via configurable variables, see /etc/debian-edu/debian-edu-fai.conf) -set img ${default_arch}+${default_codename} - -goto start - -:start -# To completely hide the menu, set menu-timeout to -1 -isset \${menu-timeout} || set menu-timeout 5000 -iseq "\${menu-timeout}" "-1" && goto \${img} || -menu Debian Edu iPXE boot menu || goto \${img} -item -item --gap Debian Edu installation: -$(cat ${menuitems}) -item -item --gap Other options: -item --key m memtest Memory test -item --key c config Enter iPXE configuration -item --key s shell Drop to iPXE shell -item --key d disk Boot from the first local disk -item -item --key x exit Exit iPXE and continue BIOS boot -choose --timeout \${menu-timeout} --default \${img} img || goto cancel -goto \${img} - -:memtest -iseq \${platform} pcbios && kernel ${memtest_bios} || kernel ${memtest_efi} -# Boot "fails" on normal memtest exit with Esc, so show the menu again -boot || -goto start - -:config -config -goto start - -:shell -echo Type 'exit' to get the back to the menu -shell -goto start - -:disk -# Boot the first local HDD -sanboot --no-describe --drive 0x80 || goto failed - -:exit -exit 1 - -:cancel -echo You cancelled the menu, dropping to a shell -goto shell - -:failed -echo Booting failed, dropping to a shell -goto shell -EOF - -cat $menufile >> "${tftpdir}/debian-edu-fai/ltsp.ipxe" - -ln -sf ltsp.ipxe "${tftpdir}/debian-edu-fai/debian-edu-fai.ipxe" diff --git a/debian/install b/debian/install index 5c39b88..37151d9 100644 --- a/debian/install +++ b/debian/install @@ -2,5 +2,5 @@ conf/debian-edu/debian-edu-fai.conf etc/debian-edu/ conf/debian-edu/fai/ etc/debian-edu/ conf/exports.d/debian-edu-fai.exports usr/share/debian-edu-fai/exports.d/ fai/config usr/share/debian-edu-fai/fai/ -bin/debian-edu-faiinstall usr/sbin/ +bin/debian-edu-fai_install usr/sbin/ bin/debian-edu-fai_updateconfigspace usr/sbin/ -- cgit v1.2.3