2

I have read through the curtin and autoinstall documentation and can't wrap my head around why this autoinstall script is working on my development laptop but not my vbox install (ver 7.0.8 on Ubuntu host). At first I thought the problem was references to /dev/mmcblk0 (virtualbox uses /dev/sda) but after making a number of different configs I don't think this is actually the problem because of the error message this gives. The is autoinstall config did not create needed bootloader partition

My theory is that this autoinstall works on the laptop because the laptop is UEFI but not on Virtualbox because it is not. I have found some suggestions elsewhere on how to make an autoinstall that works for UEFI work on MBR, but none that are able to do both.

Is that the problem with this autoinstall partitioning layout? Is there any solution? I can't use the built-in layouts (lvm etc) due to this project's specific requirements. I realize I could change the Virtualbox settings to EFI boot, but this ISO will have to be installed on a wide variety of machines some of which may not support EFI.

Here is my current partitioning layout, which is working on a laptop with a device at /dev/mmcblk0

How does this script need to be modified to work on any system? And yes, the /boot partition really does need to be that large for this setup.

autoinstall:
  version: 1
  storage:
    config:
    - ptable: gpt
      wipe: superblock-recursive
      preserve: false
      name: ''
      grub_device: false
      type: disk
      id: disk-mmcblk0
      match:
        size: largest
    - device: disk-mmcblk0
      size: 1127219200
      wipe: superblock
      flag: boot
      number: 1
      preserve: false
      grub_device: true
      type: partition
      id: partition-0
    - fstype: fat32
      volume: partition-0
      preserve: false
      type: format
      id: format-0
    - device: disk-mmcblk0
      size: 5GB
      wipe: superblock
      number: 2
      preserve: false
      type: partition
      id: partition-1
    - fstype: ext4
      volume: partition-1
      preserve: false
      type: format
      id: format-1
    - device: disk-mmcblk0
      size: -1
      wipe: superblock
      number: 3
      preserve: false
      type: partition
      id: partition-2
    - volume: partition-2
      key: password
      path: /dev/mapper/dm_crypt-0
      preserve: false
      type: dm_crypt
      id: dm_crypt-0
    - name: ubuntu-vg
      devices:
      - dm_crypt-0
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - name: ubuntu-lv
      volgroup: lvm_volgroup-0
      size: -1
      wipe: superblock
      preserve: false
      path: /dev/ubuntu-vg/ubuntu-lv
      type: lvm_partition
      id: lvm_partition-0
    - fstype: btrfs
      volume: lvm_partition-0
      preserve: false
      type: format
      id: format-2
    - path: /
      device: format-2
      type: mount
      id: mount-2
      options: 'noatime,discard,compress=zstd:1'
    - path: /boot
      device: format-1
      type: mount
      id: mount-1
    - path: /boot/efi
      device: format-0
      type: mount
      id: mount-0
Mr. T
  • 201

1 Answers1

4

As @AndrewLowther pointed out in the answer his comment points to:

Officially, you can't create a single storage config that supports both BIOS and UEFI. The grub_device settings are incompatible.

So you have two options:

  1. Modify your user-data with the workaround Andrew suggested
  2. Create separate user-data files. One for BIOS and one for UEFI

I'll outline the first option below, which is what you want. This means it'll work for either a BIOS or UEFI computer.


First off, your user-data file supplied is missing #cloud-config as the first line as well as the identity section. Both are required, so I added them in the example below. The identity section is defined with a default username of ubuntu and password of ubuntu. Furthermore, the encrypted drive is configured with a password of ubuntu. Change accordingly.

There are several things with the user-data file below that are different than yours.

  1. grub_device: true is set for the disk instead of grub_device: false

    - type: disk
      id: disk-mmcblk0
      ptable: gpt
      match:
        size: largest
      preserve: false
      name: ''
      grub_device: true
      wipe: superblock-recursive
    
  2. A small un-formatted partition with flag: bios_grub is added.

    - type: partition
      id: partition-0
      device: disk-mmcblk0
      size: 4194304
      wipe: superblock
      flag: bios_grub
      number: 1
      preserve: false
      grub_device: false
    

