Skip to content

Commit

Permalink
manifest: use experimentalflags.String("buildroot")
Browse files Browse the repository at this point in the history
This commit allows to force a container based buildroot as part
of images when setting:
```
$ IMAGE_BUILDER_EXPERIMENTAL=buildroot=ghcr.io/mvo5/fedora-buildroot:41 \
   image-builder manifest --arch=riscv64 minimal-raw --distro=fedora-41
```
and it will replace the buildroot with the given container.

This will allow to do cross-arch building for riscv. The generated
manifest can be build with osbuild (as long as qemu-user is installed)
and will generate a minimal-raw for riscv64.

Cross-building is useful because qemu-user is a lot faster
(and easier to setup) than full riscv system emulation.
A minimal raw build on a really fast AWS machine takes about
100 minutes. A full minimal-raw build on my (moderate) PC takes
about 20min - which is fast enough so that we can run this in
GH workflows as part of the CI.

Long term I would love to see this generalized and that we would
(optionally) support container based buildroots for most/all(?)
our distro/arch combos. This could be done without too much
maintenance burden on our side via e.g. just pointing to the official
 `ubi` containers for rhel that we then install extra rpms into
(like the mkfs.* tools). This would then allow cross-arch image
building for e.g. a raspberry pi from a normal PC. But obviously
this is all long term stuff that needs more design/discussion
(I'm just mentioning it to make clear that this is not a dead-end
but has more potential).
  • Loading branch information
mvo5 committed Feb 24, 2025
1 parent 1e6f652 commit d60b311
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
28 changes: 28 additions & 0 deletions pkg/manifest/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package manifest
import (
"fmt"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/experimentalflags"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/rpmmd"
"github.com/osbuild/images/pkg/runner"
Expand Down Expand Up @@ -49,6 +51,13 @@ func NewBuild(m *Manifest, runner runner.Runner, repos []rpmmd.RepoConfig, opts
opts = &BuildOptions{}
}

// This allows to override the buildroot with a custom container
// for e.g. cross-arch-build experiments, remove once we have
// a standard way of doing this
if fb := experimentalForcedContainerBuildroot(m, runner, opts); fb != nil {
return fb
}

name := "build"
pipeline := &BuildrootFromPackages{
Base: NewBase(name, nil),
Expand Down Expand Up @@ -149,6 +158,25 @@ func (p *BuildrootFromPackages) getSELinuxLabels() map[string]string {
return labels
}

// experimentalForcedContainerBuildroot will return a container buildroot
// if if the "IMAGE_BUILDER_EXPERIMENTAL=buildroot=<container-ref>" is
// defined. This allows us to do cross-arch build experimentation.
func experimentalForcedContainerBuildroot(m *Manifest, runner runner.Runner, opts *BuildOptions) Build {
forcedBuildroot := experimentalflags.String("buildroot")
if forcedBuildroot == "" {
return nil
}

cntSrcs := []container.SourceSpec{
{
Source: forcedBuildroot,
Name: forcedBuildroot,
TLSVerify: common.ToPtr(false),
},
}
return NewBuildFromContainer(m, runner, cntSrcs, opts)
}

type BuildrootFromContainer struct {
Base

Expand Down
29 changes: 29 additions & 0 deletions pkg/manifest/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/rpmmd"
Expand Down Expand Up @@ -146,3 +147,31 @@ func TestBuildFromContainerSpecsGetSelinuxLabelsWithContainerBuildable(t *testin
"/usr/bin/umount": "system_u:object_r:install_exec_t:s0",
})
}

func TestNewBuildWithExperimentalOverride(t *testing.T) {
for _, withForcedBuildroot := range []bool{false, true} {
if withForcedBuildroot {
t.Setenv("IMAGE_BUILDER_EXPERIMENTAL", "buildroot=ghcr.io/ondrejbudai/cool:stuff")
} else {
t.Setenv("IMAGE_BUILDER_EXPERIMENTAL", "")
}
mf := New()
runner := &runner.Fedora{Version: 42}
buildIf := NewBuild(&mf, runner, nil, nil)
require.NotNil(t, buildIf)
if withForcedBuildroot {
br, ok := buildIf.(*BuildrootFromContainer)
assert.True(t, ok)
assert.Equal(t, []container.SourceSpec{
{
Source: "ghcr.io/ondrejbudai/cool:stuff",
Name: "ghcr.io/ondrejbudai/cool:stuff",
TLSVerify: common.ToPtr(false),
},
}, br.containers)
} else {
_, ok := buildIf.(*BuildrootFromPackages)
assert.True(t, ok)
}
}
}

0 comments on commit d60b311

Please sign in to comment.