#!/bin/bash
#
# Configure a Debian Edu system with 'LTSP-Server' profile' for both diskless
# workstations and also thin clients (using X2Go).

# LTSP has been re-written in 2019. LTSP5 has been discontinued and isn't available
# any longer in the Debian archive, the known tools are gone. This script takes care
# for the special Debian Edu requirements.

# The configuration below applies to a Debian Edu machine in the internal
# backbone network with two NICs. This system needs to be registered w/ GOsa² in
# case it isn't the main server (i.e. a 'combined' server).
# Kerberized NFS is used (with krb5i as default), see:
# https://wiki.debian.org/DebianEdu/Documentation/Bookworm/HowTo/Administration#Kerberized_NFS
# The modified system provides a separate LTSP client network attached to eth1.
#
# Author/Copyright:	Wolfgang Schweer <wschweer@arcor.de>
# Author/Copyright:	Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
# Licence:		GPL2+
# first edited:	2019-11-21

version=2026-11-11

set -e

get_timezone() {
	if ! [ -L "$DPKG_ROOT/etc/localtime" ] ; then
		return
	fi
	timezone="$(readlink "$DPKG_ROOT/etc/localtime")"
	timezone="$(cd "$DPKG_ROOT/etc" && realpath -m -s "$timezone")"
	echo "${timezone#/usr/share/zoneinfo/}"
}

select_desktop () {
	# select the first found desktop as the default, based on what x2goclient
	# (src/onmainwindow.cpp) and x2goserver (x2goserver/bin/x2goruncommand)
	# support
	if [ -x /usr/bin/startxfce4 ]; then # from xfce4-session
		echo XFCE
	elif [ -x /usr/bin/startplasma-x11 ]; then # from plasma-workspace
		echo KDE
	elif [ -x /usr/bin/gnome-session ]; then # from gnome-session-bin
		echo GNOME
	elif [ -x /usr/bin/mate-session ]; then # from mate-session
		echo MATE
	elif [ -x /usr/bin/startlxde ]; then # from openbox-lxde-session
		echo LXDE
	elif [ -x /usr/bin/startlxqt ]; then # from lxqt-session
		echo LXQT
	elif [ -x /usr/bin/cinnamon-session-cinnamon2d ]; then # from cinnamon
		echo CINNAMON
	elif [ -x /usr/bin/openbox-session ]; then # from openbox
		echo OPENBOX
	elif [ -x /usr/bin/icewm-session ]; then # from icewm
		echo ICEWM
	else
		echo XFCE
	fi
}

# usage
if [ -z "$1" ] ; then
	echo "Use $0 -h or $0 --help for more information"
	exit 0
fi

if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then
	cat <<EOF

Usage information:

debian-edu-ltsp-install --arch <amd64|i386> --dist <stable|testing|sid> --dns_server <10.0.2.2|dns server ip> --diskless_workstation <yes|no> --thin_type <bare|display|desktop> --dlw <yes|no> --img <yes|no> --desktop <xfce|cinnamon|gnome|kde|lxde|lxqt|mate|none> --x2go_desktop <xfce|cinnamon|gnome|kde|lxde|lxqt|mate|openbox|icewm>

Turn a Debian Edu workstation into an LTSP server for both diskless
workstations and thin clients.

--arch       takes effect for a thin client chroot setup, default value is the system architecture one.

--dist       takes effect for a LTSP/X2Go client chroot setup, default value is the one the LTSP server is running.

--dns_server defaults to 10.0.2.2 if omitted.

--diskless_workstation defaults to no if omitted.

--dlw        used to create a diskless workstation LTSP chroot (root fs via NFS), default is no.

--img        takes effect for LTSP diskless workstation and X2Go thin client chroot setup, default is yes.

--desktop    takes effect for LTSP diskless workstation chroot setup, default is xfce.
             Other values: cinnamon, gnome, kde, lxde, lxqt, mate.
             (And 'none' for modular installations - also useful for testing).

