diff --git a/pkg/disk/disk.go b/pkg/disk/disk.go index 6c0a3d664..5c26d18aa 100644 --- a/pkg/disk/disk.go +++ b/pkg/disk/disk.go @@ -60,6 +60,9 @@ const ( // DosFat16B used for the ESP-System partition DosFat16B = "06" + + // Partition type ID for any native Linux filesystem on dos + DosLinuxTypeID = "83" ) // FSType is the filesystem type enum. diff --git a/pkg/disk/partition_table.go b/pkg/disk/partition_table.go index 407074edb..add00d302 100644 --- a/pkg/disk/partition_table.go +++ b/pkg/disk/partition_table.go @@ -795,7 +795,7 @@ func (pt *PartitionTable) ensureBtrfs() error { if pt.Type == "gpt" { part.Type = FilesystemDataGUID } else { - part.Type = "83" + part.Type = DosLinuxTypeID } } else { @@ -894,3 +894,163 @@ func (pt *PartitionTable) GetMountpointSize(mountpoint string) (uint64, error) { panic(fmt.Sprintf("no sizeable of the entity path for mountpoint %s, this is a programming error", mountpoint)) } + +// EnsureRootFilesystem adds a root filesystem if the partition table doesn't +// already have one. +// +// When adding the root filesystem, add it to: +// +// - The first LVM Volume Group if one exists, otherwise +// - The first Btrfs volume if one exists, otherwise +// - At the end of the plain partitions. +// +// For LVM and Plain, the fsType argument must be a valid filesystem type. +func EnsureRootFilesystem(pt *PartitionTable, defaultFsType FSType) error { + // collect all labels and subvolume names to avoid conflicts + subvolNames := make(map[string]bool) + labels := make(map[string]bool) + var foundRoot bool + _ = pt.ForEachMountable(func(mnt Mountable, path []Entity) error { + if mnt.GetMountpoint() == "/" { + foundRoot = true + return nil + } + + labels[mnt.GetFSSpec().Label] = true + switch mountable := mnt.(type) { + case *BtrfsSubvolume: + subvolNames[mountable.Name] = true + } + return nil + }) + if foundRoot { + // nothing to do + return nil + } + + for _, part := range pt.Partitions { + switch payload := part.Payload.(type) { + case *LVMVolumeGroup: + if defaultFsType == FS_NONE { + return fmt.Errorf("error creating root logical volume: no default filesystem type") + } + + rootLabel, err := genUniqueString("root", labels) + if err != nil { + return fmt.Errorf("error creating root logical volume: %w", err) + } + rootfs := &Filesystem{ + Type: defaultFsType.String(), + Label: rootLabel, + Mountpoint: "/", + FSTabOptions: "defaults", + } + // Let the function autogenerate the name to avoid conflicts + // with LV names from customizations. + // Set the size to 0 and it will be adjusted by + // EnsureDirectorySizes() and relayout(). + if _, err := payload.CreateLogicalVolume("", 0, rootfs); err != nil { + return fmt.Errorf("error creating root logical volume: %w", err) + } + return nil + case *Btrfs: + rootName, err := genUniqueString("root", subvolNames) + if err != nil { + return fmt.Errorf("error creating root subvolume: %w", err) + } + rootsubvol := BtrfsSubvolume{ + Name: rootName, + Mountpoint: "/", + } + payload.Subvolumes = append(payload.Subvolumes, rootsubvol) + return nil + } + } + + // We're going to create a root partition, so we have to ensure the default type is set. + if defaultFsType == FS_NONE { + return fmt.Errorf("error creating root partition: no default filesystem type") + } + + // add a plain root partition at the end of the partition table + rootLabel, err := genUniqueString("root", labels) + if err != nil { + return fmt.Errorf("error creating root partition: %w", err) + } + + var partType string + switch pt.Type { + case "dos": + partType = DosLinuxTypeID + case "gpt": + partType = FilesystemDataGUID + default: + return fmt.Errorf("error creating root partition: unknown or unsupported partition table type: %s", pt.Type) + } + rootpart := Partition{ + Type: partType, + Size: 0, // Set the size to 0 and it will be adjusted by EnsureDirectorySizes() and relayout() + Payload: &Filesystem{ + Type: defaultFsType.String(), + Label: rootLabel, + Mountpoint: "/", + FSTabOptions: "defaults", + }, + } + pt.Partitions = append(pt.Partitions, rootpart) + return nil +} + +// EnsureBootPartition creates a boot partition if one does not already exist. +// The function will append the boot partition to the end of the existing +// partition table therefore it is best to call this function early to put boot +// near the front (as is conventional). +func EnsureBootPartition(pt *PartitionTable, bootFsType FSType) error { + // collect all labels to avoid conflicts + labels := make(map[string]bool) + var foundBoot bool + _ = pt.ForEachMountable(func(mnt Mountable, path []Entity) error { + if mnt.GetMountpoint() == "/boot" { + foundBoot = true + return nil + } + + labels[mnt.GetFSSpec().Label] = true + return nil + }) + if foundBoot { + // nothing to do + return nil + } + + if bootFsType == FS_NONE { + return fmt.Errorf("error creating boot partition: no filesystem type") + } + + bootLabel, err := genUniqueString("boot", labels) + if err != nil { + return fmt.Errorf("error creating boot partition: %w", err) + } + + var partType string + switch pt.Type { + case "dos": + partType = DosLinuxTypeID + case "gpt": + partType = XBootLDRPartitionGUID + default: + return fmt.Errorf("error creating boot partition: unknown or unsupported partition table type: %s", pt.Type) + } + bootPart := Partition{ + Type: partType, + Size: 512 * datasizes.MiB, + Payload: &Filesystem{ + Type: bootFsType.String(), + Label: bootLabel, + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + } + pt.Partitions = append(pt.Partitions, bootPart) + return nil +} diff --git a/pkg/disk/partition_table_test.go b/pkg/disk/partition_table_test.go index 89c80381b..ffd486c19 100644 --- a/pkg/disk/partition_table_test.go +++ b/pkg/disk/partition_table_test.go @@ -105,3 +105,921 @@ func TestPartitionTable_GenerateUUIDs_VFAT(t *testing.T) { assert.Equal(t, "6e4ff95f", pt.Partitions[0].Payload.(*disk.Filesystem).UUID) } + +func TestEnsureRootFilesystem(t *testing.T) { + type testCase struct { + pt disk.PartitionTable + expected disk.PartitionTable + defaultFsType disk.FSType + } + + testCases := map[string]testCase{ + "empty-plain-gpt": { + pt: disk.PartitionTable{Type: "gpt"}, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Start: 0, + Size: 0, + Type: disk.FilesystemDataGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "empty-plain-dos": { + pt: disk.PartitionTable{Type: "dos"}, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Start: 0, + Size: 0, + Type: disk.DosLinuxTypeID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "simple-plain-gpt": { + pt: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + }, + }, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 0, + Type: disk.FilesystemDataGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "simple-plain-dos": { + pt: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + }, + }, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 0, + Type: disk.DosLinuxTypeID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "simple-lvm": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Mountpoint: "/data", + FSTabOptions: "defaults", + Type: "ext4", + }, + }, + }, + }, + }, + }, + }, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + }, + "simple-btrfs": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + }, + }, + }, + }, + }, + // no default fs required + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + { + Name: "root", + Mountpoint: "/", + }, + }, + }, + }, + }, + }, + }, + "noop-lvm": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + }, + "noop-btrfs": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + { + Name: "root", + Mountpoint: "/", + }, + }, + }, + }, + }, + }, + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + { + Name: "root", + Mountpoint: "/", + }, + }, + }, + }, + }, + }, + }, + "plain-collision": { + pt: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/root", + FSTabOptions: "defaults", + }, + }, + }, + }, + defaultFsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root", + Mountpoint: "/root", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 0, + Type: disk.FilesystemDataGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "root00", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "lvm-collision": { + pt: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/root", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + defaultFsType: disk.FS_XFS, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/root", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv00", + Payload: &disk.Filesystem{ + Label: "root00", + Type: "xfs", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + }, + "btrfs-collision": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + { + Name: "root", + Mountpoint: "/root", + }, + }, + }, + }, + }, + }, + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Btrfs{ + Subvolumes: []disk.BtrfsSubvolume{ + { + Name: "subvol/home", + Mountpoint: "/home", + }, + { + Name: "root", + Mountpoint: "/root", + }, + { + Name: "root00", + Mountpoint: "/", + }, + }, + }, + }, + }, + }, + }, + } + + for name := range testCases { + tc := testCases[name] + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + pt := tc.pt + err := disk.EnsureRootFilesystem(&pt, tc.defaultFsType) + assert.NoError(err) + assert.Equal(tc.expected, pt) + }) + } +} + +func TestEnsureRootFilesystemErrors(t *testing.T) { + type testCase struct { + pt disk.PartitionTable + defaultFsType disk.FSType + errmsg string + } + + testCases := map[string]testCase{ + "err-empty": { + pt: disk.PartitionTable{}, + errmsg: "error creating root partition: no default filesystem type", + }, + "err-no-pt-type": { + pt: disk.PartitionTable{}, + defaultFsType: disk.FS_EXT4, + errmsg: "error creating root partition: unknown or unsupported partition table type: ", + }, + "err-plain": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + }, + }, + errmsg: "error creating root partition: no default filesystem type", + }, + "err-lvm": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Mountpoint: "/data", + FSTabOptions: "defaults", + Type: "ext4", + }, + }, + }, + }, + }, + }, + }, + errmsg: "error creating root logical volume: no default filesystem type", + }, + } + + for name := range testCases { + tc := testCases[name] + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + pt := tc.pt + err := disk.EnsureRootFilesystem(&pt, tc.defaultFsType) + assert.EqualError(err, tc.errmsg) + }) + } +} + +func TestEnsureBootPartition(t *testing.T) { + type testCase struct { + pt disk.PartitionTable + expected disk.PartitionTable + fsType disk.FSType + errmsg string + } + + testCases := map[string]testCase{ + "empty-plain-gpt": { + pt: disk.PartitionTable{Type: "gpt"}, + fsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Start: 0, + Size: 512 * datasizes.MiB, + Type: disk.XBootLDRPartitionGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "empty-plain-dos": { + pt: disk.PartitionTable{Type: "dos"}, + fsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Start: 0, + Size: 512 * datasizes.MiB, + Type: disk.DosLinuxTypeID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "simple-plain-gpt": { + pt: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + }, + }, + fsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 512 * datasizes.MiB, + Type: disk.XBootLDRPartitionGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "simple-plain-dos": { + pt: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + }, + }, + fsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "dos", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 512 * datasizes.MiB, + Type: disk.DosLinuxTypeID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "noop": { + pt: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Start: 0, + Size: 0, + Type: disk.XBootLDRPartitionGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + expected: disk.PartitionTable{ + Partitions: []disk.Partition{ + { + Start: 0, + Size: 0, + Type: disk.XBootLDRPartitionGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + { + Payload: &disk.LVMVolumeGroup{ + Name: "testvg", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Name: "varloglv", + Payload: &disk.Filesystem{ + Label: "var-log", + Type: "xfs", + Mountpoint: "/var/log", + }, + }, + { + Name: "datalv", + Payload: &disk.Filesystem{ + Label: "data", + Type: "ext4", + Mountpoint: "/data", + FSTabOptions: "defaults", + }, + }, + { + Name: "rootlv", + Payload: &disk.Filesystem{ + Label: "root", + Type: "ext4", + Mountpoint: "/", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + }, + }, + }, + "label-collision": { + pt: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/collections/footwear/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + fsType: disk.FS_EXT4, + expected: disk.PartitionTable{ + Type: "gpt", + Partitions: []disk.Partition{ + { + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot", + Mountpoint: "/collections/footwear/boot", + FSTabOptions: "defaults", + }, + }, + { + Start: 0, + Size: 512 * datasizes.MiB, + Type: disk.XBootLDRPartitionGUID, + Bootable: false, + UUID: "", + Payload: &disk.Filesystem{ + Type: "ext4", + Label: "boot00", + Mountpoint: "/boot", + FSTabOptions: "defaults", + }, + }, + }, + }, + }, + "err-nofs": { + pt: disk.PartitionTable{}, + errmsg: "error creating boot partition: no filesystem type", + }, + } + + for name := range testCases { + tc := testCases[name] + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + pt := tc.pt + err := disk.EnsureBootPartition(&pt, tc.fsType) + if tc.errmsg == "" { + assert.NoError(err) + assert.Equal(tc.expected, pt) + } else { + assert.EqualError(err, tc.errmsg) + } + }) + } +} diff --git a/pkg/distro/fedora/partition_tables.go b/pkg/distro/fedora/partition_tables.go index 3984210fb..1f243ab6c 100644 --- a/pkg/distro/fedora/partition_tables.go +++ b/pkg/distro/fedora/partition_tables.go @@ -238,7 +238,7 @@ var minimalrawPartitionTables = distro.BasePartitionTableMap{ }, { Size: 1 * datasizes.GibiByte, - Type: "83", + Type: disk.DosLinuxTypeID, Payload: &disk.Filesystem{ Type: "ext4", Mountpoint: "/boot", @@ -250,7 +250,7 @@ var minimalrawPartitionTables = distro.BasePartitionTableMap{ }, { Size: 2 * datasizes.GibiByte, - Type: "83", + Type: disk.DosLinuxTypeID, Payload: &disk.Filesystem{ Type: "ext4", Label: "root", @@ -333,7 +333,7 @@ var iotBasePartitionTables = distro.BasePartitionTableMap{ }, { Size: 1 * datasizes.GibiByte, - Type: "83", + Type: disk.DosLinuxTypeID, Payload: &disk.Filesystem{ Type: "ext4", Mountpoint: "/boot", @@ -345,7 +345,7 @@ var iotBasePartitionTables = distro.BasePartitionTableMap{ }, { Size: 2569 * datasizes.MebiByte, - Type: "83", + Type: disk.DosLinuxTypeID, Payload: &disk.Filesystem{ Type: "ext4", Label: "root",