Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modularity: depsolver and manifests (COMPOSER-2366) #1095

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
51 changes: 43 additions & 8 deletions pkg/dnfjson/dnfjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type Solver struct {
type DepsolveResult struct {
Packages []rpmmd.PackageSpec
Repos []rpmmd.RepoConfig
Modules []rpmmd.ModuleConfig
SBOM *sbom.Document
Solver string
}
Expand Down Expand Up @@ -231,7 +232,7 @@ func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, sbomType sbom.StandardType
return nil, fmt.Errorf("decoding depsolve result failed: %w", err)
}

packages, repos := result.toRPMMD(rhsmMap)
packages, repos, modules := result.toRPMMD(rhsmMap)

var sbomDoc *sbom.Document
if sbomType != sbom.StandardTypeNone {
Expand All @@ -243,6 +244,7 @@ func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, sbomType sbom.StandardType

return &DepsolveResult{
Packages: packages,
Modules: modules,
Repos: repos,
SBOM: sbomDoc,
Solver: result.Solver,
Expand Down Expand Up @@ -415,6 +417,17 @@ type repoConfig struct {
repoHash string
}

type moduleConfigModule struct {
Data string `json:"data"`
Path string `json:"path"`
}

type moduleConfig struct {
Name string `json:"name"`
ModuleFile moduleConfigModule `json:"module-file"`
FailsafeFile moduleConfigModule `json:"failsafe-file"`
}

// use the hash calculated by the `rpmmd.RepoConfig.Hash()`
// function rather than re-implementing the same code
func (r *repoConfig) Hash() string {
Expand Down Expand Up @@ -454,9 +467,10 @@ func (s *Solver) makeDepsolveRequest(pkgSets []rpmmd.PackageSet, sbomType sbom.S
transactions := make([]transactionArgs, len(pkgSets))
for dsIdx, pkgSet := range pkgSets {
transactions[dsIdx] = transactionArgs{
PackageSpecs: pkgSet.Include,
ExcludeSpecs: pkgSet.Exclude,
InstallWeakDeps: pkgSet.InstallWeakDeps,
PackageSpecs: pkgSet.Include,
ExcludeSpecs: pkgSet.Exclude,
ModuleEnableSpecs: pkgSet.EnabledModules,
InstallWeakDeps: pkgSet.InstallWeakDeps,
}

for _, jobRepo := range pkgSet.Repositories {
Expand Down Expand Up @@ -568,9 +582,10 @@ func (s *Solver) makeSearchRequest(repos []rpmmd.RepoConfig, packages []string)
// convert internal a list of PackageSpecs and map of repoConfig to the rpmmd
// equivalents and attach key and subscription information based on the
// repository configs.
func (result depsolveResult) toRPMMD(rhsm map[string]bool) ([]rpmmd.PackageSpec, []rpmmd.RepoConfig) {
func (result depsolveResult) toRPMMD(rhsm map[string]bool) ([]rpmmd.PackageSpec, []rpmmd.RepoConfig, []rpmmd.ModuleConfig) {
pkgs := result.Packages
repos := result.Repos
modules := result.Modules
rpmDependencies := make([]rpmmd.PackageSpec, len(pkgs))
for i, dep := range pkgs {
repo, ok := repos[dep.RepoID]
Expand Down Expand Up @@ -624,7 +639,23 @@ func (result depsolveResult) toRPMMD(rhsm map[string]bool) ([]rpmmd.PackageSpec,
SSLClientCert: repo.SSLClientCert,
})
}
return rpmDependencies, repoConfigs

var moduleConfigs []rpmmd.ModuleConfig
for moduleName := range modules {
module := modules[moduleName]

moduleConfigs = append(moduleConfigs, rpmmd.ModuleConfig{
Name: moduleName,

ModuleFilePath: module.ModuleFile.Path,
ModuleFileData: module.ModuleFile.Data,

FailsafeFilePath: module.FailsafeFile.Path,
FailsafeFileData: module.FailsafeFile.Data,
})
}

return rpmDependencies, repoConfigs, moduleConfigs
}

// Request command and arguments for dnf-json
Expand Down Expand Up @@ -712,6 +743,9 @@ type transactionArgs struct {
// Packages to exclude from results
ExcludeSpecs []string `json:"exclude-specs"`

// Modules to enable
ModuleEnableSpecs []string `json:"module-enable-specs"`

// IDs of repositories to use for this depsolve
RepoIDs []string `json:"repo-ids"`

Expand All @@ -722,8 +756,9 @@ type transactionArgs struct {
type packageSpecs []PackageSpec

type depsolveResult struct {
Packages packageSpecs `json:"packages"`
Repos map[string]repoConfig `json:"repos"`
Packages packageSpecs `json:"packages"`
Repos map[string]repoConfig `json:"repos"`
Modules map[string]moduleConfig `json:"modules"`

// (optional) contains the solver used, e.g. "dnf5"
Solver string `json:"solver,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/anaconda_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func (p *AnacondaInstaller) getPackageSpecs() []rpmmd.PackageSpec {
return p.packageSpecs
}

func (p *AnacondaInstaller) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig) {
func (p *AnacondaInstaller) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/anaconda_installer_iso_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (p *AnacondaInstallerISOTree) getBuildPackages(_ Distro) []string {
return packages
}

func (p *AnacondaInstallerISOTree) serializeStart(_ []rpmmd.PackageSpec, containers []container.Spec, commits []ostree.CommitSpec, _ []rpmmd.RepoConfig) {
func (p *AnacondaInstallerISOTree) serializeStart(_ []rpmmd.PackageSpec, containers []container.Spec, commits []ostree.CommitSpec, _ []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if p.ostreeCommitSpec != nil || p.containerSpec != nil {
panic("double call to serializeStart()")
}
Expand Down
48 changes: 24 additions & 24 deletions pkg/manifest/anaconda_installer_iso_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,11 @@ func TestAnacondaISOTreePayloadsBad(t *testing.T) {

assert.PanicsWithValue(
"pipeline supports at most one ostree commit",
func() { pipeline.serializeStart(nil, nil, make([]ostree.CommitSpec, 2), nil) },
func() { pipeline.serializeStart(nil, nil, make([]ostree.CommitSpec, 2), nil, nil) },
)
assert.PanicsWithValue(
"pipeline supports at most one container",
func() { pipeline.serializeStart(nil, make([]container.Spec, 2), nil, nil) },
func() { pipeline.serializeStart(nil, make([]container.Spec, 2), nil, nil, nil) },
)
}

Expand All @@ -290,7 +290,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
t.Run("plain", func(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.OSPipeline = osPayload
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, payloadStages,
Expand All @@ -303,7 +303,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.OSPipeline = osPayload
pipeline.Kickstart = &kickstart.Options{Path: testKsPath}
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.kickstart"),
Expand All @@ -316,7 +316,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
pipeline.OSPipeline = osPayload
pipeline.Kickstart = &kickstart.Options{Path: testKsPath}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
Expand All @@ -328,7 +328,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
pipeline.OSPipeline = osPayload
pipeline.Kickstart = &kickstart.Options{Path: testKsPath, Unattended: true}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
Expand All @@ -345,7 +345,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
SudoNopasswd: []string{`%wheel`, `%sudo`},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
Expand All @@ -365,7 +365,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
Expand All @@ -385,7 +385,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
assert.Panics(t, func() { pipeline.serialize() })
})

Expand All @@ -401,7 +401,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, nil, nil)
pipeline.serializeStart(nil, nil, nil, nil, nil)
assert.Panics(t, func() { pipeline.serialize() })
})
}
Expand All @@ -428,7 +428,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
t.Run("plain", func(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath, OSTree: &kickstart.OSTree{}}
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, payloadStages,
Expand All @@ -440,7 +440,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath, OSTree: &kickstart.OSTree{}}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -450,7 +450,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath, Unattended: true, OSTree: &kickstart.OSTree{}}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -466,7 +466,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
OSTree: &kickstart.OSTree{},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -485,7 +485,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
OSTree: &kickstart.OSTree{},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -504,7 +504,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
OSTree: &kickstart.OSTree{},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
assert.Panics(t, func() { pipeline.serialize() })
})

Expand All @@ -521,7 +521,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
OSTree: &kickstart.OSTree{},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil)
pipeline.serializeStart(nil, nil, []ostree.CommitSpec{ostreeCommit}, nil, nil)
assert.Panics(t, func() { pipeline.serialize() })
})
}
Expand Down Expand Up @@ -552,7 +552,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
t.Run("kspath", func(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath}
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, payloadStages,
Expand All @@ -564,7 +564,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -577,7 +577,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
Unattended: true,
KernelOptionsAppend: []string{"kernel.opt=1", "debug"},
}
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
kickstartSt := findStage("org.osbuild.kickstart", sp.Stages)
Expand All @@ -589,7 +589,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
t.Run("network-on-boot", func(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath, NetworkOnBoot: true}
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
kickstartSt := findStage("org.osbuild.kickstart", sp.Stages)
Expand All @@ -609,7 +609,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
},
}
pipeline.ISOLinux = true
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
Expand All @@ -620,7 +620,7 @@ func TestAnacondaISOTreeSerializeWithContainer(t *testing.T) {
pipeline := newTestAnacondaISOTree()
pipeline.Kickstart = &kickstart.Options{Path: testKsPath}
pipeline.PayloadRemoveSignatures = true
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
skopeoStage := findStage("org.osbuild.skopeo", sp.Stages)
Expand Down Expand Up @@ -651,7 +651,7 @@ restorecon -rvF /etc/sudoers.d

func stagesFrom(pipeline Pipeline) []*osbuild.Stage {
containerPayload := makeFakeContainerPayload()
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil)
pipeline.serializeStart(nil, []container.Spec{containerPayload}, nil, nil, nil)
sp := pipeline.serialize()
pipeline.serializeEnd()
return sp.Stages
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/anaconda_installer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func TestAnacondaInstallerModules(t *testing.T) {
installerPipeline.UseLegacyAnacondaConfig = legacy
installerPipeline.AdditionalAnacondaModules = tc.enable
installerPipeline.DisabledAnacondaModules = tc.disable
installerPipeline.serializeStart(pkgs, nil, nil, nil)
installerPipeline.serializeStart(pkgs, nil, nil, nil, nil)
pipeline := installerPipeline.serialize()

require := require.New(t)
Expand Down
4 changes: 2 additions & 2 deletions pkg/manifest/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (p *BuildrootFromPackages) getPackageSpecs() []rpmmd.PackageSpec {
return p.packageSpecs
}

func (p *BuildrootFromPackages) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig) {
func (p *BuildrootFromPackages) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()")
}
Expand Down Expand Up @@ -199,7 +199,7 @@ func (p *BuildrootFromContainer) getContainerSpecs() []container.Spec {
return p.containerSpecs
}

func (p *BuildrootFromContainer) serializeStart(_ []rpmmd.PackageSpec, containerSpecs []container.Spec, _ []ostree.CommitSpec, _ []rpmmd.RepoConfig) {
func (p *BuildrootFromContainer) serializeStart(_ []rpmmd.PackageSpec, containerSpecs []container.Spec, _ []ostree.CommitSpec, _ []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if len(p.containerSpecs) > 0 {
panic("double call to serializeStart()")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func TestNewBuildFromContainerSpecs(t *testing.T) {
}
// containerSpecs is "nil" until serializeStart populates it
require.Nil(t, build.getContainerSpecs())
build.serializeStart(nil, fakeContainerSpecs, nil, nil)
build.serializeStart(nil, fakeContainerSpecs, nil, nil, nil)
assert.Equal(t, build.getContainerSpecs(), fakeContainerSpecs)

osbuildPipeline := build.serialize()
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/commit_server_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (p *OSTreeCommitServer) getPackageSpecs() []rpmmd.PackageSpec {
return p.packageSpecs
}

func (p *OSTreeCommitServer) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig) {
func (p *OSTreeCommitServer) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/coreos_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (p *CoreOSInstaller) getPackageSpecs() []rpmmd.PackageSpec {
return p.packageSpecs
}

func (p *CoreOSInstaller) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig) {
func (p *CoreOSInstaller) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec, rpmRepos []rpmmd.RepoConfig, _ []rpmmd.ModuleConfig) {
if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()")
}
Expand Down
Loading
Loading