From the curtin documentation regarding bios_grub:

If the host system for curtin has been booted using UEFI then curtin will install grub to the esp partition. If the system installation media has been booted using an MBR, grub will be installed onto the disk’s MBR. However, on a disk with a gpt partition table, there is not enough space after the MBR for grub to store its second stage core.img, so a small un-formatted partition with the bios_grub flag is needed. This partition should be placed at the beginning of the disk and should be 1MB in size. It should not contain a filesystem or be mounted anywhere on the system.

  1. grub_device: false is set for all partitions with the exception of the ESP partition used by an UEFI installion. For this partition, grub_device: UEFI is set instead. This is really just a place-holder at the moment and will be edited with early-commands, as outlined next.

    - type: partition
      id: partition-1
      device: disk-mmcblk0
      size: 111149056
      wipe: superblock
      flag: boot
      number: 2
      preserve: false
      grub_device: UEFI
    
  2. The use of early-commands in the user-data file will modify the autoinstall.yaml file based on whether the computer is UEFI or BIOS. This will modify the grub_device: UEFI setting defined above.

Take a look at the following:

  early-commands:
    - |
      if [ -e "/sys/firmware/efi" ]; then
        sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml
      else
        sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml
      fi

What this is doing is editing the autoinstall.yaml file based on a conditional. From what I understand, the autoinstall.yaml file is created during the installation and resides in the root directory of the Live Installation. This is a combination of your user-data file and the default autoinstall unanswered/unconfigured questions that the installer fills in.

This checks if the file /sys/firmware/efi exists:

  • if [ -e "/sys/firmware/efi" ]; then

If true:

  • Indicates the system is UEFI

  • Replaces grub_device: UEFI with grub_device: true using sed:

    sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml

Otherwise:

  • Indicates the system is BIOS

  • Replaces grub_device: UEFI with grub_device: false using sed:

    sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml


And that's it. After the early-commands are run, the installation will continue.

Here's the complete user-data file:

#cloud-config
autoinstall:
  version: 1
  identity:
    hostname: ubuntu-server
    password: $6$5lpwCLsKLEzMkSJc$keOAhA6aO/5RocGThmhVA7LSNuW911Rx5HHXFEa75oGK20cEdAAgn14H5f5nGeq6QgcSyLPrWcg1.JvjXbhrN/
    realname: Ubuntu User
    username: ubuntu
  storage:
    config:
    - type: disk
      id: disk-mmcblk0
      ptable: gpt
      match:
        size: largest
      preserve: false
      name: ''
      grub_device: true
      wipe: superblock-recursive
- type: partition
  id: partition-0
  device: disk-mmcblk0
  size: 4194304
  wipe: superblock
  flag: bios_grub
  number: 1
  preserve: false
  grub_device: false

- type: partition
  id: partition-1
  device: disk-mmcblk0
  size: 111149056
  wipe: superblock
  flag: boot
  number: 2
  preserve: false
  grub_device: UEFI

- type: format
  id: format-0
  volume: partition-1
  fstype: fat32
  preserve: false

- type: partition
  id: partition-2
  device: disk-mmcblk0
  size: 5GB
  wipe: superblock
  number: 3
  preserve: false
  grub_device: false

- type: format
  id: format-1
  volume: partition-2
  fstype: ext4
  preserve: false

- type: partition
  id: partition-3
  device: disk-mmcblk0
  size: -1
  wipe: superblock
  number: 4
  preserve: false
  grub_device: false

- type: dm_crypt
  id: dm_crypt-0
  volume: partition-3
  preserve: false
  key: 'ubuntu'

- type: lvm_volgroup
  id: lvm_volgroup-0
  devices:
  - dm_crypt-0
  preserve: false
  name: ubuntu-vg

- type: lvm_partition
  id: lvm_partition-0
  volgroup: lvm_volgroup-0
  size: -1
  preserve: false
  wipe: superblock
  name: ubuntu-lv

- type: format
  id: format-2
  volume: lvm_partition-0
  fstype: btrfs
  preserve: false

- type: mount
  id: mount-0
  device: format-0
  path: /boot/efi

- type: mount
  id: mount-1
  device: format-1
  path: /boot

- type: mount
  id: mount-2
  device: format-2
  path: /

early-commands: - | if [ -e "/sys/firmware/efi" ]; then sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml else sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml fi


If you install on both a UEFI and BIOS computer and then compare, you'll notice that the partition scheme will be the same. The UEFI installation will have an unused bios_grub partition, and the BIOS installation will have an unused ESP partition mounted at /boot/efi. The /boot/efi will be empty in a BIOS installation and will have files in an UEFI installation.

The following installations were done with ISO: ubuntu-22.04.3-live-server-amd64.iso. This was unpacked with the above user-data file added to /nocloud and then re-packed.

EFI installation:

$ sudo parted /dev/sda
GNU Parted 3.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 26.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags 1 1049kB 5243kB 4194kB bios_grub 2 5243kB 116MB 111MB fat32 boot, esp 3 116MB 5485MB 5369MB ext4 4 5485MB 26.8GB 21.4GB

$ lsblk -o name,fssize,fsused,fsavail,fstype,mountpoint NAME FSSIZE FSUSED FSAVAIL FSTYPE MOUNTPOINT loop0 53.4M 53.4M 0 squashfs /snap/snapd/19457 loop1 112M 112M 0 squashfs /snap/lxd/24322 loop2 63.5M 63.5M 0 squashfs /snap/core20/1974 sda
├─sda1
├─sda2 104.3M 6M 98.3M vfat /boot/efi ├─sda3 4.8G 129.6M 4.4G ext4 /boot └─sda4 crypto_LUKS └─dm_crypt-0 LVM2_member └─ubuntu--vg-ubuntu--lv 19.9G 3G 16G btrfs /

$ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 491M 1.1M 490M 1% /run /dev/mapper/ubuntu--vg-ubuntu--lv 20G 3.0G 17G 16% / tmpfs 2.4G 0 2.4G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock /dev/sda3 4.9G 130M 4.5G 3% /boot /dev/sda2 105M 6.1M 99M 6% /boot/efi tmpfs 491M 4.0K 491M 1% /run/user/1000

$ ls /boot/efi EFI

BIOS installation:

$ sudo parted /dev/sda
GNU Parted 3.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 26.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags 1 1049kB 5243kB 4194kB bios_grub 2 5243kB 116MB 111MB fat32 boot, esp 3 116MB 5485MB 5369MB ext4 4 5485MB 26.8GB 21.4GB

$ lsblk -o name,fssize,fsused,fsavail,fstype,mountpoint NAME FSSIZE FSUSED FSAVAIL FSTYPE MOUNTPOINT loop0 63.5M 63.5M 0 squashfs /snap/core20/1974 loop1 53.4M 53.4M 0 squashfs /snap/snapd/19457 loop2 112M 112M 0 squashfs /snap/lxd/24322 sda
├─sda1
├─sda2 104.3M 512B 104.3M vfat /boot/efi ├─sda3 4.8G 128.6M 4.4G ext4 /boot └─sda4 crypto_LUKS └─dm_crypt-0 LVM2_member └─ubuntu--vg-ubuntu--lv 19.9G 3G 16G btrfs /

$ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 492M 1.1M 491M 1% /run /dev/mapper/ubuntu--vg-ubuntu--lv 20G 3.0G 17G 16% / tmpfs 2.4G 0 2.4G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock /dev/sda3 4.9G 129M 4.5G 3% /boot /dev/sda2 105M 512 105M 1% /boot/efi tmpfs 492M 4.0K 492M 1% /run/user/1000

$ ls /boot/efi

mpboden
  • 3,046