main: auto-cross build for foreign architectures
This commit is contained in:
parent
dd4547034b
commit
8e6a6673f5
3 changed files with 40 additions and 31 deletions
|
|
@ -14,7 +14,6 @@ import (
|
||||||
|
|
||||||
"github.com/osbuild/bootc-image-builder/bib/pkg/progress"
|
"github.com/osbuild/bootc-image-builder/bib/pkg/progress"
|
||||||
"github.com/osbuild/images/pkg/arch"
|
"github.com/osbuild/images/pkg/arch"
|
||||||
"github.com/osbuild/images/pkg/experimentalflags"
|
|
||||||
"github.com/osbuild/images/pkg/imagefilter"
|
"github.com/osbuild/images/pkg/imagefilter"
|
||||||
"github.com/osbuild/images/pkg/osbuild"
|
"github.com/osbuild/images/pkg/osbuild"
|
||||||
"github.com/osbuild/images/pkg/ostree"
|
"github.com/osbuild/images/pkg/ostree"
|
||||||
|
|
@ -82,7 +81,7 @@ func ostreeImageOptions(cmd *cobra.Command) (*ostree.ImageOptions, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []string, w io.Writer, archChecker func(string) error) (*imagefilter.Result, error) {
|
func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []string, w io.Writer, needBootstrap func(string) bool) (*imagefilter.Result, error) {
|
||||||
dataDir, err := cmd.Flags().GetString("data-dir")
|
dataDir, err := cmd.Flags().GetString("data-dir")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -157,13 +156,6 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// assume that users with the "bootstrap" flag want cross building
|
|
||||||
// and skip arch checks then
|
|
||||||
if archChecker != nil && experimentalflags.String("bootstrap") == "" {
|
|
||||||
if err := archChecker(img.Arch.Name()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(img.ImgType.Exports()) > 1 {
|
if len(img.ImgType.Exports()) > 1 {
|
||||||
return nil, fmt.Errorf("image %q has multiple exports: this is current unsupport: please report this as a bug", basenameFor(img, ""))
|
return nil, fmt.Errorf("image %q has multiple exports: this is current unsupport: please report this as a bug", basenameFor(img, ""))
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +170,13 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
|
||||||
|
|
||||||
ForceRepos: forceRepos,
|
ForceRepos: forceRepos,
|
||||||
}
|
}
|
||||||
|
if needBootstrap != nil {
|
||||||
|
opts.UseBootstrapContainer = needBootstrap(img.Arch.Name())
|
||||||
|
}
|
||||||
|
if opts.UseBootstrapContainer {
|
||||||
|
fmt.Fprintf(os.Stderr, "WARNING: using experimental cross-architecture building to build %q\n", img.Arch.Name())
|
||||||
|
}
|
||||||
|
|
||||||
err = generateManifest(dataDir, extraRepos, img, w, opts)
|
err = generateManifest(dataDir, extraRepos, img, w, opts)
|
||||||
return img, err
|
return img, err
|
||||||
}
|
}
|
||||||
|
|
@ -244,11 +243,8 @@ func cmdBuild(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
var mf bytes.Buffer
|
var mf bytes.Buffer
|
||||||
// XXX: check env here, i.e. if user is root and osbuild is installed
|
// XXX: check env here, i.e. if user is root and osbuild is installed
|
||||||
res, err := cmdManifestWrapper(pbar, cmd, args, &mf, func(archStr string) error {
|
res, err := cmdManifestWrapper(pbar, cmd, args, &mf, func(archStr string) bool {
|
||||||
if archStr != arch.Current().String() {
|
return archStr != arch.Current().String()
|
||||||
return fmt.Errorf("cannot build for arch %q from %q", archStr, arch.Current().String())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -814,7 +814,7 @@ func TestManifestOverrideRepo(t *testing.T) {
|
||||||
// DNF error occurred: RepoError: There was a problem reading a repository: Failed to download metadata for repo '9828718901ab404ac1b600157aec1a8b19f4b2139e7756f347fb0ecc06c92929' [forced repo#0 xxx.abcdefgh-no-such-host.com/repo: http://xxx.abcdefgh-no-such-host.com/repo]: Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried`
|
// DNF error occurred: RepoError: There was a problem reading a repository: Failed to download metadata for repo '9828718901ab404ac1b600157aec1a8b19f4b2139e7756f347fb0ecc06c92929' [forced repo#0 xxx.abcdefgh-no-such-host.com/repo: http://xxx.abcdefgh-no-such-host.com/repo]: Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildCrossArchCheckSkippedOnExperimentalBuildroot(t *testing.T) {
|
func TestBuildCrossArchSmoke(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("manifest generation takes a while")
|
t.Skip("manifest generation takes a while")
|
||||||
}
|
}
|
||||||
|
|
@ -826,31 +826,42 @@ func TestBuildCrossArchCheckSkippedOnExperimentalBuildroot(t *testing.T) {
|
||||||
defer restore()
|
defer restore()
|
||||||
|
|
||||||
tmpdir := t.TempDir()
|
tmpdir := t.TempDir()
|
||||||
for _, withExperimentalBootstrapEnv := range []bool{false, true} {
|
for _, withCrossArch := range []bool{false, true} {
|
||||||
if withExperimentalBootstrapEnv {
|
cmd := []string{
|
||||||
t.Setenv("IMAGE_BUILDER_EXPERIMENTAL", "bootstrap=ghcr.io/mvo5/fedora-buildroot:41")
|
|
||||||
}
|
|
||||||
restore = main.MockOsArgs([]string{
|
|
||||||
"build",
|
"build",
|
||||||
"qcow2",
|
"qcow2",
|
||||||
"--distro", "centos-9",
|
"--distro", "centos-9",
|
||||||
"--cache", tmpdir,
|
"--cache", tmpdir,
|
||||||
"--arch=s390x",
|
|
||||||
"--output-dir", tmpdir,
|
"--output-dir", tmpdir,
|
||||||
})
|
}
|
||||||
|
if withCrossArch {
|
||||||
|
cmd = append(cmd, "--arch=aarch64")
|
||||||
|
}
|
||||||
|
restore = main.MockOsArgs(cmd)
|
||||||
defer restore()
|
defer restore()
|
||||||
|
|
||||||
script := makeFakeOsbuildScript()
|
script := makeFakeOsbuildScript()
|
||||||
fakeOsbuildCmd := testutil.MockCommand(t, "osbuild", script)
|
fakeOsbuildCmd := testutil.MockCommand(t, "osbuild", script)
|
||||||
defer fakeOsbuildCmd.Restore()
|
defer fakeOsbuildCmd.Restore()
|
||||||
|
|
||||||
err := main.Run()
|
var err error
|
||||||
if withExperimentalBootstrapEnv {
|
_, stderr := testutil.CaptureStdio(t, func() {
|
||||||
assert.NoError(t, err)
|
err = main.Run()
|
||||||
require.Equal(t, 1, len(fakeOsbuildCmd.Calls()))
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
manifest, err := os.ReadFile(fakeOsbuildCmd.Path() + ".stdin")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
pipelines, err := manifesttest.PipelineNamesFrom(manifest)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
crossArchPipeline := "bootstrap-buildroot"
|
||||||
|
crossArchWarning := `WARNING: using experimental cross-architecture building to build "aarch64"`
|
||||||
|
if withCrossArch {
|
||||||
|
assert.Contains(t, pipelines, crossArchPipeline)
|
||||||
|
assert.Contains(t, stderr, crossArchWarning)
|
||||||
} else {
|
} else {
|
||||||
assert.EqualError(t, err, `cannot build for arch "s390x" from "x86_64"`)
|
assert.NotContains(t, pipelines, crossArchPipeline)
|
||||||
require.Equal(t, 0, len(fakeOsbuildCmd.Calls()))
|
assert.NotContains(t, stderr, crossArchWarning)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ type manifestOptions struct {
|
||||||
RpmDownloader osbuild.RpmDownloader
|
RpmDownloader osbuild.RpmDownloader
|
||||||
WithSBOM bool
|
WithSBOM bool
|
||||||
|
|
||||||
ForceRepos []string
|
ForceRepos []string
|
||||||
|
UseBootstrapContainer bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func sbomWriter(outputDir, filename string, content io.Reader) error {
|
func sbomWriter(outputDir, filename string, content io.Reader) error {
|
||||||
|
|
@ -51,8 +52,9 @@ func generateManifest(dataDir string, extraRepos []string, img *imagefilter.Resu
|
||||||
}
|
}
|
||||||
// XXX: add --rpmmd/cachedir option like bib
|
// XXX: add --rpmmd/cachedir option like bib
|
||||||
manifestGenOpts := &manifestgen.Options{
|
manifestGenOpts := &manifestgen.Options{
|
||||||
Output: output,
|
Output: output,
|
||||||
RpmDownloader: opts.RpmDownloader,
|
RpmDownloader: opts.RpmDownloader,
|
||||||
|
UseBootstrapContainer: opts.UseBootstrapContainer,
|
||||||
}
|
}
|
||||||
if opts.WithSBOM {
|
if opts.WithSBOM {
|
||||||
outputDir := basenameFor(img, opts.OutputDir)
|
outputDir := basenameFor(img, opts.OutputDir)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue