manifest: make packageSpecs optional
Allow manifests to be instantiated without providing packageSpecs. This allows manifests without packageSpecs to be introspected, but not serialized. The only reason we used to require packegaSpecs to be passed at instantiation time was to compute the kernelVer based on the kernelName and the NEVRAs in the package set. Now move this to be done at serialize time. This means that in order to serialize a manifest, you need to pass the packageSpecs at initialization time, but if you don't need to serialize, only to introspect it, then you don't need to pass it at all. In a future patch packageSpecs will be passed at serialization time to not have to make that commitment up front. The new logic is now that before a pipeline can be serialized, all the pipelines in the manifest must be "prepared" for serialization by calling serialize_start() on each of them, which does whatever would in the past have been done at initialization time which required the pacakgeSpecs. Once serialization has been finished serialize_end() must be called on each of the pipelines to undo any of the preparation, making sure we can serialize repeatedly, possibly while changing the fields of our pipeline in-between, and that serialization appears from the outside to not have any side-effects. In a future PR we may want to rework this logic to instead use a serialization context.
This commit is contained in:
parent
8f9b6eef8f
commit
1cb2f0276d
4 changed files with 56 additions and 7 deletions
|
|
@ -27,6 +27,7 @@ type AnacondaPipeline struct {
|
|||
|
||||
repos []rpmmd.RepoConfig
|
||||
packageSpecs []rpmmd.PackageSpec
|
||||
kernelName string
|
||||
kernelVer string
|
||||
arch string
|
||||
product string
|
||||
|
|
@ -46,12 +47,11 @@ func NewAnacondaPipeline(buildPipeline *BuildPipeline,
|
|||
arch,
|
||||
product,
|
||||
version string) *AnacondaPipeline {
|
||||
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
|
||||
p := &AnacondaPipeline{
|
||||
BasePipeline: NewBasePipeline("anaconda-tree", buildPipeline, nil),
|
||||
repos: repos,
|
||||
packageSpecs: packages,
|
||||
kernelVer: kernelVer,
|
||||
kernelName: kernelName,
|
||||
arch: arch,
|
||||
product: product,
|
||||
version: version,
|
||||
|
|
@ -74,6 +74,20 @@ func (p *AnacondaPipeline) getPackageSpecs() []rpmmd.PackageSpec {
|
|||
return p.packageSpecs
|
||||
}
|
||||
|
||||
func (p *AnacondaPipeline) serializeStart() {
|
||||
if p.kernelVer != "" {
|
||||
panic("double call to serializeStart()")
|
||||
}
|
||||
p.kernelVer = rpmmd.GetVerStrFromPackageSpecListPanic(p.packageSpecs, p.kernelName)
|
||||
}
|
||||
|
||||
func (p *AnacondaPipeline) serializeEnd() {
|
||||
if p.kernelVer == "" {
|
||||
panic("serializeEnd() call when serialization not in progress")
|
||||
}
|
||||
p.kernelVer = ""
|
||||
}
|
||||
|
||||
func (p *AnacondaPipeline) serialize() osbuild2.Pipeline {
|
||||
pipeline := p.BasePipeline.serialize()
|
||||
|
||||
|
|
|
|||
|
|
@ -79,9 +79,15 @@ func (m Manifest) Serialize() (distro.Manifest, error) {
|
|||
}
|
||||
|
||||
pipelines := make([]osbuild2.Pipeline, 0)
|
||||
for _, pipeline := range m.pipelines {
|
||||
pipeline.serializeStart()
|
||||
}
|
||||
for _, pipeline := range m.pipelines {
|
||||
pipelines = append(pipelines, pipeline.serialize())
|
||||
}
|
||||
for _, pipeline := range m.pipelines {
|
||||
pipeline.serializeEnd()
|
||||
}
|
||||
|
||||
return json.Marshal(
|
||||
osbuild2.Manifest{
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ type OSPipeline struct {
|
|||
partitionTable *disk.PartitionTable
|
||||
bootLoader BootLoader
|
||||
grubLegacy string
|
||||
kernelName string
|
||||
kernelVer string
|
||||
}
|
||||
|
||||
|
|
@ -115,10 +116,6 @@ func NewOSPipeline(buildPipeline *BuildPipeline,
|
|||
if osTree {
|
||||
name = "ostree-tree"
|
||||
}
|
||||
var kernelVer string
|
||||
if kernelName != "" {
|
||||
kernelVer = rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
|
||||
}
|
||||
p := &OSPipeline{
|
||||
BasePipeline: NewBasePipeline(name, buildPipeline, nil),
|
||||
osTree: osTree,
|
||||
|
|
@ -129,7 +126,7 @@ func NewOSPipeline(buildPipeline *BuildPipeline,
|
|||
partitionTable: partitionTable,
|
||||
bootLoader: bootLoader,
|
||||
grubLegacy: grubLegacy,
|
||||
kernelVer: kernelVer,
|
||||
kernelName: kernelName,
|
||||
Language: "C.UTF-8",
|
||||
Hostname: "localhost.localdomain",
|
||||
Timezone: "UTC",
|
||||
|
|
@ -174,6 +171,26 @@ func (p *OSPipeline) getPackageSpecs() []rpmmd.PackageSpec {
|
|||
return p.packageSpecs
|
||||
}
|
||||
|
||||
func (p *OSPipeline) serializeStart() {
|
||||
if p.kernelName == "" {
|
||||
return
|
||||
}
|
||||
if p.kernelVer != "" {
|
||||
panic("double call to serializeStart()")
|
||||
}
|
||||
p.kernelVer = rpmmd.GetVerStrFromPackageSpecListPanic(p.packageSpecs, p.kernelName)
|
||||
}
|
||||
|
||||
func (p *OSPipeline) serializeEnd() {
|
||||
if p.kernelName == "" {
|
||||
return
|
||||
}
|
||||
if p.kernelVer == "" {
|
||||
panic("serializeEnd() call when serialization not in progress")
|
||||
}
|
||||
p.kernelVer = ""
|
||||
}
|
||||
|
||||
func (p *OSPipeline) serialize() osbuild2.Pipeline {
|
||||
pipeline := p.BasePipeline.serialize()
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ type Pipeline interface {
|
|||
Name() string
|
||||
getBuildPackages() []string
|
||||
getPackageSetChain() []rpmmd.PackageSet
|
||||
serializeStart()
|
||||
serializeEnd()
|
||||
serialize() osbuild2.Pipeline
|
||||
getPackageSpecs() []rpmmd.PackageSpec
|
||||
getOSTreeCommits() []osTreeCommit
|
||||
|
|
@ -79,6 +81,16 @@ func NewBasePipeline(name string, build *BuildPipeline, runner *string) BasePipe
|
|||
return p
|
||||
}
|
||||
|
||||
// serializeStart must be called exactly once before each call
|
||||
// to serialize().
|
||||
func (p BasePipeline) serializeStart() {
|
||||
}
|
||||
|
||||
// serializeEnd must be called exactly once after each call to
|
||||
// serialize().
|
||||
func (p BasePipeline) serializeEnd() {
|
||||
}
|
||||
|
||||
// Serialize turns a given pipeline into an osbuild2.Pipeline object. This object is
|
||||
// meant to be treated as opaque and not to be modified further outside of the pipeline
|
||||
// package.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue