Skip to content

Commit

Permalink
Add support for COPY --exclude and ADD --exclude options
Browse files Browse the repository at this point in the history
Fixes: #5678

Signed-off-by: Daniel J Walsh <[email protected]>
  • Loading branch information
rhatdan committed Sep 12, 2024
1 parent 18d09f0 commit 8297d91
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 20 deletions.
25 changes: 14 additions & 11 deletions cmd/buildah/addcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,24 @@ import (

type addCopyResults struct {
addHistory bool
authfile string
blobCache string
certDir string
checksum string
chmod string
chown string
checksum string
quiet bool
ignoreFile string
contextdir string
from string
blobCache string
creds string
decryptionKeys []string
excludes []string
from string
ignoreFile string
quiet bool
removeSignatures bool
signaturePolicy string
authfile string
creds string
tlsVerify bool
certDir string
retry int
retryDelay string
signaturePolicy string
tlsVerify bool
}

func createCommand(addCopy string, desc string, short string, opts *addCopyResults) *cobra.Command {
Expand Down Expand Up @@ -78,6 +79,7 @@ func applyFlagVars(flags *pflag.FlagSet, opts *addCopyResults) {
if err := flags.MarkHidden("decryption-key"); err != nil {
panic(fmt.Sprintf("error marking decryption-key as hidden: %v", err))
}
flags.StringSliceVar(&opts.excludes, "exclude", nil, "exclude pattern when copying files")
flags.StringVar(&opts.ignoreFile, "ignorefile", "", "path to .containerignore file")
flags.StringVar(&opts.contextdir, "contextdir", "", "context directory path")
flags.IntVar(&opts.retry, "retry", cli.MaxPullPushRetries, "number of times to retry in case of failure when performing pull")
Expand Down Expand Up @@ -238,6 +240,7 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe
Checksum: iopts.checksum,
ContextDir: contextdir,
IDMappingOptions: idMappingOptions,
Excludes: iopts.excludes,
// These next two fields are set based on command line flags
// with more generic-sounding names.
CertPath: systemContext.DockerCertPath,
Expand All @@ -251,7 +254,7 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe
if err != nil {
return err
}
options.Excludes = excludes
options.Excludes = append(excludes, options.Excludes...)
}
if iopts.retryDelay != "" {
retryDelay, err := time.ParseDuration(iopts.retryDelay)
Expand Down
5 changes: 5 additions & 0 deletions docs/buildah-add.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ Build context directory. Specifying a context directory causes Buildah to
chroot into that context directory. This means copying files pointed at
by symbolic links outside of the chroot will fail.

**--exclude** *pattern*

Exclude coping files mattching the specified pattern. Option can be specified
multiple times.

**--from** *containerOrImage*

Use the root directory of the specified working container or image as the root
Expand Down
7 changes: 7 additions & 0 deletions docs/buildah-copy.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ Build context directory. Specifying a context directory causes Buildah to
chroot into the context directory. This means copying files pointed at
by symbolic links outside of the chroot will fail.

**--exclude** *pattern*

Exclude coping files mattching the specified pattern. Option can be specified
multiple times.

**--from** *containerOrImage*

Use the root directory of the specified working container or image as the root
Expand Down Expand Up @@ -86,6 +91,8 @@ talking to an insecure registry.

buildah copy containerID '/myapp/app.conf' '/myapp/app.conf'

buildah copy --exclude=**/*.md docs containerID 'docs' '/docs'

buildah copy --chown myuser:mygroup containerID '/myapp/app.conf' '/myapp/app.conf'

buildah copy --chmod 660 containerID '/myapp/app.conf' '/myapp/app.conf'
Expand Down
15 changes: 6 additions & 9 deletions imagebuildah/stage_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,7 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err
return errors.New("COPY --parents is not supported")
}
if len(cp.Excludes) > 0 {
if cp.Download {
return errors.New("ADD --excludes is not supported")
}
return errors.New("COPY --excludes is not supported")
excludes = append(excludes, cp.Excludes...)
}
}
s.builder.ContentDigester.Restart()
Expand Down Expand Up @@ -1344,12 +1341,12 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
// Also check the chmod and the chown flags for validity.
for _, flag := range step.Flags {
command := strings.ToUpper(step.Command)
// chmod, chown and from flags should have an '=' sign, '--chmod=', '--chown=' or '--from='
if command == "COPY" && (flag == "--chmod" || flag == "--chown" || flag == "--from") {
return "", nil, false, fmt.Errorf("COPY only supports the --chmod=<permissions> --chown=<uid:gid> and the --from=<image|stage> flags")
// chmod, chown and from flags should have an '=' sign, '--chmod=', '--chown=' or '--from=' or '--exclude='
if command == "COPY" && (flag == "--chmod" || flag == "--chown" || flag == "--from" || flag == "--exclude") {
return "", nil, false, fmt.Errorf("COPY only supports the --chmod=<permissions> --chown=<uid:gid> and the --from=<image|stage> --exclude=<pattern> flags")
}
if command == "ADD" && (flag == "--chmod" || flag == "--chown" || flag == "--checksum") {
return "", nil, false, fmt.Errorf("ADD only supports the --chmod=<permissions>, --chown=<uid:gid>, and --checksum=<checksum> flags")
if command == "ADD" && (flag == "--chmod" || flag == "--chown" || flag == "--checksum" || flag == "--exclude") {
return "", nil, false, fmt.Errorf("ADD only supports the --chmod=<permissions>, --chown=<uid:gid>, and --checksum=<checksum> --exclude=<pattern> flags")
}
if strings.Contains(flag, "--from") && command == "COPY" {
arr := strings.Split(flag, "=")
Expand Down
8 changes: 8 additions & 0 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -5907,6 +5907,14 @@ _EOF
expect_output --substring 'building.*"COPY \*foo /testdir".*no such file or directory'
}

@test "bud with copy --exclude" {
run_buildah build -t test $WITH_POLICY_JSON $BUDFILES/copy-exclude
assert "$output" !~ "test1.txt"

run_buildah build -t test2 -f Containerfile.missing $WITH_POLICY_JSON $BUDFILES/copy-exclude
assert "$output" !~ "test2.txt"
}

@test "bud with containerfile secret" {
_prefetch alpine
mytmpdir=${TEST_SCRATCH_DIR}/my-dir1
Expand Down
1 change: 1 addition & 0 deletions tests/bud/copy-exclude/.#Containerfile.bad
3 changes: 3 additions & 0 deletions tests/bud/copy-exclude/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM alpine
COPY --exclude=*txt . /testdir
run ls /testdir
3 changes: 3 additions & 0 deletions tests/bud/copy-exclude/Containerfile.missing
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM alpine
COPY --exclude=*foo --exclude=test*.txt . /testdir
run ls /testdir
Empty file.
Empty file.
25 changes: 25 additions & 0 deletions tests/copy.bats
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,31 @@ stuff/mystuff"
expect_output --from="$filelist" "$expect" "container file list"
}

@test "copy --exclude" {
mytest=${TEST_SCRATCH_DIR}/mytest
mkdir -p ${mytest}
touch ${mytest}/mystuff
touch ${mytest}/source.go
mkdir -p ${mytest}/notmystuff
touch ${mytest}/notmystuff/notmystuff

expect="
stuff
stuff/mystuff"

run_buildah from $WITH_POLICY_JSON scratch
cid=$output

run_buildah copy --exclude=**/*.go --exclude=.ignore --exclude=**/notmystuff $cid ${mytest} /stuff

run_buildah mount $cid
mnt=$output
run find $mnt -printf "%P\n"
filelist=$(LC_ALL=C sort <<<"$output")
run_buildah umount $cid
expect_output --from="$filelist" "$expect" "container file list"
}

@test "copy-quiet" {
createrandom ${TEST_SCRATCH_DIR}/randomfile
_prefetch alpine
Expand Down

0 comments on commit 8297d91

Please sign in to comment.