Skip to content

Commit

Permalink
dnf: mark packages as user
Browse files Browse the repository at this point in the history
Package marking is enabled per image type and propagated down to the OS
pipeline where package marking is performed.

We only enable package marking for Fedora and only for version 39 and up
(rawhide, at time of writing). This is due to: not wanting to deal with
modularity (will be removed in f39), only wanting to deal with dnf5
(will be the default in f39).
  • Loading branch information
supakeen committed Jul 14, 2023
1 parent da35345 commit 451d44b
Show file tree
Hide file tree
Showing 24 changed files with 14,296 additions and 13,158 deletions.
12 changes: 12 additions & 0 deletions pkg/distro/fedora/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ func liveImage(workload workload.Workload,

img.Filename = t.Filename()

distro := t.Arch().Distro()

// We start marking packages in the dnf state database in Fedora 39 and up
if !common.VersionLessThan(distro.Releasever(), "39") {
img.MarkPackages = true
}

return img, nil
}

Expand Down Expand Up @@ -265,6 +272,11 @@ func liveInstallerImage(workload workload.Workload,
img.AdditionalKernelOpts = []string{"inst.webui"}
}

// We start marking packages in the dnf state database in Fedora 39 and up
if !common.VersionLessThan(distro.Releasever(), "39") {
img.MarkPackages = true
}

img.Platform = t.platform
img.Workload = workload
img.ExtraBasePackages = packageSets[installerPkgsKey]
Expand Down
2 changes: 2 additions & 0 deletions pkg/image/anaconda_live_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type AnacondaLiveInstaller struct {
OSVersion string
Release string

MarkPackages bool

Filename string

AdditionalKernelOpts []string
Expand Down
2 changes: 2 additions & 0 deletions pkg/image/live.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type LiveImage struct {
Workload workload.Workload
Filename string
Compression string
MarkPackages bool
ForceSize *bool
PartTool osbuild.PartTool

Expand Down Expand Up @@ -57,6 +58,7 @@ func (img *LiveImage) InstantiateManifest(m *manifest.Manifest,
osPipeline.OSProduct = img.OSProduct
osPipeline.OSVersion = img.OSVersion
osPipeline.OSNick = img.OSNick
osPipeline.MarkPackages = img.MarkPackages

imagePipeline := manifest.NewRawImage(m, buildPipeline, osPipeline)
imagePipeline.PartTool = img.PartTool
Expand Down
19 changes: 13 additions & 6 deletions pkg/manifest/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ type OS struct {
containerSpecs []container.Spec
ostreeParentSpec *ostree.CommitSpec

MarkPackages bool

platform platform.Platform
kernelVer string

Expand Down Expand Up @@ -317,7 +319,7 @@ func (p *OS) getContainerSpecs() []container.Spec {
}

func (p *OS) serializeStart(packages []rpmmd.PackageSpec, containers []container.Spec, commits []ostree.CommitSpec) {
if len(p.packageSpecs) > 0 {
if len(p.getPackageSpecs()) > 0 {
panic("double call to serializeStart()")
}

Expand All @@ -331,12 +333,12 @@ func (p *OS) serializeStart(packages []rpmmd.PackageSpec, containers []container
}

if p.KernelName != "" {
p.kernelVer = rpmmd.GetVerStrFromPackageSpecListPanic(p.packageSpecs, p.KernelName)
p.kernelVer = rpmmd.GetVerStrFromPackageSpecListPanic(p.getPackageSpecs(), p.KernelName)
}
}

func (p *OS) serializeEnd() {
if len(p.packageSpecs) == 0 {
if len(p.getPackageSpecs()) == 0 {
panic("serializeEnd() call when serialization not in progress")
}
p.kernelVer = ""
Expand All @@ -346,7 +348,7 @@ func (p *OS) serializeEnd() {
}

func (p *OS) serialize() osbuild.Pipeline {
if len(p.packageSpecs) == 0 {
if len(p.getPackageSpecs()) == 0 {
panic("serialization not started")
}

Expand All @@ -373,7 +375,12 @@ func (p *OS) serialize() osbuild.Pipeline {
rpmOptions.OSTreeBooted = common.ToPtr(true)
rpmOptions.DBPath = "/usr/share/rpm"
}
pipeline.AddStage(osbuild.NewRPMStage(rpmOptions, osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs)))

pipeline.AddStage(osbuild.NewRPMStage(rpmOptions, osbuild.NewRpmStageSourceFilesInputs(p.getPackageSpecs())))

if p.MarkPackages {
pipeline.AddStage(osbuild.NewDNFMarkStageFromPackageSetChain(p.getPackageSetChain(p.GetManifest().Distro)))
}

if !p.NoBLS {
// If the /boot is on a separate partition, the prefix for the BLS stage must be ""
Expand Down Expand Up @@ -608,7 +615,7 @@ func (p *OS) serialize() osbuild.Pipeline {
Nick: p.OSNick,
}

_, err := rpmmd.GetVerStrFromPackageSpecList(p.packageSpecs, "dracut-config-rescue")
_, err := rpmmd.GetVerStrFromPackageSpecList(p.getPackageSpecs(), "dracut-config-rescue")
hasRescue := err == nil
bootloader = osbuild.NewGrub2LegacyStage(
osbuild.NewGrub2LegacyStageOptions(
Expand Down
76 changes: 76 additions & 0 deletions pkg/osbuild/dnf_mark_stage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package osbuild

import (
"sort"
"strings"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/rpmmd"
)

type DNFMarkStagePackageOptions struct {
Name string `json:"name"`
Mark string `json:"mark"`
Group string `json:"group,omitempty"`
}

type DNFMarkStageOptions struct {
Packages []DNFMarkStagePackageOptions `json:"packages"`
}

func (o DNFMarkStageOptions) isStageOptions() {}

func (o DNFMarkStageOptions) validate() error {
return nil
}

func NewDNFMarkStageOptions(packages []DNFMarkStagePackageOptions) *DNFMarkStageOptions {
return &DNFMarkStageOptions{
Packages: packages,
}
}

type DNFMarkStage struct {
}

func NewDNFMarkStage(options *DNFMarkStageOptions) *Stage {
if err := options.validate(); err != nil {
panic(err)
}

return &Stage{
Type: "org.osbuild.dnf.mark",
Options: options,
}
}

func NewDNFMarkStageFromPackageSetChain(packageSetChain []rpmmd.PackageSet) *Stage {
var packages []DNFMarkStagePackageOptions
var packageNames []string

for _, ps := range packageSetChain {
for _, pn := range ps.Include {
// XXX dirty hack until I figure out how to do
// XXX group support
if strings.HasPrefix(pn, "@") {
continue
}

// Make sure we don't mark packages multiple times
if !common.IsStringInSortedSlice(packageNames, pn) {

packageNames = append(packageNames, pn)
sort.Strings(packageNames)

packages = append(packages, DNFMarkStagePackageOptions{
Name: pn,
Mark: "user",
})
}
}
}

options := NewDNFMarkStageOptions(packages)

return NewDNFMarkStage(options)
}
Loading

0 comments on commit 451d44b

Please sign in to comment.