1
0
mirror of https://github.com/containers/buildah.git synced 2026-02-05 09:45:38 +01:00

Merge pull request #6521 from lsm5/raw-iidfile

build: add --iidfile-raw CLI option
This commit is contained in:
Miloslav Trmač
2026-01-12 17:45:10 +01:00
committed by GitHub
7 changed files with 103 additions and 6 deletions

View File

@@ -262,6 +262,8 @@ type BuildOptions struct {
DefaultMountsFilePath string
// IIDFile tells the builder to write the image ID to the specified file
IIDFile string
// IIDFileRaw tells the builder to write the image ID to the specified file without the algorithm prefix
IIDFileRaw string
// Squash tells the builder to produce an image with a single layer instead of with
// possibly more than one layer, by only committing a new layer after processing the
// final instruction.

View File

@@ -515,6 +515,14 @@ Path to an alternative .containerignore (.dockerignore) file.
Write the built image's ID to the file. When `--platform` is specified more
than once, attempting to use this option will trigger an error.
**--iidfile-raw** *ImageIDfile*
Write the built image's ID to the file without the algorithm prefix
(e.g., `sha256:`). When `--platform` is specified more than once, attempting to
use this option will trigger an error.
An alias `--raw-iidfile` is also available.
**--inherit-annotations** *bool-value*
Inherit the annotations from the base image or base stages. (default true).

View File

@@ -83,11 +83,16 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
if len(paths) == 0 {
return "", nil, errors.New("building: no dockerfiles specified")
}
if len(options.Platforms) > 1 && options.IIDFile != "" {
return "", nil, fmt.Errorf("building multiple images, but iidfile %q can only be used to store one image ID", options.IIDFile)
}
if len(options.Platforms) > 1 && options.MetadataFile != "" {
return "", nil, fmt.Errorf("building multiple images, but metadata file %q can only be used to store information about one image", options.MetadataFile)
if len(options.Platforms) > 1 {
if options.IIDFile != "" {
return "", nil, fmt.Errorf("building multiple images, but iidfile %q can only be used to store one image ID", options.IIDFile)
}
if options.IIDFileRaw != "" {
return "", nil, fmt.Errorf("building multiple images, but iidfile-raw %q can only be used to store one image ID", options.IIDFileRaw)
}
if options.MetadataFile != "" {
return "", nil, fmt.Errorf("building multiple images, but metadata file %q can only be used to store information about one image", options.MetadataFile)
}
}
logger := logrus.New()

View File

@@ -106,6 +106,7 @@ type executor struct {
commonBuildOptions *define.CommonBuildOptions
defaultMountsFilePath string
iidfile string
iidfileRaw string
squash bool
labels []string
layerLabels []string
@@ -293,6 +294,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
commonBuildOptions: options.CommonBuildOpts,
defaultMountsFilePath: options.DefaultMountsFilePath,
iidfile: options.IIDFile,
iidfileRaw: options.IIDFileRaw,
squash: options.Squash,
labels: slices.Clone(options.Labels),
layerLabels: slices.Clone(options.LayerLabels),
@@ -1107,7 +1109,13 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
if err = os.WriteFile(b.iidfile, []byte(iid), 0o644); err != nil {
return imageID, ref, fmt.Errorf("failed to write image ID to file %q: %w", b.iidfile, err)
}
} else {
}
if b.iidfileRaw != "" {
if err = os.WriteFile(b.iidfileRaw, []byte(imageID), 0o644); err != nil {
return imageID, ref, fmt.Errorf("failed to write image ID to file %q: %w", b.iidfileRaw, err)
}
}
if b.iidfile == "" && b.iidfileRaw == "" {
if _, err := stdout.Write([]byte(imageID + "\n")); err != nil {
return imageID, ref, fmt.Errorf("failed to write image ID to stdout: %w", err)
}

View File

@@ -408,6 +408,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
GroupAdd: iopts.GroupAdd,
IDMappingOptions: idmappingOptions,
IIDFile: iopts.Iidfile,
IIDFileRaw: iopts.IidfileRaw,
IgnoreFile: iopts.IgnoreFile,
In: stdin,
InheritLabels: inheritLabels,

View File

@@ -73,6 +73,7 @@ type BudResults struct {
Format string
From string
Iidfile string
IidfileRaw string
InheritLabels bool
InheritAnnotations bool
Label []string
@@ -253,6 +254,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.StringSliceVarP(&flags.File, "file", "f", []string{}, "`pathname or URL` of a Dockerfile")
fs.StringVar(&flags.Format, "format", DefaultFormat(), "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.")
fs.StringVar(&flags.Iidfile, "iidfile", "", "`file` to write the image ID to")
fs.StringVar(&flags.IidfileRaw, "iidfile-raw", "", "`file` to write the image ID to (without algorithm prefix)")
fs.IntVar(&flags.Jobs, "jobs", 1, "how many stages to run in parallel")
fs.StringArrayVar(&flags.Label, "label", []string{}, "set metadata for an image (default [])")
fs.StringArrayVar(&flags.LayerLabel, "layer-label", []string{}, "set metadata for an intermediate image (default [])")
@@ -357,6 +359,7 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
flagCompletion["hooks-dir"] = commonComp.AutocompleteNone
flagCompletion["ignorefile"] = commonComp.AutocompleteDefault
flagCompletion["iidfile"] = commonComp.AutocompleteDefault
flagCompletion["iidfile-raw"] = commonComp.AutocompleteDefault
flagCompletion["jobs"] = commonComp.AutocompleteNone
flagCompletion["label"] = commonComp.AutocompleteNone
flagCompletion["layer-label"] = commonComp.AutocompleteNone
@@ -545,6 +548,8 @@ func AliasFlags(_ *pflag.FlagSet, name string) pflag.NormalizedName {
name = "os"
case "purge":
name = "rm"
case "raw-iidfile":
name = "iidfile-raw"
case "tty":
name = "terminal"
}

View File

@@ -9018,6 +9018,74 @@ EOF
done
}
@test "bud with --iidfile-raw" {
target=scratch-image
local contextdir=${TEST_SCRATCH_DIR}/context
mkdir -p "${contextdir}"
cat > "${contextdir}"/Dockerfile <<-EOF
FROM scratch
COPY . .
EOF
for layers in "--layers=true" "--layers=false" ; do
for destination in "dir:${TEST_SCRATCH_DIR}/dir" "oci-archive:${TEST_SCRATCH_DIR}/oci-archive" "docker-archive:${TEST_SCRATCH_DIR}/docker-archive" "oci:${TEST_SCRATCH_DIR}/oci-layout" "local" ; do
rm -f "${TEST_SCRATCH_DIR}"/iidfile-raw
fsname="${destination#*:}" # assume : is used in a non-containers-storage name rather than a repository name + tag combination
if test "${fsname}" != "${destination}" ; then
rm -fr "${fsname}"
fi
run_buildah build --iidfile-raw "${TEST_SCRATCH_DIR}"/iidfile-raw --no-cache "${layers}" -t "${destination}" "${contextdir}"
local iid_raw=$(cat "${TEST_SCRATCH_DIR}"/iidfile-raw)
# iidfile-raw should contain just the hash without sha256: prefix
assert "${iid_raw}" != ""
assert "${iid_raw}" =~ "^[0-9a-f]{64}$"
# Verify it doesn't contain sha256: prefix
assert "${iid_raw}" !~ "sha256:"
if test "${fsname}" != "${destination}" ; then
test -e "${fsname}"
fi
done
done
}
@test "bud with --iidfile and --iidfile-raw comparison" {
target=scratch-image
local contextdir=${TEST_SCRATCH_DIR}/context
mkdir -p "${contextdir}"
cat > "${contextdir}"/Dockerfile <<-EOF
FROM scratch
COPY . .
EOF
# Build with both --iidfile and --iidfile-raw to verify they write the same image ID
run_buildah build --iidfile "${TEST_SCRATCH_DIR}"/iidfile --iidfile-raw "${TEST_SCRATCH_DIR}"/iidfile-raw -t "${target}" "${contextdir}"
local iid=$(cat "${TEST_SCRATCH_DIR}"/iidfile)
local iid_raw=$(cat "${TEST_SCRATCH_DIR}"/iidfile-raw)
# iid should have sha256: prefix, iid_raw should not
assert "${iid}" =~ "^sha256:[0-9a-f]{64}$"
assert "${iid_raw}" =~ "^[0-9a-f]{64}$"
# The hash portion should be identical
assert "${iid#sha256:}" == "${iid_raw}"
}
@test "bud with --raw-iidfile alias" {
target=scratch-image
local contextdir=${TEST_SCRATCH_DIR}/context
mkdir -p "${contextdir}"
cat > "${contextdir}"/Dockerfile <<-EOF
FROM scratch
COPY . .
EOF
# Test that --raw-iidfile works as an alias for --iidfile-raw
run_buildah build --raw-iidfile "${TEST_SCRATCH_DIR}"/iidfile-alias -t "${target}" "${contextdir}"
local iid_alias=$(cat "${TEST_SCRATCH_DIR}"/iidfile-alias)
# Should contain just the hash without sha256: prefix
assert "${iid_alias}" != ""
assert "${iid_alias}" =~ "^[0-9a-f]{64}$"
assert "${iid_alias}" !~ "sha256:"
}
@test "build-oci-archive-switch" {
local base=busybox
_prefetch $base