mirror of
https://github.com/containers/podman.git
synced 2025-06-30 15:49:03 +08:00
Set volume NeedsCopyUp to false iff data was copied up
Currently Docker copies up the first volume on a mountpoint with data. Fixes: https://github.com/containers/podman/issues/12714 Also added NeedsCopyUP, NeedsChown and MountCount to the podman volume inspect code. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -1700,13 +1700,6 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
|
|||||||
if vol.state.NeedsCopyUp {
|
if vol.state.NeedsCopyUp {
|
||||||
logrus.Debugf("Copying up contents from container %s to volume %s", c.ID(), vol.Name())
|
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.
|
// If the volume is not empty, we should not copy up.
|
||||||
volMount := vol.mountPoint()
|
volMount := vol.mountPoint()
|
||||||
contents, err := ioutil.ReadDir(volMount)
|
contents, err := ioutil.ReadDir(volMount)
|
||||||
@ -1753,6 +1746,13 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
|
|||||||
return vol, nil
|
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.
|
// Buildah Copier accepts a reader, so we'll need a pipe.
|
||||||
reader, writer := io.Pipe()
|
reader, writer := io.Pipe()
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
@ -48,4 +48,12 @@ type InspectVolumeData struct {
|
|||||||
// volume for a specific container, and will be be removed when any
|
// volume for a specific container, and will be be removed when any
|
||||||
// container using it is removed.
|
// container using it is removed.
|
||||||
Anonymous bool `json:"Anonymous,omitempty"`
|
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"`
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,9 @@ func (v *Volume) Inspect() (*define.InspectVolumeData, error) {
|
|||||||
data.UID = v.uid()
|
data.UID = v.uid()
|
||||||
data.GID = v.gid()
|
data.GID = v.gid()
|
||||||
data.Anonymous = v.config.IsAnon
|
data.Anonymous = v.config.IsAnon
|
||||||
|
data.MountCount = v.state.MountCount
|
||||||
|
data.NeedsCopyUp = v.state.NeedsCopyUp
|
||||||
|
data.NeedsChown = v.state.NeedsChown
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
@ -345,4 +345,44 @@ EOF
|
|||||||
is "$output" "tmpfs" "volume should be tmpfs"
|
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
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user