diff --git a/cmd/osbuild-playground/playground.go b/cmd/osbuild-playground/playground.go index 97579d54f..cf2379cd1 100644 --- a/cmd/osbuild-playground/playground.go +++ b/cmd/osbuild-playground/playground.go @@ -2,6 +2,7 @@ package main import ( "github.com/osbuild/osbuild-composer/internal/manifest" + "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) @@ -31,7 +32,7 @@ func MyManifest(m *manifest.Manifest, options *MyOptions, repos []rpmmd.RepoConf build := manifest.NewBuildPipeline(m, runner, repos) // create a non-bootable OS tree containing the `core` comps group - os := manifest.NewOSPipeline(m, build, manifest.ARCH_X86_64, repos) + os := manifest.NewOSPipeline(m, build, &platform.X86{}, repos) os.ExtraBasePackages = []string{ "@core", } diff --git a/internal/distro/fedora/distro.go b/internal/distro/fedora/distro.go index fca290281..3a5d85eb9 100644 --- a/internal/distro/fedora/distro.go +++ b/internal/distro/fedora/distro.go @@ -11,6 +11,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/manifest" + "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) @@ -273,7 +274,6 @@ var ( defaultImageConfig: defaultEc2ImageConfig, kernelOptions: defaultKernelOptions, bootable: true, - bootType: distro.LegacyBootType, defaultSize: 6 * GigaByte, manifest: ec2Manifest, buildPipelines: []string{"build"}, @@ -421,8 +421,6 @@ type architecture struct { name string imageTypes map[string]distro.ImageType imageTypeAliases map[string]string - legacy string - bootType distro.BootType } func (a *architecture) Name() string { @@ -453,13 +451,14 @@ func (a *architecture) GetImageType(name string) (distro.ImageType, error) { return t, nil } -func (a *architecture) addImageTypes(imageTypes ...imageType) { +func (a *architecture) addImageTypes(platform platform.Platform, imageTypes ...imageType) { if a.imageTypes == nil { a.imageTypes = map[string]distro.ImageType{} } for idx := range imageTypes { it := imageTypes[idx] it.arch = a + it.platform = platform a.imageTypes[it.name] = &it for _, alias := range it.nameAliases { if a.imageTypeAliases == nil { @@ -483,6 +482,7 @@ type packageSetFunc func(t *imageType) rpmmd.PackageSet type imageType struct { arch *architecture + platform platform.Platform name string nameAliases []string filename string @@ -503,8 +503,6 @@ type imageType struct { rpmOstree bool // bootable image bootable bool - // If set to a value, it is preferred over the architecture value - bootType distro.BootType // List of valid arches for the image type basePartitionTables distro.BasePartitionTableMap } @@ -581,9 +579,9 @@ func (t *imageType) PackageSets(bp blueprint.Blueprint, options distro.ImageOpti // the layout is converted to LVM so we need to corresponding packages if t.bootable && !t.rpmOstree { - pt, exists := t.basePartitionTables[t.arch.Name()] + pt, exists := t.basePartitionTables[t.platform.GetArch().String()] if !exists { - panic(fmt.Sprintf("unknown architecture with boot type: %s %s", t.arch.Name(), t.bootType)) + panic(fmt.Sprintf("unknown no partition table for architecture %s", t.platform.GetArch().String())) } haveNewMountpoint := false @@ -643,23 +641,6 @@ func (t *imageType) Exports() []string { return []string{"assembler"} } -// getBootType returns the BootType which should be used for this particular -// combination of architecture and image type. -func (t *imageType) getBootType() distro.BootType { - bootType := t.arch.bootType - if t.bootType != distro.UnsetBootType { - if bootType == distro.HybridBootType { - bootType = t.bootType - } - } - return bootType -} - -func (t *imageType) supportsUEFI() bool { - bootType := t.getBootType() - return bootType == distro.HybridBootType || bootType == distro.UEFIBootType -} - func (t *imageType) getPartitionTable( mountpoints []blueprint.FilesystemCustomization, options distro.ImageOptions, @@ -794,51 +775,99 @@ func newDistro(distroName string) distro.Distro { // Architecture definitions x86_64 := architecture{ - name: distro.X86_64ArchName, - distro: &rd, - legacy: "i386-pc", - bootType: distro.HybridBootType, + name: distro.X86_64ArchName, + distro: &rd, } aarch64 := architecture{ - name: distro.Aarch64ArchName, - distro: &rd, - bootType: distro.UEFIBootType, + name: distro.Aarch64ArchName, + distro: &rd, } s390x := architecture{ - distro: &rd, - name: distro.S390xArchName, - bootType: distro.LegacyBootType, + distro: &rd, + name: distro.S390xArchName, } ociImgType := qcow2ImgType ociImgType.name = "oci" x86_64.addImageTypes( - amiImgType, - containerImgType, + &platform.X86{ + BIOS: true, + UEFIVendor: "fedora", + }, qcow2ImgType, openstackImgType, vhdImgType, vmdkImgType, ociImgType, + ) + x86_64.addImageTypes( + &platform.X86{ + BIOS: true, + }, + amiImgType, + ) + x86_64.addImageTypes( + &platform.X86{}, + containerImgType, + ) + x86_64.addImageTypes( + &platform.X86{ + BasePlatform: platform.BasePlatform{ + FirmwarePackages: []string{ + "microcode_ctl", // ?? + "iwl1000-firmware", + "iwl100-firmware", + "iwl105-firmware", + "iwl135-firmware", + "iwl2000-firmware", + "iwl2030-firmware", + "iwl3160-firmware", + "iwl5000-firmware", + "iwl5150-firmware", + "iwl6000-firmware", + "iwl6050-firmware", + }, + }, + BIOS: true, + UEFIVendor: "fedora", + }, iotOCIImgType, iotCommitImgType, iotInstallerImgType, ) aarch64.addImageTypes( + &platform.Aarch64{ + UEFIVendor: "fedora", + }, amiImgType, - containerImgType, qcow2ImgType, openstackImgType, ociImgType, + ) + aarch64.addImageTypes( + &platform.Aarch64{}, + containerImgType, + ) + aarch64.addImageTypes( + &platform.Aarch64{ + BasePlatform: platform.BasePlatform{ + FirmwarePackages: []string{ + "uboot-images-armv8", // ?? + "bcm283x-firmware", + "arm-image-installer", // ?? + }, + }, + UEFIVendor: "fedora", + }, iotCommitImgType, iotOCIImgType, iotInstallerImgType, ) - s390x.addImageTypes() + s390x.addImageTypes(nil) rd.addArches(x86_64, aarch64, s390x) return &rd diff --git a/internal/distro/fedora/manifests.go b/internal/distro/fedora/manifests.go index 53490dd22..b15dd4344 100644 --- a/internal/distro/fedora/manifests.go +++ b/internal/distro/fedora/manifests.go @@ -208,19 +208,7 @@ func osPipeline(m *manifest.Manifest, imageConfig := t.getDefaultImageConfig() - var arch manifest.Arch - switch t.Arch().Name() { - case distro.X86_64ArchName: - arch = manifest.ARCH_X86_64 - case distro.Aarch64ArchName: - arch = manifest.ARCH_AARCH64 - case distro.Ppc64leArchName: - arch = manifest.ARCH_PPC64LE - case distro.S390xArchName: - arch = manifest.ARCH_S390X - } - - pl := manifest.NewOSPipeline(m, buildPipeline, arch, repos) + pl := manifest.NewOSPipeline(m, buildPipeline, t.platform, repos) if t.bootable { var err error @@ -232,12 +220,6 @@ func osPipeline(m *manifest.Manifest, } if t.bootable || t.rpmOstree { - if t.supportsUEFI() { - pl.UEFIVendor = t.arch.distro.vendor - } - - pl.BIOSPlatform = t.arch.legacy - pl.KernelName = c.GetKernel().Name var kernelOptions []string diff --git a/internal/distro/fedora/package_sets.go b/internal/distro/fedora/package_sets.go index 07377c38e..ad8b083ce 100644 --- a/internal/distro/fedora/package_sets.go +++ b/internal/distro/fedora/package_sets.go @@ -235,46 +235,11 @@ func iotCommitPackageSet(t *imageType) rpmmd.PackageSet { "iwlax2xx-firmware", }, } - switch t.Arch().Name() { - case distro.X86_64ArchName: - ps = ps.Append(x8664IOTCommitPackageSet()) - - case distro.Aarch64ArchName: - ps = ps.Append(aarch64IOTCommitPackageSet()) - } return ps } -func x8664IOTCommitPackageSet() rpmmd.PackageSet { - return rpmmd.PackageSet{ - Include: []string{ - "microcode_ctl", - "iwl1000-firmware", - "iwl100-firmware", - "iwl105-firmware", - "iwl135-firmware", - "iwl2000-firmware", - "iwl2030-firmware", - "iwl3160-firmware", - "iwl5000-firmware", - "iwl5150-firmware", - "iwl6000-firmware", - "iwl6050-firmware", - }, - } -} - -func aarch64IOTCommitPackageSet() rpmmd.PackageSet { - return rpmmd.PackageSet{ - Include: []string{ - "uboot-images-armv8", - "bcm283x-firmware", - "arm-image-installer"}, - } -} - // INSTALLER PACKAGE SET func installerPackageSet(t *imageType) rpmmd.PackageSet { diff --git a/internal/manifest/live.go b/internal/manifest/live.go index 1260704b9..44688c8e4 100644 --- a/internal/manifest/live.go +++ b/internal/manifest/live.go @@ -2,6 +2,7 @@ package manifest import ( "github.com/osbuild/osbuild-composer/internal/osbuild2" + "github.com/osbuild/osbuild-composer/internal/platform" ) // A LiveImgPipeline represents a raw image file which can be booted in a @@ -51,12 +52,12 @@ func (p *LiveImgPipeline) serialize() osbuild2.Pipeline { pipeline.AddStage(stage) } - switch p.treePipeline.arch { - case ARCH_S390X: + switch p.treePipeline.platform.GetArch() { + case platform.ARCH_S390X: loopback := osbuild2.NewLoopbackDevice(&osbuild2.LoopbackDeviceOptions{Filename: p.filename}) pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.treePipeline.kernelVer, pt), loopback, copyDevices, copyMounts)) default: - if grubLegacy := p.treePipeline.BIOSPlatform; grubLegacy != "" { + if grubLegacy := p.treePipeline.platform.GetBIOSPlatform(); grubLegacy != "" { pipeline.AddStage(osbuild2.NewGrub2InstStage(osbuild2.NewGrub2InstStageOption(p.filename, pt, grubLegacy))) } } diff --git a/internal/manifest/os.go b/internal/manifest/os.go index 3289a7cfd..f7055e74d 100644 --- a/internal/manifest/os.go +++ b/internal/manifest/os.go @@ -9,6 +9,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/common" "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/osbuild2" + "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) @@ -49,12 +50,6 @@ type OSPipeline struct { KernelOptionsAppend []string // UEFIVendor indicates whether or not the image should support UEFI and // if set namespaces the UEFI binaries with this string. - UEFIVendor string - // BIOSPlatform indicates whether or not the image should support BIOS - // booting and if set, the name of the platform, e.g., i386-pc - BIOSPlatform string - // GPGKeyFiles are a list of filenames in the OS which will be imported - // as GPG keys into the RPM database. GPGKeyFiles []string Language string Keyboard *string @@ -98,7 +93,7 @@ type OSPipeline struct { repos []rpmmd.RepoConfig packageSpecs []rpmmd.PackageSpec - arch Arch + platform platform.Platform kernelVer string } @@ -110,12 +105,12 @@ type OSPipeline struct { // kernel package that will be used on the target system. func NewOSPipeline(m *Manifest, buildPipeline *BuildPipeline, - arch Arch, + platform platform.Platform, repos []rpmmd.RepoConfig) *OSPipeline { p := &OSPipeline{ BasePipeline: NewBasePipeline(m, "os", buildPipeline, nil), repos: repos, - arch: arch, + platform: platform, Language: "C.UTF-8", Hostname: "localhost.localdomain", Timezone: "UTC", @@ -127,34 +122,7 @@ func NewOSPipeline(m *Manifest, } func (p *OSPipeline) getPackageSetChain() []rpmmd.PackageSet { - packages := []string{} - - switch p.arch { - case ARCH_X86_64: - if p.BIOSPlatform != "" { - packages = append(packages, - "dracut-config-generic", - "grub2-pc") - } - if p.UEFIVendor != "" { - packages = append(packages, - "dracut-config-generic", - "efibootmgr", - "grub2-efi-x64", - "shim-x64") - } - case ARCH_AARCH64: - if p.UEFIVendor != "" { - packages = append(packages, - "dracut-config-generic", - "efibootmgr", - "grub2-efi-aa64", - "grub2-tools", - "shim-aa64") - } - default: - panic("unsupported architecture") - } + packages := p.platform.GetPackages() chain := []rpmmd.PackageSet{ { @@ -175,10 +143,7 @@ func (p *OSPipeline) getPackageSetChain() []rpmmd.PackageSet { } func (p *OSPipeline) getBuildPackages() []string { - packages := []string{} - if p.BIOSPlatform != "" { - packages = append(packages, "grub2-pc") - } + packages := p.platform.GetBuildPackages() if p.OSTree != nil { packages = append(packages, "rpm-ostree") } @@ -383,11 +348,15 @@ func (p *OSPipeline) serialize() osbuild2.Pipeline { pipeline.AddStage(osbuild2.NewFSTabStage(osbuild2.NewFSTabStageOptions(pt))) var bootloader *osbuild2.Stage - switch p.arch { - case ARCH_S390X: + switch p.platform.GetArch() { + case platform.ARCH_S390X: bootloader = osbuild2.NewZiplStage(new(osbuild2.ZiplStageOptions)) default: - options := osbuild2.NewGrub2StageOptionsUnified(pt, p.kernelVer, p.UEFIVendor != "", p.BIOSPlatform, p.UEFIVendor, false) + options := osbuild2.NewGrub2StageOptionsUnified(pt, + p.kernelVer, + p.platform.GetUEFIVendor() != "", + p.platform.GetBIOSPlatform(), + p.platform.GetUEFIVendor(), false) if cfg := p.Grub2Config; cfg != nil { // TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary // grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified` diff --git a/internal/platform/aarch64.go b/internal/platform/aarch64.go new file mode 100644 index 000000000..2a55a697c --- /dev/null +++ b/internal/platform/aarch64.go @@ -0,0 +1,29 @@ +package platform + +type Aarch64 struct { + BasePlatform + UEFIVendor string +} + +func (p *Aarch64) GetArch() Arch { + return ARCH_AARCH64 +} + +func (p *Aarch64) GetUEFIVendor() string { + return p.UEFIVendor +} + +func (p *Aarch64) GetPackages() []string { + packages := p.BasePlatform.FirmwarePackages + + if p.UEFIVendor != "" { + packages = append(packages, + "dracut-config-generic", + "efibootmgr", + "grub2-efi-aa64", + "grub2-tools", + "shim-aa64") + } + + return packages +} diff --git a/internal/platform/platform.go b/internal/platform/platform.go new file mode 100644 index 000000000..259ab9cef --- /dev/null +++ b/internal/platform/platform.go @@ -0,0 +1,58 @@ +package platform + +type Arch uint64 + +const ( + ARCH_AARCH64 Arch = iota + ARCH_PPC64LE + ARCH_S390X + ARCH_X86_64 +) + +func (a Arch) String() string { + switch a { + case ARCH_AARCH64: + return "aarch64" + case ARCH_PPC64LE: + return "ppc64le" + case ARCH_S390X: + return "s390x" + case ARCH_X86_64: + return "x86_64" + default: + panic("invalid architecture") + } +} + +type Platform interface { + GetArch() Arch + GetBIOSPlatform() string + GetUEFIVendor() string + GetZiplSupport() bool + GetPackages() []string + GetBuildPackages() []string +} + +type BasePlatform struct { + FirmwarePackages []string +} + +func (p BasePlatform) GetBIOSPlatform() string { + return "" +} + +func (p BasePlatform) GetUEFIVendor() string { + return "" +} + +func (p BasePlatform) GetZiplSupport() bool { + return false +} + +func (p BasePlatform) GetPackages() []string { + return p.FirmwarePackages +} + +func (p BasePlatform) GetBuildPackages() []string { + return []string{} +} diff --git a/internal/platform/x86_64.go b/internal/platform/x86_64.go new file mode 100644 index 000000000..d9403b2f7 --- /dev/null +++ b/internal/platform/x86_64.go @@ -0,0 +1,52 @@ +package platform + +type X86BootLoader uint64 + +type X86 struct { + BasePlatform + BIOS bool + UEFIVendor string +} + +func (p *X86) GetArch() Arch { + return ARCH_X86_64 +} + +func (p *X86) GetBIOSPlatform() string { + if p.BIOS { + return "i386-pc" + } + return "" +} + +func (p *X86) GetUEFIVendor() string { + return p.UEFIVendor +} + +func (p *X86) GetPackages() []string { + packages := p.BasePlatform.FirmwarePackages + + if p.BIOS { + packages = append(packages, + "dracut-config-generic", + "grub2-pc") + } + + if p.UEFIVendor != "" { + packages = append(packages, + "dracut-config-generic", + "efibootmgr", + "grub2-efi-x64", + "shim-x64") + } + + return packages +} + +func (p *X86) GetBuildPackages() []string { + packages := []string{} + if p.BIOS { + packages = append(packages, "grub2-pc") + } + return packages +}