11#! /bin/bash
22set -euo pipefail
33
4- # Cleanup function to ensure mounted filesystems are unmounted
5- cleanup () {
6- local exit_code=$?
7- if [ -n " ${MOUNTPOINT:- } " ] && [ -d " $MOUNTPOINT " ]; then
8- if mountpoint -q " $MOUNTPOINT " 2> /dev/null; then
9- echo " Unmounting $MOUNTPOINT ..."
10- umount " $MOUNTPOINT " 2> /dev/null || true
11- fi
12- rmdir " $MOUNTPOINT " 2> /dev/null || true
13- fi
14- if [ $exit_code -ne 0 ]; then
15- echo " Script failed with exit code $exit_code " >&2
16- fi
17- exit $exit_code
18- }
19-
20- # Set up trap to call cleanup on exit
21- trap cleanup EXIT INT TERM
4+ # Install script using nbc (SNOW bootc installer)
5+ # Outputs JSON Lines for streaming progress to the installer GUI
226
237if [ -z " $1 " ] || [ -z " $2 " ] || [ -z " $3 " ]; then
24- echo " usage:"
25- echo " install-to-disk <image> <filesystem> <device> [fde]"
8+ echo ' {"type":"error","message":"Missing arguments. Usage: install-to-disk <image> <filesystem> <device> [fde]"}'
269 exit 5
2710fi
2811
2912if ! [ " $UID " == " 0" ]; then
30- echo " this script must be run with super user privileges"
13+ echo ' {"type":"error","message":"This script must be run with super user privileges"} '
3114 exit 6
3215fi
3316
34-
3517if ! [ -b " $3 " ]; then
36- echo " device ' $3 ' is not a valid block device"
18+ echo ' {"type":"error","message":"Device ' " ' $3 '" ' is not a valid block device"} '
3719 exit 9
3820fi
3921
40- # Parse FDE parameters
22+ IMAGE=" $1 "
23+ FILESYSTEM=" $2 "
24+ DEVICE=" $3 "
4125FDE=" ${4:- false} "
4226
4327# Validate FDE parameter
4428if [ " $FDE " != " true" ] && [ " $FDE " != " false" ]; then
45- echo " fde parameter must be 'true' or 'false', got: $FDE "
29+ echo ' {"type":"error","message":"FDE parameter must be ' " ' true'" ' or ' " ' false'" ' , got: ' " $FDE " ' "} '
4630 exit 7
4731fi
4832
49- BLOCKSETUP=" direct"
50- if [ " $FDE " == " true" ]; then
51- BLOCKSETUP=" tpm2-luks"
52- fi
53-
54- # if FDE is requested, verify that there is a tpm2 device available
55- if [ " $FDE " == " true" ]; then
56- if ! [ -e /dev/tpm0 ] && ! [ -e /dev/tpmrm0 ]; then
57- echo " FDE with tpm2-luks requested, but no TPM2 device found"
58- exit 8
59- fi
60- fi
61-
62- # Check that bootc is available
63- if ! command -v bootc & > /dev/null; then
64- echo " bootc command not found, cannot proceed with installation"
33+ # Check that nbc is available
34+ if ! command -v nbc & > /dev/null; then
35+ echo ' {"type":"error","message":"nbc command not found, cannot proceed with installation"}'
6536 exit 14
6637fi
6738
68- echo " Starting bootc installation to $3 ..."
69- if ! RUST_LOG=debug bootc \
70- install \
71- to-disk \
72- --composefs-backend \
73- --block-setup " $BLOCKSETUP " \
74- --filesystem " $2 " \
75- --source-imgref docker://" $1 " \
76- --target-imgref " $1 " \
77- --wipe \
78- --bootloader systemd \
79- --karg " quiet" \
80- --karg " splash" \
81- " $3 " ; then
82- echo " bootc installation failed"
83- exit 15
84- fi
85- echo " bootc installation completed successfully"
86-
87- # HACK: fix secure boot in bootc
88- # now that the install is done, we can fix the efi binaries
89- # to support secure boot.
90- # This is a workaround for the fact that the bootc installs
91- # systemd-boot only. What we require is the signed-shim as
92- # the first efi binary, which then loads systemd-boot.
93- # shim is hard-coded to load grub, so we'll "fix" that by copying the
94- # systemd-boot binaries into the right place with grub's name.
95- # HACK ALERT! We're copying the efi binaries from the installer image
96- # to the target image. This is not ideal, but it works for now.
97-
98- # Mount the EFI partition from the target device ($3)
99- # EFI partition is the second partition, so we use partprobe
100- # to ensure the kernel sees it
101- echo " Probing partitions on $3 ..."
102- if ! partprobe " $3 " ; then
103- echo " Failed to probe partitions on $3 "
104- exit 16
105- fi
106-
107- # Give the kernel a moment to recognize the new partitions
108- sleep 2
109-
110- DEVICE=" $3 "
111-
112- # adjust partition names for devices that require 'p' before partition number
113- if [[ " $DEVICE " == * " nvme" * || " $DEVICE " == * " mmcblk" * || " $DEVICE " == * " loop" * ]]; then
114- DEVICE=" ${DEVICE} p"
115- fi
116-
117- EFI_PARTITION=" ${DEVICE} 2"
118-
119- # Verify the EFI partition exists
120- if ! [ -b " $EFI_PARTITION " ]; then
121- echo " EFI partition $EFI_PARTITION does not exist or is not a block device"
122- exit 17
123- fi
124-
125- echo " Creating temporary mount point..."
126- MOUNTPOINT=$( mktemp -d)
127- if [ ! -d " $MOUNTPOINT " ]; then
128- echo " Failed to create temporary mount point"
129- exit 18
130- fi
39+ # Build nbc install command with --json for streaming output
40+ NBC_ARGS=(
41+ " install"
42+ " --image" " $IMAGE "
43+ " --device" " $DEVICE "
44+ " --filesystem" " $FILESYSTEM "
45+ " --json"
46+ )
13147
132- echo " Mounting EFI partition $EFI_PARTITION to $MOUNTPOINT ..."
133- if ! mount " $EFI_PARTITION " " $MOUNTPOINT " ; then
134- echo " Failed to mount EFI partition $EFI_PARTITION "
135- rmdir " $MOUNTPOINT " 2> /dev/null || true
136- exit 19
137- fi
138-
139-
140- if [ ! -d " $MOUNTPOINT /EFI/BOOT" ]; then
141- echo " Creating $MOUNTPOINT /EFI/BOOT directory..."
142- if ! mkdir -p " $MOUNTPOINT /EFI/BOOT" ; then
143- echo " Failed to create EFI/BOOT directory"
144- exit 20
145- fi
146- fi
147-
148- # make sure the source files exists
149- echo " Verifying source EFI files..."
150- if [ ! -f /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed ]; then
151- echo " systemd-bootx64.efi.signed not found, cannot copy to EFI partition"
152- exit 10
153- fi
154- if [ ! -f /usr/lib/shim/shimx64.efi.signed ]; then
155- echo " shimx64.efi.signed not found, cannot copy to EFI partition"
156- exit 11
157- fi
158- if [ ! -f /usr/lib/shim/fbx64.efi.signed ]; then
159- echo " fbx64.efi.signed not found, cannot copy to EFI partition"
160- exit 12
161- fi
162- if [ ! -f /usr/lib/shim/mmx64.efi.signed ]; then
163- echo " mmx64.efi.signed not found, cannot copy to EFI partition"
164- exit 13
165- fi
166-
167- # replicate a debian secureboot efi setup
168- echo " Creating EFI/snow directory..."
169- if ! mkdir -p " $MOUNTPOINT /EFI/snow" ; then
170- echo " Failed to create EFI/snow directory"
171- exit 21
172- fi
173-
174- echo " Copying secure boot EFI binaries..."
175- if ! cp /usr/lib/shim/shimx64.efi.signed " $MOUNTPOINT /EFI/snow/shimx64.efi" ; then
176- echo " Failed to copy shimx64.efi"
177- exit 22
178- fi
179- if ! cp /usr/lib/shim/fbx64.efi.signed " $MOUNTPOINT /EFI/snow/fbx64.efi" ; then
180- echo " Failed to copy fbx64.efi"
181- exit 23
182- fi
183- if ! cp /usr/lib/shim/mmx64.efi.signed " $MOUNTPOINT /EFI/snow/mmx64.efi" ; then
184- echo " Failed to copy mmx64.efi"
185- exit 24
186- fi
187- if ! cp /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed " $MOUNTPOINT /EFI/snow/grubx64.efi" ; then
188- echo " Failed to copy systemd-bootx64.efi as grubx64.efi"
189- exit 25
190- fi
191-
192- # create a new boot entry for shim
193- echo " Creating EFI boot entry..."
194- if command -v efibootmgr & > /dev/null; then
195- if ! efibootmgr --create --disk " $3 " --part 2 --loader ' \EFI\snow\shimx64.efi' --label " Snow Secure Boot" ; then
196- echo " Warning: Failed to create EFI boot entry (continuing anyway)"
197- fi
198- else
199- echo " Warning: efibootmgr not found, skipping boot entry creation"
200- fi
201-
202- # finally uncomment the line in loader.conf that sets the timeout
203- # so that the boot menu appears, allowing the user to edit the kargs
204- # if needed to unlock the disk
205- if [ -f " $MOUNTPOINT /loader/loader.conf" ]; then
206- echo " Configuring bootloader timeout..."
207- if ! sed -i ' s/^#timeout/timeout/' " $MOUNTPOINT /loader/loader.conf" ; then
208- echo " Warning: Failed to update loader.conf (continuing anyway)"
209- fi
210- else
211- echo " Warning: loader.conf not found at $MOUNTPOINT /loader/loader.conf"
212- fi
213-
214- # clean up
215- echo " Unmounting EFI partition..."
216- if ! umount " $MOUNTPOINT " ; then
217- echo " Warning: Failed to unmount $MOUNTPOINT cleanly"
218- # Try force unmount as last resort
219- umount -f " $MOUNTPOINT " 2> /dev/null || true
48+ # Add FDE flag if enabled
49+ if [ " $FDE " == " true" ]; then
50+ NBC_ARGS+=(" --fde" )
22051fi
221- rmdir " $MOUNTPOINT " 2> /dev/null || true
22252
223- echo " Installation completed successfully!"
53+ # Run nbc install with JSON output streaming directly to stdout
54+ # nbc outputs JSON Lines (one JSON object per line) for real-time progress
55+ exec nbc " ${NBC_ARGS[@]} "
0 commit comments