From bf61ca422f68b6947a231a02cc80df12739151a9 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Tue, 29 Jun 2021 16:18:37 +0200 Subject: [PATCH] distro/rhel85: introduce the qcow2 image type - distro definition - qcow2 package set - pipeline generation function (unfinished) --- internal/distro/rhel85/distro.go | 37 +++++++++++-- internal/distro/rhel85/package_sets.go | 76 +++++++++++++++++++++++++- internal/distro/rhel85/pipelines.go | 48 +++++++++++++++- 3 files changed, 152 insertions(+), 9 deletions(-) diff --git a/internal/distro/rhel85/distro.go b/internal/distro/rhel85/distro.go index 0d897a3ba..60b60a6ea 100644 --- a/internal/distro/rhel85/distro.go +++ b/internal/distro/rhel85/distro.go @@ -74,6 +74,8 @@ type architecture struct { name string imageTypes map[string]distro.ImageType packageSets map[string]rpmmd.PackageSet + legacy string + uefi bool } func (a *architecture) Name() string { @@ -123,6 +125,7 @@ type imageType struct { enabledServices []string disabledServices []string defaultTarget string + kernelOptions string defaultSize uint64 exports []string pipelines pipelinesFunc @@ -324,6 +327,8 @@ func NewHostDistro(name, modulePlatformID, ostreeRef string) distro.Distro { } func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { + const GigaByte = 1024 * 1024 * 1024 + rd := &distribution{ name: name, modulePlatformID: modulePlatformID, @@ -509,6 +514,24 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { packageSets: map[string]rpmmd.PackageSet{ "boot": x8664BootPackageSet(), }, + legacy: "i386-pc", + uefi: true, + } + + qcow2ImageType := imageType{ + name: "qcow2", + filename: "disk.qcow2", + mimeType: "application/x-qemu-disk", + defaultTarget: "multi-user.target", + kernelOptions: "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto", + packageSets: map[string]rpmmd.PackageSet{ + "build": x8664BuildPackageSet(), + "packages": qcow2CommonPkgSet(), + }, + bootable: true, + defaultSize: 10 * GigaByte, + pipelines: qcow2Pipelines, + exports: []string{"qcow2"}, } tarImgType := imageType{ @@ -584,7 +607,8 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { pipelines: edgeInstallerPipelines, exports: []string{"bootiso"}, } - x86_64.addImageTypes(tarImgType, tarInstallerImgTypeX86_64, edgeCommitImgTypeX86_64, edgeInstallerImgTypeX86_64, edgeOCIImgTypeX86_64) + x86_64.addImageTypes(qcow2ImageType, tarImgType, tarInstallerImgTypeX86_64, edgeCommitImgTypeX86_64, edgeInstallerImgTypeX86_64, edgeOCIImgTypeX86_64) + aarch64 := architecture{ name: "aarch64", distro: rd, @@ -592,7 +616,7 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { "boot": aarch64BootPackageSet(), }, } - aarch64.addImageTypes(tarImgType, edgeCommitImgTypeAarch64, edgeOCIImgTypeAarch64, edgeInstallerImgTypeAarch64) + aarch64.addImageTypes(qcow2ImageType, tarImgType, edgeCommitImgTypeAarch64, edgeOCIImgTypeAarch64, edgeInstallerImgTypeAarch64) ppc64le := architecture{ distro: rd, @@ -600,16 +624,21 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { packageSets: map[string]rpmmd.PackageSet{ "boot": ppc64leBootPackageSet(), }, + legacy: "powerpc-ieee1275", + uefi: false, } - ppc64le.addImageTypes(tarImgType) + ppc64le.addImageTypes(qcow2ImageType, tarImgType) + s390x := architecture{ distro: rd, name: "s390x", packageSets: map[string]rpmmd.PackageSet{ "boot": s390xBootPackageSet(), }, + uefi: false, } - s390x.addImageTypes(tarImgType) + s390x.addImageTypes(qcow2ImageType, tarImgType) + rd.addArches(x86_64, aarch64, ppc64le, s390x) return rd } diff --git a/internal/distro/rhel85/package_sets.go b/internal/distro/rhel85/package_sets.go index f37e91194..78726b8ae 100644 --- a/internal/distro/rhel85/package_sets.go +++ b/internal/distro/rhel85/package_sets.go @@ -93,9 +93,81 @@ func s390xBootPackageSet() rpmmd.PackageSet { } } -func x8664BasePackageSet() rpmmd.PackageSet { +// OS package sets + +func qcow2CommonPkgSet() rpmmd.PackageSet { return rpmmd.PackageSet{ - Include: []string{"grub2-pc"}, + Include: []string{ + "@core", + "authselect-compat", + "chrony", + "cloud-init", + "cloud-utils-growpart", + "cockpit-system", + "cockpit-ws", + "dhcp-client", + "dnf", + "dnf-utils", + "dosfstools", + "dracut-norescue", + "insights-client", + "NetworkManager", + "net-tools", + "nfs-utils", + "oddjob", + "oddjob-mkhomedir", + "psmisc", + "python3-jsonschema", + "qemu-guest-agent", + "redhat-release", + "redhat-release-eula", + "rsync", + "subscription-manager-cockpit", + "tar", + "tcpdump", + "yum", + }, + Exclude: []string{ + "aic94xx-firmware", + "alsa-firmware", + "alsa-lib", + "alsa-tools-firmware", + "biosdevname", + "dnf-plugin-spacewalk", + "dracut-config-rescue", + "fedora-release", + "fedora-repos", + "firewalld", + "fwupd", + "iprutils", + "ivtv-firmware", + "iwl100-firmware", + "iwl1000-firmware", + "iwl105-firmware", + "iwl135-firmware", + "iwl2000-firmware", + "iwl2030-firmware", + "iwl3160-firmware", + "iwl3945-firmware", + "iwl4965-firmware", + "iwl5000-firmware", + "iwl5150-firmware", + "iwl6000-firmware", + "iwl6000g2a-firmware", + "iwl6000g2b-firmware", + "iwl6050-firmware", + "iwl7260-firmware", + "langpacks-*", + "langpacks-en", + "langpacks-en", + "libertas-sd8686-firmware", + "libertas-sd8787-firmware", + "libertas-usb8388-firmware", + "nss", + "plymouth", + "rng-tools", + "udisks2", + }, } } diff --git a/internal/distro/rhel85/pipelines.go b/internal/distro/rhel85/pipelines.go index 638108ff0..dc6f14da6 100644 --- a/internal/distro/rhel85/pipelines.go +++ b/internal/distro/rhel85/pipelines.go @@ -10,6 +10,47 @@ import ( "github.com/osbuild/osbuild-composer/internal/rpmmd" ) +func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { + pipelines := make([]osbuild.Pipeline, 0) + pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs["build"])) + treePipeline, err := osPipeline(repos, packageSetSpecs["packages"], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget) + if err != nil { + return nil, err + } + if options.Subscription != nil { + commands := []string{ + fmt.Sprintf("/usr/sbin/subscription-manager register --org=%d --activationkey=%s --serverurl %s --baseurl %s", options.Subscription.Organization, options.Subscription.ActivationKey, options.Subscription.ServerUrl, options.Subscription.BaseUrl), + } + if options.Subscription.Insights { + commands = append(commands, "/usr/bin/insights-client --register") + } + + treePipeline.AddStage(osbuild.NewFirstBootStage(&osbuild.FirstBootStageOptions{ + Commands: commands, + WaitForNetwork: true, + }, + )) + } else { + // RHSM DNF plugins should be by default disabled on RHEL Guest KVM images + treePipeline.AddStage(osbuild.NewRHSMStage(&osbuild.RHSMStageOptions{ + DnfPlugins: &osbuild.RHSMStageOptionsDnfPlugins{ + ProductID: &osbuild.RHSMStageOptionsDnfPlugin{ + Enabled: false, + }, + SubscriptionManager: &osbuild.RHSMStageOptionsDnfPlugin{ + Enabled: false, + }, + }, + })) + } + partitionTable := defaultPartitionTable(options, t.arch, rng) + treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2())) + treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs["packages"], t.arch.uefi, t.arch.legacy))) + pipelines = append(pipelines, *treePipeline) + + return pipelines, nil +} + func tarPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { pipelines := make([]osbuild.Pipeline, 0) pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs["build"])) @@ -162,12 +203,13 @@ func coreStages(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, c *bluep } if users := c.GetUsers(); len(users) > 0 { - options, err := userStageOptions(users) + userOptions, err := userStageOptions(users) if err != nil { return nil, err } - stages = append(stages, osbuild.NewUsersStage(options)) - stages = append(stages, osbuild.NewFirstBootStage(usersFirstBootOptions(options))) + stages = append(stages, osbuild.NewUsersStage(userOptions)) + // TODO: First boot stage for users should be OSTree only + stages = append(stages, osbuild.NewFirstBootStage(usersFirstBootOptions(userOptions))) } if services := c.GetServices(); services != nil || enabledServices != nil || disabledServices != nil || defaultTarget != "" {