rhel86: automatically convert to LVM on fs customizations

Whenever we create a new mountpoint due to a user customization,
ensure the layout uses LVM, i.e. convert plain layouts to it, if
needed. It uses the existing lvm-ification code but enhances it
so that we also create a `/boot` partition in case it does not
yet exist.
Adjust the existing tests that assumed we can not create more
than 4 partitions on mbr layouts, since that is now not true
anymore.
This commit is contained in:
Christian Kellner 2022-02-28 19:03:07 +01:00 committed by Achilleas Koutsou
parent 98aba06ca5
commit 63aa1556fc
3 changed files with 38 additions and 9 deletions

View file

@ -26,7 +26,10 @@ func NewPartitionTable(basePT *PartitionTable, mountpoints []blueprint.Filesyste
resizeEntityBranch(path, size)
} else {
if lvmify {
newPT.ensureLVM()
err := newPT.ensureLVM()
if err != nil {
return nil, err
}
}
if err := newPT.createFilesystem(mnt.Mountpoint, size); err != nil {
return nil, err
@ -458,17 +461,24 @@ func (pt *PartitionTable) GenUUID(rng *rand.Rand) {
// ensureLVM will ensure that the root partition is on an LVM volume, i.e. if
// it currently is not, it will wrap it in one
func (pt *PartitionTable) ensureLVM() {
func (pt *PartitionTable) ensureLVM() error {
rootPath := entityPath(pt, "/")
if rootPath == nil {
panic("no root mountpoint for PartitionTable")
}
// we need a /boot partition to boot LVM, ensure one exists
bootPath := entityPath(pt, "/boot")
if bootPath == nil {
_, err := pt.CreateMountpoint("/boot", 512*1024*1024)
return err
}
parent := rootPath[1] // NB: entityPath has reversed order
if _, ok := parent.(*LVMLogicalVolume); ok {
return
return nil
} else if part, ok := parent.(*Partition); ok {
filesystem := part.Payload
@ -496,4 +506,6 @@ func (pt *PartitionTable) ensureLVM() {
} else {
panic("unsupported parent for LVM")
}
return nil
}

View file

@ -331,6 +331,24 @@ func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.Package
bpPackages = append(bpPackages, "chrony")
}
// if we have file system customization that will need to a new mount point
// the layout is converted to LVM so we need to corresponding packages
if !t.rpmOstree {
archName := t.arch.Name()
pt := t.basePartitionTables[archName]
haveNewMountpoint := false
if fs := bp.Customizations.GetFilesystems(); fs != nil {
for i := 0; !haveNewMountpoint && i < len(fs); i++ {
haveNewMountpoint = !pt.ContainsMountpoint(fs[i].Mountpoint)
}
}
if haveNewMountpoint {
bpPackages = append(bpPackages, "lvm2")
}
}
// depsolve bp packages separately
// bp packages aren't restricted by exclude lists
mergedSets[blueprintPkgsKey] = rpmmd.PackageSet{Include: bpPackages}
@ -394,7 +412,9 @@ func (t *imageType) getPartitionTable(
imageSize := t.Size(options.Size)
return disk.NewPartitionTable(&basePartitionTable, mountpoints, imageSize, false, rng)
lvmify := !t.rpmOstree
return disk.NewPartitionTable(&basePartitionTable, mountpoints, imageSize, lvmify, rng)
}
func (t *imageType) getDefaultImageConfig() *distro.ImageConfig {

View file

@ -704,13 +704,10 @@ func TestDistro_MountpointsWithArbitraryDepthAllowed(t *testing.T) {
imgType, _ := arch.GetImageType(imgTypeName)
testPackageSpecSets := distro_test_common.GetTestingPackageSpecSets("kernel", arch.Name(), imgType.PayloadPackageSets())
_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, testPackageSpecSets, 0)
layout := imgType.PartitionType()
if layout == "" || strings.HasPrefix(imgTypeName, "edge-") {
if strings.HasPrefix(imgTypeName, "edge-") {
continue
} else if layout == "gpt" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, "failed creating volume: maximum number of partitions reached (4)")
assert.NoError(t, err)
}
}
}