Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Implement lxd-client interface exposing the lxd snap (LP: #1634880) #2225
Merged
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
dce2cb0
Add preliminary lxd client interface
kalikiana 1f6d84f
Rename lxd interface to lxd-client and add tests
kalikiana bda950a
No access to executables and unit test fix
kalikiana 89070b6
No more autoconnecting and no seccomp rules
kalikiana 5ae897f
Formatting fixes and unused code
kalikiana ff92d3f
Undo rename, make lxd manually connected only
kalikiana cd006f9
Adjust unit tests
kalikiana
Jump to file or symbol
Failed to load files and symbols.
| @@ -0,0 +1,91 @@ | ||
| +// -*- 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 lxdConnectedPlugAppArmor = ` | ||
| +# Description: allow access to the LXD daemon socket. This gives privileged | ||
| +# access to the system via LXD's socket API. | ||
| + | ||
| +/var/snap/lxd/common/lxd/unix.socket rw, | ||
| +` | ||
| + | ||
| +const lxdConnectedPlugSecComp = ` | ||
| +# Description: allow access to the LXD daemon socket. This gives privileged | ||
| +# access to the system via LXD's socket API. | ||
| + | ||
| +shutdown | ||
| +` | ||
| + | ||
| +type LxdInterface struct{} | ||
| + | ||
| +func (iface *LxdInterface) Name() string { | ||
| + return "lxd" | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) PermanentPlugSnippet(plug *interfaces.Plug, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + return nil, nil | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) ConnectedPlugSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + switch securitySystem { | ||
| + case interfaces.SecurityAppArmor: | ||
| + return []byte(lxdConnectedPlugAppArmor), nil | ||
| + case interfaces.SecuritySecComp: | ||
| + return []byte(lxdConnectedPlugSecComp), nil | ||
| + } | ||
| + return nil, nil | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) PermanentSlotSnippet(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + return nil, nil | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) ConnectedSlotSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + return nil, nil | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) 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 *LxdInterface) SanitizeSlot(slot *interfaces.Slot) error { | ||
| + if iface.Name() != slot.Interface { | ||
| + panic(fmt.Sprintf("slot is not of interface %q", iface.Name())) | ||
| + } | ||
| + return nil | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) LegacyAutoConnect() bool { | ||
| + return false | ||
| +} | ||
| + | ||
| +func (iface *LxdInterface) AutoConnect(*interfaces.Plug, *interfaces.Slot) bool { | ||
| + // allow what declarations allowed | ||
| + return true | ||
| +} |
| @@ -0,0 +1,102 @@ | ||
| +// -*- 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_test | ||
| + | ||
| +import ( | ||
| + . "gopkg.in/check.v1" | ||
| + | ||
| + "github.com/snapcore/snapd/interfaces" | ||
| + "github.com/snapcore/snapd/interfaces/builtin" | ||
| + "github.com/snapcore/snapd/snap" | ||
| + "github.com/snapcore/snapd/testutil" | ||
| +) | ||
| + | ||
| +type LxdInterfaceSuite struct { | ||
| + iface interfaces.Interface | ||
| + slot *interfaces.Slot | ||
| + plug *interfaces.Plug | ||
| +} | ||
| + | ||
| +var _ = Suite(&LxdInterfaceSuite{ | ||
| + iface: &builtin.LxdInterface{}, | ||
| + slot: &interfaces.Slot{ | ||
| + SlotInfo: &snap.SlotInfo{ | ||
| + Snap: &snap.Info{SuggestedName: "core", Type: snap.TypeOS}, | ||
| + Name: "lxd", | ||
| + Interface: "lxd", | ||
| + }, | ||
| + }, | ||
| + | ||
| + plug: &interfaces.Plug{ | ||
| + PlugInfo: &snap.PlugInfo{ | ||
| + Snap: &snap.Info{ | ||
| + SuggestedName: "lxd", | ||
| + SideInfo: snap.SideInfo{Developer: "canonical"}, | ||
| + }, | ||
| + Name: "lxd", | ||
| + Interface: "lxd", | ||
| + }, | ||
| + }, | ||
| +}) | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestName(c *C) { | ||
| + c.Assert(s.iface.Name(), Equals, "lxd") | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestSanitizeSlot(c *C) { | ||
| + err := s.iface.SanitizeSlot(s.slot) | ||
| + c.Assert(err, IsNil) | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestSanitizePlug(c *C) { | ||
| + err := s.iface.SanitizePlug(s.plug) | ||
| + c.Assert(err, IsNil) | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestUsedSecuritySystems(c *C) { | ||
| + // connected plugs have a non-nil security snippet for apparmor | ||
| + snippet, err := s.iface.ConnectedPlugSnippet(s.plug, s.slot, interfaces.SecurityAppArmor) | ||
| + c.Assert(err, IsNil) | ||
| + c.Assert(snippet, Not(IsNil)) | ||
|
|
||
| + snippet, err = s.iface.ConnectedPlugSnippet(s.plug, s.slot, interfaces.SecuritySecComp) | ||
| + c.Assert(err, IsNil) | ||
| + c.Assert(snippet, Not(IsNil)) | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestConnectedPlugSnippetAppArmor(c *C) { | ||
| + snippet, err := s.iface.ConnectedPlugSnippet(s.plug, s.slot, interfaces.SecurityAppArmor) | ||
| + c.Assert(err, IsNil) | ||
| + c.Check(string(snippet), testutil.Contains, "/var/snap/lxd/common/lxd/unix.socket rw,\n") | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestConnectedPlugSnippetSecComp(c *C) { | ||
| + snippet, err := s.iface.ConnectedPlugSnippet(s.plug, s.slot, interfaces.SecuritySecComp) | ||
| + c.Assert(err, IsNil) | ||
| + c.Check(string(snippet), testutil.Contains, "shutdown\n") | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestLegacyAutoConnect(c *C) { | ||
| + c.Check(s.iface.LegacyAutoConnect(), Equals, false) | ||
| +} | ||
| + | ||
| +func (s *LxdInterfaceSuite) TestAutoConnect(c *C) { | ||
jdstrand
Contributor
|
||
| + // allow what declarations allowed | ||
| + c.Check(s.iface.AutoConnect(nil, nil), Equals, true) | ||
| +} | ||
Please add another test to TestSlotInstallation() for lxd, underneath the docker one.