mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Export all spec generation opts
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
cb902f4430
commit
c478553640
6 changed files with 543 additions and 511 deletions
|
@ -10,10 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/container"
|
|
||||||
"github.com/docker/docker/daemon/config"
|
"github.com/docker/docker/daemon/config"
|
||||||
"github.com/docker/docker/oci"
|
|
||||||
"github.com/docker/docker/pkg/idtools"
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
is "gotest.tools/assert/cmp"
|
is "gotest.tools/assert/cmp"
|
||||||
|
@ -115,54 +112,6 @@ func TestNotCleanupMounts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestTmpfsDevShmSizeOverride checks that user-specified /dev/tmpfs mount
|
|
||||||
// size is not overridden by the default shmsize (that should only be used
|
|
||||||
// for default /dev/shm (as in "shareable" and "private" ipc modes).
|
|
||||||
// https://github.com/moby/moby/issues/35271
|
|
||||||
func TestTmpfsDevShmSizeOverride(t *testing.T) {
|
|
||||||
size := "777m"
|
|
||||||
mnt := "/dev/shm"
|
|
||||||
|
|
||||||
d := Daemon{
|
|
||||||
idMapping: &idtools.IdentityMapping{},
|
|
||||||
}
|
|
||||||
c := &container.Container{
|
|
||||||
HostConfig: &containertypes.HostConfig{
|
|
||||||
ShmSize: 48 * 1024, // size we should NOT end up with
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ms := []container.Mount{
|
|
||||||
{
|
|
||||||
Source: "tmpfs",
|
|
||||||
Destination: mnt,
|
|
||||||
Data: "size=" + size,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert ms to spec
|
|
||||||
spec := oci.DefaultSpec()
|
|
||||||
err := setMounts(&d, &spec, c, ms)
|
|
||||||
assert.Check(t, err)
|
|
||||||
|
|
||||||
// Check the resulting spec for the correct size
|
|
||||||
found := false
|
|
||||||
for _, m := range spec.Mounts {
|
|
||||||
if m.Destination == mnt {
|
|
||||||
for _, o := range m.Options {
|
|
||||||
if !strings.HasPrefix(o, "size=") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Logf("%+v\n", m.Options)
|
|
||||||
assert.Check(t, is.Equal("size="+size, o))
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
t.Fatal("/dev/shm not found in spec, or size option missing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateContainerIsolationLinux(t *testing.T) {
|
func TestValidateContainerIsolationLinux(t *testing.T) {
|
||||||
d := Daemon{}
|
d := Daemon{}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package daemon // import "github.com/docker/docker/daemon"
|
package daemon // import "github.com/docker/docker/daemon"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/daemon/exec"
|
"github.com/docker/docker/daemon/exec"
|
||||||
"github.com/docker/docker/oci/caps"
|
"github.com/docker/docker/oci/caps"
|
||||||
|
@ -54,6 +56,6 @@ func (daemon *Daemon) execSetPlatformOpt(c *container.Container, ec *exec.Config
|
||||||
}
|
}
|
||||||
p.ApparmorProfile = appArmorProfile
|
p.ApparmorProfile = appArmorProfile
|
||||||
}
|
}
|
||||||
daemon.setRlimits(&specs.Spec{Process: p}, c)
|
s := &specs.Spec{Process: p}
|
||||||
return nil
|
return WithRlimits(daemon, c)(context.Background(), nil, nil, s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,11 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const inContainerInitPath = "/sbin/" + daemonconfig.DefaultInitBinary
|
||||||
inContainerInitPath = "/sbin/" + daemonconfig.DefaultInitBinary
|
|
||||||
)
|
|
||||||
|
|
||||||
func (daemon *Daemon) setRlimits(s *specs.Spec, c *container.Container) error {
|
// WithRlimits sets the container's rlimits along with merging the daemon's rlimits
|
||||||
|
func WithRlimits(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
var rlimits []specs.POSIXRlimit
|
var rlimits []specs.POSIXRlimit
|
||||||
|
|
||||||
// We want to leave the original HostConfig alone so make a copy here
|
// We want to leave the original HostConfig alone so make a copy here
|
||||||
|
@ -54,6 +54,100 @@ func (daemon *Daemon) setRlimits(s *specs.Spec, c *container.Container) error {
|
||||||
|
|
||||||
s.Process.Rlimits = rlimits
|
s.Process.Rlimits = rlimits
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLibnetwork sets the libnetwork hook
|
||||||
|
func WithLibnetwork(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
if s.Hooks == nil {
|
||||||
|
s.Hooks = &specs.Hooks{}
|
||||||
|
}
|
||||||
|
for _, ns := range s.Linux.Namespaces {
|
||||||
|
if ns.Type == "network" && ns.Path == "" && !c.Config.NetworkDisabled {
|
||||||
|
target := filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe")
|
||||||
|
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{
|
||||||
|
Path: target,
|
||||||
|
Args: []string{
|
||||||
|
"libnetwork-setkey",
|
||||||
|
"-exec-root=" + daemon.configStore.GetExecRoot(),
|
||||||
|
c.ID,
|
||||||
|
daemon.netController.ID(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRootless sets the spec to the rootless configuration
|
||||||
|
func WithRootless(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
return specconv.ToRootless(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOOMScore sets the oom score
|
||||||
|
func WithOOMScore(score *int) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
s.Process.OOMScoreAdj = score
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSelinux sets the selinux labels
|
||||||
|
func WithSelinux(c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
s.Process.SelinuxLabel = c.GetProcessLabel()
|
||||||
|
s.Linux.MountLabel = c.MountLabel
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithApparmor sets the apparmor profile
|
||||||
|
func WithApparmor(c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
if apparmor.IsEnabled() {
|
||||||
|
var appArmorProfile string
|
||||||
|
if c.AppArmorProfile != "" {
|
||||||
|
appArmorProfile = c.AppArmorProfile
|
||||||
|
} else if c.HostConfig.Privileged {
|
||||||
|
appArmorProfile = "unconfined"
|
||||||
|
} else {
|
||||||
|
appArmorProfile = "docker-default"
|
||||||
|
}
|
||||||
|
|
||||||
|
if appArmorProfile == "docker-default" {
|
||||||
|
// Unattended upgrades and other fun services can unload AppArmor
|
||||||
|
// profiles inadvertently. Since we cannot store our profile in
|
||||||
|
// /etc/apparmor.d, nor can we practically add other ways of
|
||||||
|
// telling the system to keep our profile loaded, in order to make
|
||||||
|
// sure that we keep the default profile enabled we dynamically
|
||||||
|
// reload it if necessary.
|
||||||
|
if err := ensureDefaultAppArmorProfile(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Process.ApparmorProfile = appArmorProfile
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCapabilities sets the container's capabilties
|
||||||
|
func WithCapabilities(c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
capabilities, err := caps.TweakCapabilities(
|
||||||
|
oci.DefaultCapabilities(),
|
||||||
|
c.HostConfig.CapAdd,
|
||||||
|
c.HostConfig.CapDrop,
|
||||||
|
c.HostConfig.Capabilities,
|
||||||
|
c.HostConfig.Privileged,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return oci.SetCapabilities(s, capabilities)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readUserFile(c *container.Container, p string) (io.ReadCloser, error) {
|
func readUserFile(c *container.Container, p string) (io.ReadCloser, error) {
|
||||||
|
@ -119,7 +213,9 @@ func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) {
|
||||||
s.Linux.Namespaces = append(s.Linux.Namespaces, ns)
|
s.Linux.Namespaces = append(s.Linux.Namespaces, ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error {
|
// WithNamespaces sets the container's namespaces
|
||||||
|
func WithNamespaces(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
userNS := false
|
userNS := false
|
||||||
// user
|
// user
|
||||||
if c.HostConfig.UsernsMode.IsPrivate() {
|
if c.HostConfig.UsernsMode.IsPrivate() {
|
||||||
|
@ -212,6 +308,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func specMapping(s []idtools.IDMap) []specs.LinuxIDMapping {
|
func specMapping(s []idtools.IDMap) []specs.LinuxIDMapping {
|
||||||
|
@ -361,7 +458,52 @@ func inSlice(slice []string, s string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []container.Mount) error {
|
// WithMounts sets the container's mounts
|
||||||
|
func WithMounts(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) (err error) {
|
||||||
|
if err := daemon.setupContainerMountsRoot(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := daemon.setupIpcDirs(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
daemon.cleanupSecretDir(c)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := daemon.setupSecretDir(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ms, err := daemon.setupMounts(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.HostConfig.IpcMode.IsPrivate() && !c.HostConfig.IpcMode.IsEmpty() {
|
||||||
|
ms = append(ms, c.IpcMounts()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpfsMounts, err := c.TmpfsMounts()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ms = append(ms, tmpfsMounts...)
|
||||||
|
|
||||||
|
secretMounts, err := c.SecretMounts()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ms = append(ms, secretMounts...)
|
||||||
|
|
||||||
|
sort.Sort(mounts(ms))
|
||||||
|
|
||||||
|
mounts := ms
|
||||||
|
|
||||||
userMounts := make(map[string]struct{})
|
userMounts := make(map[string]struct{})
|
||||||
for _, m := range mounts {
|
for _, m := range mounts {
|
||||||
userMounts[m.Destination] = struct{}{}
|
userMounts[m.Destination] = struct{}{}
|
||||||
|
@ -532,9 +674,13 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) error {
|
// WithCommonOptions sets common docker options
|
||||||
|
func WithCommonOptions(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
if c.BaseFS == nil {
|
if c.BaseFS == nil {
|
||||||
return errors.New("populateCommonSpec: BaseFS of container " + c.ID + " is unexpectedly nil")
|
return errors.New("populateCommonSpec: BaseFS of container " + c.ID + " is unexpectedly nil")
|
||||||
}
|
}
|
||||||
|
@ -585,9 +731,11 @@ func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container)
|
||||||
setLinuxDomainname(c, s)
|
setLinuxDomainname(c, s)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
// WithCgroups sets the container's cgroups
|
||||||
|
func WithCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
var cgroupsPath string
|
var cgroupsPath string
|
||||||
scopePrefix := "docker"
|
scopePrefix := "docker"
|
||||||
|
@ -636,7 +784,8 @@ func withCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withContainerDevices(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
// WithDevices sets the container's devices
|
||||||
|
func WithDevices(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
// Build lists of devices allowed and created within the container.
|
// Build lists of devices allowed and created within the container.
|
||||||
var devs []specs.LinuxDevice
|
var devs []specs.LinuxDevice
|
||||||
|
@ -684,7 +833,8 @@ func withContainerDevices(daemon *Daemon, c *container.Container) coci.SpecOpts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withResources(c *container.Container) coci.SpecOpts {
|
// WithResources applies the container resources
|
||||||
|
func WithResources(c *container.Container) coci.SpecOpts {
|
||||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
r := c.HostConfig.Resources
|
r := c.HostConfig.Resources
|
||||||
weightDevices, err := getBlkioWeightDevices(r)
|
weightDevices, err := getBlkioWeightDevices(r)
|
||||||
|
@ -738,7 +888,8 @@ func withResources(c *container.Container) coci.SpecOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withSysctls(c *container.Container) coci.SpecOpts {
|
// WithSysctls sets the container's sysctls
|
||||||
|
func WithSysctls(c *container.Container) coci.SpecOpts {
|
||||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
// We merge the sysctls injected above with the HostConfig (latter takes
|
// We merge the sysctls injected above with the HostConfig (latter takes
|
||||||
// precedence for backwards-compatibility reasons).
|
// precedence for backwards-compatibility reasons).
|
||||||
|
@ -749,7 +900,8 @@ func withSysctls(c *container.Container) coci.SpecOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUser(c *container.Container) coci.SpecOpts {
|
// WithUser sets the container's user
|
||||||
|
func WithUser(c *container.Container) coci.SpecOpts {
|
||||||
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
uid, gid, additionalGids, err := getUser(c, c.Config.User)
|
uid, gid, additionalGids, err := getUser(c, c.Config.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -767,133 +919,36 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e
|
||||||
opts []coci.SpecOpts
|
opts []coci.SpecOpts
|
||||||
s = oci.DefaultSpec()
|
s = oci.DefaultSpec()
|
||||||
)
|
)
|
||||||
if err := daemon.populateCommonSpec(&s, c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = append(opts,
|
opts = append(opts,
|
||||||
withCgroups(daemon, c),
|
WithCommonOptions(daemon, c),
|
||||||
withResources(c),
|
WithCgroups(daemon, c),
|
||||||
withSysctls(c),
|
WithResources(c),
|
||||||
withContainerDevices(daemon, c),
|
WithSysctls(c),
|
||||||
withUser(c),
|
WithDevices(daemon, c),
|
||||||
|
WithUser(c),
|
||||||
|
WithRlimits(daemon, c),
|
||||||
|
WithNamespaces(daemon, c),
|
||||||
|
WithCapabilities(c),
|
||||||
|
WithSeccomp(daemon, c),
|
||||||
|
WithMounts(daemon, c),
|
||||||
|
WithLibnetwork(daemon, c),
|
||||||
|
WithApparmor(c),
|
||||||
|
WithSelinux(c),
|
||||||
|
WithOOMScore(&c.HostConfig.OomScoreAdj),
|
||||||
)
|
)
|
||||||
|
if c.NoNewPrivileges {
|
||||||
if err := daemon.setRlimits(&s, c); err != nil {
|
opts = append(opts, coci.WithNoNewPrivileges)
|
||||||
return nil, fmt.Errorf("linux runtime spec rlimits: %v", err)
|
|
||||||
}
|
}
|
||||||
if err := setNamespaces(daemon, &s, c); err != nil {
|
|
||||||
return nil, fmt.Errorf("linux spec namespaces: %v", err)
|
|
||||||
}
|
|
||||||
capabilities, err := caps.TweakCapabilities(oci.DefaultCapabilities(), c.HostConfig.CapAdd, c.HostConfig.CapDrop, c.HostConfig.Capabilities, c.HostConfig.Privileged)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("linux spec capabilities: %v", err)
|
|
||||||
}
|
|
||||||
if err := oci.SetCapabilities(&s, capabilities); err != nil {
|
|
||||||
return nil, fmt.Errorf("linux spec capabilities: %v", err)
|
|
||||||
}
|
|
||||||
if err := setSeccomp(daemon, &s, c); err != nil {
|
|
||||||
return nil, fmt.Errorf("linux seccomp: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := daemon.setupContainerMountsRoot(c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := daemon.setupIpcDirs(c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
daemon.cleanupSecretDir(c)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err := daemon.setupSecretDir(c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ms, err := daemon.setupMounts(c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.HostConfig.IpcMode.IsPrivate() && !c.HostConfig.IpcMode.IsEmpty() {
|
|
||||||
ms = append(ms, c.IpcMounts()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpfsMounts, err := c.TmpfsMounts()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ms = append(ms, tmpfsMounts...)
|
|
||||||
|
|
||||||
secretMounts, err := c.SecretMounts()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ms = append(ms, secretMounts...)
|
|
||||||
|
|
||||||
sort.Sort(mounts(ms))
|
|
||||||
if err := setMounts(daemon, &s, c, ms); err != nil {
|
|
||||||
return nil, fmt.Errorf("linux mounts: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.Hooks == nil {
|
|
||||||
s.Hooks = &specs.Hooks{}
|
|
||||||
}
|
|
||||||
for _, ns := range s.Linux.Namespaces {
|
|
||||||
if ns.Type == "network" && ns.Path == "" && !c.Config.NetworkDisabled {
|
|
||||||
target := filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe")
|
|
||||||
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{
|
|
||||||
Path: target,
|
|
||||||
Args: []string{"libnetwork-setkey", "-exec-root=" + daemon.configStore.GetExecRoot(), c.ID, daemon.netController.ID()},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if apparmor.IsEnabled() {
|
|
||||||
var appArmorProfile string
|
|
||||||
if c.AppArmorProfile != "" {
|
|
||||||
appArmorProfile = c.AppArmorProfile
|
|
||||||
} else if c.HostConfig.Privileged {
|
|
||||||
appArmorProfile = "unconfined"
|
|
||||||
} else {
|
|
||||||
appArmorProfile = "docker-default"
|
|
||||||
}
|
|
||||||
|
|
||||||
if appArmorProfile == "docker-default" {
|
|
||||||
// Unattended upgrades and other fun services can unload AppArmor
|
|
||||||
// profiles inadvertently. Since we cannot store our profile in
|
|
||||||
// /etc/apparmor.d, nor can we practically add other ways of
|
|
||||||
// telling the system to keep our profile loaded, in order to make
|
|
||||||
// sure that we keep the default profile enabled we dynamically
|
|
||||||
// reload it if necessary.
|
|
||||||
if err := ensureDefaultAppArmorProfile(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Process.ApparmorProfile = appArmorProfile
|
|
||||||
}
|
|
||||||
s.Process.SelinuxLabel = c.GetProcessLabel()
|
|
||||||
s.Process.NoNewPrivileges = c.NoNewPrivileges
|
|
||||||
s.Process.OOMScoreAdj = &c.HostConfig.OomScoreAdj
|
|
||||||
s.Linux.MountLabel = c.MountLabel
|
|
||||||
|
|
||||||
// Set the masked and readonly paths with regard to the host config options if they are set.
|
// Set the masked and readonly paths with regard to the host config options if they are set.
|
||||||
if c.HostConfig.MaskedPaths != nil {
|
if c.HostConfig.MaskedPaths != nil {
|
||||||
s.Linux.MaskedPaths = c.HostConfig.MaskedPaths
|
opts = append(opts, coci.WithMaskedPaths(c.HostConfig.MaskedPaths))
|
||||||
}
|
}
|
||||||
if c.HostConfig.ReadonlyPaths != nil {
|
if c.HostConfig.ReadonlyPaths != nil {
|
||||||
s.Linux.ReadonlyPaths = c.HostConfig.ReadonlyPaths
|
opts = append(opts, coci.WithReadonlyPaths(c.HostConfig.ReadonlyPaths))
|
||||||
}
|
}
|
||||||
|
|
||||||
if daemon.configStore.Rootless {
|
if daemon.configStore.Rootless {
|
||||||
if err := specconv.ToRootless(&s); err != nil {
|
opts = append(opts, WithRootless)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
||||||
ID: c.ID,
|
ID: c.ID,
|
||||||
|
|
|
@ -3,17 +3,22 @@
|
||||||
package daemon // import "github.com/docker/docker/daemon"
|
package daemon // import "github.com/docker/docker/daemon"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
coci "github.com/containerd/containerd/oci"
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var supportsSeccomp = false
|
var supportsSeccomp = false
|
||||||
|
|
||||||
func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
|
// WithSeccomp sets the seccomp profile
|
||||||
|
func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
if c.SeccompProfile != "" && c.SeccompProfile != "unconfined" {
|
if c.SeccompProfile != "" && c.SeccompProfile != "unconfined" {
|
||||||
return fmt.Errorf("seccomp profiles are not supported on this daemon, you cannot specify a custom seccomp profile")
|
return fmt.Errorf("seccomp profiles are not supported on this daemon, you cannot specify a custom seccomp profile")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
package daemon // import "github.com/docker/docker/daemon"
|
package daemon // import "github.com/docker/docker/daemon"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
coci "github.com/containerd/containerd/oci"
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/profiles/seccomp"
|
"github.com/docker/docker/profiles/seccomp"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
@ -13,7 +16,9 @@ import (
|
||||||
|
|
||||||
var supportsSeccomp = true
|
var supportsSeccomp = true
|
||||||
|
|
||||||
func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
|
// WithSeccomp sets the seccomp profile
|
||||||
|
func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
var profile *specs.LinuxSeccomp
|
var profile *specs.LinuxSeccomp
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -32,24 +37,25 @@ func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if c.SeccompProfile != "" {
|
if c.SeccompProfile != "" {
|
||||||
profile, err = seccomp.LoadProfile(c.SeccompProfile, rs)
|
profile, err = seccomp.LoadProfile(c.SeccompProfile, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if daemon.seccompProfile != nil {
|
if daemon.seccompProfile != nil {
|
||||||
profile, err = seccomp.LoadProfile(string(daemon.seccompProfile), rs)
|
profile, err = seccomp.LoadProfile(string(daemon.seccompProfile), s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
profile, err = seccomp.GetDefaultProfile(rs)
|
profile, err = seccomp.GetDefaultProfile(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rs.Linux.Seccomp = profile
|
s.Linux.Seccomp = profile
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,19 @@
|
||||||
|
|
||||||
package daemon // import "github.com/docker/docker/daemon"
|
package daemon // import "github.com/docker/docker/daemon"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
coci "github.com/containerd/containerd/oci"
|
||||||
|
"github.com/docker/docker/container"
|
||||||
|
)
|
||||||
|
|
||||||
var supportsSeccomp = false
|
var supportsSeccomp = false
|
||||||
|
|
||||||
|
// WithSeccomp sets the seccomp profile
|
||||||
|
func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
||||||
|
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue