distro/rhel9: add the edge-ami image type based on edgeRawImage

Creates the 'edge-ami' image type based on edgeRawImage, which generates
a raw image (x86_64, aarch64) ready to upload to AWS EC2.

This 'edge-ami' image type has Ignition support.

Signed-off-by: Irene Diez <idiez@redhat.com>
This commit is contained in:
Irene Diez 2023-04-28 16:09:47 +02:00 committed by Tomáš Hozza
parent 76b9906332
commit a8f7ff487d
25 changed files with 72007 additions and 16 deletions

View file

@ -253,6 +253,7 @@ func TestDistro_KernelOption(t *testing.T, d distro.Distro) {
"edge-simplified-installer": true, "edge-simplified-installer": true,
"iot-raw-image": true, "iot-raw-image": true,
"edge-raw-image": true, "edge-raw-image": true,
"edge-ami": true,
// the tar image type is a minimal image type which is not expected to // the tar image type is a minimal image type which is not expected to
// be usable without a blueprint (see commit 83a63aaf172f556f6176e6099ffaa2b5357b58f5). // be usable without a blueprint (see commit 83a63aaf172f556f6176e6099ffaa2b5357b58f5).

View file

@ -144,6 +144,7 @@ var (
name: "iot-raw-image", name: "iot-raw-image",
nameAliases: []string{"fedora-iot-raw-image"}, nameAliases: []string{"fedora-iot-raw-image"},
filename: "image.raw.xz", filename: "image.raw.xz",
compression: "xz",
mimeType: "application/xz", mimeType: "application/xz",
packageSets: map[string]packageSetFunc{}, packageSets: map[string]packageSetFunc{},
defaultImageConfig: &distro.ImageConfig{ defaultImageConfig: &distro.ImageConfig{

View file

@ -447,6 +447,7 @@ func iotRawImage(workload workload.Workload,
img.PartitionTable = pt img.PartitionTable = pt
img.Filename = t.Filename() img.Filename = t.Filename()
img.Compression = t.compression
return img, nil return img, nil
} }

View file

@ -33,6 +33,7 @@ type imageType struct {
name string name string
nameAliases []string nameAliases []string
filename string filename string
compression string
mimeType string mimeType string
packageSets map[string]packageSetFunc packageSets map[string]packageSetFunc
defaultImageConfig *distro.ImageConfig defaultImageConfig *distro.ImageConfig

View file

@ -62,6 +62,7 @@ func edgeRawImgType() imageType {
name: "edge-raw-image", name: "edge-raw-image",
nameAliases: []string{"rhel-edge-raw-image"}, nameAliases: []string{"rhel-edge-raw-image"},
filename: "image.raw.xz", filename: "image.raw.xz",
compression: "xz",
mimeType: "application/xz", mimeType: "application/xz",
packageSets: nil, packageSets: nil,
defaultSize: 10 * common.GibiByte, defaultSize: 10 * common.GibiByte,

View file

@ -461,6 +461,7 @@ func edgeRawImage(workload workload.Workload,
img.PartitionTable = pt img.PartitionTable = pt
img.Filename = t.Filename() img.Filename = t.Filename()
img.Compression = t.compression
return img, nil return img, nil
} }

View file

@ -318,6 +318,7 @@ func newDistro(name string, minor int) *distribution {
edgeInstallerImgType, edgeInstallerImgType,
edgeRawImgType, edgeRawImgType,
imageInstaller, imageInstaller,
edgeAMIImgType,
) )
x86_64.addImageTypes( x86_64.addImageTypes(
@ -361,6 +362,7 @@ func newDistro(name string, minor int) *distribution {
edgeInstallerImgType, edgeInstallerImgType,
edgeSimplifiedInstallerImgType, edgeSimplifiedInstallerImgType,
imageInstaller, imageInstaller,
edgeAMIImgType,
) )
aarch64.addImageTypes( aarch64.addImageTypes(
&platform.Aarch64{ &platform.Aarch64{

View file

@ -196,6 +196,14 @@ func TestFilenameFromType(t *testing.T) {
mimeType: "application/gzip", mimeType: "application/gzip",
}, },
}, },
{
name: "edge-ami",
args: args{"edge-ami"},
want: wantResult{
filename: "image.raw",
mimeType: "application/octet-stream",
},
},
{ {
name: "invalid-output-type", name: "invalid-output-type",
args: args{"foobar"}, args: args{"foobar"},
@ -461,8 +469,8 @@ func TestDistro_ManifestError(t *testing.T) {
_, _, err := imgType.Manifest(&bp, imgOpts, nil, 0) _, _, err := imgType.Manifest(&bp, imgOpts, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" { if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
assert.EqualError(t, err, "kernel boot parameter customizations are not supported for ostree types") assert.EqualError(t, err, "kernel boot parameter customizations are not supported for ostree types")
} else if imgTypeName == "edge-raw-image" { } else if imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" {
assert.EqualError(t, err, "edge raw images require specifying a URL from which to retrieve the OSTree commit") assert.EqualError(t, err, fmt.Sprintf("\"%s\" images require specifying a URL from which to retrieve the OSTree commit", imgTypeName))
} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" { } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" {
assert.EqualError(t, err, fmt.Sprintf("boot ISO image type \"%s\" requires specifying a URL from which to retrieve the OSTree commit", imgTypeName)) assert.EqualError(t, err, fmt.Sprintf("boot ISO image type \"%s\" requires specifying a URL from which to retrieve the OSTree commit", imgTypeName))
} else { } else {
@ -496,6 +504,7 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
"edge-installer", "edge-installer",
"edge-raw-image", "edge-raw-image",
"edge-simplified-installer", "edge-simplified-installer",
"edge-ami",
"gce", "gce",
"gce-rhui", "gce-rhui",
"tar", "tar",
@ -515,6 +524,7 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
"edge-installer", "edge-installer",
"edge-simplified-installer", "edge-simplified-installer",
"edge-raw-image", "edge-raw-image",
"edge-ami",
"tar", "tar",
"image-installer", "image-installer",
"vhd", "vhd",
@ -634,7 +644,7 @@ func TestDistro_CustomFileSystemManifestError(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" { 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 imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" { } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" {
continue continue
} else { } else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/etc\"]") assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/etc\"]")
@ -662,7 +672,7 @@ func TestDistro_TestRootMountPoint(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" { 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 imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" { } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" {
continue continue
} else { } else {
assert.NoError(t, err) assert.NoError(t, err)
@ -796,7 +806,7 @@ func TestDistro_CustomFileSystemPatternMatching(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" { 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 imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" { } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" {
continue continue
} else { } else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/variable\" \"/variable/log/audit\"]") assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/variable\" \"/variable/log/audit\"]")
@ -824,7 +834,7 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if imgTypeName == "edge-commit" || imgTypeName == "edge-container" { 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 imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" { } else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" || imgTypeName == "edge-ami" {
continue continue
} else { } else {
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -6,6 +6,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/common" "github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/environment"
"github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd" "github.com/osbuild/osbuild-composer/internal/rpmmd"
) )
@ -58,6 +59,7 @@ var (
name: "edge-raw-image", name: "edge-raw-image",
nameAliases: []string{"rhel-edge-raw-image"}, nameAliases: []string{"rhel-edge-raw-image"},
filename: "image.raw.xz", filename: "image.raw.xz",
compression: "xz",
mimeType: "application/xz", mimeType: "application/xz",
packageSets: nil, packageSets: nil,
defaultImageConfig: &distro.ImageConfig{ defaultImageConfig: &distro.ImageConfig{
@ -130,6 +132,27 @@ var (
basePartitionTables: edgeBasePartitionTables, basePartitionTables: edgeBasePartitionTables,
} }
edgeAMIImgType = imageType{
name: "edge-ami",
filename: "image.raw",
mimeType: "application/octet-stream",
packageSets: nil,
defaultImageConfig: &distro.ImageConfig{
Locale: common.ToPtr("en_US.UTF-8"),
},
defaultSize: 10 * common.GibiByte,
rpmOstree: true,
bootable: true,
bootISO: false,
image: edgeRawImage,
buildPipelines: []string{"build"},
payloadPipelines: []string{"ostree-deployment", "image"},
exports: []string{"image"},
basePartitionTables: edgeBasePartitionTables,
environment: &environment.EC2{},
}
// Shared Services // Shared Services
edgeServices = []string{ edgeServices = []string{
// TODO(runcom): move fdo-client-linuxapp.service to presets? // TODO(runcom): move fdo-client-linuxapp.service to presets?

View file

@ -428,6 +428,7 @@ func edgeRawImage(workload workload.Workload,
img.PartitionTable = pt img.PartitionTable = pt
img.Filename = t.Filename() img.Filename = t.Filename()
img.Compression = t.compression
return img, nil return img, nil
} }

View file

@ -341,10 +341,10 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp
} }
} }
if t.name == "edge-raw-image" { if t.name == "edge-raw-image" || t.name == "edge-ami" {
// check the checksum instead of the URL, because the URL should have been used to resolve the checksum and we need both // check the checksum instead of the URL, because the URL should have been used to resolve the checksum and we need both
if ostreeChecksum == "" { if ostreeChecksum == "" {
return warnings, fmt.Errorf("edge raw images require specifying a URL from which to retrieve the OSTree commit") return warnings, fmt.Errorf("%q images require specifying a URL from which to retrieve the OSTree commit", t.name)
} }
allowed := []string{"Ignition", "Kernel", "User", "Group"} allowed := []string{"Ignition", "Kernel", "User", "Group"}

View file

@ -1,6 +1,7 @@
package image package image
import ( import (
"fmt"
"math/rand" "math/rand"
"github.com/osbuild/osbuild-composer/internal/artifact" "github.com/osbuild/osbuild-composer/internal/artifact"
@ -38,6 +39,8 @@ type OSTreeRawImage struct {
Filename string Filename string
Compression string
Ignition bool Ignition bool
Directories []*fsnode.Directory Directories []*fsnode.Directory
@ -52,6 +55,15 @@ func NewOSTreeRawImage(commit ostree.CommitSpec) *OSTreeRawImage {
} }
func ostreeCompressedImagePipelines(img *OSTreeRawImage, m *manifest.Manifest, buildPipeline *manifest.Build) *manifest.XZ { func ostreeCompressedImagePipelines(img *OSTreeRawImage, m *manifest.Manifest, buildPipeline *manifest.Build) *manifest.XZ {
imagePipeline := baseRawOstreeImage(img, m, buildPipeline)
xzPipeline := manifest.NewXZ(m, buildPipeline, imagePipeline)
xzPipeline.Filename = img.Filename
return xzPipeline
}
func baseRawOstreeImage(img *OSTreeRawImage, m *manifest.Manifest, buildPipeline *manifest.Build) *manifest.RawOSTreeImage {
osPipeline := manifest.NewOSTreeDeployment(m, buildPipeline, img.Commit, img.OSName, img.Ignition, img.Platform) osPipeline := manifest.NewOSTreeDeployment(m, buildPipeline, img.Commit, img.OSName, img.Ignition, img.Platform)
osPipeline.PartitionTable = img.PartitionTable osPipeline.PartitionTable = img.PartitionTable
osPipeline.Remote = img.Remote osPipeline.Remote = img.Remote
@ -68,12 +80,7 @@ func ostreeCompressedImagePipelines(img *OSTreeRawImage, m *manifest.Manifest, b
osPipeline.EnabledServices = img.Workload.GetServices() osPipeline.EnabledServices = img.Workload.GetServices()
osPipeline.DisabledServices = img.Workload.GetDisabledServices() osPipeline.DisabledServices = img.Workload.GetDisabledServices()
imagePipeline := manifest.NewRawOStreeImage(m, buildPipeline, img.Platform, osPipeline) return manifest.NewRawOStreeImage(m, buildPipeline, img.Platform, osPipeline)
xzPipeline := manifest.NewXZ(m, buildPipeline, imagePipeline)
xzPipeline.Filename = img.Filename
return xzPipeline
} }
func (img *OSTreeRawImage) InstantiateManifest(m *manifest.Manifest, func (img *OSTreeRawImage) InstantiateManifest(m *manifest.Manifest,
@ -83,8 +90,18 @@ func (img *OSTreeRawImage) InstantiateManifest(m *manifest.Manifest,
buildPipeline := manifest.NewBuild(m, runner, repos) buildPipeline := manifest.NewBuild(m, runner, repos)
buildPipeline.Checkpoint() buildPipeline.Checkpoint()
xzPipeline := ostreeCompressedImagePipelines(img, m, buildPipeline) var art *artifact.Artifact
switch img.Compression {
case "xz":
ostreeCompressed := ostreeCompressedImagePipelines(img, m, buildPipeline)
art = ostreeCompressed.Export()
case "":
ostreeBase := baseRawOstreeImage(img, m, buildPipeline)
ostreeBase.Filename = img.Filename
art = ostreeBase.Export()
default:
panic(fmt.Sprintf("unsupported compression type %q on %q", img.Compression, img.name))
}
art := xzPipeline.Export()
return art, nil return art, nil
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -866,6 +866,22 @@
"blueprint": {} "blueprint": {}
}, },
"overrides": {} "overrides": {}
},
"edge-ami": {
"compose-request": {
"distro": "",
"arch": "",
"image-type": "edge-ami",
"repositories": [],
"filename": "image.raw",
"ostree": {
"ref": "test/edge",
"url": "http://edge.example.com/repo",
"parent": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
},
"blueprint": {}
},
"overrides": {}
}, },
"oci": { "oci": {
"compose-request": { "compose-request": {