Skip to content

Commit

Permalink
Merge pull request openshift#51 from crosbymichael/type-context
Browse files Browse the repository at this point in the history
Strongly type context on the Config
  • Loading branch information
vmarmol committed Jun 25, 2014
2 parents 5210a23 + 43e877e commit e49f5f4
Show file tree
Hide file tree
Showing 9 changed files with 464 additions and 27 deletions.
17 changes: 11 additions & 6 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,17 @@ type Config struct {
// placed into to limit the resources the container has available
Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"`

// Context is a generic key value format that allows for additional settings to be passed
// on the container's creation
// This is commonly used to specify apparmor profiles, selinux labels, and different restrictions
// placed on the container's processes
// TODO(vishh): Avoid overloading this field with params for different subsystems. Strongtype this.
Context map[string]string `json:"context,omitempty"`
// AppArmorProfile specifies the profile to apply to the process running in the container and is
// change at the time the process is execed
AppArmorProfile string `json:"apparmor_profile,omitempty"`

// ProcessLabel specifies the label to apply to the process running in the container. It is
// commonly used by selinux
ProcessLabel string `json:"process_label,omitempty"`

// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
// /proc/bus
RestrictSys bool `json:"restrict_sys,omitempty"`
}

// Routes can be specified to create entries in the route table as the container is started
Expand Down
52 changes: 47 additions & 5 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package libcontainer
import (
"encoding/json"
"os"
"path/filepath"
"testing"

"github.com/docker/libcontainer/devices"
Expand Down Expand Up @@ -32,17 +33,27 @@ func containsDevice(expected *devices.Device, values []*devices.Device) bool {
return false
}

func TestConfigJsonFormat(t *testing.T) {
f, err := os.Open("sample_configs/attach_to_bridge.json")
func loadConfig(name string) (*Config, error) {
f, err := os.Open(filepath.Join("sample_configs", name))
if err != nil {
t.Fatal("Unable to open container.json")
return nil, err
}
defer f.Close()

var container *Config
if err := json.NewDecoder(f).Decode(&container); err != nil {
t.Fatalf("failed to decode container config: %s", err)
return nil, err
}

return container, nil
}

func TestConfigJsonFormat(t *testing.T) {
container, err := loadConfig("attach_to_bridge.json")
if err != nil {
t.Fatal(err)
}

if container.Hostname != "koye" {
t.Log("hostname is not set")
t.Fail()
Expand Down Expand Up @@ -111,8 +122,39 @@ func TestConfigJsonFormat(t *testing.T) {

for _, d := range devices.DefaultSimpleDevices {
if !containsDevice(d, container.MountConfig.DeviceNodes) {
t.Logf("expected defice configuration for %s", d.Path)
t.Logf("expected device configuration for %s", d.Path)
t.Fail()
}
}

if !container.RestrictSys {
t.Log("expected restrict sys to be true")
t.Fail()
}
}

func TestApparmorProfile(t *testing.T) {
container, err := loadConfig("apparmor.json")
if err != nil {
t.Fatal(err)
}

if container.AppArmorProfile != "docker-default" {
t.Fatalf("expected apparmor profile to be docker-default but received %q", container.AppArmorProfile)
}
}

func TestSelinuxLabels(t *testing.T) {
container, err := loadConfig("selinux.json")
if err != nil {
t.Fatal(err)
}
label := "system_u:system_r:svirt_lxc_net_t:s0:c164,c475"

if container.ProcessLabel != label {
t.Fatalf("expected process label %q but received %q", label, container.ProcessLabel)
}
if container.MountConfig.MountLabel != label {
t.Fatalf("expected mount label %q but received %q", label, container.MountConfig.MountLabel)
}
}
1 change: 1 addition & 0 deletions mount/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mount

import (
"errors"

"github.com/docker/libcontainer/devices"
)

Expand Down
4 changes: 2 additions & 2 deletions namespaces/execin.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func NsEnter(container *libcontainer.Config, nspid int, args []string) error {
return err
}

if process_label, ok := container.Context["process_label"]; ok {
if err := label.SetProcessLabel(process_label); err != nil {
if container.ProcessLabel != "" {
if err := label.SetProcessLabel(container.ProcessLabel); err != nil {
return err
}
}
Expand Down
12 changes: 8 additions & 4 deletions namespaces/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
(*mount.MountConfig)(container.MountConfig)); err != nil {
return fmt.Errorf("setup mount namespace %s", err)
}

if container.Hostname != "" {
if err := system.Sethostname(container.Hostname); err != nil {
return fmt.Errorf("sethostname %s", err)
Expand All @@ -82,13 +83,16 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn

runtime.LockOSThread()

if err := apparmor.ApplyProfile(container.Context["apparmor_profile"]); err != nil {
return fmt.Errorf("set apparmor profile %s: %s", container.Context["apparmor_profile"], err)
if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil {
return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err)
}
if err := label.SetProcessLabel(container.Context["process_label"]); err != nil {

if err := label.SetProcessLabel(container.ProcessLabel); err != nil {
return fmt.Errorf("set process label %s", err)
}
if container.Context["restrictions"] != "" {

// TODO: (crosbymichael) make this configurable at the Config level
if container.RestrictSys {
if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus", "sys"); err != nil {
return err
}
Expand Down
196 changes: 196 additions & 0 deletions sample_configs/apparmor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
{
"capabilities": [
"CHOWN",
"DAC_OVERRIDE",
"FOWNER",
"MKNOD",
"NET_RAW",
"SETGID",
"SETUID",
"SETFCAP",
"SETPCAP",
"NET_BIND_SERVICE",
"SYS_CHROOT",
"KILL"
],
"cgroups": {
"allowed_devices": [
{
"cgroup_permissions": "m",
"major_number": -1,
"minor_number": -1,
"type": 99
},
{
"cgroup_permissions": "m",
"major_number": -1,
"minor_number": -1,
"type": 98
},
{
"cgroup_permissions": "rwm",
"major_number": 5,
"minor_number": 1,
"path": "/dev/console",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 4,
"path": "/dev/tty0",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 4,
"minor_number": 1,
"path": "/dev/tty1",
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 136,
"minor_number": -1,
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 5,
"minor_number": 2,
"type": 99
},
{
"cgroup_permissions": "rwm",
"major_number": 10,
"minor_number": 200,
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 3,
"path": "/dev/null",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 5,
"path": "/dev/zero",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 7,
"path": "/dev/full",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 5,
"path": "/dev/tty",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 9,
"path": "/dev/urandom",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 8,
"path": "/dev/random",
"type": 99
}
],
"name": "docker-koye",
"parent": "docker"
},
"restrict_sys": true,
"apparmor_profile": "docker-default",
"mount_config": {
"device_nodes": [
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 3,
"path": "/dev/null",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 5,
"path": "/dev/zero",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 7,
"path": "/dev/full",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 5,
"path": "/dev/tty",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 9,
"path": "/dev/urandom",
"type": 99
},
{
"cgroup_permissions": "rwm",
"file_mode": 438,
"major_number": 1,
"minor_number": 8,
"path": "/dev/random",
"type": 99
}
]
},
"environment": [
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"HOSTNAME=koye",
"TERM=xterm"
],
"hostname": "koye",
"namespaces": {
"NEWIPC": true,
"NEWNET": true,
"NEWNS": true,
"NEWPID": true,
"NEWUTS": true
},
"networks": [
{
"address": "127.0.0.1/0",
"gateway": "localhost",
"mtu": 1500,
"type": "loopback"
}
],
"tty": true,
"user": "daemon"
}
6 changes: 1 addition & 5 deletions sample_configs/attach_to_bridge.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@
"name": "docker-koye",
"parent": "docker"
},
"context": {
"mount_label": "",
"process_label": "",
"restrictions": "true"
},
"restrict_sys": true,
"mount_config": {
"device_nodes": [
{
Expand Down
6 changes: 1 addition & 5 deletions sample_configs/minimal.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@
"name": "docker-koye",
"parent": "docker"
},
"context": {
"mount_label": "",
"process_label": "",
"restrictions": "true"
},
"restrict_sys": true,
"mount_config": {
"device_nodes": [
{
Expand Down

0 comments on commit e49f5f4

Please sign in to comment.