diff --git a/internal/distro/rhel84/distro_v2.go b/internal/distro/rhel84/distro_v2.go index aafccdec0..f50723506 100644 --- a/internal/distro/rhel84/distro_v2.go +++ b/internal/distro/rhel84/distro_v2.go @@ -699,7 +699,7 @@ func (t *imageTypeS2) dracutStageOptions(kernelVer string) *osbuild.DracutStageO func (t *imageTypeS2) kickstartStageOptions(ostreeURL, ostreeRef string) *osbuild.KickstartStageOptions { return &osbuild.KickstartStageOptions{ Path: "/usr/share/anaconda/interactive-defaults.ks", - OSTree: osbuild.OSTreeOptions{ + OSTree: &osbuild.OSTreeOptions{ OSName: "rhel", URL: ostreeURL, Ref: ostreeRef, diff --git a/internal/distro/rhel85/distro.go b/internal/distro/rhel85/distro.go index d1d9cfd88..9407e184e 100644 --- a/internal/distro/rhel85/distro.go +++ b/internal/distro/rhel85/distro.go @@ -472,6 +472,34 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { distro: rd, } + baseBuildPkgSet := rpmmd.PackageSet{ + Include: []string{ + "dnf", "dosfstools", "e2fsprogs", "glibc", + "lorax-templates-generic", "lorax-templates-rhel", + "policycoreutils", "python36", "python3-iniparse", "qemu-img", + "selinux-policy-targeted", "systemd", "tar", "xfsprogs", "xz", + }, + } + installerBuildPkgSet := rpmmd.PackageSet{ + Include: append(baseBuildPkgSet.Include, + "efibootmgr", "genisoimage", "grub2-efi-ia32-cdboot", + "grub2-efi-x64", "grub2-efi-x64-cdboot", "grub2-pc", + "grub2-pc-modules", "grub2-tools", "grub2-tools-efi", + "grub2-tools-extra", "grub2-tools-minimal", "isomd5sum", + "lorax-templates-generic", "lorax-templates-rhel", "rpm-ostree", + "shim-ia32", "shim-x64", "squashfs-tools", "syslinux", + "syslinux-nonlinux", "xorriso"), + Exclude: nil, + } + x86bootPkgSet := rpmmd.PackageSet{ + Include: []string{ + "dracut-config-generic", + "grub2-pc", + "grub2-efi-x64", + "shim-x64", + }, + Exclude: nil, + } installerPkgSet := rpmmd.PackageSet{ Include: []string{ "aajohan-comfortaa-fonts", "abattis-cantarell-fonts", @@ -529,8 +557,11 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro { filename: "installer.iso", mimeType: "application/x-iso9660-image", packageSets: map[string]rpmmd.PackageSet{ - "build": {}, - "packages": {}, + "build": installerBuildPkgSet, + "packages": { + Include: append(x86bootPkgSet.Include, "lvm2", "policycoreutils", "selinux-policy-targeted"), + Exclude: []string{"rng-tools"}, + }, "installer": installerPkgSet, }, rpmOstree: false, diff --git a/internal/distro/rhel85/pipelines.go b/internal/distro/rhel85/pipelines.go index 10c444a45..85833d7f8 100644 --- a/internal/distro/rhel85/pipelines.go +++ b/internal/distro/rhel85/pipelines.go @@ -34,6 +34,13 @@ func edgeInstallerPipelines(t *imageType, customizations *blueprint.Customizatio func tarInstallerPipelines(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, t.enabledServices, t.disabledServices, t.defaultTarget) + if err != nil { + return nil, err + } + pipelines = append(pipelines, *treePipeline) + kernelPkg := new(rpmmd.PackageSpec) installerPackages := packageSetSpecs["installer"] for _, pkg := range installerPackages { @@ -95,37 +102,36 @@ func buildPipeline(repos []rpmmd.RepoConfig, buildPackageSpecs []rpmmd.PackageSp return p } -func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, c *blueprint.Customizations, enabledServices, disabledServices []string, defaultTarget string) (*osbuild.Pipeline, error) { - p := new(osbuild.Pipeline) - p.Name = "ostree-tree" - p.Build = "name:build" - p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(packages))) +func coreStages(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, c *blueprint.Customizations, enabledServices, disabledServices []string, defaultTarget string) ([]*osbuild.Stage, error) { + stages := make([]*osbuild.Stage, 0) + stages = append(stages, osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(packages))) + stages = append(stages, osbuild.NewFixBLSStage()) language, keyboard := c.GetPrimaryLocale() if language != nil { - p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: *language})) + stages = append(stages, osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: *language})) } else { - p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"})) + stages = append(stages, osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"})) } if keyboard != nil { - p.AddStage(osbuild.NewKeymapStage(&osbuild.KeymapStageOptions{Keymap: *keyboard})) + stages = append(stages, osbuild.NewKeymapStage(&osbuild.KeymapStageOptions{Keymap: *keyboard})) } if hostname := c.GetHostname(); hostname != nil { - p.AddStage(osbuild.NewHostnameStage(&osbuild.HostnameStageOptions{Hostname: *hostname})) + stages = append(stages, osbuild.NewHostnameStage(&osbuild.HostnameStageOptions{Hostname: *hostname})) } timezone, ntpServers := c.GetTimezoneSettings() if timezone != nil { - p.AddStage(osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: *timezone})) + stages = append(stages, osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: *timezone})) } else { - p.AddStage(osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: "America/New_York"})) + stages = append(stages, osbuild.NewTimezoneStage(&osbuild.TimezoneStageOptions{Zone: "America/New_York"})) } if len(ntpServers) > 0 { - p.AddStage(osbuild.NewChronyStage(&osbuild.ChronyStageOptions{Timeservers: ntpServers})) + stages = append(stages, osbuild.NewChronyStage(&osbuild.ChronyStageOptions{Timeservers: ntpServers})) } if groups := c.GetGroups(); len(groups) > 0 { - p.AddStage(osbuild.NewGroupsStage(groupStageOptions(groups))) + stages = append(stages, osbuild.NewGroupsStage(groupStageOptions(groups))) } if users := c.GetUsers(); len(users) > 0 { @@ -133,21 +139,21 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, if err != nil { return nil, err } - p.AddStage(osbuild.NewUsersStage(options)) - p.AddStage(osbuild.NewFirstBootStage(usersFirstBootOptions(options))) + stages = append(stages, osbuild.NewUsersStage(options)) + stages = append(stages, osbuild.NewFirstBootStage(usersFirstBootOptions(options))) } if services := c.GetServices(); services != nil || enabledServices != nil || disabledServices != nil || defaultTarget != "" { - p.AddStage(osbuild.NewSystemdStage(systemdStageOptions(enabledServices, disabledServices, services, defaultTarget))) + stages = append(stages, osbuild.NewSystemdStage(systemdStageOptions(enabledServices, disabledServices, services, defaultTarget))) } if firewall := c.GetFirewall(); firewall != nil { - p.AddStage(osbuild.NewFirewallStage(firewallStageOptions(firewall))) + stages = append(stages, osbuild.NewFirewallStage(firewallStageOptions(firewall))) } - p.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false))) + stages = append(stages, osbuild.NewSELinuxStage(selinuxStageOptions(false))) // These are the current defaults for the sysconfig stage. This can be changed to be image type exclusive if different configs are needed. - p.AddStage(osbuild.NewSysconfigStage(&osbuild.SysconfigStageOptions{ + stages = append(stages, osbuild.NewSysconfigStage(&osbuild.SysconfigStageOptions{ Kernel: osbuild.SysconfigKernelOptions{ UpdateDefault: true, DefaultKernel: "kernel", @@ -158,6 +164,32 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, }, })) + return stages, nil +} + +func osPipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, c *blueprint.Customizations, enabledServices, disabledServices []string, defaultTarget string) (*osbuild.Pipeline, error) { + p := new(osbuild.Pipeline) + p.Name = "os" + stages, err := coreStages(repos, packages, c, enabledServices, disabledServices, defaultTarget) + if err != nil { + return nil, err + } + p.Stages = stages + + return p, nil +} + +func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, c *blueprint.Customizations, enabledServices, disabledServices []string, defaultTarget string) (*osbuild.Pipeline, error) { + p := new(osbuild.Pipeline) + p.Name = "ostree-tree" + p.Build = "name:build" + + stages, err := coreStages(repos, packages, c, enabledServices, disabledServices, defaultTarget) + if err != nil { + return nil, err + } + p.Stages = stages + p.AddStage(osbuild.NewOSTreePrepTreeStage(&osbuild.OSTreePrepTreeStageOptions{ EtcGroupMembers: []string{ // NOTE: We may want to make this configurable. @@ -261,9 +293,14 @@ func anacondaOSTreePayloadStages(options distro.ImageOptions) []*osbuild.Stage { } func anacondaTarPayloadStages(options distro.ImageOptions) []*osbuild.Stage { - // TODO: assemble the tarball - tarPath := "" + tarPath := "/liveimg.tar" stages := make([]*osbuild.Stage, 0) + tree := new(osbuild.TarStageInput) + tree.Type = "org.osbuild.tree" + tree.Origin = "org.osbuild.pipeline" + tree.References = []string{"name:os"} + tarStage := osbuild.NewTarStage(&osbuild.TarStageOptions{Filename: tarPath}, &osbuild.TarStageInputs{Tree: tree}) + stages = append(stages, tarStage) stages = append(stages, osbuild.NewKickstartStage(tarKickstartStageOptions(fmt.Sprintf("file://%s", tarPath)))) return stages } diff --git a/internal/distro/rhel85/stage_options.go b/internal/distro/rhel85/stage_options.go index 107423705..8444c8dfc 100644 --- a/internal/distro/rhel85/stage_options.go +++ b/internal/distro/rhel85/stage_options.go @@ -237,7 +237,7 @@ func tarKickstartStageOptions(tarURL string) *osbuild.KickstartStageOptions { func ostreeKickstartStageOptions(ostreeURL, ostreeRef string) *osbuild.KickstartStageOptions { return &osbuild.KickstartStageOptions{ Path: "/usr/share/anaconda/interactive-defaults.ks", - OSTree: osbuild.OSTreeOptions{ + OSTree: &osbuild.OSTreeOptions{ OSName: "rhel", URL: ostreeURL, Ref: ostreeRef, @@ -271,7 +271,7 @@ func bootISOMonoStageOptions(kernelVer string, arch string) *osbuild.BootISOMono }, Templates: "80-rhel", RootFS: osbuild.RootFS{ - Size: 4096, + Size: 9216, Compression: osbuild.FSCompression{ Method: "xz", Options: comprOptions, diff --git a/internal/osbuild2/kickstart_stage.go b/internal/osbuild2/kickstart_stage.go index 06d1e6cb4..4224334c0 100644 --- a/internal/osbuild2/kickstart_stage.go +++ b/internal/osbuild2/kickstart_stage.go @@ -4,7 +4,7 @@ type KickstartStageOptions struct { // Where to place the kickstart file Path string `json:"path"` - OSTree OSTreeOptions `json:"ostree,omitempty"` + OSTree *OSTreeOptions `json:"ostree,omitempty"` LiveIMG *LiveIMG `json:"liveimg,omitempty"` }