From f1e805658c1013e8098276604ca4a5f8a13e6f36 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Wed, 12 May 2021 15:11:51 +0200 Subject: [PATCH] rhel85: distro and arch package sets Add package sets to the top level distribution and the architectures. Merge package sets when requested through `imageType.PackageSets()`. This allows us to have "cascading" package sets: distro > arch > image type Previously this was only supported for the build packages. The idea is generalised based on the idea of arbitrary package sets. Certain package sets have special meaning (for the distro): - packages: blueprint packages and special option packages are merged into this one. - build: is not expected to be defined on the image type so it is merged from the distro and arch explicitly. --- internal/distro/rhel85/distro.go | 53 +++++++++++++++++++++++--------- internal/rpmmd/repository.go | 8 +++++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/internal/distro/rhel85/distro.go b/internal/distro/rhel85/distro.go index bcd143775..823f6b60d 100644 --- a/internal/distro/rhel85/distro.go +++ b/internal/distro/rhel85/distro.go @@ -23,6 +23,7 @@ type distribution struct { modulePlatformID string ostreeRef string arches map[string]distro.Arch + packageSets map[string]rpmmd.PackageSet } func (d *distribution) Name() string { @@ -69,9 +70,10 @@ func (d *distribution) addArches(arches ...architecture) { } type architecture struct { - distro *distribution - name string - imageTypes map[string]distro.ImageType + distro *distribution + name string + imageTypes map[string]distro.ImageType + packageSets map[string]rpmmd.PackageSet } func (a *architecture) Name() string { @@ -164,19 +166,40 @@ func (t *imageType) Size(size uint64) uint64 { } func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.PackageSet { - sets := make(map[string]rpmmd.PackageSet) - for name, pkgSet := range t.packageSets { - if name == "packages" { - // combine image packages with blueprint - pkgSet.Include = append(pkgSet.Include, bp.GetPackages()...) - timezone, _ := bp.Customizations.GetTimezoneSettings() - if timezone != nil { - pkgSet.Include = append(pkgSet.Include, "chrony") - } - } - sets[name] = pkgSet + // merge package sets that appear in the image type (or are enabled by + // flags) with the package sets of the same name from the distro and arch + mergedSets := make(map[string]rpmmd.PackageSet) + + imageSets := t.packageSets + distroSets := t.arch.distro.packageSets + archSets := t.arch.packageSets + for name := range imageSets { + mergedSets[name] = imageSets[name].Append(archSets[name]).Append(distroSets[name]) } - return sets + + if _, hasPackages := imageSets["packages"]; !hasPackages { + // should this be possible?? + mergedSets["packages"] = rpmmd.PackageSet{} + } + + // build is usually not defined on the image type + // so handle it explicitly + if _, hasBuild := imageSets["build"]; !hasBuild { + buildSet := archSets["build"].Append(distroSets["build"]) + if t.rpmOstree { + buildSet.Include = append(buildSet.Include, "rpm-ostree") + } + mergedSets["build"] = buildSet + } + + // blueprint packages + bpPackages := bp.GetPackages() + timezone, _ := bp.Customizations.GetTimezoneSettings() + if timezone != nil { + bpPackages = append(bpPackages, "chrony") + } + mergedSets["packages"] = mergedSets["packages"].Append(rpmmd.PackageSet{Include: bpPackages}) + return mergedSets } diff --git a/internal/rpmmd/repository.go b/internal/rpmmd/repository.go index 8ebf55256..70aeb2ce1 100644 --- a/internal/rpmmd/repository.go +++ b/internal/rpmmd/repository.go @@ -107,6 +107,14 @@ type PackageSet struct { Exclude []string } +// Append the Include and Exclude package list from another PackageSet and +// return the result. +func (ps PackageSet) Append(other PackageSet) PackageSet { + ps.Include = append(ps.Include, other.Include...) + ps.Exclude = append(ps.Exclude, other.Exclude...) + return ps +} + // TODO: the public API of this package should not be reused for serialization. type PackageSpec struct { Name string `json:"name"`