--x2go_desktop takes effect for X2Go thin client setup, default is any
             of the installed desktop environments
             Other values: cinnamon, gnome, kde, lxde, lxqt, mate, openbox,
                           icewm

--thin_type  has no default value. These are available:
    bare:    preconfigured x2go client running via 'startx' as user 'thin' with sound and
             client side mass storage support.
    display: x2gothinclient running in display mode.
    desktop: x2gothinclient running in minidesktop mode.

Example 1: 'debian-edu-ltsp-install --diskless_workstation yes' creates diskless workstation support (SquashFS image).

Example 2: 'debian-edu-ltsp-install --arch amd64 --diskless_workstation yes --thin_type bare' creates diskless workstation
            and 64-bit thin client support. LTSP client boot defaults to diskless workstation.

Example 3: 'debian-edu-ltsp-install --arch i386 --thin_type bare' creates additional 32-bit thin client support.

Example 4: 'debian-edu-ltsp-install --diskless_workstation yes' updates the diskless workstation SquashFS image.

Example 5: 'debian-edu-ltsp-install --dlw yes --img no' creates a diskless workstation LTSP chroot.
            Please note that about 15 GiB of additional disk space is needed. In the default case, run the commands
            'lvresize -L+15G /dev/vg_system/srv+ltsp' and 'resize2fs /dev/vg_system/srv+ltsp'.

Example 6: 'debian-edu-ltsp-install --dlw yes' creates diskless workstation LTSP chroot and
           the related SquashFS image. Another 5 GiB more additional disk space is needed.

This script applies to a system with two NICs on the internal backbone network.

EOF
	exit 0
fi

if [ -r /etc/debian-edu/config ] ; then
    . /etc/debian-edu/config
    # Obtained from /etc/debian-edu/config
    if [ -n "${LOCALE}" ]; then
        export LANG="${LOCALE}"
    fi
fi

# Grab dist value for both testing and stable release cases.
if grep -q / /etc/debian_version ; then
	dist="$(cat /etc/debian_version | cut -d/ -f1)"
else
	dist=$(lsb_release -sc)
fi

# Set default values.
arch="$(dpkg --print-architecture)"
dns_server="10.0.2.2"
diskless_workstation="no"
thin_type=""
dlw="no"
img="yes"
desktop="xfce"
x2go_desktop="$(select_desktop)"

# If apt was configured to use a proxy (e.g. in a VM), use it here too
if [ -z "$http_proxy" ]; then
    eval $(apt-config shell http_proxy Acquire::http::Proxy)
fi
if [ -z "$https_proxy" ]; then
    eval $(apt-config shell https_proxy Acquire::https::Proxy)
fi
if [ -z "$ftp_proxy" ]; then
    eval $(apt-config shell ftp_proxy Acquire::ftp::Proxy)
fi

while [ $# -gt 0 ] ; do
  case "$1" in
    --arch) arch="$2" ; shift ;;
    --dist) dist="$2" ; shift ;;
    --dns_server) dns_server="$2"  ; shift ;;
    --diskless_workstation) diskless_workstation="$2" ; shift ;;
    --thin_type) thin_type="$2" ; shift ;;
    --dlw) dlw="$2" ; shift ;;
    --img) img="$2" ; shift ;;
    --desktop) desktop="$2" ; shift ;;
    --x2go_desktop)
        x2go_desktop="$(printf '%s\n' "$2" | tr '[:lower:]' '[:upper:]')"
        shift ;;
    --version) echo $version; exit 0 ;;
  esac
  shift
done

# Hand over the x2go_desktop (either detected automatically or specified via cmdline option)
# to debian-edu-ltsp-initrd (needed for x2go-bare thinclient variant setup).
echo "${x2go_desktop}" > "/var/lib/debian-edu/debian-edu-ltsp-initrd_x2go-command"

kernel_arch="$arch"

