diff --git a/cmd/snap-failure/cmd_snapd.go b/cmd/snap-failure/cmd_snapd.go index 1892e728f9d..2062b426eae 100644 --- a/cmd/snap-failure/cmd_snapd.go +++ b/cmd/snap-failure/cmd_snapd.go @@ -31,6 +31,8 @@ import ( "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/logger" "github.com/snapcore/snapd/osutil" + "github.com/snapcore/snapd/release" + "github.com/snapcore/snapd/snapdtool" ) func init() { @@ -112,6 +114,16 @@ var ( ) func (c *cmdSnapd) Execute(args []string) error { + if release.OnClassic { + // snap failure was invoked in a classic system, while there are + // scenarios in which it may make sense, they are limited to a + // case when snapd is being reexec'd from the snapd snap + if !snapdtool.DistroSupportsReExec() || !snapdtool.IsReexecEnabled() { + logger.Noticef("re-exec unsupported or disabled") + return nil + } + } + var snapdPath string // find previous the snapd snap prevRev, err := prevRevision("snapd") diff --git a/cmd/snap-failure/cmd_snapd_test.go b/cmd/snap-failure/cmd_snapd_test.go index 729066defde..3143b1187ee 100644 --- a/cmd/snap-failure/cmd_snapd_test.go +++ b/cmd/snap-failure/cmd_snapd_test.go @@ -31,6 +31,7 @@ import ( failure "github.com/snapcore/snapd/cmd/snap-failure" "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" + "github.com/snapcore/snapd/release" "github.com/snapcore/snapd/snap" "github.com/snapcore/snapd/testutil" ) @@ -438,3 +439,38 @@ func (r *failureSuite) TestStickySnapdSocket(c *C) { // make sure the socket file was deleted c.Assert(osutil.FileExists(dirs.SnapdSocket), Equals, false) } + +func (r *failureSuite) testNoReexec(c *C) { + origArgs := os.Args + defer func() { os.Args = origArgs }() + + writeSeqFile(c, "snapd", snap.R(100), []*snap.SideInfo{ + {Revision: snap.R(99)}, + {Revision: snap.R(100)}, + }) + + // mock snapd command from 'previous' revision + snapdCmd := testutil.MockCommand(c, filepath.Join(dirs.SnapMountDir, "snapd", "99", "/usr/lib/snapd/snapd"), "exit 1") + defer snapdCmd.Restore() + + os.Args = []string{"snap-failure", "snapd"} + err := failure.Run() + c.Check(err, IsNil) + + c.Check(snapdCmd.Calls(), HasLen, 0) + c.Check(r.systemctlCmd.Calls(), HasLen, 0) + c.Check(r.log.String(), testutil.Contains, "re-exec unsupported or disabled") +} + +func (r *failureSuite) TestReexecDisabled(c *C) { + os.Setenv("SNAP_REEXEC", "0") + defer os.Unsetenv("SNAP_REEXEC") + r.testNoReexec(c) + +} + +func (r *failureSuite) TestReexecUnsupported(c *C) { + r.AddCleanup(release.MockReleaseInfo(&release.OS{ID: "fedora"})) + dirs.SetRootDir(r.rootdir) + r.testNoReexec(c) +} diff --git a/cmd/snap-failure/main_test.go b/cmd/snap-failure/main_test.go index 1ae4d81560d..a5e3411abc8 100644 --- a/cmd/snap-failure/main_test.go +++ b/cmd/snap-failure/main_test.go @@ -28,6 +28,7 @@ import ( failure "github.com/snapcore/snapd/cmd/snap-failure" "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/logger" + "github.com/snapcore/snapd/release" "github.com/snapcore/snapd/testutil" ) @@ -59,6 +60,8 @@ func (r *failureSuite) SetUpTest(c *C) { failure.Stderr = r.stderr failure.Stdout = r.stdout + r.AddCleanup(release.MockReleaseInfo(&release.OS{ID: "ubuntu"})) + r.rootdir = c.MkDir() dirs.SetRootDir(r.rootdir) r.AddCleanup(func() { dirs.SetRootDir("/") })