Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Cleanup transient mount destinations with every RUN step #3525

Merged
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
22 changes: 22 additions & 0 deletions run_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,11 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
return nil, err
}

// prepare list of mount destinations which can be cleaned up safely.
// we can clean bindFiles, subscriptionMounts and specMounts
// everything other than these might have users content
mountArtifacts.RunMountTargets = append(append(append(mountArtifacts.RunMountTargets, cleanableDestinationListFromMounts(bindFileMounts)...), cleanableDestinationListFromMounts(subscriptionMounts)...), cleanableDestinationListFromMounts(specMounts)...)

allMounts := util.SortMounts(append(append(append(append(append(append(volumes, builtins...), runMounts...), subscriptionMounts...), bindFileMounts...), specMounts...), sysfsMount...))
// Add them all, in the preferred order, except where they conflict with something that was previously added.
for _, mount := range allMounts {
Expand All @@ -561,6 +566,23 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
return mountArtifacts, nil
}

// Destinations which can be cleaned up after every RUN
func cleanableDestinationListFromMounts(mounts []spec.Mount) []string {
mountDest := []string{}
for _, mount := range mounts {
// Add all destination to mountArtifacts so that they can be cleaned up later
if mount.Destination != "" {
// we dont want to remove destinations with /etc, /dev, /sys, /proc as rootfs already contains these files
// and unionfs will create a `whiteout` i.e `.wh` files on removal of overlapping files from these directories.
// everything other than these will be cleanedup
if !strings.HasPrefix(mount.Destination, "/etc") && !strings.HasPrefix(mount.Destination, "/dev") && !strings.HasPrefix(mount.Destination, "/sys") && !strings.HasPrefix(mount.Destination, "/proc") {
mountDest = append(mountDest, mount.Destination)
}
}
}
return mountDest
}

// addResolvConf copies files from host and sets them up to bind mount into container
func (b *Builder) addResolvConf(rdir string, chownOpts *idtools.IDPair, dnsServers, dnsSearch, dnsOptions []string, namespaceOptions define.NamespaceOptions) (string, error) {
resolvConf := "/etc/resolv.conf"
Expand Down
52 changes: 52 additions & 0 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -3446,3 +3446,55 @@ _EOF

run_buildah rmi -f ${target}
}

@test "bud with run should not leave mounts behind cleanup test" {
skip_if_in_container
run which podman
if [[ $status -ne 0 ]]; then
skip "podman is not installed"
fi

# Create target dir where we will export tar
target=cleanable
flouthoc marked this conversation as resolved.
Show resolved Hide resolved
mkdir ${TESTDIR}/${target}

# Build and export container to tar
run_buildah build --no-cache --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/bud/containerfile/Containerfile.in ${TESTSDIR}/bud/containerfile
podman export $(podman create --name ${target} ${target}) --output=${TESTDIR}/${target}.tar

# We are done exporting so remove images and containers which are not needed
podman rm -f ${target}
run_buildah rmi ${target}

# Explode tar
tar -xf ${TESTDIR}/${target}.tar -C ${TESTDIR}/${target}
count=$(ls -A ${TESTDIR}/${target}/run | wc -l)
## exported /run should be empty
assert "$count" == "0"
}

@test "bud with custom files in /run/ should persist cleanup test" {
skip_if_in_container
run which podman
if [[ $status -ne 0 ]]; then
skip "podman is not installed"
fi

# Create target dir where we will export tar
target=cleanable
mkdir ${TESTDIR}/${target}

# Build and export container to tar
run_buildah build --no-cache --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/bud/add-run-dir
podman export $(podman create --name ${target} ${target}) --output=${TESTDIR}/${target}.tar

# We are done exporting so remove images and containers which are not needed
podman rm -f ${target}
run_buildah rmi ${target}

# Explode tar
tar -xf ${TESTDIR}/${target}.tar -C ${TESTDIR}/${target}
count=$(ls -A ${TESTDIR}/${target}/run | wc -l)
## exported /run should not be empty
assert "$count" == "1"
}
2 changes: 2 additions & 0 deletions tests/bud/add-run-dir/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM alpine
RUN touch /run/hello