Permalink
Browse files

dirs,interfaces,overlord,snap,snapenv,test: export per-snap XDG_RUNTI…

…ME_DIR per user (LP: #1620442) (#2281)

* interfaces: allow access to snap-specific XDG_RUNTIME_DIR

* export XDG_RUNTIME_DIR as part of snapenv

* cleanup XdgRuntimeDir for all users on removal

* tests: add test for XDG and SNAP variables

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

* tests: fix typo

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

* add missing test for XdgRuntimeDir()

* clarify name of function and improve comments

* remove check for XDG_SESSION_ID which isn't managed by snapd
  • Loading branch information...
1 parent 132bf9b commit 81bb59245048e0fef23677e564b57b0f721f98d1 @jdstrand jdstrand committed on GitHub Nov 17, 2016
View
@@ -66,6 +66,8 @@ var (
ClassicDir string
LibExecDir string
+
+ XdgRuntimeDirGlob string
)
var (
@@ -142,4 +144,6 @@ func SetRootDir(rootdir string) {
ClassicDir = filepath.Join(rootdir, "/writable/classic")
LibExecDir = filepath.Join(rootdir, "/usr/lib/snapd")
+
+ XdgRuntimeDirGlob = filepath.Join(rootdir, "/run/user/*/")
}
@@ -320,6 +320,10 @@ var defaultTemplate = []byte(`
# access in /dev/shm for shm_open() and files in subdirectories for open()
/{dev,run}/shm/snap.@{SNAP_NAME}.** mrwlkix,
+ # Snap-specific XDG_RUNTIME_DIR that is based on the UID of the user
+ owner /{dev,run}/user/[0-9]*/snap.@{SNAP_NAME}/ rw,
+ owner /{dev,run}/user/[0-9]*/snap.@{SNAP_NAME}/** mrwklix,
+
# Allow apps from the same package to communicate with each other via an
# abstract or anonymous socket
unix peer=(label=snap.@{SNAP_NAME}.*),
@@ -97,6 +97,14 @@ func snapCommonDataDirs(snap *snap.Info) ([]string, error) {
if err != nil {
return nil, err
}
+
+ // then XDG_RUNTIME_DIRs for the users
+ foundXdg, err := filepath.Glob(snap.XdgRuntimeDirs())
+ if err != nil {
+ return nil, err
+ }
+ found = append(found, foundXdg...)
+
// then system data
found = append(found, snap.CommonDataDir())
View
@@ -56,6 +56,9 @@ type PlaceInfo interface {
// CommonDataHomeDir returns the per user data directory common across revisions of the snap.
CommonDataHomeDir() string
+
+ // XdgRuntimeDirs returns the XDG_RUNTIME_DIR directories for all users of the snap.
+ XdgRuntimeDirs() string
}
// MinimalPlaceInfo returns a PlaceInfo with just the location information for a snap of the given name and revision.
@@ -230,6 +233,16 @@ func (s *Info) CommonDataHomeDir() string {
return filepath.Join(dirs.SnapDataHomeGlob, s.Name(), "common")
}
+// UserXdgRuntimeDir returns the XDG_RUNTIME_DIR directory of the snap for a particular user.
+func (s *Info) UserXdgRuntimeDir(euid int) string {
+ return filepath.Join("/run/user", fmt.Sprintf("%d/snap.%s", euid, s.Name()))
+}
+
+// XdgRuntimeDirs returns the XDG_RUNTIME_DIR directories for all users of the snap.
+func (s *Info) XdgRuntimeDirs() string {
+ return filepath.Join(dirs.XdgRuntimeDirGlob, fmt.Sprintf("snap.%s", s.Name()))
+}
+
// NeedsDevMode retursn whether the snap needs devmode.
func (s *Info) NeedsDevMode() bool {
return s.Confinement == DevmodeConfinement
View
@@ -477,7 +477,9 @@ func (s *infoSuite) TestDirAndFileMethods(c *C) {
c.Check(info.UserDataDir("/home/bob"), Equals, "/home/bob/snap/name/1")
c.Check(info.UserCommonDataDir("/home/bob"), Equals, "/home/bob/snap/name/common")
c.Check(info.CommonDataDir(), Equals, "/var/snap/name/common")
+ c.Check(info.UserXdgRuntimeDir(12345), Equals, "/run/user/12345/snap.name")
// XXX: Those are actually a globs, not directories
c.Check(info.DataHomeDir(), Equals, "/home/*/snap/name/1")
c.Check(info.CommonDataHomeDir(), Equals, "/home/*/snap/name/common")
+ c.Check(info.XdgRuntimeDirs(), Equals, "/run/user/*/snap.name")
}
@@ -91,6 +91,7 @@ func userEnv(info *snap.Info, home string) map[string]string {
"HOME": info.UserDataDir(home),
"SNAP_USER_COMMON": info.UserCommonDataDir(home),
"SNAP_USER_DATA": info.UserDataDir(home),
+ "XDG_RUNTIME_DIR": info.UserXdgRuntimeDir(os.Geteuid()),
}
}
@@ -79,6 +79,7 @@ func (ts *HTestSuite) TestUser(c *C) {
"HOME": "/root/snap/foo/17",
"SNAP_USER_COMMON": "/root/snap/foo/common",
"SNAP_USER_DATA": "/root/snap/foo/17",
+ "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo", os.Geteuid()),
})
}
@@ -112,6 +113,7 @@ func (s *HTestSuite) TestSnapRunSnapExecEnv(c *C) {
"SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname/common", usr.HomeDir),
"SNAP_USER_DATA": fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir),
"SNAP_VERSION": "1.0",
+ "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.snapname", os.Geteuid()),
})
}
}
@@ -0,0 +1,30 @@
+summary: inspect all the set environment variables prefixed with SNAP_ and XDG_
+prepare: |
+ snapbuild $TESTSLIB/snaps/test-snapd-tools .
+ snap install --dangerous test-snapd-tools_1.0_all.snap
+restore: |
+ rm -f *.snap
+execute: |
+ echo "Collect SNAP and XDG environment variables"
+ test-snapd-tools.env | egrep '^SNAP_' | sort > snap-vars.txt
+ test-snapd-tools.env | egrep '^XDG_' | sort > xdg-vars.txt
+
+ echo "Ensure that SNAP environment variables are what we expect"
+ egrep -q '^SNAP_ARCH=(amd64|i386|arm64|armhf)$' snap-vars.txt
+ egrep -q '^SNAP_COMMON=/var/snap/test-snapd-tools/common$' snap-vars.txt
+ egrep -q '^SNAP_DATA=/var/snap/test-snapd-tools/x1$' snap-vars.txt
+ egrep -q '^SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:$' snap-vars.txt
+ egrep -q '^SNAP_NAME=test-snapd-tools$' snap-vars.txt
+ # XXX: probably not something we ought to test
+ # egrep -q '^SNAP_REEXEC=0$' snap-vars.txt
+ egrep -q '^SNAP_REVISION=x1$' snap-vars.txt
+ egrep -q '^SNAP_USER_COMMON=/root/snap/test-snapd-tools/common$' snap-vars.txt
+ egrep -q '^SNAP_USER_DATA=/root/snap/test-snapd-tools/x1$' snap-vars.txt
+ egrep -q '^SNAP_VERSION=1.0$' snap-vars.txt
+ test $(wc -l < snap-vars.txt) -eq 10
+
+ echo "Enure that XDG environment variables are what we expect"
+ egrep -q '^XDG_RUNTIME_DIR=/run/user/0/snap.test-snapd-tools$' xdg-vars.txt
+ test $(wc -l < xdg-vars.txt) -eq 2
+debug: |
+ cat *-vars.txt

0 comments on commit 81bb592

Please sign in to comment.