# Special case i386.
if [ "i386" == "$arch" ] ; then
	#kernel_arch="686-pae"
	# next one optimal for very old TC machines w/o PAE.
	kernel_arch="686"
fi

# Common Debian Edu specific configuration (dirs and HERE documents), only minor
# difference for thin clients and diskless workstation (in ltsp.conf), see below.
# Next two lines are needed in case of a separate LTSP server.
ETH0_IP="$(hostname -I | cut -d' ' -f1)"
ETH1_IP="$(hostname -I | cut -d' ' -f2)"
ETH1_IP=${ETH1_IP:-"192.168.0.254"}
HOSTNAME="$(hostname -s)"
if [ ! -d /etc/ltsp/client ] ; then
	mkdir -p /etc/ltsp/client/init

	# We are using NFS/Kerberos (krb5i) and autofs instead of sshfs for home dirs.
	touch  /etc/ltsp/client/init/54-pam.sh

	# Debian Edu wants a greeter w/o user list, i.e. don't modify existing config.
	touch  /etc/ltsp/client/init/55-display-manager.sh
fi

if [ ! -r /etc/ltsp/ltsp.conf ]; then
	# make ipxe menu entries more user friendly.
	cat <<EOF > /etc/ltsp/ltsp.conf
# /bin/sh -n
# LTSP configuration file
# Documentation=man:ltsp.conf(5)

[server]
# Provide a full menu name for x2go-bare-amd64.img
IPXE_X2GO_BARE_AMD64_IMG="Plain X2Go Thin Client (amd64, SquashFS)"
# Provide a full menu name for x2go-bare-i386.img
IPXE_X2GO_BARE_I386_IMG="Plain X2Go Thin Client (i386, SquashFS)"

# Provide a full menu name for x2go-bare-amd64
IPXE_X2GO_BARE_AMD64="Plain X2Go Thin Client (amd64, NFS rootfs)"
# Provide a full menu name for x2go-bare-i386
IPXE_X2GO_BARE_I386="Plain X2Go Thin Client (i386, NFS rootfs)"

# Provide a full menu name for x2go-display-amd64.img
IPXE_X2GO_DISPLAY_AMD64_IMG="Display Mode X2Go Thin Client (amd64, SquashFS)"
# Provide a full menu name for x2go-display-i386.img
IPXE_X2GO_DISPLAY_I386_IMG="Display Mode X2Go Thin Client (i386, SquashFS)"

# Provide a full menu name for x2go-display-amd64
IPXE_X2GO_DISPLAY_AMD64="Display Mode X2Go Thin Client (amd64, NFS rootfs)"
# Provide a full menu name for x2go-display-i386
IPXE_X2GO_DISPLAY_I386="Display Mode X2Go Thin Client (i386, NFS rootfs)"

# Provide a full menu name for x2go-desktop-amd64.img
IPXE_X2GO_DESKTOP_AMD64_IMG="Desktop Mode X2Go Thin Client (amd64, SquashFS)"
# Provide a full menu name for thin/desktop-i386.img
IPXE_X2GO_DESKTOP_I386_IMG="Desktop Mode X2Go Thin Client (i386, SquashFS)"

# Provide a full menu name for x2go-desktop-amd64
IPXE_X2GO_DESKTOP_AMD64="Desktop Mode X2Go Thin Client (amd64, NFS rootfs)"
# Provide a full menu name for thin/desktop-i386
IPXE_X2GO_DESKTOP_I386="Desktop Mode X2Go Thin Client (i386, NFS rootfs)"

# Provide a full menu name for x86_64.img
IPXE_X86_64_IMG="Diskless Workstation (amd64, SquashFS)"
# Provide a full menu name for x86_32.img
IPXE_X86_32_IMG="Diskless Workstation (i386, SquashFS)"

# Provide a full menu name for dlw.img
IPXE_DLW_IMG="Diskless Workstation (amd64, SquashFS)"
# Provide a full menu name for dlw
IPXE_DLW="Diskless Workstation (amd64, NFS rootfs)"

##### Set default boot value ######
# Default value is x86_64 or x86_32 (arch specific, Diskless Workstation)
# Plain X2Go Thin Client (amd64)
#DEFAULT_IMAGE="x2go-bare-amd64"
# Plain X2Go Thin Client (i386)
#DEFAULT_IMAGE="x2go-bare-i386"
# Display Mode X2Go Thin Client (amd64)
#DEFAULT_IMAGE="x2go-display-amd64"
# Desktop Mode X2Go Thin Client (amd64)
#DEFAULT_IMAGE="x2go-desktop-amd64"
# Diskless Workstation (Chroot as NFS rootfs)
#DEFAULT_IMAGE="dlw"
# Install Debian Edu/amd64 (amd64)
#DEFAULT_IMAGE="amd64"
# Install Debian Edu/i386  (i386)
#DEFAULT_IMAGE="i386"

##### Set default iPXE menu timeout ######
# Default value is 5000 milliseconds, i.e. 5 seconds.
#MENU_TIMEOUT="5000"
# Don't show the menu.
#MENU_TIMEOUT="-1"

# Debian Edu specific
DNS_SERVER=10.0.2.2
SEARCH_DOMAIN=intern
ADD_IMAGE_EXCLUDES="/etc/ltsp/image-local.excludes"
# This takes effect for hosts behind the LTSP eth1 interface.
NAT=1

# In the special [clients] section, parameters for all clients can be defined.
# Most ltsp.conf parameters should be placed here.
[clients]
POST_INIT_PRINTER="cp /etc/ltsp/p910d.conf /etc/default/p910d"
HOSTS_1="10.0.2.2 tjener.intern tjener"
HOSTS_2="$ETH1_IP $HOSTNAME"
KERNEL_PARAMETERS="quiet splash"
EOF
fi

# Debian Edu specific common additional image excludes; for diskless
# workstations the /skole mountpoint (for autofs) needs to be clean.
# This applies for both a combined server and a separate LTSP server.
# For a combined server image the autofs service needs to be enabled (see below).
if echo "$PROFILE" | grep -Eq 'Workstation|LTSP-Server' ; then
	cat <<EOF > /etc/ltsp/image-local.excludes
skole/*
EOF
	cat <<EOF > /etc/ltsp/p910d.conf
# Use attached USB printer (default is /dev/lp0, i.e. parallel port printer).
P910ND_OPTS=" -f /dev/usb/lp0"
# Debian specific (set to 1 to enable daemon start, default is 0)
P910ND_START=1
# See 'man p910nd' for details and settings.
EOF
fi

# If the BD ISO image is used, ensure that it is mounted.
# FIXME: this does not honour metal box installations from a USB iso9660 medium!
if grep -q BD /etc/apt/sources.list && ! mountpoint -q /media/cdrom && blkid /dev/sr0 1>/dev/null; then
	bd_iso_was_mounted="yes"
	mount /media/cdrom -o ro
fi
# If the BD ISO image is used, get as many packages as possible from the BD image instead of downloading them.
if grep -q BD /etc/apt/sources.list && [ -e /media/cdrom/.disk/cd_type ] ; then
	BD_ISO="true";
	mirror="file:///media/cdrom/"
else
	mirror="http://deb.debian.org/debian"
fi

# Create thin client chroot and generate image.
export DEBIAN_FRONTEND=noninteractive
if [ "" != "$thin_type" ]; then

	if [ -d "/srv/ltsp/x2go-${thin_type}-${arch}" ]; then
		echo "ERROR: X2Go thinclient chroot '/srv/ltsp/x2go-${thin_type}-${arch}' already exists."
		echo "       Remove the chroot and re-run this script."
		exit 1
	fi

	mkdir -p /srv/tftp/ltsp/x2go-"$thin_type"-"$arch"
	# Install common thin client packages.
	debootstrap --arch="$arch" \
	            --no-check-gpg \
	            --variant=minbase \
	            --include=console-setup,locales,sitesummary-client,linux-image-"${kernel_arch}" \
	            "${dist}" "/srv/ltsp/x2go-${thin_type}-${arch}" "${mirror}"
	# Unset temporary directory variables to avoid problems when directory
	# is missing inside the chroot. https://bugs.debian.org/765443
	unset TMPDIR TEMP TEMPDIR TMP
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get clean

	# Configure locale et al.
	cp /etc/locale.gen /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/
	cp /etc/default/locale /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/default
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch" locale-gen
	cp /etc/default/keyboard /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/default
	cp /etc/default/console-setup /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/default
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch" setupcon -k

	# Set timezone properly.
	timezone="$(get_timezone)"
	echo "${timezone}" > "/srv/ltsp/x2go-${thin_type}-${arch}/etc/timezone"
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch" ln -fs "/usr/share/zoneinfo/${timezone}" "/etc/localtime"
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch" dpkg-reconfigure -f noninteractive tzdata

	# Care for complete sources list (security, also nonfree -- in case firmware is needed).
	if [ -e /srv/ltsp/x2go-"$thin_type"-"$arch"/usr/share/doc/apt/examples/sources.list ] ; then
		# Up to bookworm
		chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ sh -c "cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list.d/full.list"
	else
		# Since trixie
		chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ sh -c "cp /usr/share/doc/apt/examples/debian.sources /etc/apt/sources.list.d/debian_full.sources"
	fi
	mount /dev/pts -t devpts /srv/ltsp/x2go-"$thin_type"-"$arch"/dev/pts
	mount proc -t proc /srv/ltsp/x2go-"$thin_type"-"$arch"/proc
	if [ "true" == "$BD_ISO" ] ; then
		mkdir -p /srv/ltsp/x2go-"$thin_type"-"$arch"/media/cdrom
		mount /media/cdrom /srv/ltsp/x2go-"$thin_type"-"$arch"/media/cdrom -o bind
		echo "deb [trusted=yes] $mirror $dist main" > /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/apt/sources.list
	fi
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get update
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q upgrade
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q install education-thin-client p910nd
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q install debian-edu-artwork
	# Install case specific additional packages.
	if [ "display" == "$thin_type" ] ; then
		chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q install x2gothinclient-displaymanager
		cp /usr/share/desktop-base/active-theme/login/background-nologin.svg /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/x2go/x2gothinclient-displaymanager_background.svg
	fi
	if [ "desktop" == "$thin_type" ] ; then
		chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q install x2gothinclient-minidesktop x2gothinclient-cdmanager x2gothinclient-usbmount
		if ! [ "en" == "$LANGCODE" ] ; then
			chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ apt-get -y -q install firefox-esr-l10n-"$LANGCODE"
		fi
		# Use Debian Edu version of x2gothinclient-minidesktop_start
		cp /etc/debian-edu/thin/x2gothinclient-minidesktop_start /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/x2go/
	fi
	if [ "true" == "$BD_ISO" ] ; then
		umount /srv/ltsp/x2go-"$thin_type"-"$arch"/media/cdrom
	fi
	umount /srv/ltsp/x2go-"$thin_type"-"$arch"/dev/pts
	umount /srv/ltsp/x2go-"$thin_type"-"$arch"/proc
	if [ "bare" == "$thin_type" ] ; then
		rm -rf /srv/ltsp/x2go-"$thin_type"-"$arch"/var/cache/debconf
		rm -rf /srv/ltsp/x2go-"$thin_type"-"$arch"/var/cache/man
	fi
	# Configure Sitesummary.
	cp -r /etc/sitesummary/config.d/ /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/sitesummary/
	cp -f /etc/sitesummary/site /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/sitesummary/
	cp -f /etc/sitesummary/sitegroup /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/sitesummary/
	echo ltsp-client > /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/sitesummary/hostclass

	# Customize X2Go client for Debian Edu use.
	if [ "display" == "$thin_type" ] || [ "desktop" == "$thin_type" ] ; then
		cat /etc/debian-edu/thin/x2gothinclient_sessions.in \
		    | sed -e "s/@HOSTNAME@/$(hostname -s)/g" \
		          -e "s/@X2GO_COMMAND@/${x2go_desktop}/g" \
		> /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/x2go/x2gothinclient_sessions
		chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ ln -fs /usr/share/images/desktop-base/desktop-background /etc/x2go/x2gothinclient-minidesktop_background.svg
	fi

	# This needs to be installed after x2gothinclient-minidesktop installation.
	chroot /srv/ltsp/x2go-"$thin_type"-"$arch"/ update-alternatives --set desktop-background /usr/share/desktop-base/active-theme/wallpaper/contents/images/1920x1080.svg

	# Firefox-ESR customization for Debian Edu.
	if [ "desktop" == "$thin_type" ] ; then
		cp /etc/environment /srv/ltsp/x2go-"$thin_type"-"$arch"/etc
		cp /etc/firefox-esr/debian-edu.js /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/firefox-esr
		cp /etc/firefox-esr/debian-edu-homepage-ldap.js /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/firefox-esr
		cp /etc/ssl/certs/Debian-Edu_rootCA.crt /srv/ltsp/x2go-"$thin_type"-"$arch"/etc/ssl/certs
		cat <<EOF > /srv/ltsp/x2go-"$thin_type"-"$arch"/usr/share/firefox-esr/distribution/policies.json
{
  "policies": {
    "Certificates": {
      "ImportEnterpriseRoots": true,
      "Install": [
        "/etc/ssl/certs/Debian-Edu_rootCA.crt"
      ]
    },
    "NewTabPage": false,
    "OverrideFirstRunPage": "",
    "SearchEngines": {
      "Add": [
        {
          "IconURL": "https://duckduckgo.com/favicon.ico",
          "Method": "POST",
          "Name": "DuckDuckGo",
          "SuggestURLTemplate": "https://duckduckgo.com/ac/?q={searchTerms}&type=list",
          "URLTemplate": "https://duckduckgo.com/?q={searchTerms}"
        }
      ],
      "Default": "DuckDuckGo"
    }
  }
}
EOF
	fi

	# Mark the chroot as successfully created.
	touch /srv/ltsp/x2go-"$thin_type"-"$arch"/CREATED_SUCCESSFULLY_$(date +%Y%m%d-%H%M)

	if [ "$img" == "yes" ] ; then
		ltsp image /srv/ltsp/x2go-"$thin_type"-"$arch"
	fi

	# Prepare X2Go thinclient kernel image for PXE booting.
	ltsp kernel "x2go-${thin_type}-${arch}"

fi

# Generate image for diskless workstation.
if [ "yes" == "$diskless_workstation"  ] ; then

	if echo "$PROFILE" | grep -Eq 'Main-Server' ; then
		echo "ERROR: Creating diskless workstations from host OS is not supported in the Main-Server"
		exit 1
	fi

	# Temporary workaround needed in some cases for configuring the resolver inside
	# the SquashFS image.
	rm -f /etc/resolv.conf
	echo "nameserver $dns_server" > /etc/resolv.conf
	echo "search intern" >> /etc/resolv.conf
	# Temporary workaround needed to turn DLW images into machines of profile type 'Workstation'
	sed -i /etc/debian-edu/config -e "s/^PROFILE=.*/PROFILE=\"Workstation\"/g"
	# Create SquashFS image.
	ltsp image /,,/boot,subdir=boot,,/usr,subdir=usr,,/var,subdir=var
	# Revert resolver workaround from above.
	rm -f /etc/resolv.conf
	ln -s /run/resolvconf/resolv.conf /etc/resolv.conf
	# Revert temporary change to PROFILE in /etc/debian-edu/config
	sed -i /etc/debian-edu/config -e "s/^PROFILE=.*/PROFILE=\"${PROFILE}\"/g"

