diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index 2b3a612b6..609878a98 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -867,6 +867,16 @@ func (mgr *ContainerManager) parseVolumes(ctx context.Context, c *types.Containe } source = mountPath + } else { + // Create the host path if it doesn't exist. + _, err := os.Stat(source) + if err != nil && !os.IsNotExist(err) { + return errors.Errorf("failed to stat %q: %v", source, err) + } + err = os.MkdirAll(source, 0755) + if err != nil { + return errors.Errorf("failed to mkdir %q: %v", source, err) + } } switch len(arr) { diff --git a/daemon/mgr/cri.go b/daemon/mgr/cri.go index 08b1398f9..d1dd5a665 100644 --- a/daemon/mgr/cri.go +++ b/daemon/mgr/cri.go @@ -284,7 +284,7 @@ func (c *CriManager) CreateContainer(ctx context.Context, r *runtime.CreateConta Tty: config.Tty, }, HostConfig: &apitypes.HostConfig{ - // TODO: generate mount bindings. + Binds: generateMountBindings(config.GetMounts()), }, NetworkingConfig: &apitypes.NetworkingConfig{}, } diff --git a/daemon/mgr/cri_utils.go b/daemon/mgr/cri_utils.go index ea6da593f..9dd110b05 100644 --- a/daemon/mgr/cri_utils.go +++ b/daemon/mgr/cri_utils.go @@ -91,6 +91,33 @@ func extractLabels(input map[string]string) (map[string]string, map[string]strin return labels, annotations } +func generateMountBindings(mounts []*runtime.Mount) []string { + result := make([]string, 0, len(mounts)) + for _, m := range mounts { + bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath) + var attrs []string + if m.Readonly { + attrs = append(attrs, "ro") + } + if m.SelinuxRelabel { + attrs = append(attrs, "Z") + } + switch m.Propagation { + case runtime.MountPropagation_PROPAGATION_PRIVATE: + // noop, default mode is private. + case runtime.MountPropagation_PROPAGATION_BIDIRECTIONAL: + attrs = append(attrs, "rshared") + case runtime.MountPropagation_PROPAGATION_HOST_TO_CONTAINER: + attrs = append(attrs, "rslave") + } + if len(attrs) > 0 { + bind = fmt.Sprintf("%s:%s", bind, strings.Join(attrs, ",")) + } + result = append(result, bind) + } + return result +} + // Sandbox related tool functions. // makeSandboxName generates sandbox name from sandbox metadata. The name diff --git a/daemon/mgr/spec_volume.go b/daemon/mgr/spec_volume.go index 4ea99dfec..5a751dc24 100644 --- a/daemon/mgr/spec_volume.go +++ b/daemon/mgr/spec_volume.go @@ -22,7 +22,14 @@ func setupMounts(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) error } opt := []string{"rbind"} if lensd == 3 { - opt = append(opt, sd[2]) + opt = append(opt, strings.Split(sd[2], ",")...) + // Set rootfs propagation, default setting is private. + if strings.Contains(sd[2], "rshared") { + s.Linux.RootfsPropagation = "rshared" + } + if strings.Contains(sd[2], "rslave") && s.Linux.RootfsPropagation != "rshared" { + s.Linux.RootfsPropagation = "rslave" + } } mounts = append(mounts, specs.Mount{ Destination: sd[1], diff --git a/hack/cri-test/test-cri.sh b/hack/cri-test/test-cri.sh index d1d311197..3bf8fafbd 100755 --- a/hack/cri-test/test-cri.sh +++ b/hack/cri-test/test-cri.sh @@ -23,7 +23,7 @@ POUCH_SOCK="/var/run/pouchcri.sock" # CRI_FOCUS focuses the test to run. # With the CRI manager completes its function, we may need to expand this field. -CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info"} +CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info|mount propagation|volume and device"} # CRI_SKIP skips the test to skip. CRI_SKIP=${CRI_SKIP:-""}