debian-forge-cli/cmd/image-builder/repos.go
Michael Vogt 75f24bbd2a main: fix --extra-repos support when cross building
This commit fixes the issue that --extra-repo are not added
correctly to the repo registry when doing cross arch building.
The issue is that they get added early at the reporegistry
level and because we don't know yet what arch will be used
it was initially only added to the host arch. This was
fine before we supported cross-arch building.

But now that we do support cross-arch building this is
of course an issue and produces subtle bugs. This commit
is the "easy" fix, the extra repos are just added to for
all architectures. This may not be right but because they
are optional its the reponsibility of the user to provide
the right ones. Eventually we should probably be smarter
here and move extra repo support into manifestgen but
that requires changes in images and an images release so
this is good enough for now.

Thanks to Simon de Vlieger for reporting this.
2025-08-19 15:18:58 +00:00

97 lines
2.8 KiB
Go

package main
import (
"fmt"
"io/fs"
"net/url"
"github.com/osbuild/images/data/repositories"
"github.com/osbuild/images/pkg/reporegistry"
"github.com/osbuild/images/pkg/rpmmd"
)
// defaultDataDirs contains the default search paths to look for
// repository data. They contain a bunch of json files of the form
// "$distro_$version".json (but that is an implementation detail that
// the "images" library takes care of).
var defaultDataDirs = []string{
"/etc/image-builder/repositories",
"/usr/share/image-builder/repositories",
}
type repoConfig struct {
DataDir string
ExtraRepos []string
}
func parseRepoURLs(repoURLs []string, what string) ([]rpmmd.RepoConfig, error) {
var repoConf []rpmmd.RepoConfig
for i, repoURL := range repoURLs {
// We want to eventually support more URIs repos here:
// - config:/path/to/repo.json
// - copr:@osbuild/osbuild (with full gpg retrival via the copr API)
// But for now just default to base-urls
baseURL, err := url.Parse(repoURL)
if err != nil {
return nil, fmt.Errorf("cannot parse extra repo %w", err)
}
if baseURL.Scheme == "" {
return nil, fmt.Errorf(`scheme missing in %q, please prefix with e.g. file:// or https://`, repoURL)
}
// TODO: to support gpg checking we will need to add signing keys.
// We will eventually add support for our own "repo.json" format
// which is rich enough to contain gpg keys (and more).
checkGPG := false
repoConf = append(repoConf, rpmmd.RepoConfig{
Id: fmt.Sprintf("%s-repo-%v", what, i),
Name: fmt.Sprintf("%s repo#%v %s%s", what, i, baseURL.Host, baseURL.Path),
BaseURLs: []string{baseURL.String()},
CheckGPG: &checkGPG,
CheckRepoGPG: &checkGPG,
})
}
return repoConf, nil
}
func newRepoRegistryImpl(dataDir string, extraRepos []string) (*reporegistry.RepoRegistry, error) {
var dataDirs []string
if dataDir != "" {
dataDirs = []string{dataDir}
} else {
dataDirs = defaultDataDirs
}
conf, err := reporegistry.LoadAllRepositories(dataDirs, []fs.FS{repos.FS})
if err != nil {
return nil, err
}
// Add extra repos to all architecture. We support
// cross-building but at this level here we don't know yet
// what manifests will be generated so we must (for now)
// rely on the user to DTRT with extraRepos.
//
// XXX: this should probably go into manifestgen.Options as a
// new Options.ExtraRepoConf eventually (just like
// OverrideRepos)
repoConf, err := parseRepoURLs(extraRepos, "extra")
if err != nil {
return nil, err
}
for _, repoArchConfigs := range conf {
for arch := range repoArchConfigs {
archCfg := repoArchConfigs[arch]
archCfg = append(archCfg, repoConf...)
repoArchConfigs[arch] = archCfg
}
}
return reporegistry.NewFromDistrosRepoConfigs(conf), nil
}
// this is a variable to make it overridable in tests
var newRepoRegistry = newRepoRegistryImpl