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.
99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package manifest
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
|
"github.com/osbuild/osbuild-composer/internal/osbuild2"
|
|
"github.com/osbuild/osbuild-composer/internal/ostree"
|
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
|
)
|
|
|
|
type osTreeCommit struct {
|
|
checksum string
|
|
url string
|
|
}
|
|
|
|
// An OSBuildManifest is an opaque JSON object, which is a valid input to osbuild
|
|
// TODO: use this instead of distro.Manifest below
|
|
type OSBuildManifest []byte
|
|
|
|
type Manifest struct {
|
|
pipelines []Pipeline
|
|
packageSpecs []rpmmd.PackageSpec
|
|
osTreeCommits []osTreeCommit
|
|
inlineData []string
|
|
}
|
|
|
|
func New() Manifest {
|
|
return Manifest{
|
|
pipelines: make([]Pipeline, 0),
|
|
packageSpecs: make([]rpmmd.PackageSpec, 0),
|
|
osTreeCommits: make([]osTreeCommit, 0),
|
|
inlineData: make([]string, 0),
|
|
}
|
|
}
|
|
|
|
func (m *Manifest) AddPipeline(p Pipeline) {
|
|
for _, pipeline := range m.pipelines {
|
|
if pipeline.Name() == p.Name() {
|
|
panic("duplicate pipeline name in manifest")
|
|
}
|
|
}
|
|
m.pipelines = append(m.pipelines, p)
|
|
m.addPackages(p.getPackageSpecs())
|
|
m.addOSTreeCommits(p.getOSTreeCommits())
|
|
m.addInline(p.getInline())
|
|
}
|
|
|
|
func (m *Manifest) addPackages(packages []rpmmd.PackageSpec) {
|
|
m.packageSpecs = append(m.packageSpecs, packages...)
|
|
}
|
|
|
|
func (m *Manifest) addOSTreeCommits(commits []osTreeCommit) {
|
|
m.osTreeCommits = append(m.osTreeCommits, commits...)
|
|
}
|
|
|
|
func (m *Manifest) addInline(data []string) {
|
|
m.inlineData = append(m.inlineData, data...)
|
|
}
|
|
|
|
func (m Manifest) GetPackageSetChains() map[string][]rpmmd.PackageSet {
|
|
chains := make(map[string][]rpmmd.PackageSet)
|
|
|
|
for _, pipeline := range m.pipelines {
|
|
chains[pipeline.Name()] = pipeline.getPackageSetChain()
|
|
}
|
|
|
|
return chains
|
|
}
|
|
|
|
func (m Manifest) Serialize() (distro.Manifest, error) {
|
|
var commits []ostree.CommitSource
|
|
for _, commit := range m.osTreeCommits {
|
|
commits = []ostree.CommitSource{
|
|
{
|
|
Checksum: commit.checksum, URL: commit.url,
|
|
},
|
|
}
|
|
}
|
|
|
|
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{
|
|
Version: "2",
|
|
Pipelines: pipelines,
|
|
Sources: osbuild2.GenSources(m.packageSpecs, commits, m.inlineData),
|
|
},
|
|
)
|
|
}
|