summaryrefslogtreecommitdiff
path: root/installer/configure-target-grub.sh
blob: a0aa756009671d103dd78f794b495496eb5138c8 (plain)
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
#!/usr/bin/env bash

set -euo pipefail

target_root=${1:?usage: configure-target-grub.sh TARGET_ROOT}

if [[ ! -d "${target_root}/etc" || ! -d "${target_root}/usr" ]]; then
  echo "Invalid target root: ${target_root}" >&2
  exit 1
fi

grub_editenv=""
for candidate in \
  "${target_root}/usr/bin/grub2-editenv" \
  "${target_root}/usr/sbin/grub2-editenv"; do
  if [[ -x "${candidate}" ]]; then
    grub_editenv="${candidate#"${target_root}"}"
    break
  fi
done

grub_mkconfig=""
for candidate in \
  "${target_root}/usr/bin/grub2-mkconfig" \
  "${target_root}/usr/sbin/grub2-mkconfig"; do
  if [[ -x "${candidate}" ]]; then
    grub_mkconfig="${candidate#"${target_root}"}"
    break
  fi
done

if [[ -z "${grub_editenv}" || -z "${grub_mkconfig}" ]]; then
  echo "The target image does not contain the required GRUB tools" >&2
  exit 1
fi

mounted_paths=()
cleanup() {
  local path
  for path in "${mounted_paths[@]}"; do
    umount -R "${path}" 2>/dev/null || true
  done
}
trap cleanup EXIT

bind_runtime_tree() {
  local source=$1
  local destination="${target_root}/${source#/}"

  mkdir -p "${destination}"
  if mountpoint -q "${destination}"; then
    return 0
  fi

  mount --rbind "${source}" "${destination}"
  mount --make-rslave "${destination}"
  mounted_paths+=("${destination}")
}

# grub2-mkconfig invokes grub-probe and needs the installer's device and EFI
# views while it runs inside the installed image.
bind_runtime_tree /dev
bind_runtime_tree /proc
bind_runtime_tree /sys

chroot "${target_root}" "${grub_editenv}" - set menu_auto_hide=1

if [[ -e "${target_root}/etc/grub2-efi.cfg" || -L "${target_root}/etc/grub2-efi.cfg" ]]; then
  grub_config=/etc/grub2-efi.cfg
elif [[ -e "${target_root}/etc/grub2.cfg" || -L "${target_root}/etc/grub2.cfg" ]]; then
  grub_config=/etc/grub2.cfg
elif [[ -d /sys/firmware/efi ]]; then
  grub_config=/etc/grub2-efi.cfg
else
  grub_config=/etc/grub2.cfg
fi

chroot "${target_root}" "${grub_mkconfig}" -o "${grub_config}"

# Preserve the target image's GRUB timeout so users have time to choose an
# entry after explicitly showing the otherwise hidden menu.
echo "Configured target GRUB: menu_auto_hide=1, ${grub_config}"