main: allow seed setting
Allow users to define the seed that's used for manifest generation. Regenerating an image with a given seed leads to the same manifest (provided depsolving does the same). The seed is normally mostly used to generate random filesystem UUIDs. This will need a bunch of documentation in a follow up since the use cases are meant to be advanced but it can really speed up multi-type and rebuilds of the same image. Signed-off-by: Simon de Vlieger <supakeen@redhat.com>
This commit is contained in:
parent
f25b5e325e
commit
02461ac2a3
3 changed files with 46 additions and 0 deletions
|
|
@ -151,6 +151,14 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var customSeed *int64
|
||||||
|
if cmd.Flags().Changed("seed") {
|
||||||
|
seedFlagVal, err := cmd.Flags().GetInt64("seed")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
customSeed = &seedFlagVal
|
||||||
|
}
|
||||||
// no error check here as this is (deliberately) not defined on
|
// no error check here as this is (deliberately) not defined on
|
||||||
// "manifest" (if "images" learn to set the output filename in
|
// "manifest" (if "images" learn to set the output filename in
|
||||||
// manifests we would change this
|
// manifests we would change this
|
||||||
|
|
@ -189,6 +197,7 @@ func cmdManifestWrapper(pbar progress.ProgressBar, cmd *cobra.Command, args []st
|
||||||
Ostree: ostreeImgOpts,
|
Ostree: ostreeImgOpts,
|
||||||
RpmDownloader: rpmDownloader,
|
RpmDownloader: rpmDownloader,
|
||||||
WithSBOM: withSBOM,
|
WithSBOM: withSBOM,
|
||||||
|
CustomSeed: customSeed,
|
||||||
|
|
||||||
ForceRepos: forceRepos,
|
ForceRepos: forceRepos,
|
||||||
}
|
}
|
||||||
|
|
@ -398,6 +407,7 @@ operating systems like Fedora, CentOS and RHEL with easy customizations support.
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
}
|
}
|
||||||
manifestCmd.Flags().String("blueprint", "", `filename of a blueprint to customize an image`)
|
manifestCmd.Flags().String("blueprint", "", `filename of a blueprint to customize an image`)
|
||||||
|
manifestCmd.Flags().Int64("seed", 0, `rng seed, some values are derived randomly, pinning the seed allows more reproducibility if you need it. must be an integer. only used when changed.`)
|
||||||
manifestCmd.Flags().String("arch", "", `build manifest for a different architecture`)
|
manifestCmd.Flags().String("arch", "", `build manifest for a different architecture`)
|
||||||
manifestCmd.Flags().String("distro", "", `build manifest for a different distroname (e.g. centos-9)`)
|
manifestCmd.Flags().String("distro", "", `build manifest for a different distroname (e.g. centos-9)`)
|
||||||
manifestCmd.Flags().String("ostree-ref", "", `OSTREE reference`)
|
manifestCmd.Flags().String("ostree-ref", "", `OSTREE reference`)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ type manifestOptions struct {
|
||||||
Ostree *ostree.ImageOptions
|
Ostree *ostree.ImageOptions
|
||||||
RpmDownloader osbuild.RpmDownloader
|
RpmDownloader osbuild.RpmDownloader
|
||||||
WithSBOM bool
|
WithSBOM bool
|
||||||
|
CustomSeed *int64
|
||||||
|
|
||||||
ForceRepos []string
|
ForceRepos []string
|
||||||
UseBootstrapContainer bool
|
UseBootstrapContainer bool
|
||||||
|
|
@ -55,6 +56,7 @@ func generateManifest(dataDir string, extraRepos []string, img *imagefilter.Resu
|
||||||
Output: output,
|
Output: output,
|
||||||
RpmDownloader: opts.RpmDownloader,
|
RpmDownloader: opts.RpmDownloader,
|
||||||
UseBootstrapContainer: opts.UseBootstrapContainer,
|
UseBootstrapContainer: opts.UseBootstrapContainer,
|
||||||
|
CustomSeed: opts.CustomSeed,
|
||||||
}
|
}
|
||||||
if opts.WithSBOM {
|
if opts.WithSBOM {
|
||||||
outputDir := basenameFor(img, opts.OutputDir)
|
outputDir := basenameFor(img, opts.OutputDir)
|
||||||
|
|
|
||||||
|
|
@ -122,3 +122,37 @@ def test_container_cross_build(tmp_path, build_container, arch):
|
||||||
f"--arch={arch}",
|
f"--arch={arch}",
|
||||||
], text=True)
|
], text=True)
|
||||||
assert os.path.exists(output_dir / f"fedora-41-container-{arch}.tar")
|
assert os.path.exists(output_dir / f"fedora-41-container-{arch}.tar")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("use_seed_arg", [False, True])
|
||||||
|
@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
|
||||||
|
def test_container_manifest_seeded_is_the_same(build_container, use_seed_arg):
|
||||||
|
manifests = set()
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
"podman", "run",
|
||||||
|
"--privileged",
|
||||||
|
build_container,
|
||||||
|
"manifest",
|
||||||
|
"--distro", "centos-9",
|
||||||
|
"minimal-raw",
|
||||||
|
]
|
||||||
|
|
||||||
|
if use_seed_arg:
|
||||||
|
cmd.extend(["--seed", "0"])
|
||||||
|
|
||||||
|
for _ in range(3):
|
||||||
|
p = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
|
||||||
|
manifests.add(p.stdout)
|
||||||
|
|
||||||
|
# verify all calls with the same seed generated the same manifest
|
||||||
|
if use_seed_arg:
|
||||||
|
assert len(manifests) == 1
|
||||||
|
else:
|
||||||
|
print(cmd)
|
||||||
|
assert len(manifests) == 3
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue