Imagine this situation: You have a RHEL system booted from an image produced
by osbuild-composer. On this system, you want to use osbuild-composer to
create another image of RHEL.
However, there's currently something funny with partitions:
All RHEL images built by osbuild-composer contain a root xfs partition. The
interesting bit is that they all share the same xfs partition UUID. This might
sound like a good thing for reproducibility but it has a quirk.
The issue appears when osbuild runs the qemu assembler: it needs to mount all
partitions of the future image to copy the OS tree into it.
Imagine that osbuild-composer is running on a system booted from an imaged
produced by osbuild-composer. This means that its root xfs partition has this
uuid:
efe8afea-c0a8-45dc-8e6e-499279f6fa5d
When osbuild-composer builds an image on this system, it runs osbuild that
runs the qemu assembler at some point. As I said previously, it will mount
all partitions of the future image. That means that it will also try to
mount the root xfs partition with this uuid:
efe8afea-c0a8-45dc-8e6e-499279f6fa5d
Do you remember this one? Yeah, it's the same one as before. However, the xfs
kernel driver doesn't like that. It contains a global table[1] of all xfs
partitions that forbids to mount 2 xfs partitions with the same uuid.
I mean... uuids are meant to be unique, right?
This commit changes the way we build RHEL 8.4 images: Each one now has a
unique uuid. It's now literally a unique universally unique identifier. haha
[1]: a349e4c659/fs/xfs/xfs_mount.c (L51)
119 lines
2.1 KiB
Go
119 lines
2.1 KiB
Go
package fedoratest
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
|
"github.com/osbuild/osbuild-composer/internal/osbuild"
|
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
|
)
|
|
|
|
const name = "fedora-30"
|
|
const modulePlatformID = "platform:f30"
|
|
|
|
type FedoraTestDistro struct{}
|
|
|
|
type arch struct {
|
|
name string
|
|
distro *FedoraTestDistro
|
|
}
|
|
|
|
type imageType struct {
|
|
name string
|
|
arch *arch
|
|
}
|
|
|
|
func (a *arch) Distro() distro.Distro {
|
|
return a.distro
|
|
}
|
|
|
|
func (t *imageType) Arch() distro.Arch {
|
|
return t.arch
|
|
}
|
|
|
|
func (d *FedoraTestDistro) ListArches() []string {
|
|
return []string{"x86_64"}
|
|
}
|
|
|
|
func (d *FedoraTestDistro) GetArch(name string) (distro.Arch, error) {
|
|
if name != "x86_64" {
|
|
return nil, errors.New("invalid architecture: " + name)
|
|
}
|
|
|
|
return &arch{
|
|
name: name,
|
|
distro: d,
|
|
}, nil
|
|
}
|
|
|
|
func (a *arch) Name() string {
|
|
return a.name
|
|
}
|
|
|
|
func (a *arch) ListImageTypes() []string {
|
|
return []string{"qcow2"}
|
|
}
|
|
|
|
func (a *arch) GetImageType(name string) (distro.ImageType, error) {
|
|
if name != "qcow2" {
|
|
return nil, errors.New("invalid image type: " + name)
|
|
}
|
|
|
|
return &imageType{
|
|
name: name,
|
|
arch: a,
|
|
}, nil
|
|
}
|
|
|
|
func (t *imageType) Name() string {
|
|
return t.name
|
|
}
|
|
|
|
func (t *imageType) Filename() string {
|
|
return "test.img"
|
|
}
|
|
|
|
func (t *imageType) MIMEType() string {
|
|
return "application/x-test"
|
|
}
|
|
|
|
func (t *imageType) Size(size uint64) uint64 {
|
|
return size
|
|
}
|
|
|
|
func (t *imageType) Packages(bp blueprint.Blueprint) ([]string, []string) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (t *imageType) BuildPackages() []string {
|
|
return nil
|
|
}
|
|
|
|
func (t *imageType) Manifest(c *blueprint.Customizations,
|
|
options distro.ImageOptions,
|
|
repos []rpmmd.RepoConfig,
|
|
packageSpecs,
|
|
buildPackageSpecs []rpmmd.PackageSpec,
|
|
seed int64) (distro.Manifest, error) {
|
|
|
|
return json.Marshal(
|
|
osbuild.Manifest{
|
|
Sources: osbuild.Sources{},
|
|
Pipeline: osbuild.Pipeline{},
|
|
},
|
|
)
|
|
}
|
|
|
|
func New() *FedoraTestDistro {
|
|
return &FedoraTestDistro{}
|
|
}
|
|
|
|
func (d *FedoraTestDistro) Name() string {
|
|
return name
|
|
}
|
|
|
|
func (d *FedoraTestDistro) ModulePlatformID() string {
|
|
return modulePlatformID
|
|
}
|