Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Schutzfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@
"centos-9": {
"dependencies": {
"osbuild": {
"commit": "4173a05047b1e3a0f5a2859e50fe55ed2642edad"
"commit": "6c34e00bedd8101293382f2d563d111825b46349"
}
}
},
"centos-10": {
"dependencies": {
"osbuild": {
"commit": "4173a05047b1e3a0f5a2859e50fe55ed2642edad"
"commit": "6c34e00bedd8101293382f2d563d111825b46349"
}
}
},
"fedora-42": {
"dependencies": {
"osbuild": {
"commit": "4173a05047b1e3a0f5a2859e50fe55ed2642edad"
"commit": "6c34e00bedd8101293382f2d563d111825b46349"
}
},
"repos": [
Expand Down Expand Up @@ -73,14 +73,14 @@
"fedora-43": {
"dependencies": {
"osbuild": {
"commit": "4173a05047b1e3a0f5a2859e50fe55ed2642edad"
"commit": "6c34e00bedd8101293382f2d563d111825b46349"
}
}
},
"fedora-44": {
"dependencies": {
"osbuild": {
"commit": "4173a05047b1e3a0f5a2859e50fe55ed2642edad"
"commit": "6c34e00bedd8101293382f2d563d111825b46349"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion data/dependencies/deps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import (
)

func TestMinimumOSBuildVersion(t *testing.T) {
assert.Equal(t, "169", dependencies.MinimumOSBuildVersion())
assert.Equal(t, "170", dependencies.MinimumOSBuildVersion())
}
2 changes: 1 addition & 1 deletion data/dependencies/osbuild
Original file line number Diff line number Diff line change
@@ -1 +1 @@
169
170
10 changes: 10 additions & 0 deletions internal/common/pointers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ func ToPtr[T any](x T) *T {
return &x
}

// ClonePtr returns a new pointer to the same value as the input pointer.
// It returns nil if the input pointer is nil. If the value is a complex type,
// the returned pointer will be a shallow copy of the input pointer.
func ClonePtr[T any](x *T) *T {
if x == nil {
return nil
}
return ToPtr(*x)
}

// ValueOrEmpty returns the value from a given pointer. If ref is nil,
// a zero value of type T will be returned.
func ValueOrEmpty[T any](ref *T) (value T) {
Expand Down
24 changes: 24 additions & 0 deletions internal/common/pointers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,30 @@ func TestToPtr(t *testing.T) {

}

func TestClonePtr(t *testing.T) {
t.Run("nil pointer returns nil", func(t *testing.T) {
var p *int
result := ClonePtr(p)
assert.Nil(t, result)
})

t.Run("non-nil pointer returns independent copy", func(t *testing.T) {
original := 42
p := &original
result := ClonePtr(p)

// Should have same value
assert.Equal(t, 42, *result)

// Should be different pointer
assert.NotSame(t, p, result)

// Modifying original should not affect clone
original = 100
assert.Equal(t, 42, *result)
})
}

func TestValueOrEmpty(t *testing.T) {
var ptrInt *int
valueInt := ValueOrEmpty(ptrInt)
Expand Down
62 changes: 22 additions & 40 deletions pkg/customizations/subscription/subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,15 @@ func (c *RHSMConfig) Clone() *RHSMConfig {

clone := &RHSMConfig{}

if c.DnfPlugins.ProductID.Enabled != nil {
clone.DnfPlugins.ProductID.Enabled = common.ToPtr(*c.DnfPlugins.ProductID.Enabled)
}
if c.DnfPlugins.SubscriptionManager.Enabled != nil {
clone.DnfPlugins.SubscriptionManager.Enabled = common.ToPtr(*c.DnfPlugins.SubscriptionManager.Enabled)
}
clone.DnfPlugins.ProductID.Enabled = common.ClonePtr(c.DnfPlugins.ProductID.Enabled)
clone.DnfPlugins.SubscriptionManager.Enabled = common.ClonePtr(c.DnfPlugins.SubscriptionManager.Enabled)

if c.YumPlugins.ProductID.Enabled != nil {
clone.YumPlugins.ProductID.Enabled = common.ToPtr(*c.YumPlugins.ProductID.Enabled)
}
if c.YumPlugins.SubscriptionManager.Enabled != nil {
clone.YumPlugins.SubscriptionManager.Enabled = common.ToPtr(*c.YumPlugins.SubscriptionManager.Enabled)
}
clone.YumPlugins.ProductID.Enabled = common.ClonePtr(c.YumPlugins.ProductID.Enabled)
clone.YumPlugins.SubscriptionManager.Enabled = common.ClonePtr(c.YumPlugins.SubscriptionManager.Enabled)

if c.SubMan.Rhsm.ManageRepos != nil {
clone.SubMan.Rhsm.ManageRepos = common.ToPtr(*c.SubMan.Rhsm.ManageRepos)
}
if c.SubMan.Rhsm.AutoEnableYumPlugins != nil {
clone.SubMan.Rhsm.AutoEnableYumPlugins = common.ToPtr(*c.SubMan.Rhsm.AutoEnableYumPlugins)
}
if c.SubMan.Rhsmcertd.AutoRegistration != nil {
clone.SubMan.Rhsmcertd.AutoRegistration = common.ToPtr(*c.SubMan.Rhsmcertd.AutoRegistration)
}
clone.SubMan.Rhsm.ManageRepos = common.ClonePtr(c.SubMan.Rhsm.ManageRepos)
clone.SubMan.Rhsm.AutoEnableYumPlugins = common.ClonePtr(c.SubMan.Rhsm.AutoEnableYumPlugins)
clone.SubMan.Rhsmcertd.AutoRegistration = common.ClonePtr(c.SubMan.Rhsmcertd.AutoRegistration)

return clone
}
Expand All @@ -112,27 +98,27 @@ func (c *RHSMConfig) Update(new *RHSMConfig) *RHSMConfig {
}

if new.DnfPlugins.ProductID.Enabled != nil {
c.DnfPlugins.ProductID.Enabled = common.ToPtr(*new.DnfPlugins.ProductID.Enabled)
c.DnfPlugins.ProductID.Enabled = common.ClonePtr(new.DnfPlugins.ProductID.Enabled)
}
if new.DnfPlugins.SubscriptionManager.Enabled != nil {
c.DnfPlugins.SubscriptionManager.Enabled = common.ToPtr(*new.DnfPlugins.SubscriptionManager.Enabled)
c.DnfPlugins.SubscriptionManager.Enabled = common.ClonePtr(new.DnfPlugins.SubscriptionManager.Enabled)
}

if new.YumPlugins.ProductID.Enabled != nil {
c.YumPlugins.ProductID.Enabled = common.ToPtr(*new.YumPlugins.ProductID.Enabled)
c.YumPlugins.ProductID.Enabled = common.ClonePtr(new.YumPlugins.ProductID.Enabled)
}
if new.YumPlugins.SubscriptionManager.Enabled != nil {
c.YumPlugins.SubscriptionManager.Enabled = common.ToPtr(*new.YumPlugins.SubscriptionManager.Enabled)
c.YumPlugins.SubscriptionManager.Enabled = common.ClonePtr(new.YumPlugins.SubscriptionManager.Enabled)
}

if new.SubMan.Rhsm.ManageRepos != nil {
c.SubMan.Rhsm.ManageRepos = common.ToPtr(*new.SubMan.Rhsm.ManageRepos)
c.SubMan.Rhsm.ManageRepos = common.ClonePtr(new.SubMan.Rhsm.ManageRepos)
}
if new.SubMan.Rhsm.AutoEnableYumPlugins != nil {
c.SubMan.Rhsm.AutoEnableYumPlugins = common.ToPtr(*new.SubMan.Rhsm.AutoEnableYumPlugins)
c.SubMan.Rhsm.AutoEnableYumPlugins = common.ClonePtr(new.SubMan.Rhsm.AutoEnableYumPlugins)
}
if new.SubMan.Rhsmcertd.AutoRegistration != nil {
c.SubMan.Rhsmcertd.AutoRegistration = common.ToPtr(*new.SubMan.Rhsmcertd.AutoRegistration)
c.SubMan.Rhsmcertd.AutoRegistration = common.ClonePtr(new.SubMan.Rhsmcertd.AutoRegistration)
}

return c
Expand All @@ -147,27 +133,23 @@ func RHSMConfigFromBP(bpRHSM *blueprint.RHSMCustomization) *RHSMConfig {
c := &RHSMConfig{}

if plugins := bpRHSM.Config.DNFPlugins; plugins != nil {
if plugins.ProductID != nil && plugins.ProductID.Enabled != nil {
c.DnfPlugins.ProductID.Enabled = common.ToPtr(*plugins.ProductID.Enabled)
if plugins.ProductID != nil {
c.DnfPlugins.ProductID.Enabled = common.ClonePtr(plugins.ProductID.Enabled)
}
if plugins.SubscriptionManager != nil && plugins.SubscriptionManager.Enabled != nil {
c.DnfPlugins.SubscriptionManager.Enabled = common.ToPtr(*plugins.SubscriptionManager.Enabled)
if plugins.SubscriptionManager != nil {
c.DnfPlugins.SubscriptionManager.Enabled = common.ClonePtr(plugins.SubscriptionManager.Enabled)
}
}

// NB: YUMPlugins are not exposed to end users as a customization

if subMan := bpRHSM.Config.SubscriptionManager; subMan != nil {
if subMan.RHSMConfig != nil {
if subMan.RHSMConfig.ManageRepos != nil {
c.SubMan.Rhsm.ManageRepos = common.ToPtr(*subMan.RHSMConfig.ManageRepos)
}
if subMan.RHSMConfig.AutoEnableYumPlugins != nil {
c.SubMan.Rhsm.AutoEnableYumPlugins = common.ToPtr(*subMan.RHSMConfig.AutoEnableYumPlugins)
}
c.SubMan.Rhsm.ManageRepos = common.ClonePtr(subMan.RHSMConfig.ManageRepos)
c.SubMan.Rhsm.AutoEnableYumPlugins = common.ClonePtr(subMan.RHSMConfig.AutoEnableYumPlugins)
}
if subMan.RHSMCertdConfig != nil && subMan.RHSMCertdConfig.AutoRegistration != nil {
c.SubMan.Rhsmcertd.AutoRegistration = common.ToPtr(*subMan.RHSMCertdConfig.AutoRegistration)
if subMan.RHSMCertdConfig != nil {
c.SubMan.Rhsmcertd.AutoRegistration = common.ClonePtr(subMan.RHSMCertdConfig.AutoRegistration)
}
}

Expand Down
13 changes: 7 additions & 6 deletions pkg/depsolvednf/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (
// It also contains raw SBOM data (Solver is responsible for creating
// sbom.Document).
type depsolveResultRaw struct {
Packages rpmmd.PackageList
Modules []rpmmd.ModuleSpec
Repos []rpmmd.RepoConfig
Solver string
SBOMRaw json.RawMessage
Packages rpmmd.PackageList
Transactions []rpmmd.PackageList
Modules []rpmmd.ModuleSpec
Repos []rpmmd.RepoConfig
Solver string
SBOMRaw json.RawMessage
}

// apiHandler defines the interface for API version implementations.
Expand Down Expand Up @@ -61,5 +62,5 @@ type solverConfig struct {
var activeHandler apiHandler

func init() {
activeHandler = newV1Handler()
activeHandler = newV2Handler()
}
40 changes: 31 additions & 9 deletions pkg/depsolvednf/depsolvednf.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,33 @@ type Solver struct {

// DepsolveResult contains the results of a depsolve operation.
type DepsolveResult struct {
// XXX: Packages is kept for backwards compatibility and should
// be removed once all clients have been updated to use Transactions.
Packages rpmmd.PackageList
Modules []rpmmd.ModuleSpec
Repos []rpmmd.RepoConfig
SBOM *sbom.Document
Solver string
// Transactions is a list of package lists, one for each depsolve
// transaction. Each transaction contains only the packages to be
// installed that are unique to that transaction. The transaction results
// are disjoint sets that should be installed in the order they appear in
// the list.
Transactions []rpmmd.PackageList
Modules []rpmmd.ModuleSpec
Repos []rpmmd.RepoConfig
SBOM *sbom.Document
Solver string
}

// DumpResult contains the results of a dump operation.
type DumpResult struct {
Packages rpmmd.PackageList
Repos []rpmmd.RepoConfig
Solver string
}

// SearchResult contains the results of a search operation.
type SearchResult struct {
Packages rpmmd.PackageList
Repos []rpmmd.RepoConfig
Solver string
}

// Create a new Solver with the given configuration. Initialising a Solver also loads system subscription information.
Expand Down Expand Up @@ -307,6 +319,11 @@ func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, sbomType sbom.StandardType
// Apply RHSM secrets to packages from RHSM repos.
applyRHSMSecrets(resultRaw.Packages, allRepos)

// Apply RHSM secrets to packages in each transaction as well.
for _, transaction := range resultRaw.Transactions {
applyRHSMSecrets(transaction, allRepos)
}

var sbomDoc *sbom.Document
if sbomType != sbom.StandardTypeNone {
sbomDoc, err = sbom.NewDocument(sbomType, resultRaw.SBOMRaw)
Expand All @@ -316,11 +333,12 @@ func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, sbomType sbom.StandardType
}

return &DepsolveResult{
Packages: resultRaw.Packages,
Modules: resultRaw.Modules,
Repos: resultRaw.Repos,
SBOM: sbomDoc,
Solver: resultRaw.Solver,
Packages: resultRaw.Packages,
Transactions: resultRaw.Transactions,
Modules: resultRaw.Modules,
Repos: resultRaw.Repos,
SBOM: sbomDoc,
Solver: resultRaw.Solver,
}, nil
}

Expand Down Expand Up @@ -375,6 +393,8 @@ func (s *Solver) FetchMetadata(repos []rpmmd.RepoConfig) (rpmmd.PackageList, err
return nil, err
}

// XXX: Cache and expose the whole operation result instead of just the packages in the future.

pkgs := res.Packages
sort.Slice(pkgs, func(i, j int) bool {
return pkgs[i].NVR() < pkgs[j].NVR()
Expand Down Expand Up @@ -421,6 +441,8 @@ func (s *Solver) SearchMetadata(repos []rpmmd.RepoConfig, packages []string) (rp
return nil, err
}

// XXX: Cache and expose the whole operation result instead of just the packages in the future.

pkgs := res.Packages
sort.Slice(pkgs, func(i, j int) bool {
return pkgs[i].NVR() < pkgs[j].NVR()
Expand Down
Loading
Loading