mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
feat: add support for sysctls compose key (#239)
* feat: add support for `sysctls` compose key * lint --------- Co-authored-by: Pasha Sviderski <me@psviderski.name>
This commit is contained in:
co-authored by
Pasha Sviderski
parent
7e739dd2f0
commit
06c3fba96e
@@ -623,6 +623,7 @@ func (s *Server) CreateServiceContainer(
|
|||||||
RestartPolicy: container.RestartPolicy{
|
RestartPolicy: container.RestartPolicy{
|
||||||
Name: container.RestartPolicyUnlessStopped,
|
Name: container.RestartPolicyUnlessStopped,
|
||||||
},
|
},
|
||||||
|
Sysctls: spec.Container.Sysctls,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the container to use the internal DNS server if it's available.
|
// Configure the container to use the internal DNS server if it's available.
|
||||||
|
|||||||
+15
-8
@@ -247,6 +247,8 @@ type ContainerSpec struct {
|
|||||||
PullPolicy string
|
PullPolicy string
|
||||||
// Resource allocation for the container.
|
// Resource allocation for the container.
|
||||||
Resources ContainerResources
|
Resources ContainerResources
|
||||||
|
// Namespaced kernel parameters to be set in container
|
||||||
|
Sysctls map[string]string
|
||||||
// User overrides the default user of the image used to run the container. Format: user|UID[:group|GID].
|
// User overrides the default user of the image used to run the container. Format: user|UID[:group|GID].
|
||||||
User string
|
User string
|
||||||
// VolumeMounts specifies how volumes are mounted into the container filesystem.
|
// VolumeMounts specifies how volumes are mounted into the container filesystem.
|
||||||
@@ -312,6 +314,14 @@ func (s *ContainerSpec) Equals(spec ContainerSpec) bool {
|
|||||||
func (s *ContainerSpec) Clone() ContainerSpec {
|
func (s *ContainerSpec) Clone() ContainerSpec {
|
||||||
spec := *s
|
spec := *s
|
||||||
|
|
||||||
|
if s.CapAdd != nil {
|
||||||
|
spec.CapAdd = make([]string, len(s.CapAdd))
|
||||||
|
copy(spec.CapAdd, s.CapAdd)
|
||||||
|
}
|
||||||
|
if s.CapDrop != nil {
|
||||||
|
spec.CapDrop = make([]string, len(s.CapDrop))
|
||||||
|
copy(spec.CapDrop, s.CapDrop)
|
||||||
|
}
|
||||||
if s.Command != nil {
|
if s.Command != nil {
|
||||||
spec.Command = make([]string, len(s.Command))
|
spec.Command = make([]string, len(s.Command))
|
||||||
copy(spec.Command, s.Command)
|
copy(spec.Command, s.Command)
|
||||||
@@ -347,15 +357,12 @@ func (s *ContainerSpec) Clone() ContainerSpec {
|
|||||||
spec.ConfigMounts[i] = cm.Clone()
|
spec.ConfigMounts[i] = cm.Clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.CapAdd != nil {
|
if s.Sysctls != nil {
|
||||||
spec.CapAdd = make([]string, len(s.CapAdd))
|
spec.Sysctls = make(map[string]string, len(s.Sysctls))
|
||||||
copy(spec.CapAdd, s.CapAdd)
|
for k, v := range s.Sysctls {
|
||||||
|
spec.Sysctls[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if s.CapDrop != nil {
|
|
||||||
spec.CapDrop = make([]string, len(s.CapDrop))
|
|
||||||
copy(spec.CapDrop, s.CapDrop)
|
|
||||||
}
|
|
||||||
|
|
||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,9 @@ func TestContainerSpec_Clone(t *testing.T) {
|
|||||||
Memory: 2345,
|
Memory: 2345,
|
||||||
MemoryReservation: 3456,
|
MemoryReservation: 3456,
|
||||||
},
|
},
|
||||||
|
Sysctls: map[string]string{
|
||||||
|
"net.ipv4.ip_forward": "1",
|
||||||
|
},
|
||||||
User: "1000:1000",
|
User: "1000:1000",
|
||||||
Volumes: []string{"/data", "/config"},
|
Volumes: []string{"/data", "/config"},
|
||||||
VolumeMounts: []VolumeMount{
|
VolumeMounts: []VolumeMount{
|
||||||
@@ -259,6 +262,7 @@ func TestContainerSpec_Clone(t *testing.T) {
|
|||||||
original.VolumeMounts[0].ContainerPath = stringModified
|
original.VolumeMounts[0].ContainerPath = stringModified
|
||||||
original.ConfigMounts[0].ContainerPath = stringModified
|
original.ConfigMounts[0].ContainerPath = stringModified
|
||||||
*original.ConfigMounts[0].Mode = 0o755 // Modify the Mode pointer value
|
*original.ConfigMounts[0].Mode = 0o755 // Modify the Mode pointer value
|
||||||
|
original.Sysctls["net.ipv4.ip_forward"] = stringModified
|
||||||
|
|
||||||
assert.False(t, original.Equals(cloned))
|
assert.False(t, original.Equals(cloned))
|
||||||
// Assert cloned values are unchanged
|
// Assert cloned values are unchanged
|
||||||
@@ -285,4 +289,5 @@ func TestContainerSpec_Clone(t *testing.T) {
|
|||||||
assert.Equal(t, "/etc/config", cloned.ConfigMounts[0].ContainerPath)
|
assert.Equal(t, "/etc/config", cloned.ConfigMounts[0].ContainerPath)
|
||||||
assert.NotNil(t, cloned.ConfigMounts[0].Mode)
|
assert.NotNil(t, cloned.ConfigMounts[0].Mode)
|
||||||
assert.Equal(t, os.FileMode(0o644), *cloned.ConfigMounts[0].Mode, "Mode should be deep copied")
|
assert.Equal(t, os.FileMode(0o644), *cloned.ConfigMounts[0].Mode, "Mode should be deep copied")
|
||||||
|
assert.Equal(t, "1", cloned.Sysctls["net.ipv4.ip_forward"])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ func ServiceSpecFromCompose(project *types.Project, serviceName string) (api.Ser
|
|||||||
Privileged: service.Privileged,
|
Privileged: service.Privileged,
|
||||||
PullPolicy: pullPolicy,
|
PullPolicy: pullPolicy,
|
||||||
Resources: resourcesFromCompose(service),
|
Resources: resourcesFromCompose(service),
|
||||||
|
Sysctls: service.Sysctls,
|
||||||
User: service.User,
|
User: service.User,
|
||||||
},
|
},
|
||||||
Name: serviceName,
|
Name: serviceName,
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ func TestServiceSpecFromCompose(t *testing.T) {
|
|||||||
Memory: 100 * units.MiB,
|
Memory: 100 * units.MiB,
|
||||||
MemoryReservation: 50 * units.MiB,
|
MemoryReservation: 50 * units.MiB,
|
||||||
},
|
},
|
||||||
|
Sysctls: map[string]string{
|
||||||
|
"net.ipv4.ip_forward": "1",
|
||||||
|
},
|
||||||
User: "nginx:nginx",
|
User: "nginx:nginx",
|
||||||
VolumeMounts: []api.VolumeMount{
|
VolumeMounts: []api.VolumeMount{
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ services:
|
|||||||
privileged: true
|
privileged: true
|
||||||
pull_policy: always
|
pull_policy: always
|
||||||
scale: 3
|
scale: 3
|
||||||
|
sysctls:
|
||||||
|
- net.ipv4.ip_forward=1
|
||||||
user: nginx:nginx
|
user: nginx:nginx
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/passwd:/host/etc/passwd:ro
|
- /etc/passwd:/host/etc/passwd:ro
|
||||||
|
|||||||
@@ -363,6 +363,27 @@ func TestEvalContainerSpecChange_ContainerPrivileged(t *testing.T) {
|
|||||||
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec))
|
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEvalContainerSpecChange_ContainerSysctls(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
currentSpec := api.ServiceSpec{
|
||||||
|
Container: api.ContainerSpec{
|
||||||
|
Image: "nginx:latest",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
newSpec := api.ServiceSpec{
|
||||||
|
Container: api.ContainerSpec{
|
||||||
|
Image: "nginx:latest",
|
||||||
|
Sysctls: map[string]string{
|
||||||
|
"net.ipv4.ip_forward": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(currentSpec, newSpec))
|
||||||
|
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec))
|
||||||
|
}
|
||||||
|
|
||||||
func TestEvalContainerSpecChange_PullPolicy(t *testing.T) {
|
func TestEvalContainerSpecChange_PullPolicy(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ The following table shows the support status for main Compose features:
|
|||||||
| `secrets` | ❌ Not supported | Use configs or environment variables |
|
| `secrets` | ❌ Not supported | Use configs or environment variables |
|
||||||
| `security_opt` | ❌ Not supported | |
|
| `security_opt` | ❌ Not supported | |
|
||||||
| `storage_opt` | ❌ Not supported | |
|
| `storage_opt` | ❌ Not supported | |
|
||||||
|
| `sysctls` | ✅ Supported | Namespaced kernel parameters |
|
||||||
| `user` | ✅ Supported | Set container user |
|
| `user` | ✅ Supported | Set container user |
|
||||||
| `volumes` | ✅ Supported | Named volumes, bind mounts, tmpfs |
|
| `volumes` | ✅ Supported | Named volumes, bind mounts, tmpfs |
|
||||||
| **Deploy** | | |
|
| **Deploy** | | |
|
||||||
|
|||||||
Reference in New Issue
Block a user