GRUB: use persistent device names under /dev/disk/by-id/ for install_devices
[grml-debootstrap.git] / chroot-script
index 25bd600..5cff484 100755 (executable)
@@ -479,11 +479,16 @@ createfstab(){
 EOF
 
   if [ -n "$TARGET_UUID" ] ; then
-    local rootfs_mount_options=",errors=remount-ro"
+    local rootfs_mount_options=""
+
+    if [ -z "${FILESYSTEM}" ] ; then
+      FILESYSTEM="$(blkid -o value -s TYPE /dev/disk/by-uuid/"${TARGET_UUID}")"
+    fi
+
     case "${FILESYSTEM}" in
-      f2fs)
-        # errors=remount-ro is unsupported, see https://github.com/grml/grml-debootstrap/issues/163
-        rootfs_mount_options=""
+      # errors=remount-ro is supported only by a few file systems
+      ext*|exfat|fat|jfs|nilfs2|vfat)
+        rootfs_mount_options=",errors=remount-ro"
         ;;
     esac
 
@@ -525,6 +530,28 @@ fstab() {
 }
 # }}}
 
+# ensure we have according filesystem tools available {{{
+install_fs_tools() {
+  local pkg=""
+
+  # note: this is supposed to be coming either via command lines'
+  # $_opt_filesystem or via createfstab()
+  case "${FILESYSTEM}" in
+    jfs)
+      pkg="jfsutils"
+      ;;
+    xfs)
+      pkg="xfsprogs"
+      ;;
+  esac
+
+  if [ -n "${pkg:-}" ] && ! dpkg --list "${pkg}" 2>/dev/null | grep -q '^ii' ; then
+    echo "Filesystem package ${pkg} not present, installing now"
+    DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL "${pkg}"
+  fi
+}
+# }}}
+
 # set up hostname {{{
 hostname() {
   if [ -n "$HOSTNAME" ] ; then
@@ -576,9 +603,9 @@ initrd() {
      echo "Generating initrd."
      if [ "$INITRD_GENERATOR" = 'dracut' ] ; then
          DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL dracut
-         dracut -N --kver "$KERNELVER" --fstab --add-fstab /etc/fstab --force
+         dracut --no-hostonly --kver "$KERNELVER" --fstab --add-fstab /etc/fstab --force --reproducible $INITRD_GENERATOR_OPTS
      else
-         update-initramfs -c -t -k "$KERNELVER"
+         update-initramfs -c -t -k "$KERNELVER" $INITRD_GENERATOR_OPTS
      fi
   fi
 }
@@ -610,6 +637,42 @@ efi_setup() {
 }
 
 # grub configuration/installation {{{
+
+# helper function to get relevant /dev/disk/by-id/* entries,
+# based on GRUB's postinst script
+available_ids() {
+  local path ids
+
+  [ -d /dev/disk/by-id ] || return
+  ids="$(
+    for path in /dev/disk/by-id/*; do
+      [ -e "${path}" ] || continue
+      printf '%s %s\n' "${path}" "$(readlink -f "${path}")"
+    done | sort -k2 -s -u | cut -d' ' -f1
+  )"
+  echo "${ids}"
+}
+
+# helper function to report corresponding /dev/disk/by-id/… for a given device name,
+# based on GRUB's postinst script
+device_to_id() {
+  local id
+
+  for id in $(available_ids); do
+    if [ "$(readlink -f "${id}")" = "$(readlink -f "$1")" ]; then
+      echo "${id}"
+      return 0
+    fi
+  done
+
+  # Fall back to the plain device name if there's no by-id link for it.
+  if [ -e "$1" ]; then
+    echo "$1"
+    return 0
+  fi
+  return 1
+}
+
 grub_install() {
 
   if [ -z "$GRUB" ] ; then
@@ -627,8 +690,15 @@ grub_install() {
 
   # make sure this is pre-defined so we have sane settings for automated
   # upgrades, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=711019
+  local grub_device
+  grub_device=$(device_to_id "${GRUB}")
+  if [ -z "${grub_device:-}" ] ; then
+     echo "Warning: Could not identify /dev/disk/by-id/... for '${GRUB}', falling back to '${GRUB}'"
+     grub_device="${GRUB}"
+  fi
+
   echo "Setting ${GRUB_PACKAGE} debconf configuration for install device to $GRUB"
-  echo "${GRUB_PACKAGE} ${GRUB_PACKAGE}/install_devices multiselect $GRUB" | debconf-set-selections
+  echo "${GRUB_PACKAGE} ${GRUB_PACKAGE}/install_devices multiselect ${grub_device}" | debconf-set-selections
 
   if ! dpkg --list ${GRUB_PACKAGE} 2>/dev/null | grep -q '^ii' ; then
     echo "Notice: grub option set but no ${GRUB_PACKAGE} package, installing it therefore."
@@ -751,7 +821,8 @@ trap signal_handler HUP INT QUIT TERM
 
  for i in chrootmirror grmlrepos backportrepos kernelimg_conf \
      kernel packages extrapackages reconfigure hosts \
-     default_locales timezone fstab hostname initrd grub_install passwords \
+     default_locales timezone fstab install_fs_tools hostname \
+     initrd grub_install passwords \
      custom_scripts upgrade_system remove_apt_cache services \
      remove_chrootmirror; do
      if stage $i ; then