Skip to content

Commit

Permalink
manifest,image: add Files,Directories to bootc customizations
Browse files Browse the repository at this point in the history
This commit adds support for Files,Directories to the bp
customizations fo BootcDiskImage and RawBootcImage.
  • Loading branch information
mvo5 committed Feb 18, 2025
1 parent 201158b commit 51a9fe1
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
7 changes: 7 additions & 0 deletions pkg/image/bootc_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/rand"

"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/manifest"
Expand All @@ -31,6 +32,10 @@ type BootcDiskImage struct {
Users []users.User
Groups []users.Group

// Custom directories and files to create in the image
Directories []*fsnode.Directory
Files []*fsnode.File

// SELinux policy, when set it enables the labeling of the tree with the
// selected profile
SELinux string
Expand Down Expand Up @@ -59,6 +64,8 @@ func (img *BootcDiskImage) InstantiateManifestFromContainers(m *manifest.Manifes
rawImage.PartitionTable = img.PartitionTable
rawImage.Users = img.Users
rawImage.Groups = img.Groups
rawImage.Files = img.Files
rawImage.Directories = img.Directories
rawImage.KernelOptionsAppend = img.KernelOptionsAppend
rawImage.SELinux = img.SELinux

Expand Down
45 changes: 45 additions & 0 deletions pkg/image/bootc_disk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/osbuild/images/internal/testdisk"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/image"
"github.com/osbuild/images/pkg/manifest"
Expand Down Expand Up @@ -42,6 +43,8 @@ type bootcDiskImageTestOpts struct {
SELinux string
Users []users.User
Groups []users.Group
Directories []*fsnode.Directory
Files []*fsnode.File

KernelOptionsAppend []string
}
Expand Down Expand Up @@ -77,6 +80,8 @@ func makeBootcDiskImageOsbuildManifest(t *testing.T, opts *bootcDiskImageTestOpt
img.Users = opts.Users
img.Groups = opts.Groups
img.SELinux = opts.SELinux
img.Files = opts.Files
img.Directories = opts.Directories

m := &manifest.Manifest{}
runi := &runner.Fedora{}
Expand Down Expand Up @@ -263,3 +268,43 @@ func TestBootcDiskImageInstantiateGroups(t *testing.T) {
}
}
}

func TestBootcDiskImageInstantiateFiles(t *testing.T) {
for _, withFiles := range []bool{true, false} {
opts := &bootcDiskImageTestOpts{}
if withFiles {
file1, err := fsnode.NewFile("/some/file", nil, nil, nil, []byte("data"))
require.NoError(t, err)
opts.Files = []*fsnode.File{file1}
}
osbuildManifest := makeBootcDiskImageOsbuildManifest(t, opts)
imagePipeline := findPipelineFromOsbuildManifest(t, osbuildManifest, "image")
require.NotNil(t, imagePipeline)
copyStage := findStageFromOsbuildPipeline(t, imagePipeline, "org.osbuild.copy")
if withFiles {
require.NotNil(t, copyStage)
} else {
require.Nil(t, copyStage)
}
}
}

func TestBootcDiskImageInstantiateDirs(t *testing.T) {
for _, withDirs := range []bool{true, false} {
opts := &bootcDiskImageTestOpts{}
if withDirs {
dir1, err := fsnode.NewDirectory("/some/dir", nil, nil, nil, true)
require.NoError(t, err)
opts.Directories = []*fsnode.Directory{dir1}
}
osbuildManifest := makeBootcDiskImageOsbuildManifest(t, opts)
imagePipeline := findPipelineFromOsbuildManifest(t, osbuildManifest, "image")
require.NotNil(t, imagePipeline)
mkdirStage := findStageFromOsbuildPipeline(t, imagePipeline, "org.osbuild.mkdir")
if withDirs {
require.NotNil(t, mkdirStage)
} else {
require.Nil(t, mkdirStage)
}
}
}
16 changes: 16 additions & 0 deletions pkg/manifest/raw_bootc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/artifact"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/osbuild"
Expand Down Expand Up @@ -36,6 +37,10 @@ type RawBootcImage struct {
Users []users.User
Groups []users.Group

// Custom directories and files to create in the image
Directories []*fsnode.Directory
Files []*fsnode.File

// SELinux policy, when set it enables the labeling of the tree with the
// selected profile
SELinux string
Expand Down Expand Up @@ -199,7 +204,18 @@ func (p *RawBootcImage) serialize() osbuild.Pipeline {
usersStage.Mounts = mounts
usersStage.Devices = devices
pipeline.AddStage(usersStage)
}

// First create custom directories, because some of the custom files may depend on them
if len(p.Directories) > 0 {
pipeline.AddStages(osbuild.GenDirectoryNodesStages(p.Directories)...)
}

if len(p.Files) > 0 {
pipeline.AddStages(osbuild.GenFileNodesStages(p.Files)...)
}

if len(p.Users) > 0 || len(p.Files) > 0 || len(p.Directories) > 0 {
// add selinux
if p.SELinux != "" {
opts := &osbuild.SELinuxStageOptions{
Expand Down
58 changes: 58 additions & 0 deletions pkg/manifest/raw_bootc_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manifest_test

import (
"fmt"
"os"
"testing"

Expand All @@ -10,6 +11,7 @@ import (
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/testdisk"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/osbuild"
Expand Down Expand Up @@ -281,3 +283,59 @@ func RawBootcImageSerializeFstabPipelineHasBootcMounts(t *testing.T) {
assert.NotNil(t, stage)
assertBootcDeploymentAndBindMount(t, stage)
}

func TestRawBootcImageSerializeCreateFilesDirs(t *testing.T) {
rawBootcPipeline := makeFakeRawBootcPipeline()

dir1, err := fsnode.NewDirectory("/path/to/dir", nil, nil, nil, false)
require.NoError(t, err)
file1, err := fsnode.NewFile("/path/to/file", nil, nil, nil, []byte("file-content"))
require.NoError(t, err)
for _, tc := range []struct {
dirs []*fsnode.Directory
files []*fsnode.File
}{
{nil, nil},
{[]*fsnode.Directory{dir1}, nil},
{nil, []*fsnode.File{file1}},
{[]*fsnode.Directory{dir1}, []*fsnode.File{file1}},
} {
tcName := fmt.Sprintf("files:%v,dirs:%v", len(tc.files), len(tc.dirs))
t.Run(tcName, func(t *testing.T) {
rawBootcPipeline.SELinux = "/path/to/selinux"
rawBootcPipeline.Directories = tc.dirs
rawBootcPipeline.Files = tc.files

pipeline := rawBootcPipeline.Serialize()

// check dirs
mkdirStage := manifest.FindStage("org.osbuild.mkdir", pipeline.Stages)
if len(tc.dirs) > 0 {
// ensure options got passed
require.NotNil(t, mkdirStage)
mkdirOptions := mkdirStage.Options.(*osbuild.MkdirStageOptions)
assert.Equal(t, "/path/to/dir", mkdirOptions.Paths[0].Path)
} else {
assert.Nil(t, mkdirStage)
}

// check files
copyStage := manifest.FindStage("org.osbuild.copy", pipeline.Stages)
if len(tc.files) > 0 {
// ensure options got passed
require.NotNil(t, copyStage)
copyOptions := copyStage.Options.(*osbuild.CopyStageOptions)
assert.Equal(t, "tree:///path/to/file", copyOptions.Paths[0].To)
} else {
assert.Nil(t, copyStage)
}

selinuxStage := manifest.FindStage("org.osbuild.selinux", pipeline.Stages)
if len(tc.dirs) > 0 || len(tc.files) > 0 {
assert.NotNil(t, selinuxStage)
} else {
assert.Nil(t, selinuxStage)
}
})
}
}

0 comments on commit 51a9fe1

Please sign in to comment.