debian-forge-composer/vendor/github.com/osbuild/images/pkg/osbuild/source.go
Tomáš Hozza 7a580f79ae go.mod: bump osbuild/images to v0.158.0
Use the version that contains the updated Koji upload code.

Also bump the version of `osbuild/blueprint` due to the new `uri` field
in file customizations.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
2025-07-14 17:20:02 +02:00

197 lines
4.9 KiB
Go

package osbuild
import (
"encoding/json"
"errors"
"fmt"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/dnfjson"
"github.com/osbuild/images/pkg/hashutil"
"github.com/osbuild/images/pkg/ostree"
"github.com/osbuild/images/pkg/rpmmd"
)
// RpmDownloader specifies what backend to use for rpm downloads
// Note that the librepo backend requires a newer osbuild.
type RpmDownloader uint64
const (
RpmDownloaderCurl = iota
RpmDownloaderLibrepo = iota
)
// SourceInputs contains the inputs to generate osbuild.Sources
// Note that for Packages/RpmRepos the depsolve resolved results
// must be passed
type SourceInputs struct {
Depsolved dnfjson.DepsolveResult
Containers []container.Spec
Commits []ostree.CommitSpec
// InlineData contans the inline data for fsnode.Files
InlineData []string
// FileRefs contains the references of paths/urls for fsnode.Files
FileRefs []string
}
// A Sources map contains all the sources made available to an osbuild run
type Sources map[string]Source
// Source specifies the operations of a given source-type.
type Source interface {
isSource()
}
type SourceOptions interface {
isSourceOptions()
}
type rawSources map[string]json.RawMessage
// UnmarshalJSON unmarshals JSON into a Source object. Each type of source has
// a custom unmarshaller for its options, selected based on the source name.
func (sources *Sources) UnmarshalJSON(data []byte) error {
var rawSources rawSources
err := json.Unmarshal(data, &rawSources)
if err != nil {
return err
}
*sources = make(map[string]Source)
for name, rawSource := range rawSources {
var source Source
switch name {
case SourceNameCurl:
source = new(CurlSource)
case SourceNameLibrepo:
source = new(LibrepoSource)
case SourceNameInline:
source = new(InlineSource)
case SourceNameOstree:
source = new(OSTreeSource)
default:
return errors.New("unexpected source name: " + name)
}
err = json.Unmarshal(rawSource, source)
if err != nil {
return err
}
(*sources)[name] = source
}
return nil
}
func (sources Sources) addPackagesCurl(packages []rpmmd.PackageSpec) error {
curl := NewCurlSource()
for _, pkg := range packages {
err := curl.AddPackage(pkg)
if err != nil {
return err
}
}
sources[SourceNameCurl] = curl
return nil
}
func (sources Sources) addPackagesLibrepo(packages []rpmmd.PackageSpec, rpmRepos []rpmmd.RepoConfig) error {
librepo := NewLibrepoSource()
for _, pkg := range packages {
err := librepo.AddPackage(pkg, rpmRepos)
if err != nil {
return err
}
}
sources[SourceNameLibrepo] = librepo
return nil
}
// GenSources generates the Sources from the given inputs. Note that
// the packages and rpmRepos need to come from the *resolved* set.
func GenSources(inputs SourceInputs, rpmDownloader RpmDownloader) (Sources, error) {
sources := Sources{}
// collect rpm package sources
if len(inputs.Depsolved.Packages) > 0 {
var err error
switch rpmDownloader {
case RpmDownloaderCurl:
err = sources.addPackagesCurl(inputs.Depsolved.Packages)
case RpmDownloaderLibrepo:
err = sources.addPackagesLibrepo(inputs.Depsolved.Packages, inputs.Depsolved.Repos)
default:
err = fmt.Errorf("unknown rpm downloader %v", rpmDownloader)
}
if err != nil {
return nil, err
}
}
// collect ostree commit sources
if len(inputs.Commits) > 0 {
ostree := NewOSTreeSource()
for _, commit := range inputs.Commits {
ostree.AddItem(commit)
}
if len(ostree.Items) > 0 {
sources[SourceNameOstree] = ostree
}
}
// collect inline data sources
if len(inputs.InlineData) > 0 {
ils := NewInlineSource()
for _, data := range inputs.InlineData {
ils.AddItem(data)
}
sources[SourceNameInline] = ils
}
// collect skopeo and local container sources
if len(inputs.Containers) > 0 {
skopeo := NewSkopeoSource()
skopeoIndex := NewSkopeoIndexSource()
localContainers := NewContainersStorageSource()
for _, c := range inputs.Containers {
if c.LocalStorage {
localContainers.AddItem(c.ImageID)
} else {
skopeo.AddItem(c.Source, c.Digest, c.ImageID, c.TLSVerify)
// if we have a list digest, add a skopeo-index source as well
if c.ListDigest != "" {
skopeoIndex.AddItem(c.Source, c.ListDigest, c.TLSVerify)
}
}
}
if len(skopeo.Items) > 0 {
sources[SourceNameSkopeo] = skopeo
}
if len(skopeoIndex.Items) > 0 {
sources[SourceNameSkopeoIndex] = skopeoIndex
}
if len(localContainers.Items) > 0 {
sources[SourceNameContainersStorage] = localContainers
}
}
// collect host resources
if len(inputs.FileRefs) > 0 {
// XXX: fugly
curl, ok := sources["org.osbuild.curl"].(*CurlSource)
if !ok || curl == nil {
curl = NewCurlSource()
}
for _, hostRes := range inputs.FileRefs {
checksum, err := hashutil.Sha256sum(hostRes)
if err != nil {
return nil, err
}
curl.Items["sha256:"+checksum] = &CurlSourceOptions{
URL: fmt.Sprintf("file:%s", hostRes),
}
}
sources["org.osbuild.curl"] = curl
}
return sources, nil
}