gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/cmd/snap-update-ns/system_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 main_test 21 22 import ( 23 "bytes" 24 "io/ioutil" 25 "os" 26 "path/filepath" 27 28 . "gopkg.in/check.v1" 29 30 update "github.com/snapcore/snapd/cmd/snap-update-ns" 31 "github.com/snapcore/snapd/dirs" 32 "github.com/snapcore/snapd/osutil" 33 "github.com/snapcore/snapd/sandbox/cgroup" 34 "github.com/snapcore/snapd/testutil" 35 ) 36 37 type systemSuite struct{} 38 39 var _ = Suite(&systemSuite{}) 40 41 func (s *systemSuite) TestLockCgroup(c *C) { 42 dirs.SetRootDir(c.MkDir()) 43 defer dirs.SetRootDir("/") 44 45 restore := cgroup.MockVersion(cgroup.V1, nil) 46 defer restore() 47 48 var frozen []string 49 var thawed []string 50 happyFreeze := func(snapName string) error { 51 frozen = append(frozen, snapName) 52 return nil 53 } 54 happyThaw := func(snapName string) error { 55 thawed = append(thawed, snapName) 56 return nil 57 } 58 cgroup.MockFreezing(happyFreeze, happyThaw) 59 60 upCtx := update.NewSystemProfileUpdateContext("foo", false) 61 unlock, err := upCtx.Lock() 62 c.Assert(err, IsNil) 63 c.Check(unlock, NotNil) 64 65 c.Check(frozen, DeepEquals, []string{"foo"}) 66 c.Check(thawed, HasLen, 0) 67 68 unlock() 69 c.Check(frozen, DeepEquals, []string{"foo"}) 70 c.Check(thawed, DeepEquals, []string{"foo"}) 71 } 72 73 func (s *systemSuite) TestAssumptions(c *C) { 74 // Non-instances can access /tmp, /var/snap and /snap/$SNAP_NAME 75 upCtx := update.NewSystemProfileUpdateContext("foo", false) 76 as := upCtx.Assumptions() 77 c.Check(as.UnrestrictedPaths(), DeepEquals, []string{"/tmp", "/var/snap", "/snap/foo", "/var/lib/snapd/hostfs/tmp"}) 78 c.Check(as.ModeForPath("/stuff"), Equals, os.FileMode(0755)) 79 c.Check(as.ModeForPath("/tmp"), Equals, os.FileMode(0755)) 80 c.Check(as.ModeForPath("/var/lib/snapd/hostfs/tmp"), Equals, os.FileMode(0755)) 81 c.Check(as.ModeForPath("/var/lib/snapd/hostfs/tmp/snap.x11-server"), Equals, os.FileMode(0700)) 82 c.Check(as.ModeForPath("/var/lib/snapd/hostfs/tmp/snap.x11-server/tmp"), Equals, os.FileMode(1777)) 83 c.Check(as.ModeForPath("/var/lib/snapd/hostfs/tmp/snap.x11-server/foo"), Equals, os.FileMode(0755)) 84 c.Check(as.ModeForPath("/var/lib/snapd/hostfs/tmp/snap.x11-server/tmp/.X11-unix"), Equals, os.FileMode(1777)) 85 86 // Instances can, in addition, access /snap/$SNAP_INSTANCE_NAME 87 upCtx = update.NewSystemProfileUpdateContext("foo_instance", false) 88 as = upCtx.Assumptions() 89 c.Check(as.UnrestrictedPaths(), DeepEquals, []string{"/tmp", "/var/snap", "/snap/foo_instance", "/snap/foo", "/var/lib/snapd/hostfs/tmp"}) 90 } 91 92 func (s *systemSuite) TestLoadDesiredProfile(c *C) { 93 // Mock directories. 94 dirs.SetRootDir(c.MkDir()) 95 defer dirs.SetRootDir("/") 96 97 upCtx := update.NewSystemProfileUpdateContext("foo", false) 98 text := "/snap/foo/42/dir /snap/bar/13/dir none bind,rw 0 0\n" 99 100 // Write a desired system mount profile for snap "foo". 101 path := update.DesiredSystemProfilePath(upCtx.InstanceName()) 102 c.Assert(os.MkdirAll(filepath.Dir(path), 0755), IsNil) 103 c.Assert(ioutil.WriteFile(path, []byte(text), 0644), IsNil) 104 105 // Ask the system profile update helper to read the desired profile. 106 profile, err := upCtx.LoadDesiredProfile() 107 c.Assert(err, IsNil) 108 builder := &bytes.Buffer{} 109 profile.WriteTo(builder) 110 111 c.Check(builder.String(), Equals, text) 112 } 113 114 func (s *systemSuite) TestLoadCurrentProfile(c *C) { 115 // Mock directories. 116 dirs.SetRootDir(c.MkDir()) 117 defer dirs.SetRootDir("/") 118 119 upCtx := update.NewSystemProfileUpdateContext("foo", false) 120 text := "/snap/foo/42/dir /snap/bar/13/dir none bind,rw 0 0\n" 121 122 // Write a current system mount profile for snap "foo". 123 path := update.CurrentSystemProfilePath(upCtx.InstanceName()) 124 c.Assert(os.MkdirAll(filepath.Dir(path), 0755), IsNil) 125 c.Assert(ioutil.WriteFile(path, []byte(text), 0644), IsNil) 126 127 // Ask the system profile update helper to read the current profile. 128 profile, err := upCtx.LoadCurrentProfile() 129 c.Assert(err, IsNil) 130 builder := &bytes.Buffer{} 131 profile.WriteTo(builder) 132 133 // The profile is returned unchanged. 134 c.Check(builder.String(), Equals, text) 135 } 136 137 func (s *systemSuite) TestSaveCurrentProfile(c *C) { 138 // Mock directories and create directory for runtime mount profiles. 139 dirs.SetRootDir(c.MkDir()) 140 defer dirs.SetRootDir("/") 141 c.Assert(os.MkdirAll(dirs.SnapRunNsDir, 0755), IsNil) 142 143 upCtx := update.NewSystemProfileUpdateContext("foo", false) 144 text := "/snap/foo/42/dir /snap/bar/13/dir none bind,rw 0 0\n" 145 146 // Prepare a mount profile to be saved. 147 profile, err := osutil.LoadMountProfileText(text) 148 c.Assert(err, IsNil) 149 150 // Ask the system profile update to write the current profile. 151 c.Assert(upCtx.SaveCurrentProfile(profile), IsNil) 152 c.Check(update.CurrentSystemProfilePath(upCtx.InstanceName()), testutil.FileEquals, text) 153 } 154 155 func (s *systemSuite) TestDesiredSystemProfilePath(c *C) { 156 c.Check(update.DesiredSystemProfilePath("foo"), Equals, "/var/lib/snapd/mount/snap.foo.fstab") 157 } 158 159 func (s *systemSuite) TestCurrentSystemProfilePath(c *C) { 160 c.Check(update.CurrentSystemProfilePath("foo"), Equals, "/run/snapd/ns/snap.foo.fstab") 161 }