github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/snap/snapenv/snapenv_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2015 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package snapenv
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"os/user"
    27  	"testing"
    28  
    29  	. "gopkg.in/check.v1"
    30  
    31  	"github.com/snapcore/snapd/arch"
    32  	"github.com/snapcore/snapd/dirs"
    33  	"github.com/snapcore/snapd/features"
    34  	"github.com/snapcore/snapd/osutil"
    35  	"github.com/snapcore/snapd/osutil/sys"
    36  	"github.com/snapcore/snapd/snap"
    37  	"github.com/snapcore/snapd/testutil"
    38  )
    39  
    40  func Test(t *testing.T) { TestingT(t) }
    41  
    42  type HTestSuite struct {
    43  	testutil.BaseTest
    44  }
    45  
    46  var _ = Suite(&HTestSuite{})
    47  
    48  var mockYaml = []byte(`name: snapname
    49  version: 1.0
    50  apps:
    51   app:
    52    command: run-app
    53  hooks:
    54   configure:
    55  `)
    56  
    57  var mockSnapInfo = &snap.Info{
    58  	SuggestedName: "foo",
    59  	Version:       "1.0",
    60  	SideInfo: snap.SideInfo{
    61  		Revision: snap.R(17),
    62  	},
    63  }
    64  var mockClassicSnapInfo = &snap.Info{
    65  	SuggestedName: "foo",
    66  	Version:       "1.0",
    67  	SideInfo: snap.SideInfo{
    68  		Revision: snap.R(17),
    69  	},
    70  	Confinement: snap.ClassicConfinement,
    71  }
    72  
    73  func (s *HTestSuite) SetUpTest(c *C) {
    74  	s.BaseTest.SetUpTest(c)
    75  	s.BaseTest.AddCleanup(snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {}))
    76  }
    77  
    78  func (s *HTestSuite) TearDownTest(c *C) {
    79  	s.BaseTest.TearDownTest(c)
    80  }
    81  
    82  func (ts *HTestSuite) TestBasic(c *C) {
    83  	env := basicEnv(mockSnapInfo)
    84  	c.Assert(env, DeepEquals, osutil.Environment{
    85  		"SNAP":               fmt.Sprintf("%s/foo/17", dirs.CoreSnapMountDir),
    86  		"SNAP_COMMON":        "/var/snap/foo/common",
    87  		"SNAP_DATA":          "/var/snap/foo/17",
    88  		"SNAP_NAME":          "foo",
    89  		"SNAP_INSTANCE_NAME": "foo",
    90  		"SNAP_INSTANCE_KEY":  "",
    91  		"SNAP_VERSION":       "1.0",
    92  		"SNAP_REVISION":      "17",
    93  		"SNAP_ARCH":          arch.DpkgArchitecture(),
    94  		"SNAP_LIBRARY_PATH":  "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void",
    95  		"SNAP_REEXEC":        "",
    96  	})
    97  }
    98  
    99  func (ts *HTestSuite) TestUser(c *C) {
   100  	env := userEnv(mockSnapInfo, "/root")
   101  	c.Assert(env, DeepEquals, osutil.Environment{
   102  		"SNAP_USER_COMMON": "/root/snap/foo/common",
   103  		"SNAP_USER_DATA":   "/root/snap/foo/17",
   104  		"HOME":             "/root/snap/foo/17",
   105  		"XDG_RUNTIME_DIR":  fmt.Sprintf("/run/user/%d/snap.foo", sys.Geteuid()),
   106  		"SNAP_REAL_HOME":   "/root",
   107  	})
   108  }
   109  
   110  func (ts *HTestSuite) TestUserForClassicConfinement(c *C) {
   111  	dirs.SetRootDir(c.MkDir())
   112  	defer dirs.SetRootDir("/")
   113  	c.Assert(os.MkdirAll(dirs.FeaturesDir, 0755), IsNil)
   114  
   115  	// With the classic-preserves-xdg-runtime-dir feature disabled the snap
   116  	// per-user environment contains an override for XDG_RUNTIME_DIR.
   117  	env := userEnv(mockClassicSnapInfo, "/root")
   118  	c.Assert(env, DeepEquals, osutil.Environment{
   119  		// NOTE: Both HOME and XDG_RUNTIME_DIR are not defined here.
   120  		"SNAP_USER_COMMON": "/root/snap/foo/common",
   121  		"SNAP_USER_DATA":   "/root/snap/foo/17",
   122  		"XDG_RUNTIME_DIR":  fmt.Sprintf(dirs.GlobalRootDir+"/run/user/%d/snap.foo", sys.Geteuid()),
   123  		"SNAP_REAL_HOME":   "/root",
   124  	})
   125  
   126  	// With the classic-preserves-xdg-runtime-dir feature enabled the snap
   127  	// per-user environment contains no overrides for XDG_RUNTIME_DIR.
   128  	f := features.ClassicPreservesXdgRuntimeDir
   129  	c.Assert(ioutil.WriteFile(f.ControlFile(), nil, 0644), IsNil)
   130  	env = userEnv(mockClassicSnapInfo, "/root")
   131  	c.Assert(env, DeepEquals, osutil.Environment{
   132  		// NOTE: Both HOME and XDG_RUNTIME_DIR are not defined here.
   133  		"SNAP_USER_COMMON": "/root/snap/foo/common",
   134  		"SNAP_USER_DATA":   "/root/snap/foo/17",
   135  		"SNAP_REAL_HOME":   "/root",
   136  	})
   137  }
   138  
   139  func (s *HTestSuite) TestSnapRunSnapExecEnv(c *C) {
   140  	info, err := snap.InfoFromSnapYaml(mockYaml)
   141  	c.Assert(err, IsNil)
   142  	info.SideInfo.Revision = snap.R(42)
   143  
   144  	usr, err := user.Current()
   145  	c.Assert(err, IsNil)
   146  
   147  	homeEnv := os.Getenv("HOME")
   148  	defer os.Setenv("HOME", homeEnv)
   149  
   150  	for _, withHomeEnv := range []bool{true, false} {
   151  		if !withHomeEnv {
   152  			os.Setenv("HOME", "")
   153  		}
   154  
   155  		env := snapEnv(info)
   156  		c.Assert(env, DeepEquals, osutil.Environment{
   157  			"SNAP":               fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir),
   158  			"SNAP_COMMON":        "/var/snap/snapname/common",
   159  			"SNAP_DATA":          "/var/snap/snapname/42",
   160  			"SNAP_NAME":          "snapname",
   161  			"SNAP_INSTANCE_NAME": "snapname",
   162  			"SNAP_INSTANCE_KEY":  "",
   163  			"SNAP_VERSION":       "1.0",
   164  			"SNAP_REVISION":      "42",
   165  			"SNAP_ARCH":          arch.DpkgArchitecture(),
   166  			"SNAP_LIBRARY_PATH":  "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void",
   167  			"SNAP_REEXEC":        "",
   168  			"SNAP_USER_COMMON":   fmt.Sprintf("%s/snap/snapname/common", usr.HomeDir),
   169  			"SNAP_USER_DATA":     fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir),
   170  			"HOME":               fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir),
   171  			"XDG_RUNTIME_DIR":    fmt.Sprintf("/run/user/%d/snap.snapname", sys.Geteuid()),
   172  			"SNAP_REAL_HOME":     usr.HomeDir,
   173  		})
   174  	}
   175  }
   176  
   177  func (s *HTestSuite) TestParallelInstallSnapRunSnapExecEnv(c *C) {
   178  	info, err := snap.InfoFromSnapYaml(mockYaml)
   179  	c.Assert(err, IsNil)
   180  	info.SideInfo.Revision = snap.R(42)
   181  
   182  	usr, err := user.Current()
   183  	c.Assert(err, IsNil)
   184  
   185  	homeEnv := os.Getenv("HOME")
   186  	defer os.Setenv("HOME", homeEnv)
   187  
   188  	// pretend it's snapname_foo
   189  	info.InstanceKey = "foo"
   190  
   191  	for _, withHomeEnv := range []bool{true, false} {
   192  		if !withHomeEnv {
   193  			os.Setenv("HOME", "")
   194  		}
   195  
   196  		env := snapEnv(info)
   197  		c.Check(env, DeepEquals, osutil.Environment{
   198  			// Those are mapped to snap-specific directories by
   199  			// mount namespace setup
   200  			"SNAP":               fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir),
   201  			"SNAP_COMMON":        "/var/snap/snapname/common",
   202  			"SNAP_DATA":          "/var/snap/snapname/42",
   203  			"SNAP_NAME":          "snapname",
   204  			"SNAP_INSTANCE_NAME": "snapname_foo",
   205  			"SNAP_INSTANCE_KEY":  "foo",
   206  			"SNAP_VERSION":       "1.0",
   207  			"SNAP_REVISION":      "42",
   208  			"SNAP_ARCH":          arch.DpkgArchitecture(),
   209  			"SNAP_LIBRARY_PATH":  "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void",
   210  			"SNAP_REEXEC":        "",
   211  			// User's data directories are not mapped to
   212  			// snap-specific ones
   213  			"SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname_foo/common", usr.HomeDir),
   214  			"SNAP_USER_DATA":   fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir),
   215  			"HOME":             fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir),
   216  			"XDG_RUNTIME_DIR":  fmt.Sprintf("/run/user/%d/snap.snapname_foo", sys.Geteuid()),
   217  			"SNAP_REAL_HOME":   usr.HomeDir,
   218  		})
   219  	}
   220  }
   221  
   222  func (ts *HTestSuite) TestParallelInstallUser(c *C) {
   223  	info := *mockSnapInfo
   224  	info.InstanceKey = "bar"
   225  	env := userEnv(&info, "/root")
   226  
   227  	c.Assert(env, DeepEquals, osutil.Environment{
   228  		"SNAP_USER_COMMON": "/root/snap/foo_bar/common",
   229  		"SNAP_USER_DATA":   "/root/snap/foo_bar/17",
   230  		"HOME":             "/root/snap/foo_bar/17",
   231  		"XDG_RUNTIME_DIR":  fmt.Sprintf("/run/user/%d/snap.foo_bar", sys.Geteuid()),
   232  		"SNAP_REAL_HOME":   "/root",
   233  	})
   234  }
   235  
   236  func (ts *HTestSuite) TestParallelInstallUserForClassicConfinement(c *C) {
   237  	dirs.SetRootDir(c.MkDir())
   238  	defer dirs.SetRootDir("/")
   239  	c.Assert(os.MkdirAll(dirs.FeaturesDir, 0755), IsNil)
   240  
   241  	info := *mockClassicSnapInfo
   242  	info.InstanceKey = "bar"
   243  
   244  	// With the classic-preserves-xdg-runtime-dir feature disabled the snap
   245  	// per-user environment contains an override for XDG_RUNTIME_DIR.
   246  	env := userEnv(&info, "/root")
   247  	c.Assert(env, DeepEquals, osutil.Environment{
   248  		"SNAP_USER_COMMON": "/root/snap/foo_bar/common",
   249  		"SNAP_USER_DATA":   "/root/snap/foo_bar/17",
   250  		"XDG_RUNTIME_DIR":  fmt.Sprintf(dirs.GlobalRootDir+"/run/user/%d/snap.foo_bar", sys.Geteuid()),
   251  		"SNAP_REAL_HOME":   "/root",
   252  	})
   253  
   254  	// With the classic-preserves-xdg-runtime-dir feature enabled the snap
   255  	// per-user environment contains no overrides for XDG_RUNTIME_DIR.
   256  	f := features.ClassicPreservesXdgRuntimeDir
   257  	c.Assert(ioutil.WriteFile(f.ControlFile(), nil, 0644), IsNil)
   258  	env = userEnv(&info, "/root")
   259  	c.Assert(env, DeepEquals, osutil.Environment{
   260  		// NOTE, Both HOME and XDG_RUNTIME_DIR are not defined here.
   261  		"SNAP_USER_COMMON": "/root/snap/foo_bar/common",
   262  		"SNAP_USER_DATA":   "/root/snap/foo_bar/17",
   263  		"SNAP_REAL_HOME":   "/root",
   264  	})
   265  }
   266  
   267  func (s *HTestSuite) TestExtendEnvForRunForNonClassic(c *C) {
   268  	env := osutil.Environment{"TMPDIR": "/var/tmp"}
   269  
   270  	ExtendEnvForRun(env, mockSnapInfo)
   271  
   272  	c.Assert(env["SNAP_NAME"], Equals, "foo")
   273  	c.Assert(env["SNAP_COMMON"], Equals, "/var/snap/foo/common")
   274  	c.Assert(env["SNAP_DATA"], Equals, "/var/snap/foo/17")
   275  
   276  	c.Assert(env["TMPDIR"], Equals, "/var/tmp")
   277  }
   278  
   279  func (s *HTestSuite) TestExtendEnvForRunForClassic(c *C) {
   280  	env := osutil.Environment{"TMPDIR": "/var/tmp"}
   281  
   282  	ExtendEnvForRun(env, mockClassicSnapInfo)
   283  
   284  	c.Assert(env["SNAP_NAME"], Equals, "foo")
   285  	c.Assert(env["SNAP_COMMON"], Equals, "/var/snap/foo/common")
   286  	c.Assert(env["SNAP_DATA"], Equals, "/var/snap/foo/17")
   287  
   288  	c.Assert(env["TMPDIR"], Equals, "/var/tmp")
   289  }