Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/image-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
if err != nil {
return nil, err
}
withRPMList, err := cmd.Flags().GetBool("with-rpmlist")
if err != nil {
return nil, err
}
ignoreWarnings, err := cmd.Flags().GetBool("ignore-warnings")
if err != nil {
return nil, err
Expand Down Expand Up @@ -351,6 +355,7 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
BootcInstallerPayloadRef: bootcInstallerPayloadRef,
BootcOmitDefaultKernelArgs: bootcOmitDefaultKernelArgs,
WithSBOM: withSBOM,
WithRPMList: withRPMList,
IgnoreWarnings: ignoreWarnings,
Subscription: subscription,
Preview: preview,
Expand Down Expand Up @@ -627,6 +632,7 @@ operating systems like Fedora, CentOS and RHEL with easy customizations support.
manifestCmd.Flags().Bool("bootc-no-default-kernel-args", false, `don't use the default kernel arguments`)
manifestCmd.Flags().Bool("use-librepo", true, `use librepo to download packages (disable if you use old versions of osbuild)`)
manifestCmd.Flags().Bool("with-sbom", false, `export SPDX SBOM document`)
manifestCmd.Flags().Bool("with-rpmlist", false, `export RPM list as JSON`)
manifestCmd.Flags().Bool("ignore-warnings", false, `ignore warnings during manifest generation`)
manifestCmd.Flags().String("registrations", "", `filename of a registrations file with e.g. subscription details`)
manifestCmd.Flags().String("rpmmd-cache", "", `osbuild directory to cache rpm metadata`)
Expand Down
13 changes: 11 additions & 2 deletions cmd/image-builder/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ type manifestOptions struct {
Subscription *subscription.ImageOptions
RpmDownloader osbuild.RpmDownloader
WithSBOM bool
WithRPMList bool
IgnoreWarnings bool
Preview *bool

ForceRepos []string
}

func sbomWriter(outputDir, filename string, content io.Reader) error {
func fileWriter(outputDir, filename string, content io.Reader) error {
p := filepath.Join(outputDir, filename)
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
return err
Expand Down Expand Up @@ -69,7 +70,7 @@ func generateManifest(repoDir string, extraRepos []string, img *imagefilter.Resu
outputDir := basenameFor(img, opts.OutputDir)
manifestGenOpts.SBOMWriter = func(filename string, content io.Reader, docType sbom.StandardType) error {
filename = fmt.Sprintf("%s.%s", basenameFor(img, opts.OutputFilename), strings.SplitN(filename, ".", 2)[1])
return sbomWriter(outputDir, filename, content)
return fileWriter(outputDir, filename, content)
}
}
if len(opts.ForceRepos) > 0 {
Expand All @@ -83,6 +84,14 @@ func generateManifest(repoDir string, extraRepos []string, img *imagefilter.Resu
manifestGenOpts.WarningsOutput = os.Stderr
}

if opts.WithRPMList {
outputDir := basenameFor(img, opts.OutputDir)
manifestGenOpts.RPMListWriter = func(filename string, content io.Reader) error {
filename = fmt.Sprintf("%s.%s", basenameFor(img, opts.OutputFilename), filename)
return fileWriter(outputDir, filename, content)
}
}

mg, err := manifestgen.New(repos, manifestGenOpts)
if err != nil {
return err
Expand Down
24 changes: 24 additions & 0 deletions test/test_build.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import os
import pathlib
import platform
Expand Down Expand Up @@ -63,6 +64,29 @@ def test_build_build_generates_manifest(tmp_path, build_container, shared_store)
assert image_manifest_path.exists()


@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
def test_build_generates_rpmlist(tmp_path, build_container, shared_store):
output_dir = tmp_path / "output"
output_dir.mkdir()
subprocess.check_call(podman_run + [
"-v", f"{output_dir}:/output",
"-v", f"{shared_store}:{OSBUILD_STORE_CONTAINER_PATH}",
build_container,
"build",
"qcow2",
"--distro", "centos-9",
"--with-rpmlist",
], stdout=subprocess.DEVNULL)
arch = platform.machine()
fn = f"centos-9-qcow2-{arch}/centos-9-qcow2-{arch}.rpmlist.json"
rpmlist_path = output_dir / fn
assert rpmlist_path.exists()
rpmlist = json.loads(rpmlist_path.read_text())
assert isinstance(rpmlist, list)
names = [p["name"] for p in rpmlist]
assert "glibc" in names, f"missing glibc in {rpmlist_path}"


# pylint: disable=too-many-arguments
@pytest.mark.parametrize("progress,needle,forbidden", [
("verbose", "osbuild-stdout-output", "[|]"),
Expand Down
22 changes: 22 additions & 0 deletions test/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ def test_manifest_generates_sbom(tmp_path, build_container):
assert "glibc" in [s["name"] for s in sbom_json["packages"]], f"missing glibc in {sbom_json}"


@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
def test_manifest_generates_rpmlist(tmp_path, build_container):
output_dir = tmp_path / "output"
output_dir.mkdir()
subprocess.check_call(podman_run + [
"-v", f"{output_dir}:/output",
build_container,
"manifest",
"minimal-raw",
"--distro", "centos-9",
"--with-rpmlist",
], stdout=subprocess.DEVNULL)
arch = platform.machine()
fn = f"centos-9-minimal-raw-{arch}/centos-9-minimal-raw-{arch}.rpmlist.json"
rpmlist_path = output_dir / fn
assert rpmlist_path.exists()
rpmlist = json.loads(rpmlist_path.read_text())
assert isinstance(rpmlist, list)
names = [p["name"] for p in rpmlist]
assert "glibc" in names, f"missing glibc in {rpmlist_path}"


@pytest.mark.parametrize("use_seed_arg", [False, True])
@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
def test_manifest_seeded_is_the_same(build_container, use_seed_arg):
Expand Down
Loading