Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Commit

Permalink
Merge pull request #647 from lucab/to-upstream/sysctl
Browse files Browse the repository at this point in the history
spec: add os/unix/sysctl isolator
  • Loading branch information
jonboulle authored Aug 29, 2016
2 parents 2449063 + a00638c commit af31bda
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 6 deletions.
6 changes: 6 additions & 0 deletions examples/pod_runtime.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@
{
"name": "resource/memory",
"value": {"limit": "4G"}
},
{
"name": "os/unix/sysctl",
"value": {
"net.ipv4.tcp_fin_timeout": "6"
}
}
],
"annotations": [
Expand Down
44 changes: 38 additions & 6 deletions schema/types/isolator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,27 @@ func TestIsolatorUnmarshal(t *testing.T) {
}`,
true,
},
{
`{
"name": "os/unix/sysctl",
"value": {"net.ipv4.tcp_rfc1337": "1"}
}`,
false,
},
{
`{
"name": "os/unix/sysctl",
"value": {"net.ipv4.tcp_rfc1337": 1}
}`,
true,
},
{
`{
"name": "os/unix/sysctl",
"value": {["net.ipv4.tcp_rfc1337"]}
}`,
true,
},
}

for i, tt := range tests {
Expand Down Expand Up @@ -205,6 +226,10 @@ func TestIsolatorsGetByName(t *testing.T) {
{
"name": "os/linux/no-new-privileges",
"value": true
},
{
"name": "os/unix/sysctl",
"value": {"net.ipv4.tcp_rfc1337": "1"}
}
]
`
Expand All @@ -215,12 +240,14 @@ func TestIsolatorsGetByName(t *testing.T) {
wrequest int64
wset []LinuxCapability
wprivs LinuxNoNewPrivileges
wsysctl UnixSysctl
}{
{"resource/cpu", 1, 30, nil, false},
{"resource/memory", 2147483648, 1000000000, nil, false},
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
{"os/linux/no-new-privileges", 0, 0, nil, LinuxNoNewPrivileges(true)},
{"resource/cpu", 1, 30, nil, false, nil},
{"resource/memory", 2147483648, 1000000000, nil, false, nil},
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false, nil},
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false, nil},
{"os/linux/no-new-privileges", 0, 0, nil, LinuxNoNewPrivileges(true), nil},
{"os/unix/sysctl", 0, 0, nil, false, UnixSysctl{"net.ipv4.tcp_rfc1337": "1"}},
}

var is Isolators
Expand Down Expand Up @@ -269,8 +296,13 @@ func TestIsolatorsGetByName(t *testing.T) {
t.Errorf("#%d: got %v, want %v", i, v, tt.wprivs)
}

case *UnixSysctl:
if !reflect.DeepEqual(*v, tt.wsysctl) {
t.Errorf("#%d: got %v, want %v", i, *v, tt.wsysctl)
}

default:
panic("unexecpected type")
panic("unexpected type")
}
}
}
Expand Down
83 changes: 83 additions & 0 deletions schema/types/isolator_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2016 The appc 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.

package types

import (
"encoding/json"
)

var (
UnixIsolatorNames = make(map[ACIdentifier]struct{})
)

const (
//TODO(lucab): add "ulimit" isolators
UnixSysctlName = "os/unix/sysctl"
)

func init() {
for name, con := range map[ACIdentifier]IsolatorValueConstructor{
UnixSysctlName: func() IsolatorValue { return &UnixSysctl{} },
} {
AddIsolatorName(name, UnixIsolatorNames)
AddIsolatorValueConstructor(name, con)
}
}

type UnixSysctl map[string]string

func (s *UnixSysctl) UnmarshalJSON(b []byte) error {
var v map[string]string
err := json.Unmarshal(b, &v)
if err != nil {
return err
}
*s = UnixSysctl(v)
return err
}

func (s UnixSysctl) AssertValid() error {
return nil
}

func (s UnixSysctl) multipleAllowed() bool {
return false
}
func (s UnixSysctl) Conflicts() []ACIdentifier {
return nil
}

func (s UnixSysctl) AsIsolator() Isolator {
isol := isolatorMap[UnixSysctlName]()

b, err := json.Marshal(s)
if err != nil {
panic(err)
}
valRaw := json.RawMessage(b)
return Isolator{
Name: UnixSysctlName,
ValueRaw: &valRaw,
value: isol,
}
}

func NewUnixSysctlIsolator(cfg map[string]string) (*UnixSysctl, error) {
s := UnixSysctl(cfg)
if err := s.AssertValid(); err != nil {
return nil, err
}
return &s, nil
}
57 changes: 57 additions & 0 deletions schema/types/isolator_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2016 The appc 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.

package types

import (
"reflect"
"testing"
)

func TestUnixSysctlIsolator(t *testing.T) {
tests := []struct {
inCfg map[string]string

expectedErr bool
expectedRes UnixSysctl
}{
// empty isolator - valid
{
make(map[string]string),

false,
UnixSysctl{},
},
// simple isolator - valid
{
map[string]string{
"foo": "bar",
},

false,
UnixSysctl{
"foo": "bar",
},
},
}
for i, tt := range tests {
gotRes, err := NewUnixSysctlIsolator(tt.inCfg)
if gotErr := err != nil; gotErr != tt.expectedErr {
t.Errorf("#%d: want err=%t, got %t (err=%v)", i, tt.expectedErr, gotErr, err)
}
if !reflect.DeepEqual(tt.expectedRes, *gotRes) {
t.Errorf("#%d: want %s, got %s", i, tt.expectedRes, *gotRes)
}
}
}
30 changes: 30 additions & 0 deletions spec/ace.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,36 @@ Small quantities can be represented directly as decimals (e.g., 0.3), or using m

**NOTE**: Network limits MUST NOT apply to localhost communication between apps in a pod.

### Unix Isolators

These isolators take care of configuring several settings that are typically available in UNIX-like environments.
This set includes isolators to tweak some standard POSIX features as well as other technologies that have been ported across multiple kernel families.

#### os/unix/sysctl

Sysctl parameters allow an application to configure kernel level options for its environment.
A number of these values are namespace-aware as well, which makes them a natural fit for for an ACE to configure.

* Scope: pod

**Parameters:**

* dictionary of `sysctl(8)` key-value entries to set kernel runtime parameters.

```json
"name": "os/unix/sysctl",
"value": {
"net.ipv4.tcp_mtu_probing": "1",
"net.ipv4.tcp_keepalive_time": "300",
"net.ipv4.tcp_keepalive_probes": "5",
"net.ipv4.tcp_keepalive_intvl": "15"
}
```
**Notes**:
1. Only a single `os/unix/sysctl` isolator can be specified per-pod.
2. Implementations SHOULD validate keys before applying sysctl parameters.
For example, a Linux implementation may want to only allow entries related to a specific namespaced subtree like `net.*`.
In such case, implementations MUST either ignore forbidden parameters or refuse to run the pod alltogether.

## App Container Metadata Service

Expand Down

0 comments on commit af31bda

Please sign in to comment.