Fix empty volume ownership.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
d7abb5b489
commit
c55776377f
18
integration/images/volume-ownership/Dockerfile
Normal file
18
integration/images/volume-ownership/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright 2018 The Containerd Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM busybox
|
||||||
|
RUN mkdir -p /test_dir && \
|
||||||
|
chown -R nobody:nogroup /test_dir
|
||||||
|
VOLUME /test_dir
|
27
integration/images/volume-ownership/Makefile
Normal file
27
integration/images/volume-ownership/Makefile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright 2018 The Containerd Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
PROJ=gcr.io/k8s-cri-containerd
|
||||||
|
VERSION=1.0
|
||||||
|
IMAGE=$(PROJ)/volume-ownership:$(VERSION)
|
||||||
|
|
||||||
|
build:
|
||||||
|
docker build -t $(IMAGE) .
|
||||||
|
|
||||||
|
push:
|
||||||
|
gcloud docker -- push $(IMAGE)
|
||||||
|
|
||||||
|
.PHONY: build push
|
@ -70,7 +70,7 @@ func TestVolumeCopyUp(t *testing.T) {
|
|||||||
assert.Equal(t, "test_content\n", string(stdout))
|
assert.Equal(t, "test_content\n", string(stdout))
|
||||||
|
|
||||||
t.Logf("Check host path of the volume")
|
t.Logf("Check host path of the volume")
|
||||||
hostCmd := fmt.Sprintf("ls %s/containers/%s/volumes/*/test_file | xargs cat", *criRoot, cn)
|
hostCmd := fmt.Sprintf("find %s/containers/%s/volumes/*/test_file | xargs cat", *criRoot, cn)
|
||||||
output, err := exec.Command("sh", "-c", hostCmd).CombinedOutput()
|
output, err := exec.Command("sh", "-c", hostCmd).CombinedOutput()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "test_content\n", string(output))
|
assert.Equal(t, "test_content\n", string(output))
|
||||||
@ -88,3 +88,51 @@ func TestVolumeCopyUp(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "new_content\n", string(output))
|
assert.Equal(t, "new_content\n", string(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVolumeOwnership(t *testing.T) {
|
||||||
|
const (
|
||||||
|
testImage = "gcr.io/k8s-cri-containerd/volume-ownership:1.0"
|
||||||
|
execTimeout = time.Minute
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Logf("Create a sandbox")
|
||||||
|
sbConfig := PodSandboxConfig("sandbox", "volume-ownership")
|
||||||
|
sb, err := runtimeService.RunPodSandbox(sbConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, runtimeService.StopPodSandbox(sb))
|
||||||
|
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
|
||||||
|
}()
|
||||||
|
|
||||||
|
t.Logf("Pull test image")
|
||||||
|
_, err = imageService.PullImage(&runtime.ImageSpec{Image: testImage}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Logf("Create a container with volume-ownership test image")
|
||||||
|
cnConfig := ContainerConfig(
|
||||||
|
"container",
|
||||||
|
testImage,
|
||||||
|
WithCommand("tail", "-f", "/dev/null"),
|
||||||
|
)
|
||||||
|
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Logf("Start the container")
|
||||||
|
require.NoError(t, runtimeService.StartContainer(cn))
|
||||||
|
|
||||||
|
// gcr.io/k8s-cri-containerd/volume-ownership:1.0 contains a test_dir
|
||||||
|
// volume, which is owned by nobody:nogroup.
|
||||||
|
t.Logf("Check ownership of test directory inside container")
|
||||||
|
stdout, stderr, err := runtimeService.ExecSync(cn, []string{
|
||||||
|
"stat", "-c", "%U:%G", "/test_dir",
|
||||||
|
}, execTimeout)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Empty(t, stderr)
|
||||||
|
assert.Equal(t, "nobody:nogroup\n", string(stdout))
|
||||||
|
|
||||||
|
t.Logf("Check ownership of test directory on the host")
|
||||||
|
hostCmd := fmt.Sprintf("find %s/containers/%s/volumes/* | xargs stat -c %%U:%%G", *criRoot, cn)
|
||||||
|
output, err := exec.Command("sh", "-c", hostCmd).CombinedOutput()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "nobody:nogroup\n", string(output))
|
||||||
|
}
|
||||||
|
@ -53,7 +53,6 @@ func WithNewSnapshot(id string, i containerd.Image) containerd.NewContainerOpts
|
|||||||
// WithVolumes copies ownership of volume in rootfs to its corresponding host path.
|
// WithVolumes copies ownership of volume in rootfs to its corresponding host path.
|
||||||
// It doesn't update runtime spec.
|
// It doesn't update runtime spec.
|
||||||
// The passed in map is a host path to container path map for all volumes.
|
// The passed in map is a host path to container path map for all volumes.
|
||||||
// TODO(random-liu): Figure out whether we need to copy volume content.
|
|
||||||
func WithVolumes(volumeMounts map[string]string) containerd.NewContainerOpts {
|
func WithVolumes(volumeMounts map[string]string) containerd.NewContainerOpts {
|
||||||
return func(ctx context.Context, client *containerd.Client, c *containers.Container) (err error) {
|
return func(ctx context.Context, client *containerd.Client, c *containers.Container) (err error) {
|
||||||
if c.Snapshotter == "" {
|
if c.Snapshotter == "" {
|
||||||
@ -108,14 +107,6 @@ func WithVolumes(volumeMounts map[string]string) containerd.NewContainerOpts {
|
|||||||
// copyExistingContents copies from the source to the destination and
|
// copyExistingContents copies from the source to the destination and
|
||||||
// ensures the ownership is appropriately set.
|
// ensures the ownership is appropriately set.
|
||||||
func copyExistingContents(source, destination string) error {
|
func copyExistingContents(source, destination string) error {
|
||||||
srcList, err := ioutil.ReadDir(source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(srcList) == 0 {
|
|
||||||
// Skip copying if source directory is empty.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
dstList, err := ioutil.ReadDir(destination)
|
dstList, err := ioutil.ReadDir(destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user