]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/bash | |
2 | ||
3 | trap "err_reboot" ERR | |
4 | ||
5 | # NOTE: we nowadays get exec'd by the initrd's PID 1, so we're the new PID 1 | |
6 | ||
7 | parse_cmdline() { | |
8 | start_auto_installer=0 | |
9 | proxdebug=0 | |
10 | proxtui=0 | |
11 | serial=0 | |
12 | # shellcheck disable=SC2013 # per word splitting is wanted here | |
13 | for par in $(cat /proc/cmdline); do | |
14 | case $par in | |
15 | proxdebug|proxmox-debug) | |
16 | proxdebug=1 | |
17 | ;; | |
18 | proxtui|proxmox-tui-mode) | |
19 | proxtui=1 | |
20 | ;; | |
21 | proxauto|proxmox-start-auto-installer) | |
22 | start_auto_installer=1 | |
23 | ;; | |
24 | console=ttyS*) | |
25 | serial=1 | |
26 | ;; | |
27 | esac | |
28 | done; | |
29 | } | |
30 | ||
31 | debugsh() { | |
32 | /bin/bash | |
33 | } | |
34 | ||
35 | eject_and_reboot() { | |
36 | iso_dev=$(awk '/ iso9660 / {print $1}' /proc/mounts) | |
37 | ||
38 | for try in 5 4 3 2 1; do | |
39 | echo "unmounting ISO" | |
40 | if umount -v -a --types iso9660; then | |
41 | break | |
42 | fi | |
43 | if test -n $try; then | |
44 | echo "unmount failed - trying again in 5 seconds" | |
45 | sleep 5 | |
46 | fi | |
47 | done | |
48 | ||
49 | if [ -n "$iso_dev" ]; then | |
50 | eject "$iso_dev" || true # cannot really work currently, don't care | |
51 | fi | |
52 | ||
53 | umount -l -n /dev | |
54 | ||
55 | echo "rebooting - please remove the ISO boot media" | |
56 | sleep 3 | |
57 | reboot -nf | |
58 | sleep 5 | |
59 | echo "trigger reset system request" | |
60 | # we do not expect the reboot above to fail, so rather to avoid kpanic when pid 1 exits | |
61 | echo b > /proc/sysrq-trigger | |
62 | sleep 100 | |
63 | } | |
64 | ||
65 | real_reboot() { | |
66 | trap - ERR | |
67 | ||
68 | if [[ -x /etc/init.d/networking ]]; then | |
69 | /etc/init.d/networking stop | |
70 | fi | |
71 | ||
72 | # stop udev (release file handles) | |
73 | /etc/init.d/udev stop | |
74 | ||
75 | swap=$(awk '/^\/dev\// { print $1 }' /proc/swaps); | |
76 | if [ -n "$swap" ]; then | |
77 | echo -n "Deactivating swap..." | |
78 | swapoff "$swap" | |
79 | echo "done." | |
80 | fi | |
81 | ||
82 | # just to be sure | |
83 | sync | |
84 | ||
85 | umount -l -n /target >/dev/null 2>&1 | |
86 | umount -l -n /dev/pts | |
87 | umount -l -n /dev/shm | |
88 | umount -l -n /run | |
89 | [ -d /sys/firmware/efi/efivars ] && umount -l -n /sys/firmware/efi/efivars | |
90 | ||
91 | # do not unmount proc and sys for now, at least /proc is still required to trigger the actual | |
92 | # reboot, and both are virtual FS only anyway | |
93 | ||
94 | echo "Terminate all remaining processes" | |
95 | kill -s TERM -1 # TERMinate all but current init (our self) PID 1 | |
96 | sleep 2 | |
97 | echo "Kill any remaining processes" | |
98 | kill -s KILL -1 # KILL all but current init (our self) PID 1 | |
99 | sleep 0.5 | |
100 | ||
101 | eject_and_reboot | |
102 | ||
103 | exit 0 # shouldn't be reached, kernel will panic in that case | |
104 | } | |
105 | ||
106 | # reachable through the ERR trap | |
107 | # shellcheck disable=SC2317 | |
108 | err_reboot() { | |
109 | printf "\nInstallation aborted - unable to continue (type exit or CTRL-D to reboot)\n" | |
110 | debugsh || true | |
111 | real_reboot | |
112 | } | |
113 | ||
114 | # NOTE: dbus must be launched before this, else iwd cannot work | |
115 | # FIXME: very crude, still needs to actually copy over any iwd config to target | |
116 | handle_wireless() { | |
117 | wireless_found= | |
118 | for iface in /sys/class/net/*; do | |
119 | if [ -d "$iface/wireless" ]; then | |
120 | wireless_found=1 | |
121 | fi | |
122 | done | |
123 | if [ -z $wireless_found ]; then | |
124 | return; | |
125 | fi | |
126 | ||
127 | if [ -x /usr/libexec/iwd ]; then | |
128 | echo "wireless device(s) found, starting iwd; use 'iwctl' to manage connections (experimental)" | |
129 | /usr/libexec/iwd & | |
130 | else | |
131 | echo "wireless device found but iwd not available, ignoring" | |
132 | fi | |
133 | } | |
134 | ||
135 | PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin | |
136 | ||
137 | echo "Starting Proxmox installation" | |
138 | ||
139 | # ensure udev doesn't ignores our request; FIXME: not required anymore, as we use switch_root now | |
140 | export SYSTEMD_IGNORE_CHROOT=1 | |
141 | ||
142 | mount -n -t proc proc /proc | |
143 | mount -n -t sysfs sysfs /sys | |
144 | if [ -d /sys/firmware/efi ]; then | |
145 | echo "EFI boot mode detected, mounting efivars filesystem" | |
146 | mount -n -t efivarfs efivarfs /sys/firmware/efi/efivars | |
147 | fi | |
148 | mount -n -t tmpfs tmpfs /run | |
149 | mkdir -p /run/proxmox-installer | |
150 | ||
151 | parse_cmdline | |
152 | ||
153 | # always load most common input drivers | |
154 | modprobe -q psmouse || true | |
155 | modprobe -q sermouse || true | |
156 | modprobe -q usbhid || true | |
157 | ||
158 | # load device mapper - used by lilo | |
159 | modprobe -q dm_mod || true | |
160 | ||
161 | echo "Installing additional hardware drivers" | |
162 | export RUNLEVEL=S | |
163 | export PREVLEVEL=N | |
164 | /etc/init.d/udev start | |
165 | ||
166 | mkdir -p /dev/shm | |
167 | mount -t tmpfs tmpfs /dev/shm | |
168 | ||
169 | # allow pseudo terminals for debuggin in X | |
170 | mkdir -p /dev/pts | |
171 | mount -vt devpts devpts /dev/pts -o gid=5,mode=620 | |
172 | ||
173 | # shellcheck disable=SC2207 | |
174 | console_dim=($(IFS=' ' stty size)) # [height, width] | |
175 | DPI=96 | |
176 | if (("${console_dim[0]}" > 100)) && (("${console_dim[1]}" > 400)); then | |
177 | # heuristic only, high resolution can still mean normal/low DPI if it's a really big screen | |
178 | # FIXME: use `edid-decode` as it can contain physical dimensions to calculate actual dpi? | |
179 | echo "detected huge console, setting bigger font/dpi" | |
180 | DPI=192 | |
181 | export GDK_SCALE=2 | |
182 | setfont /usr/share/consolefonts/Uni2-Terminus32x16.psf.gz | |
183 | fi | |
184 | ||
185 | # set the hostname | |
186 | hostname proxmox | |
187 | ||
188 | if command -v dbus-daemon; then | |
189 | echo "starting D-Bus daemon" | |
190 | mkdir /run/dbus | |
191 | dbus-daemon --system --syslog-only | |
192 | ||
193 | if [ $proxdebug -ne 0 ]; then # FIXME: better intergration, e.g., use iwgtk? | |
194 | handle_wireless # no-op if not wireless dev is found | |
195 | fi | |
196 | fi | |
197 | ||
198 | # we use a trimmed down debootstrap so make busybox tools available to compensate that | |
199 | busybox --install -s || true | |
200 | ||
201 | setupcon || echo "setupcon failed, TUI rendering might be garbled - $?" | |
202 | ||
203 | if [ "$serial" -ne 0 ]; then | |
204 | echo "Setting terminal size to 80x24 for serial install" | |
205 | stty columns 80 rows 24 | |
206 | fi | |
207 | ||
208 | if [ $proxdebug -ne 0 ]; then | |
209 | /sbin/agetty -o '-p -- \\u' --noclear tty9 & | |
210 | printf "\nDropping in debug shell before starting installation\n" | |
211 | echo "type 'exit' or press CTRL + D to continue and start the installation wizard" | |
212 | debugsh || true | |
213 | fi | |
214 | ||
215 | # add custom DHCP options for auto installer | |
216 | if [ $start_auto_installer -ne 0 ]; then | |
217 | echo "Preparing DHCP as potential source to get location of automatic-installation answer file" | |
218 | cat >> /etc/dhcp/dhclient.conf <<EOF | |
219 | option proxmox-auto-installer-manifest-url code 250 = text; | |
220 | option proxmox-auto-installer-cert-fingerprint code 251 = text; | |
221 | also request proxmox-auto-installer-manifest-url, proxmox-auto-installer-cert-fingerprint; | |
222 | EOF | |
223 | fi | |
224 | ||
225 | # try to get ip config with dhcp | |
226 | echo -n "Attempting to get DHCP leases... " | |
227 | dhclient -v | |
228 | echo "done" | |
229 | ||
230 | echo "Starting chrony for opportunistic time-sync... " | |
231 | chronyd || echo "starting chrony failed ($?)" | |
232 | ||
233 | echo "Starting a root shell on tty3." | |
234 | setsid /sbin/agetty -a root --noclear tty3 & | |
235 | ||
236 | /usr/bin/proxmox-low-level-installer dump-env | |
237 | ||
238 | if [ $proxtui -ne 0 ]; then | |
239 | echo "Starting the TUI installer" | |
240 | /usr/bin/proxmox-tui-installer 2>/dev/tty2 | |
241 | elif [ $start_auto_installer -ne 0 ]; then | |
242 | echo "Caching device info from udev" | |
243 | /usr/bin/proxmox-low-level-installer dump-udev | |
244 | ||
245 | if [ -f /cdrom/auto-installer-mode.toml ]; then | |
246 | echo "Fetching answers for automatic installation" | |
247 | /usr/bin/proxmox-fetch-answer >/run/automatic-installer-answers | |
248 | else | |
249 | printf "\nAutomatic installation selected but no config for fetching the answer file found!\n" | |
250 | echo "Starting debug shell, to fetch the answer file manually use:" | |
251 | echo " proxmox-fetch-answer MODE >/run/automatic-installer-answers" | |
252 | echo "and enter 'exit' or press 'CTRL' + 'D' when finished." | |
253 | debugsh || true | |
254 | fi | |
255 | echo "Starting automatic installation" | |
256 | /usr/bin/proxmox-auto-installer </run/automatic-installer-answers | |
257 | else | |
258 | echo "Starting the installer GUI - see tty2 (CTRL+ALT+F2) for any errors..." | |
259 | xinit -- -dpi "$DPI" -s 0 >/dev/tty2 2>&1 | |
260 | fi | |
261 | ||
262 | # just to be sure everything is on disk | |
263 | sync | |
264 | ||
265 | if [ $proxdebug -ne 0 ]; then | |
266 | printf "\nDebug shell after installation exited (type exit or CTRL-D to reboot)\n" | |
267 | debugsh || true | |
268 | fi | |
269 | ||
270 | echo "Installation done, rebooting... " | |
271 | ||
272 | killall5 -15 | |
273 | ||
274 | real_reboot | |
275 | ||
276 | # never reached | |
277 | # shellcheck disable=SC2317 | |
278 | exit 0 |