From 56b58ecef28e7303088dfdf3dc4ec6aef3b69478 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 16 Feb 2024 15:36:29 +0100 Subject: [PATCH] osbuild: add missing inputs to boots.install-to-filesystem Add the missing inputs to boots.install-to-filesystem - they are required because boots needs to know what container to deploy. --- .../bootc_install_to_filesystem_stage.go | 11 +++- .../bootc_install_to_filesystem_stage_test.go | 53 +++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/pkg/osbuild/bootc_install_to_filesystem_stage.go b/pkg/osbuild/bootc_install_to_filesystem_stage.go index 7e369079cd..26402a2bd5 100644 --- a/pkg/osbuild/bootc_install_to_filesystem_stage.go +++ b/pkg/osbuild/bootc_install_to_filesystem_stage.go @@ -1,5 +1,9 @@ package osbuild +import ( + "fmt" +) + // NewBootcInstallToFilesystem creates a new stage for the // org.osbuild.bootc.install-to-filesystem stage. // @@ -8,13 +12,18 @@ package osbuild // bootc/bootupd find and install all required bootloader bits. // // The mounts input should be generated with GenBootupdDevicesMounts. -func NewBootcInstallToFilesystemStage(devices map[string]Device, mounts []Mount) (*Stage, error) { +func NewBootcInstallToFilesystemStage(inputs ContainersInput, devices map[string]Device, mounts []Mount) (*Stage, error) { if err := validateBootupdMounts(mounts); err != nil { return nil, err } + if len(inputs.References) != 1 { + return nil, fmt.Errorf("expected exactly one container input but got: %v (%v)", len(inputs.References), inputs.References) + } + return &Stage{ Type: "org.osbuild.bootc.install-to-filesystem", + Inputs: inputs, Devices: devices, Mounts: mounts, }, nil diff --git a/pkg/osbuild/bootc_install_to_filesystem_stage_test.go b/pkg/osbuild/bootc_install_to_filesystem_stage_test.go index 4a8a08c130..cbac772583 100644 --- a/pkg/osbuild/bootc_install_to_filesystem_stage_test.go +++ b/pkg/osbuild/bootc_install_to_filesystem_stage_test.go @@ -7,28 +7,65 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/osbuild/images/pkg/container" "github.com/osbuild/images/pkg/osbuild" ) +func makeFakeContainerInputs() osbuild.ContainersInput { + return osbuild.NewContainersInputForSources([]container.Spec{ + { + ImageID: "id-0", + Source: "registry.example.org/reg/img", + LocalName: "local-name", + }, + }) +} + func TestBootcInstallToFilesystemStageNewHappy(t *testing.T) { devices := makeOsbuildDevices("dev-for-/", "dev-for-/boot", "dev-for-/boot/efi") mounts := makeOsbuildMounts("/", "/boot", "/boot/efi") + inputs := makeFakeContainerInputs() expectedStage := &osbuild.Stage{ Type: "org.osbuild.bootc.install-to-filesystem", + Inputs: inputs, Devices: devices, Mounts: mounts, } - stage, err := osbuild.NewBootcInstallToFilesystemStage(devices, mounts) + stage, err := osbuild.NewBootcInstallToFilesystemStage(inputs, devices, mounts) require.Nil(t, err) assert.Equal(t, stage, expectedStage) } +func TestBootcInstallToFilesystemStageNewNoContainers(t *testing.T) { + devices := makeOsbuildDevices("dev-for-/", "dev-for-/boot", "dev-for-/boot/efi") + mounts := makeOsbuildMounts("/", "/boot", "/boot/efi") + inputs := osbuild.ContainersInput{} + + _, err := osbuild.NewBootcInstallToFilesystemStage(inputs, devices, mounts) + assert.EqualError(t, err, "expected exactly one container input but got: 0 (map[])") +} + +func TestBootcInstallToFilesystemStageNewTwoContainers(t *testing.T) { + devices := makeOsbuildDevices("dev-for-/", "dev-for-/boot", "dev-for-/boot/efi") + mounts := makeOsbuildMounts("/", "/boot", "/boot/efi") + inputs := osbuild.ContainersInput{ + References: map[string]osbuild.ContainersInputSourceRef{ + "1": {}, + "2": {}, + }, + } + + _, err := osbuild.NewBootcInstallToFilesystemStage(inputs, devices, mounts) + assert.EqualError(t, err, "expected exactly one container input but got: 2 (map[1:{} 2:{}])") +} + func TestBootcInstallToFilesystemStageMissingMounts(t *testing.T) { devices := makeOsbuildDevices("dev-for-/") mounts := makeOsbuildMounts("/") + inputs := makeFakeContainerInputs() - stage, err := osbuild.NewBootcInstallToFilesystemStage(devices, mounts) + stage, err := osbuild.NewBootcInstallToFilesystemStage(inputs, devices, mounts) // XXX: rename error assert.ErrorContains(t, err, "required mounts for bootupd stage [/boot /boot/efi] missing") require.Nil(t, stage) @@ -37,13 +74,23 @@ func TestBootcInstallToFilesystemStageMissingMounts(t *testing.T) { func TestBootcInstallToFilesystemStageJsonHappy(t *testing.T) { devices := makeOsbuildDevices("disk", "dev-for-/", "dev-for-/boot", "dev-for-/boot/efi") mounts := makeOsbuildMounts("/", "/boot", "/boot/efi") + inputs := makeFakeContainerInputs() - stage, err := osbuild.NewBootcInstallToFilesystemStage(devices, mounts) + stage, err := osbuild.NewBootcInstallToFilesystemStage(inputs, devices, mounts) require.Nil(t, err) stageJson, err := json.MarshalIndent(stage, "", " ") require.Nil(t, err) assert.Equal(t, string(stageJson), `{ "type": "org.osbuild.bootc.install-to-filesystem", + "inputs": { + "type": "org.osbuild.containers", + "origin": "org.osbuild.source", + "references": { + "id-0": { + "name": "local-name" + } + } + }, "devices": { "dev-for-/": { "type": "org.osbuild.loopback"