Skip to content

Commit 164b0d0

Browse files
committed
feat: better installer
1 parent 1e50073 commit 164b0d0

4 files changed

Lines changed: 102 additions & 14 deletions

File tree

‎installer-factory/create_iso.sh‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
set -ex
44

5+
VOLID="CUOS"
56
WORKDIR="/build"
67
ISO_DIR="${WORKDIR}/iso"
78
OUTPUT_DIR="/output"
@@ -19,14 +20,25 @@ export DOCKER_CONTEXT=default
1920

2021
rm -f "${OUTPUT_DIR}/installer.iso"
2122

22-
cp "${OUTPUT_DIR}/image.img" "${ISO_DIR}"
23+
# compress image using zstd (multi-threaded, level 9) and copy to the ISO dir
24+
# choose level 9 as a balance between compression ratio and build time; adjust as desired
25+
zstd -T0 -9 -c "${OUTPUT_DIR}/image.img" > "${ISO_DIR}/image.img.zst"
26+
27+
if [[ -f "${OUTPUT_DIR}/system.json" ]]; then
28+
cp "${OUTPUT_DIR}/system.json" "${ISO_DIR}"
29+
30+
if jq -e '.installer_auto_overwrite_disk == true' "${OUTPUT_DIR}/system.json" > /dev/null; then
31+
touch "${ISO_DIR}/installer_auto_overwrite_disk.txt"
32+
fi
33+
34+
fi
2335

24-
VOLID="CUOS"
2536
grub-mkrescue \
2637
-o "${OUTPUT_DIR}/installer.iso" \
2738
-V "${VOLID}" \
2839
-iso-level 3 \
2940
-full-iso9660-filenames \
30-
"${ISO_DIR}"
41+
"${ISO_DIR}" || exit 1
3142

43+
echo "ISO creation complete."
3244
echo "Installer written to ${OUTPUT_DIR/\//}/installer.iso"

‎installer-factory/initramfs-tools/hooks/cuos-installer‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ esac
1010

1111
copy_exec /usr/bin/dialog
1212
copy_exec /usr/bin/lsblk
13+
copy_exec /usr/bin/pv
14+
copy_exec /bin/gzip || true
15+
copy_exec /usr/bin/zstd
1316

1417
mkdir -p "$DESTDIR/usr/share/terminfo/l/"
1518
cp -p /usr/share/terminfo/l/linux "$DESTDIR/usr/share/terminfo/l/linux"
16-
17-

‎installer-factory/initramfs-tools/scripts/init-premount/cuos-installer‎

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,44 @@ find_dev() {
106106
echo "$l_iso_dev"
107107
}
108108

