From 7a5d80d761bc345d47b504491b5e08f1d957b998 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Fri, 29 Nov 2024 21:34:34 +0100 Subject: [PATCH] distro/rhel: support new partitioning customizations on RHEL 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. --- pkg/distro/rhel/imagetype.go | 27 +++++++++++++++++++++++++++ pkg/distro/rhel/rhel10/options.go | 19 +++++++++++++++++-- pkg/distro/rhel/rhel8/distro_test.go | 6 +++--- pkg/distro/rhel/rhel8/options.go | 22 ++++++++++++++++++---- pkg/distro/rhel/rhel9/distro_test.go | 6 +++--- pkg/distro/rhel/rhel9/options.go | 26 ++++++++++++++++++++------ 6 files changed, 88 insertions(+), 18 deletions(-) diff --git a/pkg/distro/rhel/imagetype.go b/pkg/distro/rhel/imagetype.go index 8a8b9742a8..e19beadfea 100644 --- a/pkg/distro/rhel/imagetype.go +++ b/pkg/distro/rhel/imagetype.go @@ -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 @@ -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_EXT4, // default fs type for Fedora + RequiredMinSizes: requiredDirectorySizes, + } + return disk.NewCustomPartitionTable(partitioning, partOptions, rng) + } return disk.NewPartitionTable(&basePartitionTable, customizations.GetFilesystems(), imageSize, options.PartitioningMode, nil, rng) } diff --git a/pkg/distro/rhel/rhel10/options.go b/pkg/distro/rhel/rhel10/options.go index b77d1c6114..60550c41ed 100644 --- a/pkg/distro/rhel/rhel10/options.go +++ b/pkg/distro/rhel/rhel10/options.go @@ -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 } diff --git a/pkg/distro/rhel/rhel8/distro_test.go b/pkg/distro/rhel/rhel8/distro_test.go index b459a40fdc..325de3ef3b 100644 --- a/pkg/distro/rhel/rhel8/distro_test.go +++ b/pkg/distro/rhel/rhel8/distro_test.go @@ -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 and partitioning are not supported for ostree types") } else if unsupported[imgTypeName] { assert.Error(t, err) } else { @@ -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 and partitioning are not supported for ostree types") } else if unsupported[imgTypeName] { assert.Error(t, err) } else { @@ -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 and partitioning are not supported for ostree types") } else if unsupported[imgTypeName] { assert.Error(t, err) } else { diff --git a/pkg/distro/rhel/rhel8/options.go b/pkg/distro/rhel/rhel8/options.go index 56c6b9ca34..7eabcf5c06 100644 --- a/pkg/distro/rhel/rhel8/options.go +++ b/pkg/distro/rhel/rhel8/options.go @@ -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 len(mountpoints) > 0 && partitioning != nil { + return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)") + } - if mountpoints != nil && t.RPMOSTree { - return warnings, fmt.Errorf("Custom mountpoints are not supported for ostree types") + if (mountpoints != nil || partitioning != nil) && t.RPMOSTree { + return warnings, fmt.Errorf("custom mountpoints and partitioning 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 } diff --git a/pkg/distro/rhel/rhel9/distro_test.go b/pkg/distro/rhel/rhel9/distro_test.go index b58c0c5f67..dd2a9c09ef 100644 --- a/pkg/distro/rhel/rhel9/distro_test.go +++ b/pkg/distro/rhel/rhel9/distro_test.go @@ -671,7 +671,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 and partitioning are not supported for ostree types") } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" || imgTypeName == "edge-vsphere" { continue } else { @@ -699,7 +699,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 and partitioning are not supported for ostree types") } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" || imgTypeName == "edge-vsphere" { continue } else { @@ -829,7 +829,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 and partitioning are not supported for ostree types") } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" || imgTypeName == "edge-vsphere" { continue } else { diff --git a/pkg/distro/rhel/rhel9/options.go b/pkg/distro/rhel/rhel9/options.go index 61fd5cab19..4bd10ac076 100644 --- a/pkg/distro/rhel/rhel9/options.go +++ b/pkg/distro/rhel/rhel9/options.go @@ -124,10 +124,13 @@ func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.Ima } mountpoints := customizations.GetFilesystems() - - if mountpoints != nil && t.RPMOSTree && (t.Name() == "edge-container" || t.Name() == "edge-commit") { - return warnings, fmt.Errorf("Custom mountpoints are not supported for ostree types") - } else if mountpoints != nil && t.RPMOSTree && !(t.Name() == "edge-container" || t.Name() == "edge-commit") { + partitioning, err := customizations.GetPartitioning() + if err != nil { + return nil, err + } + if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && (t.Name() == "edge-container" || t.Name() == "edge-commit") { + return warnings, fmt.Errorf("custom mountpoints and partitioning are not supported for ostree types") + } else if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && !(t.Name() == "edge-container" || t.Name() == "edge-commit") { //customization allowed for edge-raw-image,edge-ami,edge-vsphere,edge-simplified-installer err := blueprint.CheckMountpointsPolicy(mountpoints, policies.OstreeMountpointPolicies) if err != nil { @@ -135,8 +138,19 @@ func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.Ima } } - err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies) - if err != nil { + if len(mountpoints) > 0 && partitioning != nil { + return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)") + } + + if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil { + return warnings, err + } + + if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil { + return warnings, err + } + + if err := partitioning.ValidateLayoutConstraints(); err != nil { return warnings, err }