debian-forge-cli/cmd/image-builder/repos.go
Michael Vogt bc5be2ba8a main: add --force-repo flag
This commit adds an `--force-repo` flag that can be used
to replace all the base repositories with a base url to
a repository. This is useful for testing but also dangerous
as it will not do any checks and happily use a fedora-42 repository
for centos-8 depsolving.

This will make the use-case of the koji builder easier and is
also something that the `build` tool in `images` supports.
2025-02-13 11:31:06 +00:00

95 lines
2.9 KiB
Go

package main
import (
"fmt"
"io/fs"
"net/url"
"github.com/osbuild/images/data/repositories"
"github.com/osbuild/images/pkg/arch"
"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
}
// 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
}
// Only add extra repos for the host architecture. We do not support
// cross-building (yet) so this is fine. Once we support cross-building
// this needs to move (probably into manifestgen) because at this
// level we we do not know (yet) what manifest we will generate.
myArch := arch.Current().String()
for _, repoArchConfigs := range conf {
archCfg := repoArchConfigs[myArch]
archCfg = append(archCfg, repoConf...)
repoArchConfigs[myArch] = archCfg
}
return reporegistry.NewFromDistrosRepoConfigs(conf), nil
}
// this is a variable to make it overridable in tests
var newRepoRegistry = newRepoRegistryImpl