From 06941b7e5ca4f937c1996828e5a543967902656d Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 13 Nov 2023 21:03:40 +0400 Subject: [PATCH] fix: allow rootfs propagation configuration for extension services Fixes #7873 Some services which perform mounts inside the container which require mounts to propagate back to the host (e.g. `stargz-snapshotter`) require this configuration setting. Signed-off-by: Andrey Smirnov --- .../machined/pkg/system/services/extension.go | 1 + internal/integration/api/extensions_qemu.go | 24 +++++++++++++++++++ pkg/machinery/extensions/services/services.go | 2 ++ .../v1.6/advanced/extension-services.md | 3 +++ 4 files changed, 30 insertions(+) diff --git a/internal/app/machined/pkg/system/services/extension.go b/internal/app/machined/pkg/system/services/extension.go index 9fe0a44bd4..1f94cef7b0 100644 --- a/internal/app/machined/pkg/system/services/extension.go +++ b/internal/app/machined/pkg/system/services/extension.go @@ -106,6 +106,7 @@ func (svc *Extension) DependsOn(r runtime.Runtime) []string { func (svc *Extension) getOCIOptions(envVars []string) []oci.SpecOpts { ociOpts := []oci.SpecOpts{ oci.WithRootFSPath(filepath.Join(constants.ExtensionServicesRootfsPath, svc.Spec.Name)), + containerd.WithRootfsPropagation(svc.Spec.Container.Security.RootfsPropagation), oci.WithCgroup(constants.CgroupExtensions), oci.WithMounts(svc.Spec.Container.Mounts), oci.WithHostNamespace(specs.NetworkNamespace), diff --git a/internal/integration/api/extensions_qemu.go b/internal/integration/api/extensions_qemu.go index e6c2760c2f..3eaa00befc 100644 --- a/internal/integration/api/extensions_qemu.go +++ b/internal/integration/api/extensions_qemu.go @@ -392,6 +392,30 @@ func (suite *ExtensionsSuiteQEMU) TestExtensionsGvisor() { suite.Require().NoError(suite.WaitForPodToBeRunning(suite.ctx, 5*time.Minute, "default", "nginx-gvisor")) } +// TestExtensionsStargz verifies stargz snapshotter. +func (suite *ExtensionsSuiteQEMU) TestExtensionsStargz() { + _, err := suite.Clientset.CoreV1().Pods("default").Create(suite.ctx, &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "stargz-hello", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "stargz-hello", + Image: "ghcr.io/stargz-containers/alpine:3.15.3-esgz", + Args: []string{"sleep", "inf"}, + }, + }, + }, + }, metav1.CreateOptions{}) + defer suite.Clientset.CoreV1().Pods("default").Delete(suite.ctx, "stargz-hello", metav1.DeleteOptions{}) //nolint:errcheck + + suite.Require().NoError(err) + + // wait for the pod to be ready + suite.Require().NoError(suite.WaitForPodToBeRunning(suite.ctx, 5*time.Minute, "default", "stargz-hello")) +} + // TestExtensionsZFS verifies zfs is working, udev rules work and the pool is mounted on reboot. func (suite *ExtensionsSuiteQEMU) TestExtensionsZFS() { node := suite.RandomDiscoveredNodeInternalIP(machine.TypeWorker) diff --git a/pkg/machinery/extensions/services/services.go b/pkg/machinery/extensions/services/services.go index 447145e1d4..e98312456d 100644 --- a/pkg/machinery/extensions/services/services.go +++ b/pkg/machinery/extensions/services/services.go @@ -58,6 +58,8 @@ type Security struct { ReadonlyPaths []string `yaml:"readonlyPaths"` // WriteableRootfs WriteableRootfs bool `yaml:"writeableRootfs"` + // RootfsPropagation is the propagation mode for the rootfs mount. + RootfsPropagation string `yaml:"rootfsPropagation,omitempty"` } // Dependency describes a service Dependency. diff --git a/website/content/v1.6/advanced/extension-services.md b/website/content/v1.6/advanced/extension-services.md index d16a2ed66e..3f129323e7 100644 --- a/website/content/v1.6/advanced/extension-services.md +++ b/website/content/v1.6/advanced/extension-services.md @@ -90,6 +90,7 @@ readonlyPaths: - "/another/readonly/path" writeableRootfs: true writeableSysfs: true +rootfsPropagation: shared ``` > * The rootfs is readonly by default unless `writeableRootfs: true` is set. @@ -113,6 +114,8 @@ To set empty read only paths use: > security: > readonlyPaths: [] > ``` +> +> * Rootfs propagation is not set by default (container mounts are private). ### `depends`