]> git.proxmox.com Git - pve-kernel-meta.git/blame - bin/pve-efiboot-tool
pve-efiboot-tool: accept also 'kernel' for the 'kernels' command
[pve-kernel-meta.git] / bin / pve-efiboot-tool
CommitLineData
b3d47d2d
SI
1#!/bin/sh
2
3set -e
4
5. /usr/share/pve-kernel-helper/scripts/functions
6
2955b2b7
FG
7_add_entry_to_list_file() {
8 file="$1"
9 entry="$2"
10
11 if [ -e "$file" ]; then
12 cp "$file" "$file.new"
13 fi
14 echo "$entry" >> "$file.new"
15 sort -uo "$file.new" "$file.new"
16 mv "$file.new" "$file"
17}
18
19_remove_entry_from_list_file() {
20 file="$1"
21 entry="$2"
22
23 # guard against removing whole file by accident!
24 if [ -z "$entry" ]; then
25 echo "cannot remove empty entry from '$file'."
26 return
27 fi
28
29 if [ -e "$file" ]; then
30 grep -vFx "$entry" "$file" > "$file.new" || true
31 mv "$file.new" "$file"
32 else
33 echo "'$file' does not exist.."
34 fi
35}
b3d47d2d
SI
36
37_get_partition_info() {
38 if [ ! -e "$1" ]; then
39 warn "E: '$1' does not exist!"
40 exit 1
41 fi
42 bdev=$(realpath "$1")
43 if [ ! -b "$bdev" ]; then
44 warn "E: '$bdev' is not a block device!"
45 exit 1
46 fi
47
48 bdev_info=$( \
49 lsblk \
50 --bytes \
51 --pairs \
52 -o 'UUID,SIZE,FSTYPE,PARTTYPE,PKNAME,MOUNTPOINT' \
53 "$bdev" \
54 )
55 if [ -z "$bdev_info" ]; then
56 warn "E: unable to get information about block device '$1'!"
57 exit 1
58 fi
59
60 count=$(echo "$bdev_info" | grep -c '^')
61 if [ "$count" -ne '1' ]; then
62 echo "$bdev_info"
63 warn "E: block device '$1' has children!"
64 exit 1
65 fi
66
67 echo "$bdev_info"
68 eval "$bdev_info"
69
70 if [ -z "$PKNAME" ]; then
71 warn "E: cannot determine parent device of '$1' - please provide a partition, not a full disk."
72 exit 1
73 fi
74
75 if [ -n "$SIZE" ] && [ "$SIZE" -lt 268435456 ]; then
76 warn "E: '$1' is too small (<256M)."
77 exit 1
78 fi
79
80 if [ -n "$MOUNTPOINT" ]; then
81 warn "E: '$1' is mounted on '$MOUNTPOINT' - exiting."
82 exit 1
83 fi
84}
85
86format() {
87 part="$1"
88 force="$2"
89
90 _get_partition_info "$part"
91
92 if [ -n "$FSTYPE" ]; then
93 if [ -z "$force" ] || [ "$force" != '--force' ]; then
94 warn "E: '$part' contains a filesystem ('$FSTYPE') - exiting (use --force to override)"
95 exit 1
96 fi
97 fi
98
99 part_basename=$(basename "$part")
100 if [ -z "$part_basename" ]; then
101 warn "E: unable to determine basename of '$part'"
102 exit 1
103 fi
104
105 part_num=$(cat /sys/block/"$PKNAME"/"$part_basename"/partition)
106 if [ -z "$part_num" ]; then
107 warn "E: unable to determine partition number of '$part'"
108 exit 1
109 fi
110
111 if [ -z "$PARTTYPE" ] || [ "$PARTTYPE" != "$ESPTYPE" ]; then
112 echo "Setting partition type of '$part' to '$ESPTYPE'.."
113 sgdisk "-t$part_num:$ESPTYPE" "/dev/$PKNAME"
114 echo "Calling 'udevadm settle'.."
115 udevadm settle --timeout=5
116 fi
117
118 echo "Formatting '$part' as vfat.."
119 mkfs.vfat -F 32 "$part"
120 echo "Done."
121 exit 0
122}
123
124init() {
125 part="$1"
126
127 _get_partition_info "$part"
128
129 if [ -z "$PARTTYPE" ] || [ "$PARTTYPE" != "$ESPTYPE" ]; then
130 warn "E: '$part' has wrong partition type (!= $ESPTYPE)."
131 exit 1
132 fi
133
134 if [ -z "$FSTYPE" ] || [ "$FSTYPE" != 'vfat' ]; then
135 warn "E: '$part' has wrong filesystem (!= vfat)."
136 exit 1
137 fi
138
139 if [ -z "$UUID" ]; then
140 warn "E: '$part' has no UUID set, required for mounting."
141 exit 1
142 fi
143
144 esp_mp="/var/tmp/espmounts/$UUID"
145
146 mkdir -p "$esp_mp"
147 echo "Mounting '$part' on '$esp_mp'."
148 mount -t vfat "$part" "$esp_mp"
149
150 echo "Installing systemd-boot.."
151 mkdir -p "$esp_mp/$PMX_ESP_DIR"
152 bootctl --path "$esp_mp" install
153
154 echo "Configuring systemd-boot.."
155 echo "timeout 3" > "$esp_mp/$PMX_LOADER_CONF.tmp"
156 echo "default proxmox-*" >> "$esp_mp/$PMX_LOADER_CONF.tmp"
157 mv "$esp_mp/$PMX_LOADER_CONF.tmp" "$esp_mp/$PMX_LOADER_CONF"
158 echo "Unmounting '$part'."
159 umount "$part"
160
161 echo "Adding '$part' to list of synced ESPs.."
2955b2b7 162 _add_entry_to_list_file "$ESP_LIST" "$UUID"
b3d47d2d
SI
163
164 echo "Refreshing kernels and initrds.."
165 refresh
166}
167
0956bd22
FG
168_clean_impl() {
169 if [ ! -e "/dev/disk/by-uuid/" ]; then
170 warn 'E: /dev/disk/by-uuid does not exist, aborting!'
171 exit 1
172 fi
173 echo -n "Checking whether ESP '$curr_uuid' exists.. "
174 if [ -e "/dev/disk/by-uuid/$curr_uuid" ]; then
175 echo "Found!"
176 else
177 echo "Not found!"
178 if [ -z "$dry_run" ] || [ "$dry_run" != '--dry-run' ]; then
179 _remove_entry_from_list_file "$ESP_LIST" "$curr_uuid"
180 fi
181 fi
182}
183
184clean() {
185 dry_run="$1"
186 rm -f "$ESP_LIST".tmp
187 loop_esp_list _clean_impl
188 if [ "$?" -eq 2 ]; then
189 warn "E: $ESP_LIST does not exist."
190 exit 1
191 fi
192 if [ -e "$ESP_LIST".tmp ]; then
193 mv "$ESP_LIST".tmp "$ESP_LIST"
194 fi
195}
196
b3d47d2d 197refresh() {
c2c22297
FG
198 hookscripts='pve-auto-removal zz-pve-efiboot'
199 for script in $hookscripts; do
200 echo "Running hook script '$script'.."
201 "/etc/kernel/postinst.d/$script"
202 done
b3d47d2d
SI
203}
204
427fba71
FG
205add_kernel() {
206 ver="$1"
207
208 if [ -z "$ver" ]; then
209 warn "E: <kernel-version> is mandatory"
210 warn ""
211 exit 1
212 fi
213
214 if [ ! -e "/boot/vmlinuz-$ver" ]; then
215 warn "E: no kernel image found in /boot for '$ver', not adding."
216 exit 1
217 fi
218 _add_entry_to_list_file "$MANUAL_KERNEL_LIST" "$ver"
d0519968 219 echo "Added kernel '$ver' to manual kernel list. Use the 'refresh' command to update the ESPs."
427fba71
FG
220}
221
222remove_kernel() {
223 ver="$1"
224
225 if [ -z "$ver" ]; then
226 warn "E: <kernel-version> is mandatory"
227 warn ""
228 exit 1
229 fi
230
231 if grep -sqFx "$ver" "$MANUAL_KERNEL_LIST"; then
232 _remove_entry_from_list_file "$MANUAL_KERNEL_LIST" "$ver"
d0519968 233 echo "Removed kernel '$ver' from manual kernel list. Use the 'refresh' command to update the ESPs."
427fba71
FG
234 else
235 echo "Kernel '$ver' not found in manual kernel list."
236 fi
237}
238
2d7389fb
FG
239list_kernels() {
240 boot_kernels="$(boot_kernel_list)"
241
242 if [ -e "$MANUAL_KERNEL_LIST" ]; then
4f11dd63
FG
243 manual_kernels="$(echo "$boot_kernels" | grep -Fx -f "$MANUAL_KERNEL_LIST" || true)"
244 boot_kernels="$(echo "$boot_kernels" | grep -Fxv -f "$MANUAL_KERNEL_LIST" || true)"
2d7389fb
FG
245 fi
246
247 if [ -z "$manual_kernels" ]; then
248 manual_kernels="None."
249 fi
250
251 echo "Manually selected kernels:"
252 echo "$manual_kernels"
253 echo ""
254 echo "Automatically selected kernels:"
255 echo "$boot_kernels"
256}
257
b3d47d2d
SI
258usage() {
259 warn "USAGE: $0 <commands> [ARGS]"
260 warn ""
261 warn " $0 format <partition> [--force]"
262 warn " $0 init <partition>"
0956bd22 263 warn " $0 clean [--dry-run]"
b3d47d2d 264 warn " $0 refresh"
992c689e
TL
265 warn " $0 kernel <add|remove> <kernel-version>"
266 warn " $0 kernel list"
0b99d576 267 warn " $0 help"
b3d47d2d
SI
268}
269
270help() {
271 echo "USAGE: $0 format <partition> [--force]"
272 echo ""
273 echo " format <partition> as EFI system partition. Use --force to format even if <partition> is currently in use."
274 echo ""
275 echo "USAGE: $0 init <partition>"
276 echo ""
277 echo " initialize EFI system partition at <partition> for automatic synchronization of pve-kernels and their associated initrds."
278 echo ""
0956bd22
FG
279 echo "USAGE: $0 clean [--dry-run]"
280 echo ""
281 echo " remove no longer existing EFI system partition UUIDs from $ESP_LIST. Use --dry-run to only print outdated entries instead of removing them."
282 echo ""
b3d47d2d
SI
283 echo "USAGE: $0 refresh"
284 echo ""
285 echo " refresh all configured EFI system partitions."
286 echo ""
992c689e 287 echo "USAGE: $0 kernel <add|remove> <kernel-version>"
427fba71
FG
288 echo ""
289 echo " add/remove pve-kernel with ABI <kernel-version> to list of synced kernels, in addition to automatically selected ones."
d0519968 290 echo " NOTE: you need to manually run 'refresh' once you're finished with adding/removing kernels from the list"
427fba71 291 echo ""
992c689e 292 echo "USAGE: $0 kernel list"
2d7389fb
FG
293 echo ""
294 echo " list kernel versions currently selected for inclusion on ESPs."
295 echo ""
b3d47d2d
SI
296}
297
298if [ -z "$1" ]; then
299 usage
300 exit 0
301fi
302
303case "$1" in
304 'format')
305 shift
306 if [ -z "$1" ]; then
307 warn "E: <partition> is mandatory."
308 warn ""
309 usage
310 exit 1
311 fi
312 format "$@"
313 exit 0
314 ;;
315 'init')
420039cd 316 reexec_in_mountns "$@"
b3d47d2d
SI
317 shift
318 if [ -z "$1" ]; then
319 warn "E: <partition> is mandatory."
320 warn ""
321 usage
322 exit 1
323 fi
324 init "$@"
325 exit 0
326 ;;
0956bd22
FG
327 'clean')
328 shift
329 clean "$@"
330 exit 0
331 ;;
b3d47d2d
SI
332 'refresh')
333 shift
334 refresh
335 exit 0
336 ;;
992c689e 337 'kernel'|'kernels')
427fba71
FG
338 shift
339 if [ -z "$1" ]; then
992c689e 340 warn "E: subcommand is mandatory for 'kernel'."
427fba71
FG
341 warn ""
342 usage
343 exit 1
344 fi
345 cmd="$1"
346 case "$cmd" in
347 'add')
348 add_kernel "$2"
349 exit 0
350 ;;
351 'remove')
352 remove_kernel "$2"
353 exit 0
354 ;;
2d7389fb
FG
355 'list')
356 list_kernels
357 exit 0
358 ;;
427fba71 359 *)
992c689e 360 warn "E: invalid 'kernel' subcommand '$cmd'."
427fba71
FG
361 warn ""
362 usage
363 exit 1
364 ;;
365 esac
366 ;;
b3d47d2d
SI
367 'help')
368 shift
369 help
370 exit 0
371 ;;
372 *)
373 warn "Invalid/unknown command '$1'."
374 warn ""
375 usage
376 exit 1
377 ;;
378esac
379
380exit 1