Skip to content

Commit

Permalink
Merge pull request canonical#1947 from jdstrand/jdstrand.docker
Browse files Browse the repository at this point in the history
interfaces/builtin: add initial docker interface
  • Loading branch information
niemeyer authored Sep 21, 2016
2 parents ac54745 + 858c9cb commit 1a4181c
Show file tree
Hide file tree
Showing 8 changed files with 1,251 additions and 0 deletions.
18 changes: 18 additions & 0 deletions docs/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,24 @@ printing.

* Auto-Connect: no

### docker

Can access snaps providing the docker interface which gives privileged access
to the system.

* Auto-Connect: no

### docker-support

Can access resources and syscalls necessary to run Docker application
containers. The ``privileged-containers`` attribute may be used to give the
necessary access to run privileged containers. Providing snaps specifying this
interface currently may only be established with the Docker project.

* Auto-Connect: no
* Attributes:
* privileged-containers (plug): true|false (defaults to ``false``)

### firewall-control

Can configure network firewalling giving privileged access to networking.
Expand Down
2 changes: 2 additions & 0 deletions interfaces/builtin/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var allInterfaces = []interfaces.Interface{
&BluezInterface{},
&BrowserSupportInterface{},
&ContentInterface{},
&DockerInterface{},
&DockerSupportInterface{},
&GpioInterface{},
&HidrawInterface{},
&LocationControlInterface{},
Expand Down
2 changes: 2 additions & 0 deletions interfaces/builtin/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func (s *AllSuite) TestInterfaces(c *C) {
c.Check(all, Contains, &builtin.BoolFileInterface{})
c.Check(all, Contains, &builtin.BluezInterface{})
c.Check(all, Contains, &builtin.BrowserSupportInterface{})
c.Check(all, Contains, &builtin.DockerInterface{})
c.Check(all, Contains, &builtin.DockerSupportInterface{})
c.Check(all, Contains, &builtin.GpioInterface{})
c.Check(all, Contains, &builtin.HidrawInterface{})
c.Check(all, Contains, &builtin.LocationControlInterface{})
Expand Down
132 changes: 132 additions & 0 deletions interfaces/builtin/docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// -*- Mode: Go; indent-tabs-mode: t -*-

/*
* Copyright (C) 2016 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package builtin

import (
"fmt"

"github.com/snapcore/snapd/interfaces"
)

const dockerConnectedPlugAppArmor = `
# Description: allow access to the Docker daemon socket. This gives privileged
# access to the system via Docker's socket API.
# Usage: reserved
# Allow talking to the docker daemon
/{,var/}run/docker.sock rw,
`

const dockerConnectedPlugSecComp = `
# Description: allow access to the Docker daemon socket. This gives privileged
# access to the system via Docker's socket API.
# Usage: reserved
setsockopt
bind
`

type DockerInterface struct{}

func (iface *DockerInterface) Name() string {
return "docker"
}

func (iface *DockerInterface) PermanentPlugSnippet(plug *interfaces.Plug, securitySystem interfaces.SecuritySystem) ([]byte, error) {
switch securitySystem {
case interfaces.SecurityAppArmor,
interfaces.SecurityDBus,
interfaces.SecurityMount,
interfaces.SecuritySecComp,
interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *DockerInterface) ConnectedPlugSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
switch securitySystem {
case interfaces.SecurityAppArmor:
snippet := []byte(dockerConnectedPlugAppArmor)
return snippet, nil
case interfaces.SecuritySecComp:
snippet := []byte(dockerConnectedPlugSecComp)
return snippet, nil
case interfaces.SecurityDBus,
interfaces.SecurityMount,
interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *DockerInterface) PermanentSlotSnippet(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
// No permanent slot policy. Instead, use the docker-support interface
switch securitySystem {
case interfaces.SecurityAppArmor,
interfaces.SecurityDBus,
interfaces.SecurityMount,
interfaces.SecuritySecComp,
interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *DockerInterface) ConnectedSlotSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
// The docker socket is a named socket and therefore mediated by
// AppArmor file rules. As such, there is no additional ConnectedSlot
// policy to add.
switch securitySystem {
case interfaces.SecurityAppArmor,
interfaces.SecurityDBus,
interfaces.SecurityMount,
interfaces.SecuritySecComp,
interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *DockerInterface) SanitizePlug(plug *interfaces.Plug) error {
if iface.Name() != plug.Interface {
panic(fmt.Sprintf("plug is not of interface %q", iface.Name()))
}
return nil
}

func (iface *DockerInterface) SanitizeSlot(slot *interfaces.Slot) error {
snapName := slot.Snap.Name()
devName := slot.Snap.Developer
// The docker slot interface can only by used with the docker project
// and Canonical
if snapName != "docker" || (devName != "canonical" && devName != "docker") {
return fmt.Errorf("docker slot interface is reserved for the upstream docker project")
}
return nil
}

func (iface *DockerInterface) AutoConnect() bool {
return false
}
Loading

0 comments on commit 1a4181c

Please sign in to comment.