Skip to content

Commit

Permalink
distro/rhel: support new partitioning customizations on RHEL 9 and 10
Browse files Browse the repository at this point in the history
Read the new Partitioning/Disk customizations in the RHEL partition
table generators.
Validate the customizations and check that they're not used at the same
time as FilesystemCustomization.

We are not enabling disk customizations on RHEL 8 currently because of
issues with kernel page size differences in some versions on aarch64.
  • Loading branch information
achilleas-k authored and supakeen committed Dec 4, 2024
1 parent e144674 commit ff53493
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 17 deletions.
27 changes: 27 additions & 0 deletions pkg/distro/rhel/imagetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ const (
BlueprintPkgsKey = "blueprint"
)

// Default directory size minimums for all image types.
var requiredDirectorySizes = map[string]uint64{
"/": 1 * datasizes.GiB,
"/usr": 2 * datasizes.GiB,
}

type ImageFunc func(workload workload.Workload, t *ImageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, containers []container.SourceSpec, rng *rand.Rand) (image.ImageKind, error)

type PackageSetFunc func(t *ImageType) rpmmd.PackageSet
Expand Down Expand Up @@ -193,6 +199,27 @@ func (t *ImageType) GetPartitionTable(
}

imageSize := t.Size(options.Size)
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if partitioning != nil {
// Use the new custom partition table to create a PT fully based on the user's customizations.
// This overrides FilesystemCustomizations, but we should never have both defined.
if options.Size > 0 {
// user specified a size on the command line, so let's override the
// customization with the calculated/rounded imageSize
partitioning.MinSize = imageSize
}

partOptions := &disk.CustomPartitionTableOptions{
PartitionTableType: basePartitionTable.Type, // PT type is not customizable, it is determined by the base PT for an image type or architecture
BootMode: t.BootMode(),
DefaultFSType: disk.FS_XFS, // default fs type for RHEL
RequiredMinSizes: requiredDirectorySizes,
}
return disk.NewCustomPartitionTable(partitioning, partOptions, rng)
}

return disk.NewPartitionTable(&basePartitionTable, customizations.GetFilesystems(), imageSize, options.PartitioningMode, nil, rng)
}
Expand Down
98 changes: 98 additions & 0 deletions pkg/distro/rhel/rhel10/distro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,3 +574,101 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
}
}
}

func TestDiskAndFilesystemCustomizationsError(t *testing.T) {
// simple test that checks that disk customizations are allowed
r8distro := rhelFamilyDistros[0].distro
bp := blueprint.Blueprint{
Customizations: &blueprint.Customizations{
Filesystem: []blueprint.FilesystemCustomization{
{
MinSize: 1024,
Mountpoint: "/home",
},
},
Disk: &blueprint.DiskCustomization{
Partitions: []blueprint.PartitionCustomization{
{
Type: "plain",
FilesystemTypedCustomization: blueprint.FilesystemTypedCustomization{
Mountpoint: "/",
Label: "root",
FSType: "ext4",
},
},
},
},
},
}

// these produce error message and are tested elsewhere
skipTest := map[string]bool{
"edge-commit": true,
"edge-container": true,
"edge-installer": true,
"edge-simplified-installer": true,
"azure-eap7-rhui": true,
"edge-vsphere": true,
"edge-raw-image": true,
"edge-ami": true,
}

for _, archName := range r8distro.ListArches() {
arch, _ := r8distro.GetArch(archName)
for _, imgTypeName := range arch.ListImageTypes() {
imgType, _ := arch.GetImageType(imgTypeName)
options := distro.ImageOptions{}
_, _, err := imgType.Manifest(&bp, options, nil, 0)
if skipTest[imgTypeName] {
continue
}
assert.EqualError(t, err, "partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
}
}

func TestNoDiskCustomizationsNoError(t *testing.T) {
// simple test that checks that disk customizations are allowed
r8distro := rhelFamilyDistros[0].distro
bp := blueprint.Blueprint{
Customizations: &blueprint.Customizations{
Disk: &blueprint.DiskCustomization{
Partitions: []blueprint.PartitionCustomization{
{
Type: "plain",
FilesystemTypedCustomization: blueprint.FilesystemTypedCustomization{
Mountpoint: "/",
Label: "root",
FSType: "ext4",
},
},
},
},
},
}

// these produce error message and are tested elsewhere
skipTest := map[string]bool{
"edge-commit": true,
"edge-container": true,
"edge-installer": true,
"edge-simplified-installer": true,
"azure-eap7-rhui": true,
"edge-vsphere": true,
"edge-raw-image": true,
"edge-ami": true,
}

for _, archName := range r8distro.ListArches() {
arch, _ := r8distro.GetArch(archName)
for _, imgTypeName := range arch.ListImageTypes() {
imgType, _ := arch.GetImageType(imgTypeName)
options := distro.ImageOptions{}
_, _, err := imgType.Manifest(&bp, options, nil, 0)
if skipTest[imgTypeName] {
continue
}
assert.NoError(t, err)
}
}
}
19 changes: 17 additions & 2 deletions pkg/distro/rhel/rhel10/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,24 @@ func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.Ima
}

mountpoints := customizations.GetFilesystems()

err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies)
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}

