distro/rhel8: update edge simplified installer to new definitions

This commit is contained in:
Achilleas Koutsou 2023-01-11 20:39:14 +01:00 committed by Tomáš Hozza
parent fe1f61c662
commit b888a170a2
4 changed files with 81 additions and 420 deletions

View file

@ -131,7 +131,6 @@ func edgeSimplifiedInstallerImgType(rd distribution) imageType {
// for other architectures, this will need to be moved to the
// architecture and the merging will happen in the PackageSets()
// method like the other sets.
buildPkgsKey: edgeSimplifiedInstallerBuildPackageSet,
installerPkgsKey: edgeSimplifiedInstallerPackageSet,
},
defaultImageConfig: &distro.ImageConfig{
@ -141,9 +140,9 @@ func edgeSimplifiedInstallerImgType(rd distribution) imageType {
rpmOstree: true,
bootable: true,
bootISO: true,
pipelines: edgeSimplifiedInstallerPipelines,
image: edgeSimplifiedInstallerImage,
buildPipelines: []string{"build"},
payloadPipelines: []string{"image-tree", "image", "archive", "coi-tree", "efiboot-tree", "bootiso-tree", "bootiso"},
payloadPipelines: []string{"image-tree", "image", "xz", "coi-tree", "efiboot-tree", "bootiso-tree", "bootiso"},
exports: []string{"bootiso"},
basePartitionTables: edgeBasePartitionTables,
}
@ -380,22 +379,6 @@ func edgeInstallerBuildPackageSet(t *imageType) rpmmd.PackageSet {
)
}
func edgeSimplifiedInstallerBuildPackageSet(t *imageType) rpmmd.PackageSet {
return edgeInstallerBuildPackageSet(t).Append(
edgeEncryptionBuildPackageSet(t),
)
}
func edgeEncryptionBuildPackageSet(t *imageType) rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{
"clevis",
"clevis-luks",
"cryptsetup",
},
}
}
func edgeServices(rd distribution) []string {
// Common Services
var edgeServices = []string{"NetworkManager.service", "firewalld.service", "sshd.service"}

View file

@ -6,6 +6,8 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/container"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/fdo"
"github.com/osbuild/osbuild-composer/internal/ignition"
"github.com/osbuild/osbuild-composer/internal/image"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/osbuild"
@ -266,3 +268,80 @@ func edgeRawImage(workload workload.Workload,
return img, nil
}
func edgeSimplifiedInstallerImage(workload workload.Workload,
t *imageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.Spec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.FetchChecksum,
}
rawImg := image.NewOSTreeRawImage(commit)
rawImg.Users = users.UsersFromBP(customizations.GetUsers())
rawImg.Groups = users.GroupsFromBP(customizations.GetGroups())
// "rw" kernel option is required when /sysroot is mounted read-only to
// keep stateful parts of the filesystem writeable (/var/ and /etc)
rawImg.KernelOptionsAppend = []string{"modprobe.blacklist=vc4", "rw"}
rawImg.Keyboard = "us"
rawImg.Locale = "C.UTF-8"
rawImg.SysrootReadOnly = true
rawImg.Platform = t.platform
rawImg.Workload = workload
rawImg.Remote = ostree.Remote{
Name: "rhel-edge",
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
rawImg.OSName = "redhat"
// TODO: move generation into LiveImage
pt, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
if err != nil {
return nil, err
}
rawImg.PartitionTable = pt
rawImg.Filename = t.Filename()
img := image.NewOSTreeSimplifiedInstaller(rawImg, customizations.InstallationDevice)
img.ExtraBasePackages = packageSets[installerPkgsKey]
// img.Workload = workload
img.Platform = t.platform
img.Filename = t.Filename()
if bpFDO := customizations.GetFDO(); bpFDO != nil {
img.FDO = fdo.FromBP(*bpFDO)
}
// ignition configs from blueprint
if bpIgnition := customizations.GetIgnition(); bpIgnition != nil {
if bpIgnition.FirstBoot != nil {
img.IgnitionFirstBoot = ignition.FirstbootOptionsFromBP(*bpIgnition.FirstBoot)
}
if bpIgnition.Embedded != nil {
var err error
img.IgnitionEmbedded, err = ignition.EmbeddedOptionsFromBP(*bpIgnition.Embedded)
if err != nil {
return nil, err
}
}
}
d := t.arch.distro
img.ISOLabelTempl = d.isolabelTmpl
img.Product = d.product
img.Variant = "edge"
img.OSName = "redhat"
img.OSVersion = d.osVersion
img.AdditionalDracutModules = []string{"prefixdevname", "prefixdevname-tools"}
return img, nil
}

View file

@ -134,31 +134,6 @@ func edgeContainerPipelines(t *imageType, customizations *blueprint.Customizatio
return pipelines, nil
}
func edgeImagePipelines(t *imageType, customizations *blueprint.Customizations, filename string, options distro.ImageOptions, rng *rand.Rand) ([]osbuild.Pipeline, string, error) {
pipelines := make([]osbuild.Pipeline, 0)
ostreeRepoPath := "/ostree/repo"
imgName := "image.raw"
partitionTable, err := t.getPartitionTable(nil, options, rng)
if err != nil {
return nil, "", err
}
// prepare ostree deployment tree
treePipeline := ostreeDeployPipeline(t, partitionTable, ostreeRepoPath, nil, "", rng, customizations, options)
pipelines = append(pipelines, *treePipeline)
// make raw image from tree
imagePipeline := liveImagePipeline(treePipeline.Name, imgName, partitionTable, t.arch, "")
pipelines = append(pipelines, *imagePipeline)
// compress image
xzPipeline := xzArchivePipeline(imagePipeline.Name, imgName, filename)
pipelines = append(pipelines, *xzPipeline)
return pipelines, xzPipeline.Name, nil
}
func buildPipeline(repos []rpmmd.RepoConfig, buildPackageSpecs []rpmmd.PackageSpec, runner string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "build"
@ -585,263 +560,6 @@ func ostreePayloadStages(options distro.ImageOptions, ostreeRepoPath string) []*
return stages
}
func edgeSimplifiedInstallerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, containers []container.Spec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0)
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner.String()))
installerPackages := packageSetSpecs[installerPkgsKey]
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(installerPackages, "kernel")
imgName := "image.raw.xz"
installDevice := customizations.GetInstallationDevice()
// create the raw image
imagePipelines, imgPipelineName, err := edgeImagePipelines(t, customizations, imgName, options, rng)
if err != nil {
return nil, err
}
pipelines = append(pipelines, imagePipelines...)
// create boot ISO with raw image
d := t.arch.distro
archName := t.Arch().Name()
installerTreePipeline := simplifiedInstallerTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "edge", customizations.GetFDO())
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
efibootTreePipeline := simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel, customizations.GetFDO())
bootISOTreePipeline := simplifiedInstallerBootISOTreePipeline(imgPipelineName, kernelVer, rng)
pipelines = append(pipelines, *installerTreePipeline, *efibootTreePipeline, *bootISOTreePipeline)
pipelines = append(pipelines, *bootISOPipeline(t.Filename(), d.isolabelTmpl, t.Arch().Name(), false))
return pipelines, nil
}
func simplifiedInstallerBootISOTreePipeline(archivePipelineName, kver string, rng *rand.Rand) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "bootiso-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewCopyStageSimple(
&osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{
{
From: "input://file/image.raw.xz",
To: "tree:///image.raw.xz",
},
},
},
osbuild.NewFilesInputs(osbuild.NewFilesInputReferencesPipeline(archivePipelineName, "image.raw.xz")),
))
p.AddStage(osbuild.NewMkdirStage(
&osbuild.MkdirStageOptions{
Paths: []osbuild.Path{
{
Path: "images",
},
{
Path: "images/pxeboot",
},
},
},
))
pt := disk.PartitionTable{
Size: 20971520,
SectorSize: 512,
Partitions: []disk.Partition{
{
Start: 0,
Size: 20971520,
Payload: &disk.Filesystem{
Type: "vfat",
Mountpoint: "/",
UUID: disk.NewVolIDFromRand(rng),
},
},
},
}
filename := "images/efiboot.img"
loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: filename})
p.AddStage(osbuild.NewTruncateStage(&osbuild.TruncateStageOptions{Filename: filename, Size: fmt.Sprintf("%d", pt.Size)}))
for _, stage := range osbuild.GenMkfsStages(&pt, loopback) {
p.AddStage(stage)
}
inputName := "root-tree"
copyInputs := osbuild.NewPipelineTreeInputs(inputName, "efiboot-tree")
copyOptions, copyDevices, copyMounts := osbuild.GenCopyFSTreeOptions(inputName, "efiboot-tree", filename, &pt)
p.AddStage(osbuild.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts))
inputName = "coi"
copyInputs = osbuild.NewPipelineTreeInputs(inputName, "coi-tree")
p.AddStage(osbuild.NewCopyStageSimple(
&osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{
{
From: fmt.Sprintf("input://%s/boot/vmlinuz-%s", inputName, kver),
To: "tree:///images/pxeboot/vmlinuz",
},
{
From: fmt.Sprintf("input://%s/boot/initramfs-%s.img", inputName, kver),
To: "tree:///images/pxeboot/initrd.img",
},
},
},
copyInputs,
))
inputName = "efi-tree"
copyInputs = osbuild.NewPipelineTreeInputs(inputName, "efiboot-tree")
p.AddStage(osbuild.NewCopyStageSimple(
&osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{
{
From: fmt.Sprintf("input://%s/EFI", inputName),
To: "tree:///",
},
},
},
copyInputs,
))
return p
}
func simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string, fdo *blueprint.FDOCustomization) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "efiboot-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewGrubISOStage(grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel, fdo)))
return p
}
func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant string, fdo *blueprint.FDOCustomization) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "coi-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewRPMStage(osbuild.NewRPMStageOptions(repos), osbuild.NewRpmStageSourceFilesInputs(packages)))
p.AddStage(osbuild.NewBuildstampStage(buildStampStageOptions(arch, product, osVersion, variant)))
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"}))
dracutStageOptions := dracutStageOptions(kernelVer, arch, []string{
"coreos-installer",
"fdo",
})
if fdo.HasFDO() && fdo.DiunPubKeyRootCerts != "" {
p.AddStage(osbuild.NewFDOStageForRootCerts(fdo.DiunPubKeyRootCerts))
dracutStageOptions.Install = []string{"/fdo_diun_pub_key_root_certs.pem"}
}
p.AddStage(osbuild.NewDracutStage(dracutStageOptions))
return p
}
func ostreeDeployPipeline(
t *imageType,
pt *disk.PartitionTable,
repoPath string,
kernel *blueprint.KernelCustomization,
kernelVer string,
rng *rand.Rand,
c *blueprint.Customizations,
options distro.ImageOptions,
) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "image-tree"
p.Build = "name:build"
osname := "redhat"
remote := "rhel-edge"
p.AddStage(osbuild.OSTreeInitFsStage())
p.AddStage(osbuild.NewOSTreePullStage(
&osbuild.OSTreePullStageOptions{Repo: repoPath, Remote: remote},
osbuild.NewOstreePullStageInputs("org.osbuild.source", options.OSTree.FetchChecksum, options.OSTree.ImageRef),
))
p.AddStage(osbuild.NewOSTreeOsInitStage(
&osbuild.OSTreeOsInitStageOptions{
OSName: osname,
},
))
p.AddStage(osbuild.NewOSTreeConfigStage(ostreeConfigStageOptions(repoPath, true)))
p.AddStage(osbuild.NewMkdirStage(efiMkdirStageOptions()))
kernelOpts := osbuild.GenImageKernelOptions(pt)
// "rw" kernel option is required when /sysroot is mounted read-only to
// keep stateful parts of the filesystem writeable (/var/ and /etc)
kernelOpts = append(kernelOpts, "rw")
p.AddStage(osbuild.NewOSTreeDeployStage(
&osbuild.OSTreeDeployStageOptions{
OsName: osname,
Ref: options.OSTree.ImageRef,
Remote: remote,
Mounts: []string{"/boot", "/boot/efi"},
Rootfs: osbuild.Rootfs{
Label: "root",
},
KernelOpts: kernelOpts,
},
))
if options.OSTree.URL != "" {
p.AddStage(osbuild.NewOSTreeRemotesStage(
&osbuild.OSTreeRemotesStageOptions{
Repo: "/ostree/repo",
Remotes: []osbuild.OSTreeRemote{
{
Name: remote,
URL: options.OSTree.URL,
},
},
},
))
}
p.AddStage(osbuild.NewOSTreeFillvarStage(
&osbuild.OSTreeFillvarStageOptions{
Deployment: osbuild.OSTreeDeployment{
OSName: osname,
Ref: options.OSTree.ImageRef,
},
},
))
fstabOptions := osbuild.NewFSTabStageOptions(pt)
fstabOptions.OSTree = &osbuild.OSTreeFstab{
Deployment: osbuild.OSTreeDeployment{
OSName: osname,
Ref: options.OSTree.ImageRef,
},
}
p.AddStage(osbuild.NewFSTabStage(fstabOptions))
if bpUsers := c.GetUsers(); len(bpUsers) > 0 {
usersStage, err := osbuild.GenUsersStage(users.UsersFromBP(bpUsers), false)
if err != nil {
panic(err)
}
usersStage.MountOSTree(osname, options.OSTree.ImageRef, 0)
p.AddStage(usersStage)
}
if bpGroups := c.GetGroups(); len(bpGroups) > 0 {
groupsStage := osbuild.GenGroupsStage(users.GroupsFromBP(bpGroups))
groupsStage.MountOSTree(osname, options.OSTree.ImageRef, 0)
p.AddStage(groupsStage)
}
p.AddStage(bootloaderConfigStage(t, *pt, kernel, kernelVer, true, true))
p.AddStage(osbuild.NewOSTreeSelinuxStage(
&osbuild.OSTreeSelinuxStageOptions{
Deployment: osbuild.OSTreeDeployment{
OSName: osname,
Ref: options.OSTree.ImageRef,
},
},
))
return p
}
func anacondaTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant string, users bool) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "anaconda-tree"
@ -924,43 +642,6 @@ func bootISOPipeline(filename, isolabel, arch string, isolinux bool) *osbuild.Pi
return p
}
func liveImagePipeline(inputPipelineName string, outputFilename string, pt *disk.PartitionTable, arch *architecture, kernelVer string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "image"
p.Build = "name:build"
for _, stage := range osbuild.GenImagePrepareStages(pt, outputFilename, osbuild.PTSfdisk) {
p.AddStage(stage)
}
inputName := "root-tree"
copyOptions, copyDevices, copyMounts := osbuild.GenCopyFSTreeOptions(inputName, inputPipelineName, outputFilename, pt)
copyInputs := osbuild.NewPipelineTreeInputs(inputName, inputPipelineName)
p.AddStage(osbuild.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts))
for _, stage := range osbuild.GenImageFinishStages(pt, outputFilename) {
p.AddStage(stage)
}
loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: outputFilename})
p.AddStage(bootloaderInstStage(outputFilename, pt, arch, kernelVer, copyDevices, copyMounts, loopback))
return p
}
func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "archive"
p.Build = "name:build"
p.AddStage(osbuild.NewXzStage(
osbuild.NewXzStageOptions(outputFilename),
osbuild.NewFilesInputs(osbuild.NewFilesInputReferencesPipeline(inputPipelineName, inputFilename)),
))
return p
}
func tarArchivePipeline(name, inputPipelineName string, tarOptions *osbuild.TarStageOptions) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = name
@ -990,16 +671,3 @@ func bootloaderConfigStage(t *imageType, partitionTable disk.PartitionTable, ker
return osbuild.NewGRUB2Stage(options)
}
func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *architecture, kernelVer string, devices *osbuild.Devices, mounts *osbuild.Mounts, disk *osbuild.Device) *osbuild.Stage {
platform := arch.legacy
if platform != "" {
return osbuild.NewGrub2InstStage(osbuild.NewGrub2InstStageOption(filename, pt, platform))
}
if arch.name == distro.S390xArchName {
return osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(kernelVer, pt), disk, devices, mounts)
}
return nil
}

View file

@ -2,7 +2,6 @@ package rhel8
import (
"fmt"
"os"
"path/filepath"
"github.com/osbuild/osbuild-composer/internal/blueprint"
@ -215,51 +214,6 @@ func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolab
}
}
func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string, fdo *blueprint.FDOCustomization) *osbuild.GrubISOStageOptions {
var architectures []string
if arch == distro.X86_64ArchName {
architectures = []string{"IA32", "X64"}
} else if arch == distro.Aarch64ArchName {
architectures = []string{"AA64"}
} else {
panic("unsupported architecture")
}
grubISOStageOptions := &osbuild.GrubISOStageOptions{
Product: osbuild.Product{
Name: product,
Version: osVersion,
},
ISOLabel: isolabel,
Kernel: osbuild.ISOKernel{
Dir: "/images/pxeboot",
Opts: []string{"rd.neednet=1",
"coreos.inst.crypt_root=1",
"coreos.inst.isoroot=" + isolabel,
"coreos.inst.install_dev=" + installDevice,
"coreos.inst.image_file=/run/media/iso/image.raw.xz",
"coreos.inst.insecure"},
},
Architectures: architectures,
Vendor: vendor,
}
if fdo.HasFDO() {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL)
if fdo.DiunPubKeyInsecure != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure)
}
if fdo.DiunPubKeyHash != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash)
}
if fdo.DiunPubKeyRootCerts != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem")
}
}
return grubISOStageOptions
}
func discinfoStageOptions(arch string) *osbuild.DiscinfoStageOptions {
return &osbuild.DiscinfoStageOptions{
BaseArch: arch,
@ -309,26 +263,3 @@ func chmodStageOptions(path, mode string, recursive bool) *osbuild.ChmodStageOpt
},
}
}
func ostreeConfigStageOptions(repo string, readOnly bool) *osbuild.OSTreeConfigStageOptions {
return &osbuild.OSTreeConfigStageOptions{
Repo: repo,
Config: &osbuild.OSTreeConfig{
Sysroot: &osbuild.SysrootOptions{
ReadOnly: common.ToPtr(readOnly),
Bootloader: "none",
},
},
}
}
func efiMkdirStageOptions() *osbuild.MkdirStageOptions {
return &osbuild.MkdirStageOptions{
Paths: []osbuild.Path{
{
Path: "/boot/efi",
Mode: os.FileMode(0700),
},
},
}
}