summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers_remote.go1
-rw-r--r--pkg/apparmor/apparmor_linux.go13
-rw-r--r--pkg/apparmor/apparmor_linux_test.go17
-rw-r--r--pkg/apparmor/apparmor_unsupported.go5
-rw-r--r--pkg/namespaces/namespaces.go57
-rw-r--r--pkg/spec/createconfig.go19
-rw-r--r--pkg/spec/spec.go21
-rw-r--r--pkg/varlinkapi/containers.go54
-rw-r--r--pkg/varlinkapi/util.go2
9 files changed, 159 insertions, 30 deletions
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index 5836d0788..c816fd980 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -493,6 +493,7 @@ func (r *LocalRuntime) Ps(c *cliconfig.PsValues, opts shared.PsOptions) ([]share
NoTrunc: &c.NoTrunct,
Pod: &c.Pod,
Quiet: &c.Quiet,
+ Size: &c.Size,
Sort: &c.Sort,
Sync: &c.Sync,
}
diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go
index 0d01f41e9..479600408 100644
--- a/pkg/apparmor/apparmor_linux.go
+++ b/pkg/apparmor/apparmor_linux.go
@@ -4,6 +4,7 @@ package apparmor
import (
"bufio"
+ "bytes"
"fmt"
"io"
"os"
@@ -104,6 +105,18 @@ func InstallDefault(name string) error {
return cmd.Wait()
}
+// DefaultContent returns the default profile content as byte slice. The
+// profile is named as the provided `name`. The function errors if the profile
+// generation fails.
+func DefaultContent(name string) ([]byte, error) {
+ p := profileData{Name: name}
+ var bytes bytes.Buffer
+ if err := p.generateDefault(&bytes); err != nil {
+ return nil, err
+ }
+ return bytes.Bytes(), nil
+}
+
// IsLoaded checks if a profile with the given name has been loaded into the
// kernel.
func IsLoaded(name string) (bool, error) {
diff --git a/pkg/apparmor/apparmor_linux_test.go b/pkg/apparmor/apparmor_linux_test.go
index ac3260723..e94293d87 100644
--- a/pkg/apparmor/apparmor_linux_test.go
+++ b/pkg/apparmor/apparmor_linux_test.go
@@ -78,10 +78,12 @@ Copyright 2009-2012 Canonical Ltd.
}
}
-func TestInstallDefault(t *testing.T) {
- profile := "libpod-default-testing"
- aapath := "/sys/kernel/security/apparmor/"
+const (
+ aapath = "/sys/kernel/security/apparmor/"
+ profile = "libpod-default-testing"
+)
+func TestInstallDefault(t *testing.T) {
if _, err := os.Stat(aapath); err != nil {
t.Skip("AppArmor isn't available in this environment")
}
@@ -127,3 +129,12 @@ func TestInstallDefault(t *testing.T) {
}
checkLoaded(false)
}
+
+func TestDefaultContent(t *testing.T) {
+ if _, err := os.Stat(aapath); err != nil {
+ t.Skip("AppArmor isn't available in this environment")
+ }
+ if err := DefaultContent(profile); err != nil {
+ t.Fatalf("Couldn't retrieve default AppArmor profile content '%s': %v", profile, err)
+ }
+}
diff --git a/pkg/apparmor/apparmor_unsupported.go b/pkg/apparmor/apparmor_unsupported.go
index b2b4de5f5..13469f1b6 100644
--- a/pkg/apparmor/apparmor_unsupported.go
+++ b/pkg/apparmor/apparmor_unsupported.go
@@ -24,3 +24,8 @@ func CheckProfileAndLoadDefault(name string) (string, error) {
}
return "", ErrApparmorUnsupported
}
+
+// DefaultContent dummy.
+func DefaultContent(name string) ([]byte, error) {
+ return nil, nil
+}
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index ec9276344..7ed95bd0f 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -4,6 +4,63 @@ import (
"strings"
)
+// CgroupMode represents cgroup mode in the container.
+type CgroupMode string
+
+// IsHost indicates whether the container uses the host's cgroup.
+func (n CgroupMode) IsHost() bool {
+ return n == "host"
+}
+
+// IsNS indicates a cgroup namespace passed in by path (ns:<path>)
+func (n CgroupMode) IsNS() bool {
+ return strings.HasPrefix(string(n), "ns:")
+}
+
+// NS gets the path associated with a ns:<path> cgroup ns
+func (n CgroupMode) NS() string {
+ parts := strings.SplitN(string(n), ":", 2)
+ if len(parts) > 1 {
+ return parts[1]
+ }
+ return ""
+}
+
+// IsContainer indicates whether the container uses a new cgroup namespace.
+func (n CgroupMode) IsContainer() bool {
+ parts := strings.SplitN(string(n), ":", 2)
+ return len(parts) > 1 && parts[0] == "container"
+}
+
+// Container returns the name of the container whose cgroup namespace is going to be used.
+func (n CgroupMode) Container() string {
+ parts := strings.SplitN(string(n), ":", 2)
+ if len(parts) > 1 {
+ return parts[1]
+ }
+ return ""
+}
+
+// IsPrivate indicates whether the container uses the a private cgroup.
+func (n CgroupMode) IsPrivate() bool {
+ return n == "private"
+}
+
+// Valid indicates whether the Cgroup namespace is valid.
+func (n CgroupMode) Valid() bool {
+ parts := strings.Split(string(n), ":")
+ switch mode := parts[0]; mode {
+ case "", "host", "private", "ns":
+ case "container":
+ if len(parts) != 2 || parts[1] == "" {
+ return false
+ }
+ default:
+ return false
+ }
+ return true
+}
+
// UsernsMode represents userns mode in the container.
type UsernsMode string
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 0042ed401..1fb1f829b 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -63,6 +63,7 @@ type CreateConfig struct {
CapDrop []string // cap-drop
CidFile string
ConmonPidFile string
+ Cgroupns string
CgroupParent string // cgroup-parent
Command []string
Detach bool // detach
@@ -101,6 +102,7 @@ type CreateConfig struct {
NetworkAlias []string //network-alias
PidMode namespaces.PidMode //pid
Pod string //pod
+ CgroupMode namespaces.CgroupMode //cgroup
PortBindings nat.PortMap
Privileged bool //privileged
Publish []string //publish
@@ -268,6 +270,23 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, string(c.NetMode), networks))
}
+ if c.CgroupMode.IsNS() {
+ ns := c.CgroupMode.NS()
+ if ns == "" {
+ return nil, errors.Errorf("invalid empty user-defined network namespace")
+ }
+ _, err := os.Stat(ns)
+ if err != nil {
+ return nil, err
+ }
+ } else if c.CgroupMode.IsContainer() {
+ connectedCtr, err := runtime.LookupContainer(c.CgroupMode.Container())
+ if err != nil {
+ return nil, errors.Wrapf(err, "container %q not found", c.CgroupMode.Container())
+ }
+ options = append(options, libpod.WithCgroupNSFrom(connectedCtr))
+ }
+
if c.PidMode.IsContainer() {
connectedCtr, err := runtime.LookupContainer(c.PidMode.Container())
if err != nil {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 0f785df01..824c99025 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -323,6 +323,10 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if err := addIpcNS(config, &g); err != nil {
return nil, err
}
+
+ if err := addCgroupNS(config, &g); err != nil {
+ return nil, err
+ }
configSpec := g.Config
// HANDLE CAPABILITIES
@@ -620,6 +624,23 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error {
return nil
}
+func addCgroupNS(config *CreateConfig, g *generate.Generator) error {
+ cgroupMode := config.CgroupMode
+ if cgroupMode.IsNS() {
+ return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), NS(string(cgroupMode)))
+ }
+ if cgroupMode.IsHost() {
+ return g.RemoveLinuxNamespace(spec.CgroupNamespace)
+ }
+ if cgroupMode.IsPrivate() {
+ return g.AddOrReplaceLinuxNamespace(spec.CgroupNamespace, "")
+ }
+ if cgroupMode.IsContainer() {
+ logrus.Debug("Using container cgroup mode")
+ }
+ return nil
+}
+
func addRlimits(config *CreateConfig, g *generate.Generator) error {
var (
kernelMax uint64 = 1048576
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 700e02b0c..6f6909fac 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -65,32 +65,34 @@ func (i *LibpodAPI) Ps(call iopodman.VarlinkCall, opts iopodman.PsOpts) error {
for _, ctr := range psContainerOutputs {
container := iopodman.PsContainer{
- Id: ctr.ID,
- Image: ctr.Image,
- Command: ctr.Command,
- Created: ctr.Created,
- Ports: ctr.Ports,
- Names: ctr.Names,
- IsInfra: ctr.IsInfra,
- Status: ctr.Status,
- State: ctr.State.String(),
- PidNum: int64(ctr.Pid),
- RootFsSize: ctr.Size.RootFsSize,
- RwSize: ctr.Size.RwSize,
- Pod: ctr.Pod,
- CreatedAt: ctr.CreatedAt.Format(time.RFC3339Nano),
- ExitedAt: ctr.ExitedAt.Format(time.RFC3339Nano),
- StartedAt: ctr.StartedAt.Format(time.RFC3339Nano),
- Labels: ctr.Labels,
- NsPid: ctr.PID,
- Cgroup: ctr.Cgroup,
- Ipc: ctr.Cgroup,
- Mnt: ctr.MNT,
- Net: ctr.NET,
- PidNs: ctr.PIDNS,
- User: ctr.User,
- Uts: ctr.UTS,
- Mounts: ctr.Mounts,
+ Id: ctr.ID,
+ Image: ctr.Image,
+ Command: ctr.Command,
+ Created: ctr.Created,
+ Ports: ctr.Ports,
+ Names: ctr.Names,
+ IsInfra: ctr.IsInfra,
+ Status: ctr.Status,
+ State: ctr.State.String(),
+ PidNum: int64(ctr.Pid),
+ Pod: ctr.Pod,
+ CreatedAt: ctr.CreatedAt.Format(time.RFC3339Nano),
+ ExitedAt: ctr.ExitedAt.Format(time.RFC3339Nano),
+ StartedAt: ctr.StartedAt.Format(time.RFC3339Nano),
+ Labels: ctr.Labels,
+ NsPid: ctr.PID,
+ Cgroup: ctr.Cgroup,
+ Ipc: ctr.Cgroup,
+ Mnt: ctr.MNT,
+ Net: ctr.NET,
+ PidNs: ctr.PIDNS,
+ User: ctr.User,
+ Uts: ctr.UTS,
+ Mounts: ctr.Mounts,
+ }
+ if ctr.Size != nil {
+ container.RootFsSize = ctr.Size.RootFsSize
+ container.RwSize = ctr.Size.RwSize
}
containers = append(containers, container)
}
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index e8f74e6aa..d3a41f7ab 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -191,7 +191,7 @@ func makePsOpts(inOpts iopodman.PsOpts) shared.PsOptions {
Latest: derefBool(inOpts.Latest),
NoTrunc: derefBool(inOpts.NoTrunc),
Pod: derefBool(inOpts.Pod),
- Size: true,
+ Size: derefBool(inOpts.Size),
Sort: derefString(inOpts.Sort),
Namespace: true,
Sync: derefBool(inOpts.Sync),