trap "err_reboot" ERR
+# NOTE: we nowadays get exec'd by the initrd's PID 1, so we're the new PID 1
+
parse_cmdline() {
- root=
+ start_auto_installer=0
proxdebug=0
+ proxtui=0
+ serial=0
+ # shellcheck disable=SC2013 # per word splitting is wanted here
for par in $(cat /proc/cmdline); do
- case $par in
- root=*)
- root=${par#root=}
- ;;
- proxdebug)
- proxdebug=1
- ;;
- esac
+ case $par in
+ proxdebug|proxmox-debug)
+ proxdebug=1
+ ;;
+ proxtui|proxmox-tui-mode)
+ proxtui=1
+ ;;
+ proxauto|proxmox-start-auto-installer)
+ start_auto_installer=1
+ ;;
+ console=ttyS*)
+ serial=1
+ ;;
+ esac
done;
}
/bin/bash
}
+eject_and_reboot() {
+ iso_dev=$(awk '/ iso9660 / {print $1}' /proc/mounts)
+
+ for try in 5 4 3 2 1; do
+ echo "unmounting ISO"
+ if umount -v -a --types iso9660; then
+ break
+ fi
+ if test -n $try; then
+ echo "unmount failed - trying again in 5 seconds"
+ sleep 5
+ fi
+ done
+
+ if [ -n "$iso_dev" ]; then
+ eject "$iso_dev" || true # cannot really work currently, don't care
+ fi
+
+ umount -l -n /dev
+
+ echo "rebooting - please remove the ISO boot media"
+ sleep 3
+ reboot -nf
+ sleep 5
+ echo "trigger reset system request"
+ # we do not expect the reboot above to fail, so rather to avoid kpanic when pid 1 exits
+ echo b > /proc/sysrq-trigger
+ sleep 100
+}
+
real_reboot() {
trap - ERR
- /etc/init.d/networking stop
+ if [[ -x /etc/init.d/networking ]]; then
+ /etc/init.d/networking stop
+ fi
# stop udev (release file handles)
/etc/init.d/udev stop
- echo -n "Deactivating swap..."
- swap=$(grep /dev /proc/swaps);
+ swap=$(awk '/^\/dev\// { print $1 }' /proc/swaps);
if [ -n "$swap" ]; then
- set $swap
- swapoff $1
+ echo -n "Deactivating swap..."
+ swapoff "$swap"
+ echo "done."
fi
- echo "done."
+
+ # just to be sure
+ sync
umount -l -n /target >/dev/null 2>&1
- umount -l -n /dev
+ umount -l -n /dev/pts
+ umount -l -n /dev/shm
umount -l -n /run
[ -d /sys/firmware/efi/efivars ] && umount -l -n /sys/firmware/efi/efivars
- umount -l -n /sys
- umount -l -n /proc
- exit 0
+ # do not unmount proc and sys for now, at least /proc is still required to trigger the actual
+ # reboot, and both are virtual FS only anyway
+
+ echo "Terminate all remaining processes"
+ kill -s TERM -1 # TERMinate all but current init (our self) PID 1
+ sleep 2
+ echo "Kill any remaining processes"
+ kill -s KILL -1 # KILL all but current init (our self) PID 1
+ sleep 0.5
+
+ eject_and_reboot
+
+ exit 0 # shouldn't be reached, kernel will panic in that case
}
+# reachable through the ERR trap
+# shellcheck disable=SC2317
err_reboot() {
- echo "\nInstallation aborted - unable to continue (type exit or CTRL-D to reboot)"
+ printf "\nInstallation aborted - unable to continue (type exit or CTRL-D to reboot)\n"
debugsh || true
real_reboot
}
-echo "Starting Proxmox installation"
+# NOTE: dbus must be launched before this, else iwd cannot work
+# FIXME: very crude, still needs to actually copy over any iwd config to target
+handle_wireless() {
+ wireless_found=
+ for iface in /sys/class/net/*; do
+ if [ -d "$iface/wireless" ]; then
+ wireless_found=1
+ fi
+ done
+ if [ -z $wireless_found ]; then
+ return;
+ fi
+
+ if [ -x /usr/libexec/iwd ]; then
+ echo "wireless device(s) found, starting iwd; use 'iwctl' to manage connections (experimental)"
+ /usr/libexec/iwd &
+ else
+ echo "wireless device found but iwd not available, ignoring"
+ fi
+}
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin
-# ensure udev isn't snippy and ignores our request
+echo "Starting Proxmox installation"
+
+# ensure udev doesn't ignores our request; FIXME: not required anymore, as we use switch_root now
export SYSTEMD_IGNORE_CHROOT=1
mount -n -t proc proc /proc
mount -n -t efivarfs efivarfs /sys/firmware/efi/efivars
fi
mount -n -t tmpfs tmpfs /run
+mkdir -p /run/proxmox-installer
parse_cmdline
mkdir -p /dev/pts
mount -vt devpts devpts /dev/pts -o gid=5,mode=620
+# shellcheck disable=SC2207
+console_dim=($(IFS=' ' stty size)) # [height, width]
+DPI=96
+if (("${console_dim[0]}" > 100)) && (("${console_dim[1]}" > 400)); then
+ # heuristic only, high resolution can still mean normal/low DPI if it's a really big screen
+ # FIXME: use `edid-decode` as it can contain physical dimensions to calculate actual dpi?
+ echo "detected huge console, setting bigger font/dpi"
+ DPI=192
+ export GDK_SCALE=2
+ setfont /usr/share/consolefonts/Uni2-Terminus32x16.psf.gz
+fi
+
+# set the hostname
+hostname proxmox
+
+if command -v dbus-daemon; then
+ echo "starting D-Bus daemon"
+ mkdir /run/dbus
+ dbus-daemon --system --syslog-only
+
+ if [ $proxdebug -ne 0 ]; then # FIXME: better intergration, e.g., use iwgtk?
+ handle_wireless # no-op if not wireless dev is found
+ fi
+fi
+
+# we use a trimmed down debootstrap so make busybox tools available to compensate that
+busybox --install -s || true
+
+setupcon || echo "setupcon failed, TUI rendering might be garbled - $?"
+
+if [ "$serial" -ne 0 ]; then
+ echo "Setting terminal size to 80x24 for serial install"
+ stty columns 80 rows 24
+fi
+
if [ $proxdebug -ne 0 ]; then
/sbin/agetty -o '-p -- \\u' --noclear tty9 &
- echo "Dropping in debug shell inside chroot before starting installation"
- echo "type exit or CTRL-D to start installation wizard"
+ printf "\nDropping in debug shell before starting installation\n"
+ echo "type 'exit' or press CTRL + D to continue and start the installation wizard"
debugsh || true
fi
-# set the hostname
-hostname proxmox
+# add custom DHCP options for auto installer
+if [ $start_auto_installer -ne 0 ]; then
+ echo "Preparing DHCP as potential source to get location of automatic-installation answer file"
+ cat >> /etc/dhcp/dhclient.conf <<EOF
+option proxmox-auto-installer-manifest-url code 250 = text;
+option proxmox-auto-installer-cert-fingerprint code 251 = text;
+also request proxmox-auto-installer-manifest-url, proxmox-auto-installer-cert-fingerprint;
+EOF
+fi
# try to get ip config with dhcp
echo -n "Attempting to get DHCP leases... "
dhclient -v
echo "done"
-echo -n "Starting chrony for opportunistic time-sync... "
-chronyd || echo "starting chrony failed"
+echo "Starting chrony for opportunistic time-sync... "
+chronyd || echo "starting chrony failed ($?)"
echo "Starting a root shell on tty3."
setsid /sbin/agetty -a root --noclear tty3 &
-xinit -- -dpi 96 >/dev/tty2 2>&1
+/usr/bin/proxmox-low-level-installer dump-env
+
+if [ $proxtui -ne 0 ]; then
+ echo "Starting the TUI installer"
+ /usr/bin/proxmox-tui-installer 2>/dev/tty2
+elif [ $start_auto_installer -ne 0 ]; then
+ echo "Caching device info from udev"
+ /usr/bin/proxmox-low-level-installer dump-udev
+
+ if [ -f /cdrom/auto-installer-mode.toml ]; then
+ echo "Fetching answers for automatic installation"
+ /usr/bin/proxmox-fetch-answer >/run/automatic-installer-answers
+ else
+ printf "\nAutomatic installation selected but no config for fetching the answer file found!\n"
+ echo "Starting debug shell, to fetch the answer file manually use:"
+ echo " proxmox-fetch-answer MODE >/run/automatic-installer-answers"
+ echo "and enter 'exit' or press 'CTRL' + 'D' when finished."
+ debugsh || true
+ fi
+ echo "Starting automatic installation"
+ /usr/bin/proxmox-auto-installer </run/automatic-installer-answers
+else
+ echo "Starting the installer GUI - see tty2 (CTRL+ALT+F2) for any errors..."
+ xinit -- -dpi "$DPI" -s 0 >/dev/tty2 2>&1
+fi
# just to be sure everything is on disk
sync
if [ $proxdebug -ne 0 ]; then
- echo "Debug shell after installation exited (type exit or CTRL-D to reboot)"
+ printf "\nDebug shell after installation exited (type exit or CTRL-D to reboot)\n"
debugsh || true
fi
real_reboot
# never reached
+# shellcheck disable=SC2317
exit 0