Merge pull request #1370 from mrunalp/update_spec_rc5
Update runtime spec to rc5
This commit is contained in:
commit
697cb97cb7
2
Makefile
2
Makefile
|
@ -41,7 +41,7 @@ static: $(SOURCES)
|
|||
CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
release:
|
||||
@flag_list=(seccomp selinux apparmor static ambient); \
|
||||
@flag_list=(seccomp selinux apparmor static); \
|
||||
unset expression; \
|
||||
for flag in "$${flag_list[@]}"; do \
|
||||
expression+="' '{'',$${flag}}"; \
|
||||
|
|
8
exec.go
8
exec.go
|
@ -176,7 +176,13 @@ func getProcess(context *cli.Context, bundle string) (*specs.Process, error) {
|
|||
p.SelinuxLabel = l
|
||||
}
|
||||
if caps := context.StringSlice("cap"); len(caps) > 0 {
|
||||
p.Capabilities = caps
|
||||
for _, c := range caps {
|
||||
p.Capabilities.Bounding = append(p.Capabilities.Bounding, c)
|
||||
p.Capabilities.Inheritable = append(p.Capabilities.Inheritable, c)
|
||||
p.Capabilities.Effective = append(p.Capabilities.Effective, c)
|
||||
p.Capabilities.Permitted = append(p.Capabilities.Permitted, c)
|
||||
p.Capabilities.Ambient = append(p.Capabilities.Ambient, c)
|
||||
}
|
||||
}
|
||||
// append the passed env variables
|
||||
p.Env = append(p.Env, context.StringSlice("env")...)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
// +build linux,ambient
|
||||
|
||||
package libcontainer
|
||||
|
||||
import "github.com/syndtr/gocapability/capability"
|
||||
|
||||
const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
|
|
@ -7,9 +7,12 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
)
|
||||
|
||||
const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
|
||||
|
||||
var capabilityMap map[string]capability.Cap
|
||||
|
||||
func init() {
|
||||
|
@ -28,40 +31,84 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func newCapWhitelist(caps []string) (*whitelist, error) {
|
||||
l := []capability.Cap{}
|
||||
for _, c := range caps {
|
||||
func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
|
||||
bounding := []capability.Cap{}
|
||||
for _, c := range capConfig.Bounding {
|
||||
v, ok := capabilityMap[c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown capability %q", c)
|
||||
}
|
||||
l = append(l, v)
|
||||
bounding = append(bounding, v)
|
||||
}
|
||||
effective := []capability.Cap{}
|
||||
for _, c := range capConfig.Effective {
|
||||
v, ok := capabilityMap[c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown capability %q", c)
|
||||
}
|
||||
effective = append(effective, v)
|
||||
}
|
||||
inheritable := []capability.Cap{}
|
||||
for _, c := range capConfig.Inheritable {
|
||||
v, ok := capabilityMap[c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown capability %q", c)
|
||||
}
|
||||
inheritable = append(inheritable, v)
|
||||
}
|
||||
permitted := []capability.Cap{}
|
||||
for _, c := range capConfig.Permitted {
|
||||
v, ok := capabilityMap[c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown capability %q", c)
|
||||
}
|
||||
permitted = append(permitted, v)
|
||||
}
|
||||
ambient := []capability.Cap{}
|
||||
for _, c := range capConfig.Ambient {
|
||||
v, ok := capabilityMap[c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown capability %q", c)
|
||||
}
|
||||
ambient = append(ambient, v)
|
||||
}
|
||||
pid, err := capability.NewPid(os.Getpid())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &whitelist{
|
||||
keep: l,
|
||||
pid: pid,
|
||||
return &containerCapabilities{
|
||||
bounding: bounding,
|
||||
effective: effective,
|
||||
inheritable: inheritable,
|
||||
permitted: permitted,
|
||||
ambient: ambient,
|
||||
pid: pid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type whitelist struct {
|
||||
pid capability.Capabilities
|
||||
keep []capability.Cap
|
||||
type containerCapabilities struct {
|
||||
pid capability.Capabilities
|
||||
bounding []capability.Cap
|
||||
effective []capability.Cap
|
||||
inheritable []capability.Cap
|
||||
permitted []capability.Cap
|
||||
ambient []capability.Cap
|
||||
}
|
||||
|
||||
// dropBoundingSet drops the capability bounding set to those specified in the whitelist.
|
||||
func (w *whitelist) dropBoundingSet() error {
|
||||
w.pid.Clear(capability.BOUNDS)
|
||||
w.pid.Set(capability.BOUNDS, w.keep...)
|
||||
return w.pid.Apply(capability.BOUNDS)
|
||||
// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
|
||||
func (c *containerCapabilities) ApplyBoundingSet() error {
|
||||
c.pid.Clear(capability.BOUNDS)
|
||||
c.pid.Set(capability.BOUNDS, c.bounding...)
|
||||
return c.pid.Apply(capability.BOUNDS)
|
||||
}
|
||||
|
||||
// drop drops all capabilities for the current process except those specified in the whitelist.
|
||||
func (w *whitelist) drop() error {
|
||||
w.pid.Clear(allCapabilityTypes)
|
||||
w.pid.Set(allCapabilityTypes, w.keep...)
|
||||
return w.pid.Apply(allCapabilityTypes)
|
||||
// Apply sets all the capabilities for the current process in the config.
|
||||
func (c *containerCapabilities) ApplyCaps() error {
|
||||
c.pid.Clear(allCapabilityTypes)
|
||||
c.pid.Set(capability.BOUNDS, c.bounding...)
|
||||
c.pid.Set(capability.PERMITTED, c.permitted...)
|
||||
c.pid.Set(capability.INHERITABLE, c.inheritable...)
|
||||
c.pid.Set(capability.EFFECTIVE, c.effective...)
|
||||
c.pid.Set(capability.AMBIENT, c.ambient...)
|
||||
return c.pid.Apply(allCapabilityTypes)
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
// +build !ambient,linux
|
||||
|
||||
package libcontainer
|
||||
|
||||
import "github.com/syndtr/gocapability/capability"
|
||||
|
||||
const allCapabilityTypes = capability.CAPS | capability.BOUNDS
|
|
@ -113,8 +113,8 @@ type Config struct {
|
|||
Namespaces Namespaces `json:"namespaces"`
|
||||
|
||||
// Capabilities specify the capabilities to keep when executing the process inside the container
|
||||
// All capbilities not specified will be dropped from the processes capability mask
|
||||
Capabilities []string `json:"capabilities"`
|
||||
// All capabilities not specified will be dropped from the processes capability mask
|
||||
Capabilities *Capabilities `json:"capabilities"`
|
||||
|
||||
// Networks specifies the container's network setup to be created
|
||||
Networks []*Network `json:"networks"`
|
||||
|
@ -197,6 +197,19 @@ type Hooks struct {
|
|||
Poststop []Hook
|
||||
}
|
||||
|
||||
type Capabilities struct {
|
||||
// Bounding is the set of capabilities checked by the kernel.
|
||||
Bounding []string
|
||||
// Effective is the set of capabilities checked by the kernel.
|
||||
Effective []string
|
||||
// Inheritable is the capabilities preserved across execve.
|
||||
Inheritable []string
|
||||
// Permitted is the limiting superset for effective capabilities.
|
||||
Permitted []string
|
||||
// Ambient is the ambient set of capabilities that are kept.
|
||||
Ambient []string
|
||||
}
|
||||
|
||||
func (hooks *Hooks) UnmarshalJSON(b []byte) error {
|
||||
var state struct {
|
||||
Prestart []CommandHook
|
||||
|
|
|
@ -120,10 +120,10 @@ func TestMarshalHooksWithUnexpectedType(t *testing.T) {
|
|||
|
||||
func TestFuncHookRun(t *testing.T) {
|
||||
state := configs.HookState{
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
BundlePath: "/bundle",
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
Bundle: "/bundle",
|
||||
}
|
||||
|
||||
fHook := configs.NewFunctionHook(func(s configs.HookState) error {
|
||||
|
@ -138,10 +138,10 @@ func TestFuncHookRun(t *testing.T) {
|
|||
|
||||
func TestCommandHookRun(t *testing.T) {
|
||||
state := configs.HookState{
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
BundlePath: "/bundle",
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
Bundle: "/bundle",
|
||||
}
|
||||
timeout := time.Second
|
||||
|
||||
|
@ -161,10 +161,10 @@ func TestCommandHookRun(t *testing.T) {
|
|||
|
||||
func TestCommandHookRunTimeout(t *testing.T) {
|
||||
state := configs.HookState{
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
BundlePath: "/bundle",
|
||||
Version: "1",
|
||||
ID: "1",
|
||||
Pid: 1,
|
||||
Bundle: "/bundle",
|
||||
}
|
||||
timeout := (10 * time.Millisecond)
|
||||
|
||||
|
|
|
@ -275,10 +275,10 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
|
|||
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
Pid: parent.pid(),
|
||||
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
Pid: parent.pid(),
|
||||
Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Poststart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
|
@ -1157,10 +1157,10 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
|||
case notify.GetScript() == "setup-namespaces":
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
Pid: int(notify.GetPid()),
|
||||
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
Pid: int(notify.GetPid()),
|
||||
Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
}
|
||||
for i, hook := range c.config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
|
|
|
@ -45,21 +45,21 @@ type network struct {
|
|||
|
||||
// initConfig is used for transferring parameters from Exec() to Init()
|
||||
type initConfig struct {
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Cwd string `json:"cwd"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
ProcessLabel string `json:"process_label"`
|
||||
AppArmorProfile string `json:"apparmor_profile"`
|
||||
NoNewPrivileges bool `json:"no_new_privileges"`
|
||||
User string `json:"user"`
|
||||
AdditionalGroups []string `json:"additional_groups"`
|
||||
Config *configs.Config `json:"config"`
|
||||
Networks []*network `json:"network"`
|
||||
PassedFilesCount int `json:"passed_files_count"`
|
||||
ContainerId string `json:"containerid"`
|
||||
Rlimits []configs.Rlimit `json:"rlimits"`
|
||||
CreateConsole bool `json:"create_console"`
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Cwd string `json:"cwd"`
|
||||
Capabilities *configs.Capabilities `json:"capabilities"`
|
||||
ProcessLabel string `json:"process_label"`
|
||||
AppArmorProfile string `json:"apparmor_profile"`
|
||||
NoNewPrivileges bool `json:"no_new_privileges"`
|
||||
User string `json:"user"`
|
||||
AdditionalGroups []string `json:"additional_groups"`
|
||||
Config *configs.Config `json:"config"`
|
||||
Networks []*network `json:"network"`
|
||||
PassedFilesCount int `json:"passed_files_count"`
|
||||
ContainerId string `json:"containerid"`
|
||||
Rlimits []configs.Rlimit `json:"rlimits"`
|
||||
CreateConsole bool `json:"create_console"`
|
||||
}
|
||||
|
||||
type initer interface {
|
||||
|
@ -121,12 +121,12 @@ func finalizeNamespace(config *initConfig) error {
|
|||
if config.Capabilities != nil {
|
||||
capabilities = config.Capabilities
|
||||
}
|
||||
w, err := newCapWhitelist(capabilities)
|
||||
w, err := newContainerCapList(capabilities)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// drop capabilities in bounding set before changing user
|
||||
if err := w.dropBoundingSet(); err != nil {
|
||||
if err := w.ApplyBoundingSet(); err != nil {
|
||||
return err
|
||||
}
|
||||
// preserve existing capabilities while we change users
|
||||
|
@ -139,8 +139,7 @@ func finalizeNamespace(config *initConfig) error {
|
|||
if err := system.ClearKeepCaps(); err != nil {
|
||||
return err
|
||||
}
|
||||
// drop all other capabilities
|
||||
if err := w.drop(); err != nil {
|
||||
if err := w.ApplyCaps(); err != nil {
|
||||
return err
|
||||
}
|
||||
if config.Cwd != "" {
|
||||
|
|
|
@ -357,17 +357,19 @@ func TestProcessCaps(t *testing.T) {
|
|||
ok(t, err)
|
||||
defer container.Destroy()
|
||||
|
||||
processCaps := append(config.Capabilities, "CAP_NET_ADMIN")
|
||||
|
||||
var stdout bytes.Buffer
|
||||
pconfig := libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"sh", "-c", "cat /proc/self/status"},
|
||||
Env: standardEnvironment,
|
||||
Capabilities: processCaps,
|
||||
Stdin: nil,
|
||||
Stdout: &stdout,
|
||||
Capabilities: &configs.Capabilities{},
|
||||
}
|
||||
pconfig.Capabilities.Bounding = append(config.Capabilities.Bounding, "CAP_NET_ADMIN")
|
||||
pconfig.Capabilities.Permitted = append(config.Capabilities.Permitted, "CAP_NET_ADMIN")
|
||||
pconfig.Capabilities.Effective = append(config.Capabilities.Effective, "CAP_NET_ADMIN")
|
||||
pconfig.Capabilities.Inheritable = append(config.Capabilities.Inheritable, "CAP_NET_ADMIN")
|
||||
err = container.Run(&pconfig)
|
||||
ok(t, err)
|
||||
|
||||
|
@ -1059,8 +1061,8 @@ func TestHook(t *testing.T) {
|
|||
defer remove(rootfs)
|
||||
|
||||
config := newTemplateConfig(rootfs)
|
||||
expectedBundlePath := bundle
|
||||
config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundlePath))
|
||||
expectedBundle := bundle
|
||||
config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundle))
|
||||
|
||||
getRootfsFromBundle := func(bundle string) (string, error) {
|
||||
f, err := os.Open(filepath.Join(bundle, "config.json"))
|
||||
|
@ -1078,11 +1080,11 @@ func TestHook(t *testing.T) {
|
|||
config.Hooks = &configs.Hooks{
|
||||
Prestart: []configs.Hook{
|
||||
configs.NewFunctionHook(func(s configs.HookState) error {
|
||||
if s.BundlePath != expectedBundlePath {
|
||||
t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
|
||||
if s.Bundle != expectedBundle {
|
||||
t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundle, s.Bundle)
|
||||
}
|
||||
|
||||
root, err := getRootfsFromBundle(s.BundlePath)
|
||||
root, err := getRootfsFromBundle(s.Bundle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1095,11 +1097,11 @@ func TestHook(t *testing.T) {
|
|||
},
|
||||
Poststart: []configs.Hook{
|
||||
configs.NewFunctionHook(func(s configs.HookState) error {
|
||||
if s.BundlePath != expectedBundlePath {
|
||||
t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
|
||||
if s.Bundle != expectedBundle {
|
||||
t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundle, s.Bundle)
|
||||
}
|
||||
|
||||
root, err := getRootfsFromBundle(s.BundlePath)
|
||||
root, err := getRootfsFromBundle(s.Bundle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1108,11 +1110,11 @@ func TestHook(t *testing.T) {
|
|||
},
|
||||
Poststop: []configs.Hook{
|
||||
configs.NewFunctionHook(func(s configs.HookState) error {
|
||||
if s.BundlePath != expectedBundlePath {
|
||||
t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
|
||||
if s.Bundle != expectedBundle {
|
||||
t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundle, s.Bundle)
|
||||
}
|
||||
|
||||
root, err := getRootfsFromBundle(s.BundlePath)
|
||||
root, err := getRootfsFromBundle(s.Bundle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1391,18 +1393,21 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
|
|||
stdinR2, stdinW2, err := os.Pipe()
|
||||
ok(t, err)
|
||||
|
||||
// Provide CAP_SYS_ADMIN
|
||||
processCaps := append(config.Capabilities, "CAP_SYS_ADMIN")
|
||||
|
||||
pconfig2 := &libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"mount", "--bind", dir2cont, dir2cont},
|
||||
Env: standardEnvironment,
|
||||
Stdin: stdinR2,
|
||||
Stdout: &stdout2,
|
||||
Capabilities: processCaps,
|
||||
Capabilities: &configs.Capabilities{},
|
||||
}
|
||||
|
||||
// Provide CAP_SYS_ADMIN
|
||||
pconfig2.Capabilities.Bounding = append(config.Capabilities.Bounding, "CAP_SYS_ADMIN")
|
||||
pconfig2.Capabilities.Permitted = append(config.Capabilities.Permitted, "CAP_SYS_ADMIN")
|
||||
pconfig2.Capabilities.Effective = append(config.Capabilities.Effective, "CAP_SYS_ADMIN")
|
||||
pconfig2.Capabilities.Inheritable = append(config.Capabilities.Inheritable, "CAP_SYS_ADMIN")
|
||||
|
||||
err = container.Run(pconfig2)
|
||||
stdinR2.Close()
|
||||
defer stdinW2.Close()
|
||||
|
|
|
@ -23,21 +23,87 @@ func newTemplateConfig(rootfs string) *configs.Config {
|
|||
allowAllDevices := false
|
||||
return &configs.Config{
|
||||
Rootfs: rootfs,
|
||||
Capabilities: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
Capabilities: &configs.Capabilities{
|
||||
Bounding: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Permitted: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Inheritable: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Ambient: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Effective: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
},
|
||||
Namespaces: configs.Namespaces([]configs.Namespace{
|
||||
{Type: configs.NEWNS},
|
||||
|
|
|
@ -53,7 +53,7 @@ type Process struct {
|
|||
|
||||
// Capabilities specify the capabilities to keep when executing the process inside the container
|
||||
// All capabilities not specified will be dropped from the processes capability mask
|
||||
Capabilities []string
|
||||
Capabilities *configs.Capabilities
|
||||
|
||||
// AppArmorProfile specifies the profile to apply to the process and is
|
||||
// changed at the time the process is execed
|
||||
|
|
|
@ -337,10 +337,10 @@ func (p *initProcess) start() error {
|
|||
if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
Version: p.container.config.Version,
|
||||
ID: p.container.id,
|
||||
Pid: p.pid(),
|
||||
BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
Version: p.container.config.Version,
|
||||
ID: p.container.id,
|
||||
Pid: p.pid(),
|
||||
Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
|
@ -357,10 +357,10 @@ func (p *initProcess) start() error {
|
|||
case procHooks:
|
||||
if p.config.Config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
Version: p.container.config.Version,
|
||||
ID: p.container.id,
|
||||
Pid: p.pid(),
|
||||
BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
Version: p.container.config.Version,
|
||||
ID: p.container.id,
|
||||
Pid: p.pid(),
|
||||
Bundle: utils.SearchLabels(p.config.Config.Labels, "bundle"),
|
||||
}
|
||||
for i, hook := range p.config.Config.Hooks.Prestart {
|
||||
if err := hook.Run(s); err != nil {
|
||||
|
|
|
@ -230,6 +230,15 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
|||
if spec.Linux.Resources != nil && spec.Linux.Resources.OOMScoreAdj != nil {
|
||||
config.OomScoreAdj = *spec.Linux.Resources.OOMScoreAdj
|
||||
}
|
||||
if spec.Process.Capabilities != nil {
|
||||
config.Capabilities = &configs.Capabilities{
|
||||
Bounding: spec.Process.Capabilities.Bounding,
|
||||
Effective: spec.Process.Capabilities.Effective,
|
||||
Permitted: spec.Process.Capabilities.Permitted,
|
||||
Inheritable: spec.Process.Capabilities.Inheritable,
|
||||
Ambient: spec.Process.Capabilities.Ambient,
|
||||
}
|
||||
}
|
||||
createHooks(spec, config)
|
||||
config.MountLabel = spec.Linux.MountLabel
|
||||
config.Version = specs.Version
|
||||
|
@ -262,10 +271,10 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
|
|||
Resources: &configs.Resources{},
|
||||
}
|
||||
|
||||
if spec.Linux != nil && spec.Linux.CgroupsPath != nil {
|
||||
myCgroupPath = libcontainerUtils.CleanPath(*spec.Linux.CgroupsPath)
|
||||
if spec.Linux != nil && spec.Linux.CgroupsPath != "" {
|
||||
myCgroupPath = libcontainerUtils.CleanPath(spec.Linux.CgroupsPath)
|
||||
if useSystemdCgroup {
|
||||
myCgroupPath = *spec.Linux.CgroupsPath
|
||||
myCgroupPath = spec.Linux.CgroupsPath
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,8 +315,8 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
|
|||
major = int64(-1)
|
||||
minor = int64(-1)
|
||||
)
|
||||
if d.Type != nil {
|
||||
t = *d.Type
|
||||
if d.Type != "" {
|
||||
t = d.Type
|
||||
}
|
||||
if d.Major != nil {
|
||||
major = *d.Major
|
||||
|
@ -315,7 +324,7 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
|
|||
if d.Minor != nil {
|
||||
minor = *d.Minor
|
||||
}
|
||||
if d.Access == nil || *d.Access == "" {
|
||||
if d.Access == "" {
|
||||
return nil, fmt.Errorf("device access at %d field cannot be empty", i)
|
||||
}
|
||||
dt, err := stringToCgroupDeviceRune(t)
|
||||
|
@ -326,7 +335,7 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
|
|||
Type: dt,
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Permissions: *d.Access,
|
||||
Permissions: d.Access,
|
||||
Allow: d.Allow,
|
||||
}
|
||||
c.Resources.Devices = append(c.Resources.Devices, dd)
|
||||
|
@ -370,11 +379,11 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
|
|||
if r.CPU.RealtimePeriod != nil {
|
||||
c.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
|
||||
}
|
||||
if r.CPU.Cpus != nil {
|
||||
c.Resources.CpusetCpus = *r.CPU.Cpus
|
||||
if r.CPU.Cpus != "" {
|
||||
c.Resources.CpusetCpus = r.CPU.Cpus
|
||||
}
|
||||
if r.CPU.Mems != nil {
|
||||
c.Resources.CpusetMems = *r.CPU.Mems
|
||||
if r.CPU.Mems != "" {
|
||||
c.Resources.CpusetMems = r.CPU.Mems
|
||||
}
|
||||
}
|
||||
if r.Pids != nil {
|
||||
|
@ -720,30 +729,30 @@ func setupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
newCall := configs.Syscall{
|
||||
Name: call.Name,
|
||||
Action: newAction,
|
||||
Args: []*configs.Arg{},
|
||||
}
|
||||
|
||||
// Loop through all the arguments of the syscall and convert them
|
||||
for _, arg := range call.Args {
|
||||
newOp, err := seccomp.ConvertStringToOperator(string(arg.Op))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for _, name := range call.Names {
|
||||
newCall := configs.Syscall{
|
||||
Name: name,
|
||||
Action: newAction,
|
||||
Args: []*configs.Arg{},
|
||||
}
|
||||
// Loop through all the arguments of the syscall and convert them
|
||||
for _, arg := range call.Args {
|
||||
newOp, err := seccomp.ConvertStringToOperator(string(arg.Op))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newArg := configs.Arg{
|
||||
Index: arg.Index,
|
||||
Value: arg.Value,
|
||||
ValueTwo: arg.ValueTwo,
|
||||
Op: newOp,
|
||||
newArg := configs.Arg{
|
||||
Index: arg.Index,
|
||||
Value: arg.Value,
|
||||
ValueTwo: arg.ValueTwo,
|
||||
Op: newOp,
|
||||
}
|
||||
|
||||
newCall.Args = append(newCall.Args, &newArg)
|
||||
}
|
||||
|
||||
newCall.Args = append(newCall.Args, &newArg)
|
||||
newConfig.Syscalls = append(newConfig.Syscalls, &newCall)
|
||||
}
|
||||
|
||||
newConfig.Syscalls = append(newConfig.Syscalls, &newCall)
|
||||
}
|
||||
|
||||
return newConfig, nil
|
||||
|
@ -751,17 +760,20 @@ func setupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) {
|
|||
|
||||
func createHooks(rspec *specs.Spec, config *configs.Config) {
|
||||
config.Hooks = &configs.Hooks{}
|
||||
for _, h := range rspec.Hooks.Prestart {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Prestart = append(config.Hooks.Prestart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststart {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststart = append(config.Hooks.Poststart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststop {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststop = append(config.Hooks.Poststop, configs.NewCommandHook(cmd))
|
||||
if rspec.Hooks != nil {
|
||||
|
||||
for _, h := range rspec.Hooks.Prestart {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Prestart = append(config.Hooks.Prestart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststart {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststart = append(config.Hooks.Poststart, configs.NewCommandHook(cmd))
|
||||
}
|
||||
for _, h := range rspec.Hooks.Poststop {
|
||||
cmd := createCommandHook(h)
|
||||
config.Hooks.Poststop = append(config.Hooks.Poststop, configs.NewCommandHook(cmd))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) {
|
|||
|
||||
spec := &specs.Spec{}
|
||||
spec.Linux = &specs.Linux{
|
||||
CgroupsPath: &cgroupsPath,
|
||||
CgroupsPath: cgroupsPath,
|
||||
}
|
||||
|
||||
cgroup, err := createCgroupConfig("ContainerID", false, spec)
|
||||
|
|
|
@ -58,9 +58,9 @@ func destroy(c *linuxContainer) error {
|
|||
func runPoststopHooks(c *linuxContainer) error {
|
||||
if c.config.Hooks != nil {
|
||||
s := configs.HookState{
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
Version: c.config.Version,
|
||||
ID: c.id,
|
||||
Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
|
||||
}
|
||||
for _, hook := range c.config.Hooks.Poststop {
|
||||
if err := hook.Run(s); err != nil {
|
||||
|
|
32
spec.go
32
spec.go
|
@ -90,10 +90,32 @@ container on your host.`,
|
|||
},
|
||||
Cwd: "/",
|
||||
NoNewPrivileges: true,
|
||||
Capabilities: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
Capabilities: &specs.LinuxCapabilities{
|
||||
Bounding: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
},
|
||||
Permitted: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
},
|
||||
Inheritable: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
},
|
||||
Ambient: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
},
|
||||
Effective: []string{
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
},
|
||||
},
|
||||
Rlimits: []specs.LinuxRlimit{
|
||||
{
|
||||
|
@ -169,7 +191,7 @@ container on your host.`,
|
|||
Devices: []specs.LinuxDeviceCgroup{
|
||||
{
|
||||
Allow: false,
|
||||
Access: sPtr("rwm"),
|
||||
Access: "rwm",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
35
update.go
35
update.go
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func i64Ptr(i int64) *int64 { return &i }
|
||||
func u64Ptr(i uint64) *uint64 { return &i }
|
||||
func u16Ptr(i uint16) *uint16 { return &i }
|
||||
|
||||
|
@ -127,12 +128,12 @@ other options are ignored.
|
|||
},
|
||||
CPU: &specs.LinuxCPU{
|
||||
Shares: u64Ptr(0),
|
||||
Quota: u64Ptr(0),
|
||||
Quota: i64Ptr(0),
|
||||
Period: u64Ptr(0),
|
||||
RealtimeRuntime: u64Ptr(0),
|
||||
RealtimeRuntime: i64Ptr(0),
|
||||
RealtimePeriod: u64Ptr(0),
|
||||
Cpus: sPtr(""),
|
||||
Mems: sPtr(""),
|
||||
Cpus: "",
|
||||
Mems: "",
|
||||
},
|
||||
BlockIO: &specs.LinuxBlockIO{
|
||||
Weight: u16Ptr(0),
|
||||
|
@ -164,10 +165,10 @@ other options are ignored.
|
|||
r.BlockIO.Weight = u16Ptr(uint16(val))
|
||||
}
|
||||
if val := context.String("cpuset-cpus"); val != "" {
|
||||
r.CPU.Cpus = &val
|
||||
r.CPU.Cpus = val
|
||||
}
|
||||
if val := context.String("cpuset-mems"); val != "" {
|
||||
r.CPU.Mems = &val
|
||||
r.CPU.Mems = val
|
||||
}
|
||||
|
||||
for _, pair := range []struct {
|
||||
|
@ -176,9 +177,7 @@ other options are ignored.
|
|||
}{
|
||||
|
||||
{"cpu-period", r.CPU.Period},
|
||||
{"cpu-quota", r.CPU.Quota},
|
||||
{"cpu-rt-period", r.CPU.RealtimePeriod},
|
||||
{"cpu-rt-runtime", r.CPU.RealtimeRuntime},
|
||||
{"cpu-share", r.CPU.Shares},
|
||||
} {
|
||||
if val := context.String(pair.opt); val != "" {
|
||||
|
@ -189,6 +188,22 @@ other options are ignored.
|
|||
}
|
||||
}
|
||||
}
|
||||
for _, pair := range []struct {
|
||||
opt string
|
||||
dest *int64
|
||||
}{
|
||||
|
||||
{"cpu-quota", r.CPU.Quota},
|
||||
{"cpu-rt-runtime", r.CPU.RealtimeRuntime},
|
||||
} {
|
||||
if val := context.String(pair.opt); val != "" {
|
||||
var err error
|
||||
*pair.dest, err = strconv.ParseInt(val, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid value for %s: %s", pair.opt, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, pair := range []struct {
|
||||
opt string
|
||||
dest *uint64
|
||||
|
@ -222,8 +237,8 @@ other options are ignored.
|
|||
config.Cgroups.Resources.CpuShares = int64(*r.CPU.Shares)
|
||||
config.Cgroups.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
|
||||
config.Cgroups.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
|
||||
config.Cgroups.Resources.CpusetCpus = *r.CPU.Cpus
|
||||
config.Cgroups.Resources.CpusetMems = *r.CPU.Mems
|
||||
config.Cgroups.Resources.CpusetCpus = r.CPU.Cpus
|
||||
config.Cgroups.Resources.CpusetMems = r.CPU.Mems
|
||||
config.Cgroups.Resources.KernelMemory = int64(*r.Memory.Kernel)
|
||||
config.Cgroups.Resources.KernelMemoryTCP = int64(*r.Memory.KernelTCP)
|
||||
config.Cgroups.Resources.Memory = int64(*r.Memory.Limit)
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/coreos/go-systemd/activation"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/specconv"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -77,11 +78,18 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
|
|||
// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
|
||||
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
|
||||
Cwd: p.Cwd,
|
||||
Capabilities: p.Capabilities,
|
||||
Label: p.SelinuxLabel,
|
||||
NoNewPrivileges: &p.NoNewPrivileges,
|
||||
AppArmorProfile: p.ApparmorProfile,
|
||||
}
|
||||
if p.Capabilities != nil {
|
||||
lp.Capabilities = &configs.Capabilities{}
|
||||
lp.Capabilities.Bounding = p.Capabilities.Bounding
|
||||
lp.Capabilities.Effective = p.Capabilities.Effective
|
||||
lp.Capabilities.Inheritable = p.Capabilities.Inheritable
|
||||
lp.Capabilities.Permitted = p.Capabilities.Permitted
|
||||
lp.Capabilities.Ambient = p.Capabilities.Ambient
|
||||
}
|
||||
for _, gid := range p.User.AdditionalGids {
|
||||
lp.AdditionalGroups = append(lp.AdditionalGroups, strconv.FormatUint(uint64(gid), 10))
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ github.com/docker/go-units 9b001659dd36225e356b4467c465d732e745f53d
|
|||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
github.com/golang/protobuf/proto f7137ae6b19afbfd61a94b746fda3b3fe0491874
|
||||
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
|
||||
github.com/opencontainers/runtime-spec/specs-go 794ca7ac88234607f9d2c76da8a6e9bbbade8cb9
|
||||
github.com/opencontainers/runtime-spec/specs-go 035da1dca3dfbb00d752eb58b0b158d6129f3776
|
||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||
github.com/syndtr/gocapability/capability e7cb7fa329f456b3855136a2642b197bad7366ba
|
||||
github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
# Open Container Initiative Runtime Specification
|
||||
|
||||
The [Open Container Initiative](http://www.opencontainers.org/) develops specifications for standards on Operating System process and application containers.
|
||||
The [Open Container Initiative][oci] develops specifications for standards on Operating System process and application containers.
|
||||
|
||||
The specification can be found [here](spec.md).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
Additional documentation about how this group operates:
|
||||
|
||||
- [Code of Conduct](https://github.com/opencontainers/tob/blob/d2f9d68c1332870e40693fe077d311e0742bc73d/code-of-conduct.md)
|
||||
- [Code of Conduct][code-of-conduct]
|
||||
- [Style and Conventions](style.md)
|
||||
- [Roadmap](ROADMAP.md)
|
||||
- [Implementations](implementations.md)
|
||||
|
@ -14,38 +16,38 @@ Additional documentation about how this group operates:
|
|||
- [project](project.md)
|
||||
- [charter][charter]
|
||||
|
||||
# Use Cases
|
||||
## Use Cases
|
||||
|
||||
To provide context for users the following section gives example use cases for each part of the spec.
|
||||
|
||||
#### Application Bundle Builders
|
||||
### Application Bundle Builders
|
||||
|
||||
Application bundle builders can create a [bundle](bundle.md) directory that includes all of the files required for launching an application as a container.
|
||||
The bundle contains an OCI [configuration file](config.md) where the builder can specify host-independent details such as [which executable to launch](config.md#process) and host-specific settings such as [mount](config.md#mounts) locations, [hook](config.md#hooks) paths, Linux [namespaces](config-linux.md#namespaces) and [cgroups](config-linux.md#control-groups).
|
||||
Because the configuration includes host-specific settings, application bundle directories copied between two hosts may require configuration adjustments.
|
||||
|
||||
#### Hook Developers
|
||||
### Hook Developers
|
||||
|
||||
[Hook](config.md#hooks) developers can extend the functionality of an OCI-compliant runtime by hooking into a container's lifecycle with an external application.
|
||||
Example use cases include sophisticated network configuration, volume garbage collection, etc.
|
||||
|
||||
#### Runtime Developers
|
||||
### Runtime Developers
|
||||
|
||||
Runtime developers can build runtime implementations that run OCI-compliant bundles and container configuration, containing low-level OS and host specific details, on a particular platform.
|
||||
|
||||
# Releases
|
||||
## Releases
|
||||
|
||||
There is a loose [Road Map](./ROADMAP.md).
|
||||
During the `0.x` series of OCI releases we make no backwards compatibility guarantees and intend to break the schema during this series.
|
||||
|
||||
# Contributing
|
||||
## Contributing
|
||||
|
||||
Development happens on GitHub for the spec.
|
||||
Issues are used for bugs and actionable items and longer discussions can happen on the [mailing list](#mailing-list).
|
||||
|
||||
The specification and code is licensed under the Apache 2.0 license found in the [LICENSE](./LICENSE) file.
|
||||
|
||||
## Discuss your design
|
||||
### Discuss your design
|
||||
|
||||
The project welcomes submissions, but please let everyone know what you are working on.
|
||||
|
||||
|
@ -56,27 +58,27 @@ It also guarantees that the design is sound before code is written; a GitHub pul
|
|||
Typos and grammatical errors can go straight to a pull-request.
|
||||
When in doubt, start on the [mailing-list](#mailing-list).
|
||||
|
||||
## Weekly Call
|
||||
### Weekly Call
|
||||
|
||||
The contributors and maintainers of all OCI projects have a weekly meeting Wednesdays at 2:00 PM (USA Pacific).
|
||||
Everyone is welcome to participate via [UberConference web][UberConference] or audio-only: 415-968-0849 (no PIN needed.)
|
||||
Everyone is welcome to participate via [UberConference web][uberconference] or audio-only: 415-968-0849 (no PIN needed.)
|
||||
An initial agenda will be posted to the [mailing list](#mailing-list) earlier in the week, and everyone is welcome to propose additional topics or suggest other agenda alterations there.
|
||||
Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived to the [wiki](https://github.com/opencontainers/runtime-spec/wiki) for those who are unable to join the call.
|
||||
Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived to the [wiki][runtime-wiki].
|
||||
|
||||
## Mailing List
|
||||
### Mailing List
|
||||
|
||||
You can subscribe and join the mailing list on [Google Groups](https://groups.google.com/a/opencontainers.org/forum/#!forum/dev).
|
||||
You can subscribe and join the mailing list on [Google Groups][dev-list].
|
||||
|
||||
## IRC
|
||||
### IRC
|
||||
|
||||
OCI discussion happens on #opencontainers on Freenode ([logs][irc-logs]).
|
||||
|
||||
## Git commit
|
||||
### Git commit
|
||||
|
||||
### Sign your work
|
||||
#### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch.
|
||||
The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
|
||||
The rules are pretty simple: if you can certify the below (from http://developercertificate.org):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
|
@ -125,10 +127,10 @@ using your real name (sorry, no pseudonyms or anonymous contributions.)
|
|||
|
||||
You can add the sign off when creating the git commit via `git commit -s`.
|
||||
|
||||
### Commit Style
|
||||
#### Commit Style
|
||||
|
||||
Simple house-keeping for clean git history.
|
||||
Read more on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) or the Discussion section of [`git-commit(1)`](http://git-scm.com/docs/git-commit).
|
||||
Read more on [How to Write a Git Commit Message][how-to-git-commit] or the Discussion section of [git-commit(1)][git-commit.1].
|
||||
|
||||
1. Separate the subject from body with a blank line
|
||||
2. Limit the subject line to 50 characters
|
||||
|
@ -140,6 +142,14 @@ Read more on [How to Write a Git Commit Message](http://chris.beams.io/posts/git
|
|||
* If there was important/useful/essential conversation or information, copy or include a reference
|
||||
8. When possible, one keyword to scope the change in the subject (i.e. "README: ...", "runtime: ...")
|
||||
|
||||
[UberConference]: https://www.uberconference.com/opencontainers
|
||||
[irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
|
||||
|
||||
[charter]: https://www.opencontainers.org/about/governance
|
||||
[code-of-conduct]: https://github.com/opencontainers/tob/blob/master/code-of-conduct.md
|
||||
[dev-list]: https://groups.google.com/a/opencontainers.org/forum/#!forum/dev
|
||||
[how-to-git-commit]: http://chris.beams.io/posts/git-commit
|
||||
[irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
|
||||
[oci]: https://www.opencontainers.org
|
||||
[runtime-wiki]: https://github.com/opencontainers/runtime-spec/wiki
|
||||
[uberconference]: https://www.uberconference.com/opencontainers
|
||||
|
||||
[git-commit.1]: http://git-scm.com/docs/git-commit
|
||||
|
|
|
@ -17,7 +17,7 @@ type Spec struct {
|
|||
// Mounts configures additional mounts (on top of Root).
|
||||
Mounts []Mount `json:"mounts,omitempty"`
|
||||
// Hooks configures callbacks for container lifecycle events.
|
||||
Hooks Hooks `json:"hooks"`
|
||||
Hooks *Hooks `json:"hooks,omitempty"`
|
||||
// Annotations contains arbitrary metadata for the container.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
|
@ -44,8 +44,8 @@ type Process struct {
|
|||
// Cwd is the current working directory for the process and must be
|
||||
// relative to the container's root.
|
||||
Cwd string `json:"cwd"`
|
||||
// Capabilities are Linux capabilities that are kept for the container.
|
||||
Capabilities []string `json:"capabilities,omitempty" platform:"linux"`
|
||||
// Capabilities are Linux capabilities that are kept for the process.
|
||||
Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
|
||||
// Rlimits specifies rlimit options to apply to the process.
|
||||
Rlimits []LinuxRlimit `json:"rlimits,omitempty" platform:"linux"`
|
||||
// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
|
||||
|
@ -56,6 +56,21 @@ type Process struct {
|
|||
SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process.
|
||||
// http://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
type LinuxCapabilities struct {
|
||||
// Bounding is the set of capabilities checked by the kernel.
|
||||
Bounding []string `json:"bounding,omitempty" platform:"linux"`
|
||||
// Effective is the set of capabilities checked by the kernel.
|
||||
Effective []string `json:"effective,omitempty" platform:"linux"`
|
||||
// Inheritable is the capabilities preserved across execve.
|
||||
Inheritable []string `json:"inheritable,omitempty" platform:"linux"`
|
||||
// Permitted is the limiting superset for effective capabilities.
|
||||
Permitted []string `json:"permitted,omitempty" platform:"linux"`
|
||||
// Ambient is the ambient set of capabilities that are kept.
|
||||
Ambient []string `json:"ambient,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
// Box specifies dimensions of a rectangle. Used for specifying the size of a console.
|
||||
type Box struct {
|
||||
// Height is the vertical dimension of a box.
|
||||
|
@ -98,10 +113,10 @@ type Mount struct {
|
|||
// Destination is the path where the mount will be placed relative to the container's root. The path and child directories MUST exist, a runtime MUST NOT create directories automatically to a mount point.
|
||||
Destination string `json:"destination"`
|
||||
// Type specifies the mount kind.
|
||||
Type string `json:"type"`
|
||||
Type string `json:"type,omitempty"`
|
||||
// Source specifies the source path of the mount. In the case of bind mounts on
|
||||
// Linux based systems this would be the file on the host.
|
||||
Source string `json:"source"`
|
||||
Source string `json:"source,omitempty"`
|
||||
// Options are fstab style mount options.
|
||||
Options []string `json:"options,omitempty"`
|
||||
}
|
||||
|
@ -139,7 +154,7 @@ type Linux struct {
|
|||
// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
|
||||
// The path is expected to be relative to the cgroups mountpoint.
|
||||
// If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
|
||||
CgroupsPath *string `json:"cgroupsPath,omitempty"`
|
||||
CgroupsPath string `json:"cgroupsPath,omitempty"`
|
||||
// Namespaces contains the namespaces that are created and/or joined by the container
|
||||
Namespaces []LinuxNamespace `json:"namespaces,omitempty"`
|
||||
// Devices are a list of device nodes that are created for the container
|
||||
|
@ -284,17 +299,17 @@ type LinuxCPU struct {
|
|||
// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
|
||||
Shares *uint64 `json:"shares,omitempty"`
|
||||
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
||||
Quota *uint64 `json:"quota,omitempty"`
|
||||
Quota *int64 `json:"quota,omitempty"`
|
||||
// CPU period to be used for hardcapping (in usecs).
|
||||
Period *uint64 `json:"period,omitempty"`
|
||||
// How much time realtime scheduling may use (in usecs).
|
||||
RealtimeRuntime *uint64 `json:"realtimeRuntime,omitempty"`
|
||||
RealtimeRuntime *int64 `json:"realtimeRuntime,omitempty"`
|
||||
// CPU period to be used for realtime scheduling (in usecs).
|
||||
RealtimePeriod *uint64 `json:"realtimePeriod,omitempty"`
|
||||
// CPUs to use within the cpuset. Default is to use any CPU available.
|
||||
Cpus *string `json:"cpus,omitempty"`
|
||||
Cpus string `json:"cpus,omitempty"`
|
||||
// List of memory nodes in the cpuset. Default is to use any available memory node.
|
||||
Mems *string `json:"mems,omitempty"`
|
||||
Mems string `json:"mems,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
|
||||
|
@ -356,20 +371,13 @@ type LinuxDeviceCgroup struct {
|
|||
// Allow or deny
|
||||
Allow bool `json:"allow"`
|
||||
// Device type, block, char, etc.
|
||||
Type *string `json:"type,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
// Major is the device's major number.
|
||||
Major *int64 `json:"major,omitempty"`
|
||||
// Minor is the device's minor number.
|
||||
Minor *int64 `json:"minor,omitempty"`
|
||||
// Cgroup access permissions format, rwm.
|
||||
Access *string `json:"access,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxSeccomp represents syscall restrictions
|
||||
type LinuxSeccomp struct {
|
||||
DefaultAction LinuxSeccompAction `json:"defaultAction"`
|
||||
Architectures []Arch `json:"architectures"`
|
||||
Syscalls []LinuxSyscall `json:"syscalls,omitempty"`
|
||||
Access string `json:"access,omitempty"`
|
||||
}
|
||||
|
||||
// Solaris contains platform specific configuration for Solaris application containers.
|
||||
|
@ -469,6 +477,13 @@ type WindowsNetworkResources struct {
|
|||
EgressBandwidth *uint64 `json:"egressBandwidth,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxSeccomp represents syscall restrictions
|
||||
type LinuxSeccomp struct {
|
||||
DefaultAction LinuxSeccompAction `json:"defaultAction"`
|
||||
Architectures []Arch `json:"architectures,omitempty"`
|
||||
Syscalls []LinuxSyscall `json:"syscalls"`
|
||||
}
|
||||
|
||||
// Arch used for additional architectures
|
||||
type Arch string
|
||||
|
||||
|
@ -491,6 +506,8 @@ const (
|
|||
ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE"
|
||||
ArchS390 Arch = "SCMP_ARCH_S390"
|
||||
ArchS390X Arch = "SCMP_ARCH_S390X"
|
||||
ArchPARISC Arch = "SCMP_ARCH_PARISC"
|
||||
ArchPARISC64 Arch = "SCMP_ARCH_PARISC64"
|
||||
)
|
||||
|
||||
// LinuxSeccompAction taken upon Seccomp rule match
|
||||
|
@ -529,7 +546,8 @@ type LinuxSeccompArg struct {
|
|||
|
||||
// LinuxSyscall is used to match a syscall in Seccomp
|
||||
type LinuxSyscall struct {
|
||||
Name string `json:"name"`
|
||||
Action LinuxSeccompAction `json:"action"`
|
||||
Args []LinuxSeccompArg `json:"args,omitempty"`
|
||||
Names []string `json:"names"`
|
||||
Action LinuxSeccompAction `json:"action"`
|
||||
Args []LinuxSeccompArg `json:"args"`
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ type State struct {
|
|||
Version string `json:"ociVersion"`
|
||||
// ID is the container ID
|
||||
ID string `json:"id"`
|
||||
// Status is the runtime state of the container.
|
||||
// Status is the runtime status of the container.
|
||||
Status string `json:"status"`
|
||||
// Pid is the process ID for the container process.
|
||||
Pid int `json:"pid"`
|
||||
// BundlePath is the path to the container's bundle directory.
|
||||
BundlePath string `json:"bundlePath"`
|
||||
// Annotations are the annotations associated with the container.
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
// Bundle is the path to the container's bundle directory.
|
||||
Bundle string `json:"bundle"`
|
||||
// Annotations are key values associated with the container.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ const (
|
|||
VersionPatch = 0
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = "-rc3"
|
||||
VersionDev = "-rc5"
|
||||
)
|
||||
|
||||
// Version is the specification version that the package types support.
|
||||
|
|
Loading…
Reference in New Issue