Skip to content

Commit

Permalink
Merge pull request #3889 from jhenstridge/desktop-interface-fonts
Browse files Browse the repository at this point in the history
interfaces: mount host system fonts in desktop interface
  • Loading branch information
mvo5 authored Sep 19, 2017
2 parents 702d1f4 + 1d76910 commit e6f3dfe
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 8 deletions.
4 changes: 4 additions & 0 deletions cmd/snap-confine/snap-confine.apparmor.in
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@
audit deny mount /** -> /snap/bin/**,
# Allow the content interface to bind fonts from the host filesystem
mount options=(ro bind) /var/lib/snapd/hostfs/usr/share/fonts/ -> /snap/*/*/**,
# Allow the desktop interface to bind fonts from the host filesystem
mount options=(ro bind) /var/lib/snapd/hostfs/usr/share/fonts -> /usr/share/fonts,
mount options=(ro bind) /var/lib/snapd/hostfs/usr/local/share/fonts -> /usr/local/share/fonts,
mount options=(ro bind) /var/lib/snapd/hostfs/var/cache/fontconfig -> /var/cache/fontconfig,

# nvidia handling, glob needs /usr/** and the launcher must be
# able to bind mount the nvidia dir
Expand Down
8 changes: 8 additions & 0 deletions dirs/dirs.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ var (
CompletionHelper string
CompletersDir string
CompleteSh string

SystemFontsDir string
SystemLocalFontsDir string
SystemFontconfigCacheDir string
)

const (
Expand Down Expand Up @@ -232,4 +236,8 @@ func SetRootDir(rootdir string) {
CompletionHelper = filepath.Join(CoreLibExecDir, "etelpmoc.sh")
CompletersDir = filepath.Join(rootdir, "/usr/share/bash-completion/completions/")
CompleteSh = filepath.Join(SnapMountDir, "core/current/usr/lib/snapd/complete.sh")

SystemFontsDir = filepath.Join(rootdir, "/usr/share/fonts")
SystemLocalFontsDir = filepath.Join(rootdir, "/usr/local/share/fonts")
SystemFontconfigCacheDir = filepath.Join(rootdir, "/var/cache/fontconfig")
}
71 changes: 63 additions & 8 deletions interfaces/builtin/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@

package builtin

import (
"github.com/snapcore/snapd/dirs"
"github.com/snapcore/snapd/interfaces"
"github.com/snapcore/snapd/interfaces/apparmor"
"github.com/snapcore/snapd/interfaces/mount"
"github.com/snapcore/snapd/osutil"
"github.com/snapcore/snapd/release"
)

const desktopSummary = `allows access to basic graphical desktop resources`

const desktopBaseDeclarationSlots = `
Expand Down Expand Up @@ -125,13 +134,59 @@ dbus (send)
deny /{dev,run,var/run}/shm/lttng-ust-* rw,
`

type desktopInterface struct{}

func (iface *desktopInterface) Name() string {
return "desktop"
}

func (iface *desktopInterface) StaticInfo() interfaces.StaticInfo {
return interfaces.StaticInfo{
Summary: desktopSummary,
ImplicitOnClassic: true,
BaseDeclarationSlots: desktopBaseDeclarationSlots,
}
}

func (iface *desktopInterface) SanitizeSlot(slot *interfaces.Slot) error {
return sanitizeSlotReservedForOS(iface, slot)
}

func (iface *desktopInterface) AutoConnect(*interfaces.Plug, *interfaces.Slot) bool {
// allow what declarations allowed
return true
}

func (iface *desktopInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.Plug, plugAttrs map[string]interface{}, slot *interfaces.Slot, slotAttrs map[string]interface{}) error {
spec.AddSnippet(desktopConnectedPlugAppArmor)
return nil
}

func (iface *desktopInterface) MountConnectedPlug(spec *mount.Specification, plug *interfaces.Plug, plugAttrs map[string]interface{}, slot *interfaces.Slot, slotAttrs map[string]interface{}) error {
if !release.OnClassic {
// There is nothing to expose on an all-snaps system
return nil
}

fontconfigDirs := []string{
dirs.SystemFontsDir,
dirs.SystemLocalFontsDir,
dirs.SystemFontconfigCacheDir,
}

for _, dir := range fontconfigDirs {
if !osutil.IsDirectory(dir) {
continue
}
spec.AddMountEntry(mount.Entry{
Name: "/var/lib/snapd/hostfs" + dir,
Dir: dirs.StripRootDir(dir),
Options: []string{"bind", "ro"},
})
}
return nil
}

func init() {
registerIface(&commonInterface{
name: "desktop",
summary: desktopSummary,
implicitOnClassic: true,
baseDeclarationSlots: desktopBaseDeclarationSlots,
connectedPlugAppArmor: desktopConnectedPlugAppArmor,
reservedForOS: true,
})
registerIface(&desktopInterface{})
}
49 changes: 49 additions & 0 deletions interfaces/builtin/desktop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@
package builtin_test

import (
"os"
"path/filepath"

. "gopkg.in/check.v1"

"github.com/snapcore/snapd/dirs"
"github.com/snapcore/snapd/interfaces"
"github.com/snapcore/snapd/interfaces/apparmor"
"github.com/snapcore/snapd/interfaces/builtin"
"github.com/snapcore/snapd/interfaces/mount"
"github.com/snapcore/snapd/release"
"github.com/snapcore/snapd/snap"
"github.com/snapcore/snapd/testutil"
)
Expand Down Expand Up @@ -56,6 +62,10 @@ func (s *DesktopInterfaceSuite) SetUpTest(c *C) {
s.coreSlot = MockSlot(c, desktopCoreYaml, nil, "desktop")
}

func (s *DesktopInterfaceSuite) TearDownTest(c *C) {
dirs.SetRootDir("/")
}

func (s *DesktopInterfaceSuite) TestName(c *C) {
c.Assert(s.iface.Name(), Equals, "desktop")
}
Expand Down Expand Up @@ -91,6 +101,45 @@ func (s *DesktopInterfaceSuite) TestAppArmorSpec(c *C) {
c.Assert(spec.SecurityTags(), HasLen, 0)
}

func (s *DesktopInterfaceSuite) TestMountSpec(c *C) {
tmpdir := c.MkDir()
dirs.SetRootDir(tmpdir)
c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/share/fonts"), 0777), IsNil)
c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/usr/local/share/fonts"), 0777), IsNil)
c.Assert(os.MkdirAll(filepath.Join(tmpdir, "/var/cache/fontconfig"), 0777), IsNil)

restore := release.MockOnClassic(false)
defer restore()

// On all-snaps systems, no mount entries are added
spec := &mount.Specification{}
c.Assert(spec.AddConnectedPlug(s.iface, s.plug, nil, s.coreSlot, nil), IsNil)
c.Check(spec.MountEntries(), HasLen, 0)

// On classic systems, a number of font related directories
// are bind mounted from the host system if they exist.
restore = release.MockOnClassic(true)
defer restore()
spec = &mount.Specification{}
c.Assert(spec.AddConnectedPlug(s.iface, s.plug, nil, s.coreSlot, nil), IsNil)

entries := spec.MountEntries()
c.Assert(entries, HasLen, 3)

const hostfs = "/var/lib/snapd/hostfs"
c.Check(entries[0].Name, Equals, hostfs+dirs.SystemFontsDir)
c.Check(entries[0].Dir, Equals, "/usr/share/fonts")
c.Check(entries[0].Options, DeepEquals, []string{"bind", "ro"})

c.Check(entries[1].Name, Equals, hostfs+dirs.SystemLocalFontsDir)
c.Check(entries[1].Dir, Equals, "/usr/local/share/fonts")
c.Check(entries[1].Options, DeepEquals, []string{"bind", "ro"})

c.Check(entries[2].Name, Equals, hostfs+dirs.SystemFontconfigCacheDir)
c.Check(entries[2].Dir, Equals, "/var/cache/fontconfig")
c.Check(entries[2].Options, DeepEquals, []string{"bind", "ro"})
}

func (s *DesktopInterfaceSuite) TestStaticInfo(c *C) {
si := interfaces.StaticInfoOf(s.iface)
c.Assert(si.ImplicitOnCore, Equals, false)
Expand Down

0 comments on commit e6f3dfe

Please sign in to comment.