diff --git a/internal/machine/docker/server.go b/internal/machine/docker/server.go index 9a3e637b..a566d76b 100644 --- a/internal/machine/docker/server.go +++ b/internal/machine/docker/server.go @@ -627,6 +627,7 @@ func (s *Server) CreateServiceContainer( Binds: spec.Container.Volumes, Init: spec.Container.Init, Mounts: mounts, + PidMode: spec.Container.Pid, PortBindings: portBindings, Privileged: spec.Container.Privileged, Resources: container.Resources{ diff --git a/pkg/api/service.go b/pkg/api/service.go index 2f2efb64..f992e739 100644 --- a/pkg/api/service.go +++ b/pkg/api/service.go @@ -11,6 +11,7 @@ import ( mapset "github.com/deckarep/golang-set/v2" "github.com/distribution/reference" + "github.com/docker/docker/api/types/container" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/psviderski/uncloud/internal/machine/api/pb" @@ -256,6 +257,8 @@ type ContainerSpec struct { Init *bool // LogDriver overrides the default logging driver for the container. Each Docker daemon can have its own default. LogDriver *LogDriver + // Pid allows setting the PID name space, currently only "" or "host" is supported. + Pid container.PidMode // Privileged gives extended privileges to the container. This is a security risk and should be used with caution. Privileged bool // PullPolicy determines when to pull the image from the registry or use the image already available in the cluster. diff --git a/pkg/api/service_test.go b/pkg/api/service_test.go index dd4f4741..dbd39070 100644 --- a/pkg/api/service_test.go +++ b/pkg/api/service_test.go @@ -206,6 +206,7 @@ func TestContainerSpec_Clone(t *testing.T) { original := ContainerSpec{ CapAdd: []string{"NET_ADMIN"}, CapDrop: []string{"ALL"}, + Pid: container.PidMode("host"), Command: []string{"sh", "-c", "echo hello"}, Entrypoint: []string{"/bin/bash"}, Env: EnvVars{ diff --git a/pkg/client/compose/service.go b/pkg/client/compose/service.go index 6210105e..81e5444b 100644 --- a/pkg/client/compose/service.go +++ b/pkg/client/compose/service.go @@ -53,6 +53,7 @@ func ServiceSpecFromCompose(project *types.Project, serviceName string) (api.Ser Healthcheck: healthcheckFromCompose(service.HealthCheck), Image: service.Image, Init: service.Init, + Pid: container.PidMode(service.Pid), Privileged: service.Privileged, PullPolicy: pullPolicy, Resources: resourcesFromCompose(service), diff --git a/pkg/client/compose/service_test.go b/pkg/client/compose/service_test.go index e490a9d6..49ec513d 100644 --- a/pkg/client/compose/service_test.go +++ b/pkg/client/compose/service_test.go @@ -127,6 +127,7 @@ func TestServiceSpecFromCompose(t *testing.T) { "max-file": "3", }, }, + Pid: "host", Privileged: true, PullPolicy: api.PullPolicyAlways, Resources: api.ContainerResources{ diff --git a/pkg/client/compose/testdata/compose-full-spec.yaml b/pkg/client/compose/testdata/compose-full-spec.yaml index d345a240..7e608eb8 100644 --- a/pkg/client/compose/testdata/compose-full-spec.yaml +++ b/pkg/client/compose/testdata/compose-full-spec.yaml @@ -6,6 +6,7 @@ services: - ALL command: ["nginx", "updated", "command"] cpus: 0.5 + pid: host deploy: update_config: order: stop-first diff --git a/pkg/client/deploy/container_test.go b/pkg/client/deploy/container_test.go index fff9c3ef..d5106f93 100644 --- a/pkg/client/deploy/container_test.go +++ b/pkg/client/deploy/container_test.go @@ -47,6 +47,26 @@ func TestEvalContainerSpecChange_ContainerCapDrop(t *testing.T) { assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec)) } +func TestEvalContainerSpecChange_ContainerPid(t *testing.T) { + t.Parallel() + + currentSpec := api.ServiceSpec{ + Container: api.ContainerSpec{ + Image: "nginx:latest", + }, + } + newSpec := api.ServiceSpec{ + Container: api.ContainerSpec{ + Image: "nginx:latest", + Pid: "host", + CapAdd: []string{"NET_ADMIN"}, + }, + } + + assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(currentSpec, newSpec)) + assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec)) +} + func TestEvalContainerSpecChange_ContainerResources(t *testing.T) { t.Parallel() diff --git a/website/docs/8-compose-file-reference/1-support-matrix.md b/website/docs/8-compose-file-reference/1-support-matrix.md index 420835b1..2c9c449c 100644 --- a/website/docs/8-compose-file-reference/1-support-matrix.md +++ b/website/docs/8-compose-file-reference/1-support-matrix.md @@ -38,6 +38,7 @@ If you rely on a specific Compose feature that is not supported by Uncloud, plea | `mem_swappiness` | ❌ Not supported | | | `memswap_limit` | ❌ Not supported | | | `networks` | ❌ Not supported | All containers share cluster network | +| `pid` | ✅ Supported | Set the PID namespace mode, `pid: host` only | | `ports` | ⚠️ Limited | `mode: host` only, use [`x-ports`](#x-ports) for HTTP/HTTPS | | `privileged` | ✅ Supported | Run containers in privileged mode | | `pull_policy` | ✅ Supported | `always`, `missing`, `never` |