]>
Commit | Line | Data |
---|---|---|
b3d47d2d SI |
1 | #!/bin/sh |
2 | ||
3 | set -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 | ||
86 | format() { | |
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 | ||
5d733131 | 99 | part_basename=$(basename "$bdev") |
b3d47d2d | 100 | if [ -z "$part_basename" ]; then |
bf10a73e | 101 | if [ "$part" != "$bdev" ]; then |
78c0b9cb AL |
102 | symlinkmsg=" -> '$bdev'" |
103 | fi | |
104 | warn "E: unable to determine basename of '$part'$symlinkmsg" | |
b3d47d2d SI |
105 | exit 1 |
106 | fi | |
107 | ||
108 | part_num=$(cat /sys/block/"$PKNAME"/"$part_basename"/partition) | |
109 | if [ -z "$part_num" ]; then | |
110 | warn "E: unable to determine partition number of '$part'" | |
111 | exit 1 | |
112 | fi | |
113 | ||
114 | if [ -z "$PARTTYPE" ] || [ "$PARTTYPE" != "$ESPTYPE" ]; then | |
115 | echo "Setting partition type of '$part' to '$ESPTYPE'.." | |
116 | sgdisk "-t$part_num:$ESPTYPE" "/dev/$PKNAME" | |
117 | echo "Calling 'udevadm settle'.." | |
118 | udevadm settle --timeout=5 | |
119 | fi | |
120 | ||
121 | echo "Formatting '$part' as vfat.." | |
122 | mkfs.vfat -F 32 "$part" | |
123 | echo "Done." | |
124 | exit 0 | |
125 | } | |
126 | ||
127 | init() { | |
128 | part="$1" | |
129 | ||
130 | _get_partition_info "$part" | |
131 | ||
132 | if [ -z "$PARTTYPE" ] || [ "$PARTTYPE" != "$ESPTYPE" ]; then | |
133 | warn "E: '$part' has wrong partition type (!= $ESPTYPE)." | |
134 | exit 1 | |
135 | fi | |
136 | ||
137 | if [ -z "$FSTYPE" ] || [ "$FSTYPE" != 'vfat' ]; then | |
138 | warn "E: '$part' has wrong filesystem (!= vfat)." | |
139 | exit 1 | |
140 | fi | |
141 | ||
142 | if [ -z "$UUID" ]; then | |
143 | warn "E: '$part' has no UUID set, required for mounting." | |
144 | exit 1 | |
145 | fi | |
146 | ||
147 | esp_mp="/var/tmp/espmounts/$UUID" | |
148 | ||
149 | mkdir -p "$esp_mp" | |
150 | echo "Mounting '$part' on '$esp_mp'." | |
151 | mount -t vfat "$part" "$esp_mp" | |
152 | ||
593001de SI |
153 | if [ -d /sys/firmware/efi ]; then |
154 | echo "Installing systemd-boot.." | |
155 | mkdir -p "$esp_mp/$PMX_ESP_DIR" | |
156 | bootctl --path "$esp_mp" install | |
157 | ||
158 | echo "Configuring systemd-boot.." | |
159 | echo "timeout 3" > "$esp_mp/$PMX_LOADER_CONF.tmp" | |
160 | echo "default proxmox-*" >> "$esp_mp/$PMX_LOADER_CONF.tmp" | |
161 | mv "$esp_mp/$PMX_LOADER_CONF.tmp" "$esp_mp/$PMX_LOADER_CONF" | |
162 | else | |
163 | echo "Installing grub i386-pc target.." | |
72905061 | 164 | grub-install.real \ |
bf10a73e | 165 | --boot-directory "$esp_mp" \ |
593001de SI |
166 | --target i386-pc \ |
167 | --no-floppy \ | |
168 | --bootloader-id='proxmox' \ | |
169 | "/dev/$PKNAME" | |
170 | fi | |
b3d47d2d SI |
171 | echo "Unmounting '$part'." |
172 | umount "$part" | |
173 | ||
174 | echo "Adding '$part' to list of synced ESPs.." | |
2955b2b7 | 175 | _add_entry_to_list_file "$ESP_LIST" "$UUID" |
b3d47d2d SI |
176 | |
177 | echo "Refreshing kernels and initrds.." | |
178 | refresh | |
179 | } | |
180 | ||
0956bd22 FG |
181 | _clean_impl() { |
182 | if [ ! -e "/dev/disk/by-uuid/" ]; then | |
183 | warn 'E: /dev/disk/by-uuid does not exist, aborting!' | |
184 | exit 1 | |
185 | fi | |
bf10a73e | 186 | printf "Checking whether ESP '%s' exists.. " "$curr_uuid" # avoid newline |
0956bd22 FG |
187 | if [ -e "/dev/disk/by-uuid/$curr_uuid" ]; then |
188 | echo "Found!" | |
189 | else | |
190 | echo "Not found!" | |
191 | if [ -z "$dry_run" ] || [ "$dry_run" != '--dry-run' ]; then | |
192 | _remove_entry_from_list_file "$ESP_LIST" "$curr_uuid" | |
193 | fi | |
194 | fi | |
195 | } | |
196 | ||
197 | clean() { | |
198 | dry_run="$1" | |
199 | rm -f "$ESP_LIST".tmp | |
200 | loop_esp_list _clean_impl | |
201 | if [ "$?" -eq 2 ]; then | |
202 | warn "E: $ESP_LIST does not exist." | |
203 | exit 1 | |
204 | fi | |
205 | if [ -e "$ESP_LIST".tmp ]; then | |
206 | mv "$ESP_LIST".tmp "$ESP_LIST" | |
207 | fi | |
33f32d0a SI |
208 | |
209 | echo "Sorting and removing duplicate ESPs.." | |
210 | sort -uo "$ESP_LIST".tmp "$ESP_LIST" | |
211 | mv "$ESP_LIST".tmp "$ESP_LIST" | |
0956bd22 FG |
212 | } |
213 | ||
b3d47d2d | 214 | refresh() { |
27d93251 | 215 | hook=$1 |
b3c98062 | 216 | hookscripts='proxmox-auto-removal zz-proxmox-boot' |
27d93251 FG |
217 | |
218 | if [ -n "$hook" ]; then | |
219 | if echo "$hookscripts" | grep -sqE "(^|[[:space:]]+)$hook([[:space:]]+|$)"; then | |
220 | hookscripts="$hook" | |
221 | else | |
222 | warn "E: '$hook' is not a valid hook script name."; | |
223 | exit 1; | |
224 | fi | |
6e829c9b SR |
225 | fi |
226 | ||
c2c22297 | 227 | for script in $hookscripts; do |
6e829c9b SR |
228 | scriptpath="/etc/kernel/postinst.d/$script" |
229 | if [ -f "$scriptpath" ] && [ -x "$scriptpath" ]; then | |
230 | echo "Running hook script '$script'.." | |
231 | $scriptpath | |
232 | else | |
233 | warn "Hook script '$script' not found or not executable, skipping." | |
234 | fi | |
c2c22297 | 235 | done |
b3d47d2d SI |
236 | } |
237 | ||
427fba71 FG |
238 | add_kernel() { |
239 | ver="$1" | |
240 | ||
241 | if [ -z "$ver" ]; then | |
242 | warn "E: <kernel-version> is mandatory" | |
243 | warn "" | |
244 | exit 1 | |
245 | fi | |
246 | ||
247 | if [ ! -e "/boot/vmlinuz-$ver" ]; then | |
248 | warn "E: no kernel image found in /boot for '$ver', not adding." | |
249 | exit 1 | |
250 | fi | |
251 | _add_entry_to_list_file "$MANUAL_KERNEL_LIST" "$ver" | |
d0519968 | 252 | echo "Added kernel '$ver' to manual kernel list. Use the 'refresh' command to update the ESPs." |
427fba71 FG |
253 | } |
254 | ||
255 | remove_kernel() { | |
256 | ver="$1" | |
257 | ||
258 | if [ -z "$ver" ]; then | |
259 | warn "E: <kernel-version> is mandatory" | |
260 | warn "" | |
261 | exit 1 | |
262 | fi | |
263 | ||
264 | if grep -sqFx "$ver" "$MANUAL_KERNEL_LIST"; then | |
265 | _remove_entry_from_list_file "$MANUAL_KERNEL_LIST" "$ver" | |
d0519968 | 266 | echo "Removed kernel '$ver' from manual kernel list. Use the 'refresh' command to update the ESPs." |
427fba71 FG |
267 | else |
268 | echo "Kernel '$ver' not found in manual kernel list." | |
269 | fi | |
270 | } | |
271 | ||
2d7389fb FG |
272 | list_kernels() { |
273 | boot_kernels="$(boot_kernel_list)" | |
274 | ||
275 | if [ -e "$MANUAL_KERNEL_LIST" ]; then | |
6a3c4ace | 276 | manual_kernels="$(cat "$MANUAL_KERNEL_LIST" || true)" |
4f11dd63 | 277 | boot_kernels="$(echo "$boot_kernels" | grep -Fxv -f "$MANUAL_KERNEL_LIST" || true)" |
2d7389fb FG |
278 | fi |
279 | ||
280 | if [ -z "$manual_kernels" ]; then | |
281 | manual_kernels="None." | |
282 | fi | |
283 | ||
284 | echo "Manually selected kernels:" | |
285 | echo "$manual_kernels" | |
286 | echo "" | |
287 | echo "Automatically selected kernels:" | |
288 | echo "$boot_kernels" | |
83a41a1a SI |
289 | |
290 | pinned_kernel="$(get_first_line "$PINNED_KERNEL_CONF")" | |
d5a182ad | 291 | nextboot_kernel="$(get_first_line "$NEXT_BOOT_PIN")" |
83a41a1a SI |
292 | if [ -n "$pinned_kernel" ]; then |
293 | echo "" | |
294 | echo "Pinned kernel:" | |
295 | echo "${pinned_kernel}" | |
296 | fi | |
d5a182ad SI |
297 | if [ -n "$nextboot_kernel" ]; then |
298 | echo "" | |
299 | echo "Kernel pinned on next-boot:" | |
300 | echo "${nextboot_kernel}" | |
301 | fi | |
2d7389fb FG |
302 | } |
303 | ||
b3d47d2d | 304 | usage() { |
73b0c930 TL |
305 | subcmd="$1" |
306 | if [ -z "$subcmd" ]; then | |
307 | warn "USAGE: $0 <commands> [ARGS]" | |
308 | warn "" | |
309 | fi | |
310 | if [ -z "$subcmd" ] || [ "$subcmd" = "format" ]; then | |
311 | warn " $0 format <partition> [--force]" | |
312 | fi | |
313 | if [ -z "$subcmd" ] || [ "$subcmd" = "init" ]; then | |
314 | warn " $0 init <partition>" | |
315 | fi | |
316 | if [ -z "$subcmd" ] || [ "$subcmd" = "clean" ]; then | |
317 | warn " $0 clean [--dry-run]" | |
318 | fi | |
319 | if [ -z "$subcmd" ] || [ "$subcmd" = "refresh" ]; then | |
320 | warn " $0 refresh [--hook <name>]" | |
321 | fi | |
322 | if [ -z "$subcmd" ] || [ "$subcmd" = "kernel" ]; then | |
323 | warn " $0 kernel <add|remove> <kernel-version>" | |
324 | warn " $0 kernel pin <kernel-version> [--next-boot]" | |
325 | warn " $0 kernel unpin [--next-boot]" | |
326 | warn " $0 kernel list" | |
327 | fi | |
328 | if [ -z "$subcmd" ] || [ "$subcmd" = "status" ]; then | |
329 | warn " $0 status [--quiet]" | |
330 | fi | |
331 | if [ -z "$subcmd" ] || [ "$subcmd" = "help" ]; then | |
332 | warn " $0 help" | |
333 | fi | |
b3d47d2d SI |
334 | } |
335 | ||
336 | help() { | |
337 | echo "USAGE: $0 format <partition> [--force]" | |
338 | echo "" | |
339 | echo " format <partition> as EFI system partition. Use --force to format even if <partition> is currently in use." | |
340 | echo "" | |
341 | echo "USAGE: $0 init <partition>" | |
342 | echo "" | |
343 | echo " initialize EFI system partition at <partition> for automatic synchronization of pve-kernels and their associated initrds." | |
344 | echo "" | |
0956bd22 FG |
345 | echo "USAGE: $0 clean [--dry-run]" |
346 | echo "" | |
347 | echo " remove no longer existing EFI system partition UUIDs from $ESP_LIST. Use --dry-run to only print outdated entries instead of removing them." | |
348 | echo "" | |
6e829c9b | 349 | echo "USAGE: $0 refresh [--hook <name>]" |
b3d47d2d | 350 | echo "" |
6e829c9b | 351 | echo " refresh all configured EFI system partitions. Use --hook to only run the specified hook, omit to run all." |
b3d47d2d | 352 | echo "" |
992c689e | 353 | echo "USAGE: $0 kernel <add|remove> <kernel-version>" |
427fba71 FG |
354 | echo "" |
355 | echo " add/remove pve-kernel with ABI <kernel-version> to list of synced kernels, in addition to automatically selected ones." | |
d0519968 | 356 | echo " NOTE: you need to manually run 'refresh' once you're finished with adding/removing kernels from the list" |
427fba71 | 357 | echo "" |
d5a182ad | 358 | echo "USAGE: $0 kernel pin <kernel-version> [--next-boot]" |
83a41a1a SI |
359 | echo "" |
360 | echo " pin pve-kernel with ABI <kernel-version> as the default entry to be booted." | |
d5a182ad | 361 | echo " with --next-boot sets <kernel-version> only for the next boot." |
83a41a1a SI |
362 | echo " NOTE: you need to manually run 'refresh' once you're finished with pinning kernels" |
363 | echo "" | |
d5a182ad | 364 | echo "USAGE: $0 kernel unpin [--next-boot]" |
83a41a1a | 365 | echo "" |
d5a182ad SI |
366 | echo " unpin removes pinned and next-boot kernel settings." |
367 | echo " with --next-boot only removes the pin for the next boot." | |
83a41a1a | 368 | echo "" |
992c689e | 369 | echo "USAGE: $0 kernel list" |
2d7389fb FG |
370 | echo "" |
371 | echo " list kernel versions currently selected for inclusion on ESPs." | |
372 | echo "" | |
182bfa3a SI |
373 | echo "USAGE: $0 status [--quiet]" |
374 | echo "" | |
375 | echo " Print details about the ESPs configuration. Exits with 0 if any ESP is configured, else with 2." | |
376 | echo "" | |
377 | } | |
378 | ||
379 | _status_detail() { | |
380 | if ! (echo "${curr_uuid}" | grep -qE '[0-9a-fA-F]{4}-[0-9a-fA-F]{4}'); then | |
381 | warn "WARN: ${curr_uuid} read from ${ESP_LIST} does not look like a VFAT-UUID - skipping" | |
382 | return | |
383 | fi | |
384 | ||
385 | path="/dev/disk/by-uuid/$curr_uuid" | |
386 | if [ ! -e "${path}" ]; then | |
387 | warn "WARN: ${path} does not exist - clean '${ESP_LIST}'! - skipping" | |
388 | return | |
389 | fi | |
390 | ||
391 | mountpoint="${MOUNTROOT}/${curr_uuid}" | |
392 | mkdir -p "${mountpoint}" || \ | |
393 | { warn "creation of mountpoint ${mountpoint} failed - skipping"; return; } | |
394 | mount "${path}" "${mountpoint}" || \ | |
395 | { warn "mount of ${path} failed - skipping"; return; } | |
396 | ||
397 | result="" | |
398 | if [ -f "${mountpoint}/$PMX_LOADER_CONF" ]; then | |
182bfa3a SI |
399 | if [ ! -d "${mountpoint}/$PMX_ESP_DIR" ]; then |
400 | warn "${path}/$PMX_ESP_DIR does not exist" | |
401 | fi | |
25c7338c SI |
402 | versions_uefi=$(ls -1 ${mountpoint}/$PMX_ESP_DIR | awk '{printf (NR>1?", ":"") $0}') |
403 | result="uefi (versions: ${versions_uefi})" | |
182bfa3a SI |
404 | fi |
405 | if [ -d "${mountpoint}/grub" ]; then | |
25c7338c | 406 | versions_grub=$(ls -1 ${mountpoint}/vmlinuz-* | awk '{ gsub(/.*\/vmlinuz-/, ""); printf (NR>1?", ":"") $0 }') |
182bfa3a | 407 | if [ -n "$result" ]; then |
25c7338c | 408 | result="${result}, grub (versions: ${versions_grub})" |
182bfa3a | 409 | else |
25c7338c | 410 | result="grub (versions: ${versions_grub})" |
182bfa3a SI |
411 | fi |
412 | fi | |
413 | echo "$curr_uuid is configured with: $result" | |
414 | umount "${mountpoint}" || \ | |
415 | { warn "umount of ${path} failed - failure"; exit 0; } | |
416 | ||
417 | rmdir "${mountpoint}" || true | |
418 | } | |
419 | ||
420 | status() { | |
421 | quiet="$1" | |
422 | if [ ! -e "${ESP_LIST}" ]; then | |
423 | if [ -z "$quiet" ]; then | |
424 | warn "E: $ESP_LIST does not exist." | |
425 | fi | |
426 | exit 2 | |
427 | fi | |
428 | if [ -z "$quiet" ]; then | |
8f256d27 SI |
429 | if [ -d /sys/firmware/efi ]; then |
430 | echo "System currently booted with uefi" | |
431 | else | |
432 | echo "System currently booted with legacy bios" | |
433 | fi | |
182bfa3a SI |
434 | loop_esp_list _status_detail |
435 | fi | |
b3d47d2d SI |
436 | } |
437 | ||
83a41a1a SI |
438 | pin_kernel() { |
439 | ver="$1" | |
d5a182ad | 440 | pin_file="$2" |
83a41a1a SI |
441 | |
442 | if [ -z "$ver" ]; then | |
33cbbb5a | 443 | boot_kernels="$(boot_kernel_list)" |
83a41a1a SI |
444 | warn "E: <kernel-version> is mandatory" |
445 | warn "" | |
33cbbb5a TL |
446 | warn "Possible Proxmox kernel versions are:" |
447 | warn "$boot_kernels" | |
83a41a1a SI |
448 | exit 1 |
449 | fi | |
450 | ||
d5a182ad SI |
451 | if [ -z "$pin_file" ]; then |
452 | pin_file="$PINNED_KERNEL_CONF" | |
453 | fi | |
454 | ||
83a41a1a | 455 | if [ ! -e "/boot/vmlinuz-$ver" ]; then |
33cbbb5a | 456 | boot_kernels="$(boot_kernel_list)" |
83a41a1a | 457 | warn "E: no kernel image found in /boot for '$ver', not setting default." |
33cbbb5a TL |
458 | warn "" |
459 | warn "Possible Proxmox kernel versions are:" | |
460 | warn "$boot_kernels" | |
83a41a1a SI |
461 | exit 1 |
462 | fi | |
4e4a9eb9 TL |
463 | |
464 | if [ -e "$pin_file" ]; then | |
465 | old_pin=$(get_first_line "${pin_file}") | |
466 | if [ "$ver" != "$old_pin" ]; then | |
467 | echo "Overriding previously pinned version '$old_pin' with '$ver'" | |
468 | fi | |
469 | fi | |
d5a182ad | 470 | echo "$ver" > "$pin_file" |
95c28bfa SI |
471 | |
472 | if [ -f "${ESP_LIST}" ]; then | |
473 | echo "Set kernel '$ver' in $pin_file. Use the 'refresh' command to update the ESPs." | |
474 | else | |
475 | next_boot_ver=$(get_first_line "${NEXT_BOOT_PIN}") | |
476 | pin_ver="${next_boot_ver:-$ver}" | |
477 | echo "Setting '$pin_ver' as grub default entry and running update-grub." | |
478 | set_grub_default "$pin_ver" | |
479 | update-grub | |
480 | fi | |
83a41a1a SI |
481 | } |
482 | ||
483 | unpin_kernel() { | |
d5a182ad | 484 | rm -f "$NEXT_BOOT_PIN" |
95c28bfa | 485 | echo "Removed $NEXT_BOOT_PIN." |
d5a182ad SI |
486 | if [ -z "$1" ]; then |
487 | rm -f "$PINNED_KERNEL_CONF" | |
95c28bfa SI |
488 | echo "Removed $PINNED_KERNEL_CONF." |
489 | fi | |
490 | ||
491 | if [ -f "${ESP_LIST}" ]; then | |
492 | echo "Use the 'refresh' command to update the ESPs." | |
493 | else | |
494 | echo "Reset default grub entry and running update-grub." | |
495 | pinned_kernel=$(get_first_line "${PINNED_KERNEL_CONF}") | |
496 | set_grub_default "$pinned_kernel" | |
497 | update-grub | |
d5a182ad | 498 | fi |
83a41a1a SI |
499 | } |
500 | ||
b3d47d2d SI |
501 | if [ -z "$1" ]; then |
502 | usage | |
503 | exit 0 | |
504 | fi | |
505 | ||
506 | case "$1" in | |
507 | 'format') | |
508 | shift | |
509 | if [ -z "$1" ]; then | |
510 | warn "E: <partition> is mandatory." | |
511 | warn "" | |
73b0c930 | 512 | usage "format" |
b3d47d2d SI |
513 | exit 1 |
514 | fi | |
515 | format "$@" | |
516 | exit 0 | |
517 | ;; | |
518 | 'init') | |
420039cd | 519 | reexec_in_mountns "$@" |
b3d47d2d SI |
520 | shift |
521 | if [ -z "$1" ]; then | |
522 | warn "E: <partition> is mandatory." | |
523 | warn "" | |
73b0c930 | 524 | usage "init" |
b3d47d2d SI |
525 | exit 1 |
526 | fi | |
527 | init "$@" | |
528 | exit 0 | |
529 | ;; | |
0956bd22 FG |
530 | 'clean') |
531 | shift | |
532 | clean "$@" | |
533 | exit 0 | |
534 | ;; | |
b3d47d2d SI |
535 | 'refresh') |
536 | shift | |
6e829c9b SR |
537 | if [ "$#" -eq 0 ]; then |
538 | refresh | |
539 | elif [ "$#" -eq 2 ] && [ "$1" = "--hook" ]; then | |
540 | refresh "$2" | |
541 | else | |
73b0c930 | 542 | usage "refresh" |
6e829c9b SR |
543 | exit 1 |
544 | fi | |
b3d47d2d SI |
545 | exit 0 |
546 | ;; | |
992c689e | 547 | 'kernel'|'kernels') |
427fba71 FG |
548 | shift |
549 | if [ -z "$1" ]; then | |
992c689e | 550 | warn "E: subcommand is mandatory for 'kernel'." |
427fba71 | 551 | warn "" |
73b0c930 | 552 | usage "kernel" |
427fba71 FG |
553 | exit 1 |
554 | fi | |
555 | cmd="$1" | |
556 | case "$cmd" in | |
557 | 'add') | |
558 | add_kernel "$2" | |
559 | exit 0 | |
560 | ;; | |
561 | 'remove') | |
562 | remove_kernel "$2" | |
563 | exit 0 | |
564 | ;; | |
2d7389fb FG |
565 | 'list') |
566 | list_kernels | |
567 | exit 0 | |
568 | ;; | |
83a41a1a | 569 | 'pin') |
d5a182ad SI |
570 | if [ "$#" -eq 3 ] && [ "$3" = '--next-boot' ]; then |
571 | pin_kernel "$2" "${NEXT_BOOT_PIN}" | |
572 | elif [ "$#" -eq 2 ]; then | |
573 | pin_kernel "$2" | |
574 | else | |
73b0c930 | 575 | usage "kernel" |
d5a182ad SI |
576 | exit 1 |
577 | fi | |
83a41a1a SI |
578 | exit 0 |
579 | ;; | |
580 | 'unpin') | |
d5a182ad SI |
581 | if [ "$#" -eq 2 ] && [ "$2" = '--next-boot' ]; then |
582 | unpin_kernel "$2" | |
583 | elif [ "$#" -eq 1 ]; then | |
584 | unpin_kernel | |
585 | else | |
73b0c930 | 586 | usage "kernel" |
d5a182ad SI |
587 | exit 1 |
588 | fi | |
83a41a1a SI |
589 | exit 0 |
590 | ;; | |
427fba71 | 591 | *) |
992c689e | 592 | warn "E: invalid 'kernel' subcommand '$cmd'." |
427fba71 | 593 | warn "" |
73b0c930 | 594 | usage "kernel" |
427fba71 FG |
595 | exit 1 |
596 | ;; | |
597 | esac | |
598 | ;; | |
182bfa3a SI |
599 | 'status') |
600 | if [ "$#" -eq 2 ] && [ "$2" = '--quiet' ]; then | |
601 | shift | |
602 | status "$1" | |
603 | elif [ "$#" -eq 1 ]; then | |
604 | reexec_in_mountns "$@" | |
605 | shift | |
606 | status | |
607 | else | |
73b0c930 | 608 | usage "status" |
182bfa3a SI |
609 | exit 1 |
610 | fi | |
611 | exit 0 | |
612 | ;; | |
b3d47d2d SI |
613 | 'help') |
614 | shift | |
615 | help | |
616 | exit 0 | |
617 | ;; | |
618 | *) | |
619 | warn "Invalid/unknown command '$1'." | |
620 | warn "" | |
621 | usage | |
622 | exit 1 | |
623 | ;; | |
624 | esac | |
625 | ||
626 | exit 1 |