if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}

if len(mountpoints) > 0 && partitioning != nil {
return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}

if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}

if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}

Expand Down
46 changes: 43 additions & 3 deletions pkg/distro/rhel/rhel8/distro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ func TestDistro_CustomFileSystemManifestError(t *testing.T) {
imgType, _ := arch.GetImageType(imgTypeName)
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
assert.EqualError(t, err, "custom mountpoints are not supported for ostree types")
} else if unsupported[imgTypeName] {
assert.Error(t, err)
} else {
Expand Down Expand Up @@ -712,7 +712,7 @@ func TestDistro_TestRootMountPoint(t *testing.T) {
imgType, _ := arch.GetImageType(imgTypeName)
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
assert.EqualError(t, err, "custom mountpoints are not supported for ostree types")
} else if unsupported[imgTypeName] {
assert.Error(t, err)
} else {
Expand Down Expand Up @@ -872,7 +872,7 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
imgType, _ := arch.GetImageType(imgTypeName)
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
assert.EqualError(t, err, "custom mountpoints are not supported for ostree types")
} else if unsupported[imgTypeName] {
assert.Error(t, err)
} else {
Expand All @@ -881,3 +881,43 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
}
}
}

func TestNoDiskCustomizationsSupported(t *testing.T) {
r8distro := rhelFamilyDistros[0].distro
bp := blueprint.Blueprint{
Customizations: &blueprint.Customizations{
Disk: &blueprint.DiskCustomization{
Partitions: []blueprint.PartitionCustomization{
{
Type: "plain",
FilesystemTypedCustomization: blueprint.FilesystemTypedCustomization{
Mountpoint: "/",
Label: "root",
FSType: "ext4",
},
},
},
},
},
}

// these produce a different error message and are tested elsewhere
skipTest := map[string]bool{
"edge-installer": true,
"edge-simplified-installer": true,
"edge-raw-image": true,
"azure-eap7-rhui": true,
}

for _, archName := range r8distro.ListArches() {
arch, _ := r8distro.GetArch(archName)
for _, imgTypeName := range arch.ListImageTypes() {
imgType, _ := arch.GetImageType(imgTypeName)
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if skipTest[imgTypeName] {
continue
}
assert.EqualError(t, err, fmt.Sprintf("partitioning customizations are not supported on %s", r8distro.Name()))
}
}
}
20 changes: 17 additions & 3 deletions pkg/distro/rhel/rhel8/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,27 @@ func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.Ima
}

mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if partitioning != nil {
return nil, fmt.Errorf("partitioning customizations are not supported on %s", t.Arch().Distro().Name())
}

if mountpoints != nil && t.RPMOSTree {
return warnings, fmt.Errorf("Custom mountpoints are not supported for ostree types")
return warnings, fmt.Errorf("custom mountpoints are not supported for ostree types")
}

err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies)
if err != nil {
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}

if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}

if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}

Expand Down
Loading

0 comments on commit ff53493

Please sign in to comment.