Skip to content

Commit 21a39d1

Browse files
committed
bib: add support for file/directory customizations
This commit adds support for files/directories in blueprint customizations. This needs osbuild/images#1227 Closes: #834
1 parent 55c9cc8 commit 21a39d1

File tree

4 files changed

+119
-16
lines changed

4 files changed

+119
-16
lines changed

bib/cmd/bootc-image-builder/image.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/osbuild/images/pkg/osbuild"
2323
"github.com/osbuild/images/pkg/pathpolicy"
2424
"github.com/osbuild/images/pkg/platform"
25+
"github.com/osbuild/images/pkg/policies"
2526
"github.com/osbuild/images/pkg/rpmmd"
2627
"github.com/osbuild/images/pkg/runner"
2728
"github.com/sirupsen/logrus"
@@ -380,6 +381,27 @@ func manifestForDiskImage(c *ManifestConfig, rng *rand.Rand) (*manifest.Manifest
380381
}
381382
img.PartitionTable = pt
382383

384+
// Check Directory/File Customizations are valid
385+
dc := customizations.GetDirectories()
386+
fc := customizations.GetFiles()
387+
if err := blueprint.ValidateDirFileCustomizations(dc, fc); err != nil {
388+
return nil, err
389+
}
390+
if err := blueprint.CheckDirectoryCustomizationsPolicy(dc, policies.OstreeCustomDirectoriesPolicies); err != nil {
391+
return nil, err
392+
}
393+
if err := blueprint.CheckFileCustomizationsPolicy(fc, policies.OstreeCustomFilesPolicies); err != nil {
394+
return nil, err
395+
}
396+
img.Files, err = blueprint.FileCustomizationsToFsNodeFiles(fc)
397+
if err != nil {
398+
return nil, err
399+
}
400+
img.Directories, err = blueprint.DirectoryCustomizationsToFsNodeDirectories(dc)
401+
if err != nil {
402+
return nil, err
403+
}
404+
383405
// For the bootc-disk image, the filename is the basename and the extension
384406
// is added automatically for each disk format
385407
img.Filename = "disk"

bib/cmd/bootc-image-builder/image_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/osbuild/images/pkg/runner"
1616

1717
bib "github.com/osbuild/bootc-image-builder/bib/cmd/bootc-image-builder"
18+
"github.com/osbuild/bootc-image-builder/bib/internal/buildconfig"
1819
"github.com/osbuild/bootc-image-builder/bib/internal/source"
1920
)
2021

@@ -680,3 +681,38 @@ func TestGenPartitionTableDiskCustomizationSizes(t *testing.T) {
680681
})
681682
}
682683
}
684+
685+
func TestManifestFilecustomizationsSad(t *testing.T) {
686+
config := getBaseConfig()
687+
config.ImageTypes = []string{"qcow2"}
688+
config.Config = &buildconfig.BuildConfig{
689+
Customizations: &blueprint.Customizations{
690+
Files: []blueprint.FileCustomization{
691+
{
692+
Path: "/not/allowed",
693+
Data: "some-data",
694+
},
695+
},
696+
},
697+
}
698+
699+
_, err := bib.Manifest(config)
700+
assert.EqualError(t, err, `the following custom files are not allowed: ["/not/allowed"]`)
701+
}
702+
703+
func TestManifestDirCustomizationsSad(t *testing.T) {
704+
config := getBaseConfig()
705+
config.ImageTypes = []string{"qcow2"}
706+
config.Config = &buildconfig.BuildConfig{
707+
Customizations: &blueprint.Customizations{
708+
Directories: []blueprint.DirectoryCustomization{
709+
{
710+
Path: "/dir/not/allowed",
711+
},
712+
},
713+
},
714+
}
715+
716+
_, err := bib.Manifest(config)
717+
assert.EqualError(t, err, `the following custom directories are not allowed: ["/dir/not/allowed"]`)
718+
}

bib/cmd/bootc-image-builder/main_test.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,23 @@ func TestManifestGenerationUserConfig(t *testing.T) {
196196
}
197197
}
198198

199+
// Disk images require a container for the build/image pipelines
200+
var containerSpec = container.Spec{
201+
Source: "test-container",
202+
Digest: "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
203+
ImageID: "sha256:1111111111111111111111111111111111111111111111111111111111111111",
204+
}
205+
206+
// diskContainers can be passed to Serialize() to get a minimal disk image
207+
var diskContainers = map[string][]container.Spec{
208+
"build": {
209+
containerSpec,
210+
},
211+
"image": {
212+
containerSpec,
213+
},
214+
}
215+
199216
// TODO: this tests at this layer is not ideal, it has too much knowledge
200217
// over the implementation details of the "images" library and how an
201218
// image.NewBootcDiskImage() works (i.e. what the pipeline names are and
@@ -208,23 +225,8 @@ func TestManifestSerialization(t *testing.T) {
208225
// Tests that the manifest is generated without error and is serialized
209226
// with expected key stages.
210227

211-
// Disk images require a container for the build/image pipelines
212-
containerSpec := container.Spec{
213-
Source: "test-container",
214-
Digest: "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
215-
ImageID: "sha256:1111111111111111111111111111111111111111111111111111111111111111",
216-
}
217-
diskContainers := map[string][]container.Spec{
218-
"build": {
219-
containerSpec,
220-
},
221-
"image": {
222-
containerSpec,
223-
},
224-
}
225-
226228
// ISOs require a container for the bootiso-tree, build packages, and packages for the anaconda-tree (with a kernel).
227-
isoContainers := map[string][]container.Spec{
229+
var isoContainers = map[string][]container.Spec{
228230
"bootiso-tree": {
229231
containerSpec,
230232
},

test/test_manifest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,46 @@ def test_iso_manifest_use_librepo(build_container, use_librepo):
779779
assert "org.osbuild.librepo" in manifest["sources"]
780780
else:
781781
assert "org.osbuild.curl" in manifest["sources"]
782+
783+
784+
def test_manifest_customization_custom_file_smoke(tmp_path, build_container):
785+
# no need to parameterize this test, toml is the same for all containers
786+
container_ref = "quay.io/centos-bootc/centos-bootc:stream9"
787+
testutil.pull_container(container_ref)
788+
789+
cfg = {
790+
"blueprint": {
791+
"customizations": {
792+
"files": [
793+
{
794+
"path": "/etc/custom_file",
795+
"data": "hello world"
796+
},
797+
],
798+
"directories": [
799+
{
800+
"path": "/etc/custom_dir",
801+
},
802+
],
803+
},
804+
},
805+
}
806+
807+
output_path = tmp_path / "output"
808+
output_path.mkdir(exist_ok=True)
809+
config_json_path = output_path / "config.json"
810+
config_json_path.write_text(json.dumps(cfg), encoding="utf-8")
811+
812+
output = subprocess.check_output([
813+
*testutil.podman_run_common,
814+
"-v", f"{output_path}:/output",
815+
build_container,
816+
"manifest", f"{container_ref}",
817+
"--config", "/output/config.json",
818+
], stderr=subprocess.PIPE, encoding="utf8")
819+
json.loads(output)
820+
assert '"to":"tree:///etc/custom_file"' in output
821+
assert ('{"type":"org.osbuild.mkdir","options":{"paths":'
822+
'[{"path":"/etc/custom_dir","exist_ok":true}]},'
823+
'"devices":{"disk":{"type":"org.osbuild.loopback"'
824+
',"options":{"filename":"disk.raw"') in output

0 commit comments

Comments
 (0)