fi

# Generate chroot and SquashFS image (optional) for diskless workstation.
if [ "yes" == "$dlw"  ] ; then

	if [ -d "/srv/ltsp/dlw" ]; then
		echo "ERROR: Diskless Workstation chroot '/srv/ltsp/dlw' already exists."
		echo "       Remove the chroot and re-run this script."
		exit 1
	fi

	# The chroot is basically a workstation installation.
	# Petter Reinholdtsen's debian-edu-bless script is used to achieve it.
	mkdir -p /srv/ltsp/dlw
	chmod 755 /srv/ltsp/dlw
	# Install base system
	debootstrap --arch="$arch" \
	            --no-check-gpg \
	            --variant=minbase \
	            --include=locales,console-setup,linux-image-"${kernel_arch}" \
	            "${dist}" /srv/ltsp/dlw "${mirror}"
	# Unset temporary directory variables to avoid problems when directory
	# is missing inside the chroot. https://bugs.debian.org/765443
	unset TMPDIR TEMP TEMPDIR TMP
	chroot /srv/ltsp/dlw/ apt-get clean

	# Care for same locale and keyboard settings in the chroot, also useful to quiet down Perl.
	cp /etc/locale.gen /srv/ltsp/dlw/etc/
	cp /etc/default/locale /srv/ltsp/dlw/etc/default
	chroot /srv/ltsp/dlw locale-gen
	cp /etc/default/keyboard /srv/ltsp/dlw/etc/default
	cp /etc/default/console-setup /srv/ltsp/dlw/etc/default
	chroot /srv/ltsp/dlw setupcon -k

	# Set timezone properly.
	timezone="$(get_timezone)"
	echo "${timezone}" > "/srv/ltsp/dlw/etc/timezone"
	chroot /srv/ltsp/dlw ln -fs "/usr/share/zoneinfo/${timezone}" "/etc/localtime"
	chroot /srv/ltsp/dlw dpkg-reconfigure -f noninteractive tzdata

	# Care for complete sources list (security, also nonfree -- in case firmware is needed).
	if [ -e /srv/ltsp/dlw/usr/share/doc/apt/examples/sources.list ] ; then
		# Up to bookworm
		chroot /srv/ltsp/dlw/ sh -c "cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list.d/full.list"
	else
		# Since trixie
		chroot /srv/ltsp/dlw/ sh -c "cp /usr/share/doc/apt/examples/debian.sources /etc/apt/sources.list.d/debian_full.sources"
	fi
	mount /dev/pts -t devpts /srv/ltsp/dlw/dev/pts
	mount proc -t proc /srv/ltsp/dlw/proc
	if [ "true" == "$BD_ISO" ] ; then
		mkdir -p /srv/ltsp/dlw/media/cdrom
		mount /media/cdrom /srv/ltsp/dlw/media/cdrom -o bind
		echo "deb [trusted=yes] $mirror $dist main" > /srv/ltsp/dlw/etc/apt/sources.list
	fi

	# Care for special files.
	mkdir -p /srv/ltsp/dlw/tmp/user/0/
	cp /usr/share/debian-edu-config/tools/debian-edu-bless /srv/ltsp/dlw/sbin

	chroot /srv/ltsp/dlw/ apt-get update
	chroot /srv/ltsp/dlw/ apt-get -q -y upgrade

	# Install the ltsp package. Most of LTSP's client code is provided by the
	# ltsp.img initrd injected into the LTSP client via kernel cmdline.
	# However, for generating the kernel's initrd from within the DLW chroot,
	# we need /usr/share/initramfs-tools/hooks/ltsp-next.
	#
	# We could copy the host's version into the DLW chroot, but who knows what
	# changes might break this process in the future (either on host or in
	# LTSP chroot). Better use ltsp from the LTSP client's Debian version.
	chroot /srv/ltsp/dlw apt-get install -y -q ltsp

	# Turn system into a Debian Edu workstation.
	chroot /srv/ltsp/dlw sh -c "PROFILE=Workstation DESKTOP=$desktop /sbin/debian-edu-bless"
	mkdir -p /srv/ltsp/dlw/skole
	chmod 755 /srv/ltsp/dlw/skole
	rm -f /srv/ltsp/dlw/etc/resolv.conf
	# Next line needed for kerberized NFS home directory access.
	cp /etc/krb5.keytab /srv/ltsp/dlw/etc/
	# Care for Debian Edu certificates.
	cp /etc/ssl/certs/debian-edu-server.crt /srv/ltsp/dlw/etc/ssl/certs/
	cp /usr/local/share/ca-certificates/*.crt /srv/ltsp/dlw/usr/local/share/ca-certificates/
	chroot /srv/ltsp/dlw update-ca-certificates
	# Adjust Sitesummary configuration
	cp -f /etc/sitesummary/site /srv/ltsp/dlw/etc/sitesummary/
	cp -f /etc/sitesummary/sitegroup /srv/ltsp/dlw/etc/sitesummary/
	echo ltsp-client > /srv/ltsp/dlw/etc/sitesummary/hostclass

	# Care for temporary mounts.
	umount /srv/ltsp/dlw/dev/pts
	umount /srv/ltsp/dlw/proc
	if [ "true" == "$BD_ISO" ] ; then
		umount /srv/ltsp/dlw/media/cdrom
	fi

	# Mark the chroot as successfully created.
	touch /srv/ltsp/dlw/CREATED_SUCCESSFULLY_$(date +%Y%m%d-%H%M)

	# Create optional SquashFS image file.
	if [ "yes" == "$img"  ] ; then
		ltsp image dlw
	fi

	# Prepare DLW kernel image for PXE booting.
	ltsp kernel dlw

fi

# Unmount the BD image, if it was mounted at the start of this script.
if [ "yes" == "$bd_iso_was_mounted" ] ; then
	umount /media/cdrom
fi

# Get rid of additional excludes just in case they exist (main server).
cat /dev/null > /etc/ltsp/image-local.excludes

# Use legacy network interfaces names.
if ! grep -q net.ifnames /etc/default/grub ; then
    sed -i 's/quiet/net.ifnames=0 quiet/' /etc/default/grub
    update-grub
fi

# Tweak network interfaces file to match the use case.
if echo "$PROFILE" | grep -Eq 'Main-Server' ; then
	cat <<EOF > /etc/network/interfaces
auto eth0 eth1
iface eth0 inet static
	address 10.0.2.2
	gateway 10.0.0.1
	dns-search intern
	dns-nameserver 127.0.0.1

iface eth1 inet static
	address $ETH1_IP
EOF
	else
	cat <<EOF > /etc/network/interfaces
auto eth0 eth1
iface eth0 inet static
	address $ETH0_IP
	gateway 10.0.0.1
	dns-search intern
	dns-nameservers 10.0.2.2

iface eth1 inet static
	address $ETH1_IP
EOF
fi

# Next line is needed upon upgrade from LTSP5.
sed -i '/ltsp/d' /etc/exports

# Adjust NFS exports for separate LTSP servers.
if ! echo "$PROFILE" | grep -Eq 'Main-Server' ; then
	rm -f /etc/exports.d/edu.exports
fi

# Configure NFS
ltsp nfs

# Restart nfs-kernel-server and give feedback about exports if running this
# script outside of the Debian Installer environment.
if [ ! -x /sbin/start-stop-daemon.REAL ] ; then
	exportfs -rav
fi


# Debian Edu diskless machines use different ltsp.img files, so create them separately.
debian-edu-ltsp-initrd

# Prepare the best ltsp.ipxe config for this server that we can...
debian-edu-ltsp-ipxe
