forked from suse-edge/misc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
make_unattended.sh
executable file
·186 lines (155 loc) · 5.63 KB
/
make_unattended.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/env bash
set -euo pipefail
usage(){
cat <<-EOF
Usage: ${0} -i SLE-Micro-SelfInstall.iso [-o tweaked-SLE-Micro-SelfInstall.iso] [-d /dev/sda]
Options:
-i Path to the original SLE Micro iso file
-o (Optional) Path to the tweaked-SLE-Micro-SelfInstall.iso file (./tweaked.iso by default)
-d (Optional) Disk device where SLE Micro will be installed (if not provided, the first one that the installer finds)
EOF
}
die(){
echo "${1}" 1>&2
exit "${2}"
}
while getopts 'i:o:d:h' OPTION; do
case "${OPTION}" in
i)
if [ -f "${OPTARG}" ]; then
INPUTISO="${OPTARG}"
else
die "Input ISO ${OPTARG} not found" 2
fi
;;
o)
if [ -d "$(dirname "${OPTARG}")" ]; then
OUTPUTISO="${OPTARG}"
else
die "Output path $(dirname "${OPTARG}") not found" 2
fi
;;
d)
WRITETO="${OPTARG}"
;;
h)
usage && exit 0
;;
?)
usage && exit 2
;;
esac
done
# INPUTISO is mandatory
if [ -z "${INPUTISO:-}" ]; then
usage && exit 2
fi
# OUTPUTISO defaults to ./tweaked.iso
OUTPUTISO="${OUTPUTISO:-./tweaked.iso}"
# Don't overwrite the destination
if [ -f ${OUTPUTISO} ]; then
usage
die "${OUTPUTISO} already exists" 2
fi
# Root needed by mount
[ "$(id -u)" -eq 0 ] || die "This script must be executed by root" 2
TMPDIR="$(mktemp -d -t make_unattended.XXXXXX)"
# shellcheck disable=SC2064
trap "rm -rf '$TMPDIR'" EXIT
# We mount the ISO and extract the files we need
mkdir -p "${TMPDIR}"/orig
mount "${INPUTISO}" "${TMPDIR}"/orig >/dev/null 2>&1
cp "${TMPDIR}"/orig/boot/x86_64/loader/initrd "${TMPDIR}"/initrd
cp "${TMPDIR}"/orig/boot/grub2/grub.cfg "${TMPDIR}"/grub.cfg-orig
umount "${TMPDIR}"/orig
rmdir "${TMPDIR}"/orig
# First step is to extract the .profile from the second cpio
lsinitrd "${TMPDIR}"/initrd .profile > "${TMPDIR}"/.profile
# Then, append the kiwi_oem flags
echo "kiwi_oemunattended='true'" >> "${TMPDIR}"/.profile
# Specify the destination disk if present
if [ -n "${WRITETO:-}" ]; then
echo "kiwi_oemunattended_id='${WRITETO}'" >> "${TMPDIR}"/.profile
fi
# Finally, we append the .profile into the initrd as:
pushd "${TMPDIR}" > /dev/null
echo ./.profile | cpio --quiet -o -H newc >> "${TMPDIR}"/initrd
popd > /dev/null
#### Old method, keeping this here just for reference
# # We mount the ISO and extract the files we need
# mkdir -p "${TMPDIR}"/{orig,init}
# mount "${INPUTISO}" "${TMPDIR}"/orig >/dev/null 2>&1
# cp "${TMPDIR}"/orig/boot/x86_64/loader/initrd "${TMPDIR}"/init
# cp "${TMPDIR}"/orig/boot/grub2/grub.cfg "${TMPDIR}"/grub.cfg-orig
# umount "${TMPDIR}"/orig
# rmdir "${TMPDIR}"/orig
# chmod 666 "${TMPDIR}"/init/initrd
# # The initrd contained in the iso is basically two cpios concatenated
# # The first one contains the microcode essentially (early cpio):
# # dd if=initrd-orig skip=0 | cpio -it
# # .
# # early_cpio
# # kernel
# # kernel/x86
# # kernel/x86/microcode
# # kernel/x86/microcode/AuthenticAMD.bin
# # kernel/x86/microcode/GenuineIntel.bin
# # 25782 blocks
# # And the second one contains the filesystem compressed with zstd:
# # dd if=./initrd-orig skip=25782 | zstd -dc | cpio -it
# # .
# # .profile
# # bin
# # bin/arping
# # bin/awk
# # bin/basename
# # bin/bash
# # bin/cat
# # bin/chmod
# # bin/chown
# # bin/cp
# # bin/date
# # [... a lot more files ...]
# # The .profile is the one used by kiwi to perform the installation
# # We need to add the kiwi_oemunattended flag to it.
# # There is also the kiwi_oemunattended_id https://github.com/OSInside/kiwi/blob/master/dracut/modules.d/90kiwi-dump/kiwi-dump-image.sh
# # which we can use to specify the device we want to use to write the image into.
# # First step is to extract the initrd filesystem content (the second cpio)
# # pushd and popd commands are needed because lsinitrd doesn't have a way to extract the data than to the current folder
# pushd "${TMPDIR}"/init > /dev/null
# lsinitrd --unpack ./initrd
# popd > /dev/null
# # Then, in order to be able to recreate it, we need to get the first cpio as well
# # We just list the content from it but we need stderr as this is where cpio prints the number of blocks written
# # The usual cat initrd | cpio -it gives a pipefail (because of cat), so use -F instead (which should be better)
# BLOCKS=$(cpio -itF "${TMPDIR}"/init/initrd 2>&1 | awk '/blocks/ { print $1 }')
# dd if="${TMPDIR}"/init/initrd skip=0 count="${BLOCKS}" of="${TMPDIR}"/first >/dev/null 2>&1
# # We have everything we need from initrd
# rm -f "${TMPDIR}"/init/initrd
# # We inject the unattended flag
# echo "kiwi_oemunattended='true'" >> "${TMPDIR}"/init/.profile
# # Specify the destination disk if present
# if [ -n "${WRITETO:-}" ]; then
# echo "kiwi_oemunattended_id='${WRITETO}'" >> "${TMPDIR}"/init/.profile
# fi
# # This will generate the "second" cpio
# pushd "${TMPDIR}"/init/ > /dev/null
# find . | cpio -o -H newc -F "${TMPDIR}"/second 2>/dev/null
# popd > /dev/null
# # We can clean up the extracted one
# rm -Rf "${TMPDIR}"/init
# # Now we need to compress the filesystem
# zstd -q "${TMPDIR}"/second
# rm -f "${TMPDIR}"/second
# # And create the proper initrd by concatenating both
# cat "${TMPDIR}"/first "${TMPDIR}"/second.zst > "${TMPDIR}"/initrd
# rm -f "${TMPDIR}"/first "${TMPDIR}"/second.zst
# This will remove the need to select "install" in grub
echo -e "set timeout=3\nset timeout_style=menu" > "${TMPDIR}"/pre-grub.txt
cat "${TMPDIR}"/pre-grub.txt "${TMPDIR}"/grub.cfg-orig > "${TMPDIR}"/grub.cfg
rm -f "${TMPDIR}"/pre-grub.txt "${TMPDIR}"/grub.cfg-orig
# Finally we create the iso replacing the initrd and grub.cfg files
xorriso -indev "${INPUTISO}" -outdev "${OUTPUTISO}" \
-map "${TMPDIR}"/grub.cfg /boot/grub2/grub.cfg \
-map "${TMPDIR}"/initrd /boot/x86_64/loader/initrd \
-boot_image any replay > /dev/null 2>&1