109+
extract_image() {
110+
image_path="$1"
111+
target="$2"
112+
# Use a named pipe so dialog reads progress separately from the decompression pipeline.
113+
PROG_FIFO="/tmp/imgprog.$$"
114+
mkfifo "$PROG_FIFO" || return 1
115+
# ensure fifo is removed on function exit
116+
_cleanup() {
117+
rm -f "$PROG_FIFO" 2>/dev/null || true
118+
}
119+
trap _cleanup EXIT
120+
121+
# Start dialog reading progress from the fifo in the background
122+
dialog --gauge "Preparing to extract image, please wait..." 10 70 0 <"$PROG_FIFO" &
123+
DIALOG_PID=$!
124+
125+
# Run the actual decompression/writing pipeline; pv will write numeric progress to stderr,
126+
# which we redirect into the fifo so dialog displays it. Capture the pipeline exit code.
127+
if echo "$image_path" | grep -qE '\.zst$'; then
128+
pv -n "$image_path" 2>"$PROG_FIFO" | zstd -d -c | dd of="/dev/$target" bs=4M conv=notrunc,noerror
129+
RC=$?
130+
elif echo "$image_path" | grep -qE '\.gz$'; then
131+
pv -n "$image_path" 2>"$PROG_FIFO" | gunzip -c | dd of="/dev/$target" bs=4M conv=notrunc,noerror
132+
RC=$?
133+
else
134+
pv -n "$image_path" 2>"$PROG_FIFO" | dd of="/dev/$target" bs=4M conv=notrunc,noerror
135+
RC=$?
136+
fi
137+
138+
# Wait for dialog to finish reading remaining input and exit
139+
wait "$DIALOG_PID" 2>/dev/null || true
140+
141+
# Cleanup and return the pipeline's exit code
142+
trap - EXIT
143+
_cleanup
144+
return "$RC"
145+
}
146+
109147
main() {
110148

111149
iso_dev="$(find_dev)"
@@ -115,9 +153,19 @@ main() {
115153

116154
mount_iso "${iso_dev}" "${mount_point}"
117155

156+
# Lower kernel console loglevel temporarily, so dialogs are not destroyed.
157+
echo 1 > /proc/sys/kernel/printk
158+
118159
# Loop-mount the embedded image (read-only by default)
119-
if [ ! -e "$mount_point$image" ]; then
120-
raise "WARN: $mount_point$image not found"
160+
# Support either uncompressed image or a gzipped image on the ISO
161+
if [ -e "$mount_point$image" ]; then
162+
image_path="$mount_point$image"
163+
elif [ -e "$mount_point${image}.zst" ]; then
164+
image_path="$mount_point${image}.zst"
165+
elif [ -e "$mount_point${image}.gz" ]; then
166+
image_path="$mount_point${image}.gz"
167+
else
168+
raise "WARN: $mount_point$image or ${image}.zst/gz not found"
121169
fi
122170

123171
echo "Running custom installer..."
@@ -127,6 +175,10 @@ main() {
127175
while read -r name type ro size model; do
128176
[ "$type" = "disk" ] || continue
129177
[ "$ro" = "0" ] || continue
178+
# Filter out iso_dev
179+
if [ "/dev/$name" = "$iso_dev" ]; then
180+
continue
181+
fi
130182
safe_model=$(echo "$model" | tr ' ' '_')
131183
label="${size}_${safe_model}"
132184
DISKS="$DISKS $name $label off"
@@ -141,18 +193,22 @@ INNEREOF
141193
if [ "$COUNT" -eq 0 ]; then
142194
raise "No writable disks found"
143195
fi
196+
if [ "$COUNT" -eq 1 ]; then
197+
# select it automatically, it replace off by on
198+
DISKS=$(echo "$DISKS" | sed 's/ off$/ on/')
199+
fi
144200

145-
#if [ "$COUNT" -eq 1 ]; then
146-
# target=$(echo "$DISKS" | awk '{print $1}')
147-
#else
201+
if [ "$COUNT" -eq 1 ] && [ -f "$mount_point/installer_auto_overwrite_disk.txt" ]; then
202+
target=$(echo "$DISKS" | awk '{print $1}')
203+
else
148204
# shellcheck disable=SC2086
149205
target=$(dialog --clear --backtitle "Installer" \
150206
--title "Select Target Disk. The disk will be OVERWRITTEN." \
151207
--no-cancel \
152208
--radiolist "\nUse up/down keys, select with space key and hit enter:\n " 15 70 5 \
153209
$DISKS 3>&1 1>&2 2>&3)
154210
clear
155-
#fi
211+
fi
156212

157213
if [ -z "$target" ]; then
158214
raise "No disk selected"
@@ -161,13 +217,14 @@ INNEREOF
161217
echo "$target"
162218

163219

164-
echo "Writing $image to /dev/$target... (this may take a while)"
165-
if ! dd if="$mount_point$image" of="/dev/$target" bs=4M iflag=fullblock; then
220+
echo "Writing $(basename "$image_path") to /dev/$target... (this may take a while)"
221+
if ! extract_image "$image_path" "$target"; then
166222
raise "Failed writing image to disk"
167223
fi
168224

169225
sync
170-
echo "Done."
226+
dialog --backtitle "Installer" --title "Image sucessfully written to disk" --infobox "\nThe system will reboot now.\n\nEnsure to boot from the selected disk." 10 70
227+
sleep 1
171228
#sh
172229
reboot -f
173230
}

‎system/cuos/init.sh‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ ensure_system_config() {
5151
cat "${SCRIPT_DIR}/system-default.json" >"${CONFIG_PATH}"
5252
fi
5353

54+
# Grab system.json from installer image
55+
mkdir -p "/mnt/installer"
56+
mount -o ro LABEL=CUOS "/mnt/installer/"
57+
if [[ -f "/mnt/installer/system.json" ]]; then
58+
report_info "cuos:init:system-json-installer" "Found system.json on Installer, merging with system.json from system"
59+
if ! NEW_CONFIG="$(jq -s '.[0] + .[1]' \
60+
"${CONFIG_PATH}" "/mnt/installer/system.json")"; then
61+
62+
report_alert "cuos:init:invalid_installer_system_json" "Provided system.json on Installer is invalid. System will reboot in 30sec"
63+
"${SCRIPT_DIR}/dialog-failed.sh" "Provided system.json file on Installer is invalid"
64+
sync
65+
/sbin/reboot
66+
67+
fi
68+
echo "${NEW_CONFIG}" >"${CONFIG_PATH}"
69+
fi
70+
umount "/mnt/installer"
71+
5472
# Grab Cloud Init data from boot dir
5573
umount "/mnt/boot"
5674
if [[ -f "/mnt/boot/user-data" ]]; then

0 commit comments

Comments
 (0)