Skip to content

Commit

Permalink
Set volume NeedsCopyUp to false iff data was copied up
Browse files Browse the repository at this point in the history
Currently Docker copies up the first volume on a mountpoint with
data.

Fixes: containers#12714

Also added NeedsCopyUP, NeedsChown and MountCount to the podman volume
inspect code.

Signed-off-by: Daniel J Walsh <[email protected]>
  • Loading branch information
rhatdan committed Jan 6, 2022
1 parent c0b3df8 commit 13f3fd2
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
14 changes: 7 additions & 7 deletions libpod/container_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -1700,13 +1700,6 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
if vol.state.NeedsCopyUp {
logrus.Debugf("Copying up contents from container %s to volume %s", c.ID(), vol.Name())

// Set NeedsCopyUp to false immediately, so we don't try this
// again when there are already files copied.
vol.state.NeedsCopyUp = false
if err := vol.save(); err != nil {
return nil, err
}

// If the volume is not empty, we should not copy up.
volMount := vol.mountPoint()
contents, err := ioutil.ReadDir(volMount)
Expand Down Expand Up @@ -1753,6 +1746,13 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
return vol, nil
}

// Set NeedsCopyUp to false since we are about to do first copy
// Do not copy second time.
vol.state.NeedsCopyUp = false
if err := vol.save(); err != nil {
return nil, err
}

// Buildah Copier accepts a reader, so we'll need a pipe.
reader, writer := io.Pipe()
defer reader.Close()
Expand Down
8 changes: 8 additions & 0 deletions libpod/define/volume_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,12 @@ type InspectVolumeData struct {
// volume for a specific container, and will be be removed when any
// container using it is removed.
Anonymous bool `json:"Anonymous,omitempty"`
// MountCount is the number of times this volume has been mounted.
MountCount uint `json:"MountCount"`
// NeedsCopyUp indicates that the next time the volume is mounted into
NeedsCopyUp bool `json:"NeedsCopyUp,omitempty"`
// NeedsChown indicates that the next time the volume is mounted into
// a container, the container will chown the volume to the container process
// UID/GID.
NeedsChown bool `json:"NeedsChown,omitempty"`
}
3 changes: 3 additions & 0 deletions libpod/volume_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ func (v *Volume) Inspect() (*define.InspectVolumeData, error) {
data.UID = v.uid()
data.GID = v.gid()
data.Anonymous = v.config.IsAnon
data.MountCount = v.state.MountCount
data.NeedsCopyUp = v.state.NeedsCopyUp
data.NeedsChown = v.state.NeedsChown

return data, nil
}
40 changes: 40 additions & 0 deletions test/system/160-volumes.bats
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,44 @@ EOF
is "$output" "tmpfs" "volume should be tmpfs"
}

# Named volumes copyup
@test "podman volume create copyup" {
myvolume=myvol$(random_string)
mylabel=$(random_string)

# Create a named volume
run_podman volume create $myvolume
is "$output" "$myvolume" "output from volume create"

# Confirm that it shows up in 'volume ls', and confirm values
run_podman volume ls --format json
tests="
Name | $myvolume
Driver | local
NeedsCopyUp | true
NeedsChown | true
"
parse_table "$tests" | while read field expect; do
actual=$(jq -r ".[0].$field" <<<"$output")
is "$actual" "$expect" "volume ls .$field"
done

run_podman run --rm --volume $myvolume:/vol $IMAGE true
run_podman volume inspect --format '{{ .NeedsCopyUp }}' $myvolume
is "${output}" "true" "If content in dest '/vol' empty NeedsCopyUP should still be true"
run_podman volume inspect --format '{{ .NeedsChown }}' $myvolume
is "${output}" "false" "After first use within a container NeedsChown should still be false"

run_podman run --rm --volume $myvolume:/etc $IMAGE ls /etc/passwd
run_podman volume inspect --format '{{ .NeedsCopyUp }}' $myvolume
is "${output}" "false" "If content in dest '/etc' non-empty NeedsCopyUP should still have happend and be false"

run_podman volume inspect --format '{{.Mountpoint}}' $myvolume
mountpoint="$output"
test -e "$mountpoint/passwd"

# Clean up
run_podman volume rm $myvolume
}

# vim: filetype=sh

0 comments on commit 13f3fd2

Please sign in to comment.