diff options
| -rw-r--r-- | cmd/snap-update-ns/common.go | 5 | ||||
| -rw-r--r-- | cmd/snap-update-ns/common_test.go | 3 | ||||
| -rw-r--r-- | cmd/snap-update-ns/export_test.go | 31 | ||||
| -rw-r--r-- | sandbox/cgroup/export_test.go | 16 | ||||
| -rw-r--r-- | sandbox/cgroup/freezer.go (renamed from cmd/snap-update-ns/freezer.go) | 38 | ||||
| -rw-r--r-- | sandbox/cgroup/freezer_test.go (renamed from cmd/snap-update-ns/freezer_test.go) | 28 | ||||
| -rw-r--r-- | tests/main/lxd-no-fuse/task.yaml | 5 | ||||
| -rw-r--r-- | tests/main/lxd-snapfuse/task.yaml | 5 |
8 files changed, 75 insertions, 56 deletions
diff --git a/cmd/snap-update-ns/common.go b/cmd/snap-update-ns/common.go index b669e8a217..805d843f41 100644 --- a/cmd/snap-update-ns/common.go +++ b/cmd/snap-update-ns/common.go @@ -25,6 +25,7 @@ import ( "github.com/snapcore/snapd/cmd/snaplock" "github.com/snapcore/snapd/logger" "github.com/snapcore/snapd/osutil" + "github.com/snapcore/snapd/sandbox/cgroup" ) type CommonProfileUpdateContext struct { @@ -78,7 +79,7 @@ func (upCtx *CommonProfileUpdateContext) Lock() (func(), error) { // introduce a symlink that would cause us to mount something other // than what we expected). logger.Debugf("freezing processes of snap %q", instanceName) - if err := freezeSnapProcesses(instanceName); err != nil { + if err := cgroup.FreezeSnapProcesses(instanceName); err != nil { // If we cannot freeze the processes we should drop the lock. lock.Close() return nil, err @@ -88,7 +89,7 @@ func (upCtx *CommonProfileUpdateContext) Lock() (func(), error) { logger.Debugf("unlocking mount namespace of snap %q", instanceName) lock.Close() logger.Debugf("thawing processes of snap %q", instanceName) - thawSnapProcesses(instanceName) + cgroup.ThawSnapProcesses(instanceName) } return unlock, nil } diff --git a/cmd/snap-update-ns/common_test.go b/cmd/snap-update-ns/common_test.go index 400579bb1e..00e54c6426 100644 --- a/cmd/snap-update-ns/common_test.go +++ b/cmd/snap-update-ns/common_test.go @@ -31,6 +31,7 @@ import ( "github.com/snapcore/snapd/cmd/snaplock" "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" + "github.com/snapcore/snapd/sandbox/cgroup" "github.com/snapcore/snapd/testutil" ) @@ -55,7 +56,7 @@ func (s *commonSuite) TestInstanceName(c *C) { func (s *commonSuite) TestLock(c *C) { // Mock away real freezer code, allowing test code to return an error when freezing. var freezingError error - restore := update.MockFreezing(func(string) error { return freezingError }, func(string) error { return nil }) + restore := cgroup.MockFreezing(func(string) error { return freezingError }, func(string) error { return nil }) defer restore() // Mock system directories, we use the lock directory. dirs.SetRootDir(s.dir) diff --git a/cmd/snap-update-ns/export_test.go b/cmd/snap-update-ns/export_test.go index 7ef3d5bbe3..7c7a254d6a 100644 --- a/cmd/snap-update-ns/export_test.go +++ b/cmd/snap-update-ns/export_test.go @@ -23,8 +23,6 @@ import ( "os" "syscall" - . "gopkg.in/check.v1" - "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/osutil/sys" ) @@ -34,10 +32,6 @@ var ( ValidateInstanceName = validateInstanceName ProcessArguments = processArguments - // freezer - FreezeSnapProcesses = freezeSnapProcesses - ThawSnapProcesses = thawSnapProcesses - // utils PlanWritableMimic = planWritableMimic ExecWritableMimic = execWritableMimic @@ -149,31 +143,6 @@ func MockSystemCalls(sc SystemCalls) (restore func()) { } } -func MockFreezerCgroupDir(c *C) (restore func()) { - old := freezerCgroupDir - freezerCgroupDir = c.MkDir() - return func() { - freezerCgroupDir = old - } -} - -func FreezerCgroupDir() string { - return freezerCgroupDir -} - -func MockFreezing(freeze, thaw func(snapName string) error) (restore func()) { - oldFreeze := freezeSnapProcesses - oldThaw := thawSnapProcesses - - freezeSnapProcesses = freeze - thawSnapProcesses = thaw - - return func() { - freezeSnapProcesses = oldFreeze - thawSnapProcesses = oldThaw - } -} - func MockChangePerform(f func(chg *Change, as *Assumptions) ([]*Change, error)) func() { origChangePerform := changePerform changePerform = f diff --git a/sandbox/cgroup/export_test.go b/sandbox/cgroup/export_test.go index ab918ba2fa..35f8381391 100644 --- a/sandbox/cgroup/export_test.go +++ b/sandbox/cgroup/export_test.go @@ -18,6 +18,10 @@ */ package cgroup +import ( + . "gopkg.in/check.v1" +) + var ( Cgroup2SuperMagic = cgroup2SuperMagic ProbeCgroupVersion = probeCgroupVersion @@ -38,3 +42,15 @@ func MockFsRootPath(p string) (restore func()) { rootPath = old } } + +func MockFreezerCgroupDir(c *C) (restore func()) { + old := freezerCgroupDir + freezerCgroupDir = c.MkDir() + return func() { + freezerCgroupDir = old + } +} + +func FreezerCgroupDir() string { + return freezerCgroupDir +} diff --git a/cmd/snap-update-ns/freezer.go b/sandbox/cgroup/freezer.go index 9cce4557c6..c7220ad0a2 100644 --- a/cmd/snap-update-ns/freezer.go +++ b/sandbox/cgroup/freezer.go @@ -17,7 +17,7 @@ * */ -package main +package cgroup import ( "bytes" @@ -30,10 +30,22 @@ import ( var freezerCgroupDir = "/sys/fs/cgroup/freezer" -var ( - freezeSnapProcesses = freezeSnapProcessesImpl - thawSnapProcesses = thawSnapProcessesImpl -) +// FreezeSnapProcessesImpl suspends execution of all the processes belonging to +// a given snap. Processes remain frozen until ThawSnapProcesses is called, +// care must be taken not to freezer processes indefinitely. +// +// The freeze operation is not instant. Once commenced it proceeds +// asynchronously. Internally the function waits for the freezing to complete +// in at most 3000ms. If this time is insufficient then the processes are +// thawed and an error is returned. +// +// This operation can be mocked with MockFreezing +var FreezeSnapProcesses = freezeSnapProcessesImpl + +// ThawSnapProcesses resumes execution of all processes belonging to a given snap. +// +// This operation can be mocked with MockFreezing +var ThawSnapProcesses = thawSnapProcessesImpl // freezeSnapProcessesImpl freezes all the processes originating from the given snap. // Processes are frozen regardless of which particular snap application they @@ -61,7 +73,7 @@ func freezeSnapProcessesImpl(snapName string) error { return nil } // If we got here then we timed out after seeing FREEZING for too long. - thawSnapProcesses(snapName) // ignore the error, this is best-effort. + ThawSnapProcesses(snapName) // ignore the error, this is best-effort. return fmt.Errorf("cannot finish freezing processes of snap %q", snapName) } @@ -77,3 +89,17 @@ func thawSnapProcessesImpl(snapName string) error { } return nil } + +// MockFreezing replaces the real implementation of freeze and thaw. +func MockFreezing(freeze, thaw func(snapName string) error) (restore func()) { + oldFreeze := FreezeSnapProcesses + oldThaw := ThawSnapProcesses + + FreezeSnapProcesses = freeze + ThawSnapProcesses = thaw + + return func() { + FreezeSnapProcesses = oldFreeze + ThawSnapProcesses = oldThaw + } +} diff --git a/cmd/snap-update-ns/freezer_test.go b/sandbox/cgroup/freezer_test.go index 89813ffbed..668cb419e8 100644 --- a/cmd/snap-update-ns/freezer_test.go +++ b/sandbox/cgroup/freezer_test.go @@ -17,7 +17,7 @@ * */ -package main_test +package cgroup_test import ( "fmt" @@ -26,7 +26,7 @@ import ( . "gopkg.in/check.v1" - update "github.com/snapcore/snapd/cmd/snap-update-ns" + "github.com/snapcore/snapd/sandbox/cgroup" "github.com/snapcore/snapd/testutil" ) @@ -35,56 +35,56 @@ type freezerSuite struct{} var _ = Suite(&freezerSuite{}) func (s *freezerSuite) TestFreezeSnapProcesses(c *C) { - restore := update.MockFreezerCgroupDir(c) + restore := cgroup.MockFreezerCgroupDir(c) defer restore() n := "foo" // snap name - p := filepath.Join(update.FreezerCgroupDir(), fmt.Sprintf("snap.%s", n)) // snap freezer cgroup + p := filepath.Join(cgroup.FreezerCgroupDir(), fmt.Sprintf("snap.%s", n)) // snap freezer cgroup f := filepath.Join(p, "freezer.state") // freezer.state file of the cgroup // When the freezer cgroup filesystem doesn't exist we do nothing at all. - c.Assert(update.FreezeSnapProcesses(n), IsNil) + c.Assert(cgroup.FreezeSnapProcesses(n), IsNil) _, err := os.Stat(f) c.Assert(os.IsNotExist(err), Equals, true) // When the freezer cgroup filesystem exists but the particular cgroup // doesn't exist we don nothing at all. - c.Assert(os.MkdirAll(update.FreezerCgroupDir(), 0755), IsNil) - c.Assert(update.FreezeSnapProcesses(n), IsNil) + c.Assert(os.MkdirAll(cgroup.FreezerCgroupDir(), 0755), IsNil) + c.Assert(cgroup.FreezeSnapProcesses(n), IsNil) _, err = os.Stat(f) c.Assert(os.IsNotExist(err), Equals, true) // When the cgroup exists we write FROZEN the freezer.state file. c.Assert(os.MkdirAll(p, 0755), IsNil) - c.Assert(update.FreezeSnapProcesses(n), IsNil) + c.Assert(cgroup.FreezeSnapProcesses(n), IsNil) _, err = os.Stat(f) c.Assert(err, IsNil) c.Assert(f, testutil.FileEquals, `FROZEN`) } func (s *freezerSuite) TestThawSnapProcesses(c *C) { - restore := update.MockFreezerCgroupDir(c) + restore := cgroup.MockFreezerCgroupDir(c) defer restore() n := "foo" // snap name - p := filepath.Join(update.FreezerCgroupDir(), fmt.Sprintf("snap.%s", n)) // snap freezer cgroup + p := filepath.Join(cgroup.FreezerCgroupDir(), fmt.Sprintf("snap.%s", n)) // snap freezer cgroup f := filepath.Join(p, "freezer.state") // freezer.state file of the cgroup // When the freezer cgroup filesystem doesn't exist we do nothing at all. - c.Assert(update.ThawSnapProcesses(n), IsNil) + c.Assert(cgroup.ThawSnapProcesses(n), IsNil) _, err := os.Stat(f) c.Assert(os.IsNotExist(err), Equals, true) // When the freezer cgroup filesystem exists but the particular cgroup // doesn't exist we don nothing at all. - c.Assert(os.MkdirAll(update.FreezerCgroupDir(), 0755), IsNil) - c.Assert(update.ThawSnapProcesses(n), IsNil) + c.Assert(os.MkdirAll(cgroup.FreezerCgroupDir(), 0755), IsNil) + c.Assert(cgroup.ThawSnapProcesses(n), IsNil) _, err = os.Stat(f) c.Assert(os.IsNotExist(err), Equals, true) // When the cgroup exists we write THAWED the freezer.state file. c.Assert(os.MkdirAll(p, 0755), IsNil) - c.Assert(update.ThawSnapProcesses(n), IsNil) + c.Assert(cgroup.ThawSnapProcesses(n), IsNil) _, err = os.Stat(f) c.Assert(err, IsNil) c.Assert(f, testutil.FileEquals, `THAWED`) diff --git a/tests/main/lxd-no-fuse/task.yaml b/tests/main/lxd-no-fuse/task.yaml index 516eacd6b3..f8149f2983 100644 --- a/tests/main/lxd-no-fuse/task.yaml +++ b/tests/main/lxd-no-fuse/task.yaml @@ -23,7 +23,10 @@ execute: | lxd.lxc config set core.proxy_https "$http_proxy" fi - lxd.lxc launch "images:ubuntu/18.04" my-ubuntu + # The snapd package we build as part of the tests will only run on the + # distro we build on. So we need to launch the right ubuntu version. + . /etc/os-release + lxd.lxc launch "ubuntu:${VERSION_ID}" my-ubuntu echo "Remove fuse to trigger the fuse sanity check" lxd.lxc exec my-ubuntu -- apt autoremove -y fuse diff --git a/tests/main/lxd-snapfuse/task.yaml b/tests/main/lxd-snapfuse/task.yaml index da4c5d6e7f..d1a20d2c96 100644 --- a/tests/main/lxd-snapfuse/task.yaml +++ b/tests/main/lxd-snapfuse/task.yaml @@ -29,7 +29,10 @@ execute: | lxd.lxc config set core.proxy_https "$http_proxy" fi - lxd.lxc launch "images:ubuntu/18.04" my-ubuntu + # The snapd package we build as part of the tests will only run on the + # distro we build on. So we need to launch the right ubuntu version. + . /etc/os-release + lxd.lxc launch "ubuntu:${VERSION_ID}" my-ubuntu echo "Install snapd" lxd.lxc exec my-ubuntu -- mkdir -p "$GOHOME" |
