Skip to content

Commit

Permalink
Revert "many: support killing running snap apps (canonical#14160)"
Browse files Browse the repository at this point in the history
This reverts commit 5f7d584.

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
  • Loading branch information
ZeyadYasser committed Sep 5, 2024
1 parent e6730dc commit 6e9df44
Show file tree
Hide file tree
Showing 11 changed files with 3 additions and 646 deletions.
13 changes: 0 additions & 13 deletions snap/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import (
"github.com/snapcore/snapd/snap/naming"
"github.com/snapcore/snapd/snapdtool"
"github.com/snapcore/snapd/strutil"
"github.com/snapcore/snapd/systemd"
"github.com/snapcore/snapd/timeout"
)

Expand Down Expand Up @@ -235,18 +234,6 @@ func NoneSecurityTag(snapName, uniqueName string) string {
return ScopedSecurityTag(snapName, "none", uniqueName)
}

// TransientScopeGlob returns the glob pattern matching
// snap's transient scope units.
//
// e.g. snap.hello-world.sh-4706fe54-7802-4808-aa7e-ae8b567239e0.scope
func TransientScopeGlob(snapName string) (string, error) {
snapSecurityTag := SecurityTag(snapName)
unitPrefix, err := systemd.SecurityTagToUnitName(snapSecurityTag)
// XXX: Should we also match snap components glob pattern (i.e. snap.name+*.*.scope?
// snap.name.*.scope
return unitPrefix + ".*.scope", err
}

// BaseDataDir returns the base directory for snap data locations.
func BaseDataDir(name string) string {
return filepath.Join(dirs.SnapDataDir, name)
Expand Down
32 changes: 0 additions & 32 deletions snap/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2370,38 +2370,6 @@ hooks:
c.Check(hook.SecurityTag(), Equals, "snap.test-snap_instance.hook.install")
}

func (s *infoSuite) TestTransientScopeGlob(c *C) {
pattern, err := snap.TransientScopeGlob("some-snap")
c.Assert(err, IsNil)
c.Check(pattern, Equals, "snap.some-snap.*.scope")
matched, err := filepath.Match(pattern, "snap.some-snap.some-app-4706fe54-7802-4808-aa7e-ae8b567239e0.scope")
c.Assert(err, IsNil)
c.Check(matched, Equals, true)
}

func (s *infoSuite) TestTransientScopeGlobInstance(c *C) {
pattern, err := snap.TransientScopeGlob("some-snap_instance-1")
c.Assert(err, IsNil)
c.Check(pattern, Equals, "snap.some-snap_instance-1.*.scope")
// matches instance
matched, err := filepath.Match(pattern, "snap.some-snap_instance-1.some-app-4706fe54-7802-4808-aa7e-ae8b567239e0.scope")
c.Assert(err, IsNil)
c.Check(matched, Equals, true)
// but not other instances
matched, err = filepath.Match(pattern, "snap.some-snap_instance-2.some-app-4706fe54-7802-4808-aa7e-ae8b567239e0.scope")
c.Assert(err, IsNil)
c.Check(matched, Equals, false)
// or the main snap
matched, err = filepath.Match(pattern, "snap.some-snap.some-app-4706fe54-7802-4808-aa7e-ae8b567239e0.scope")
c.Assert(err, IsNil)
c.Check(matched, Equals, false)
}

func (s *infoSuite) TestTransientScopeError(c *C) {
_, err := snap.TransientScopeGlob("invalid?name")
c.Assert(err.Error(), Equals, "invalid character in security tag: '?'")
}

func (s *infoSuite) TestComponentMountDir(c *C) {
dir := snap.ComponentMountDir("comp", snap.R(1), "snap")
c.Check(dir, Equals, filepath.Join(dirs.SnapMountDir, "snap", "components", "mnt", "comp", "1"))
Expand Down
4 changes: 0 additions & 4 deletions systemd/emulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,6 @@ func (s *emulation) ListMountUnits(snapName, origin string) ([]string, error) {
return nil, &notImplementedError{"ListMountUnits"}
}

func (s *emulation) ListUnits(pattern string) ([]string, error) {
return nil, &notImplementedError{"ListUnits"}
}

func (s *emulation) Mask(service string) error {
_, err := systemctlCmd("--root", s.rootDir, "mask", service)
return err
Expand Down
24 changes: 0 additions & 24 deletions systemd/systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@ type Systemd interface {
// ListMountUnits gets the list of targets of the mount units created by
// the `origin` module for the given snap
ListMountUnits(snapName, origin string) ([]string, error)
// ListUnits get the list of units currently in memory including transient units.
ListUnits(pattern string) ([]string, error)
// Mask the given service.
Mask(service string) error
// Unmask the given service.
Expand Down Expand Up @@ -1696,28 +1694,6 @@ func (s *systemd) ListMountUnits(snapName, origin string) ([]string, error) {
return mountPoints, nil
}

func (s *systemd) ListUnits(pattern string) ([]string, error) {
out, err := s.systemctl("list-units", "--output=json", pattern)
if err != nil {
return nil, err
}

type rawUnit struct {
UnitName string `json:"unit"`
}
var parsedUnits []rawUnit
err = json.Unmarshal(out, &parsedUnits)
if err != nil {
return nil, fmt.Errorf("cannot parse systemctl output: %w", err)
}

units := make([]string, len(parsedUnits))
for i, parsedUnit := range parsedUnits {
units[i] = parsedUnit.UnitName
}
return units, nil
}

func (s *systemd) ReloadOrRestart(serviceNames []string) error {
if s.mode == GlobalUserMode {
panic("cannot call restart with GlobalUserMode")
Expand Down
47 changes: 0 additions & 47 deletions systemd/systemd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2311,53 +2311,6 @@ X-SnapdOrigin=%s
c.Check(err, IsNil)
}

func (s *SystemdTestSuite) TestListUnitsEmpty(c *C) {
s.outs = [][]byte{
[]byte("[]"),
}

sysd := New(UserMode, nil)
units, err := sysd.ListUnits("snap.some-snap.*.scope")
c.Check(units, HasLen, 0)
c.Check(err, IsNil)
}

func (s *SystemdTestSuite) TestListUnitsMalformed(c *C) {
s.outs = [][]byte{
[]byte(`[{"unit":}]
`),
}

sysd := New(UserMode, nil)
units, err := sysd.ListUnits("snap.some-snap.*.scope")
c.Check(units, HasLen, 0)
c.Check(err, ErrorMatches, "cannot parse systemctl output:.*")
}

func (s *SystemdTestSuite) TestListUnitsHappy(c *C) {
type rawUnit struct {
UnitName string `json:"unit"`
}
var fakeUnits = []rawUnit{
{UnitName: "snap.some-snap.some-app-7414e1a3-6d08-43ff-a81c-6547242a78b0.scope"},
{UnitName: "snap.some-snap.some-app-ff81c9d9-cabb-494b-84b5-494ba945a458.scope"},
{UnitName: "snap.some-snap.some-other-app-f3a1d6fa-c660-4b7d-a450-aaa8849614c7.scope"},
}
systemctlOutput, err := json.Marshal(fakeUnits)
c.Assert(err, IsNil)

s.outs = [][]byte{systemctlOutput}

sysd := New(UserMode, nil)
units, err := sysd.ListUnits("some-snap.*.scope")
c.Assert(err, IsNil)
c.Check(units, DeepEquals, []string{
"snap.some-snap.some-app-7414e1a3-6d08-43ff-a81c-6547242a78b0.scope",
"snap.some-snap.some-app-ff81c9d9-cabb-494b-84b5-494ba945a458.scope",
"snap.some-snap.some-other-app-f3a1d6fa-c660-4b7d-a450-aaa8849614c7.scope",
})
}

func (s *SystemdTestSuite) TestMountHappy(c *C) {
sysd := New(SystemMode, nil)

Expand Down
1 change: 0 additions & 1 deletion usersession/agent/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
var (
SessionInfoCmd = sessionInfoCmd
ServiceControlCmd = serviceControlCmd
AppControlCmd = appControlCmd
ServiceStatusCmd = serviceStatusCmd
PendingRefreshNotificationCmd = pendingRefreshNotificationCmd
FinishRefreshNotificationCmd = finishRefreshNotificationCmd
Expand Down
1 change: 0 additions & 1 deletion usersession/agent/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ const (
errorKindLoginRequired = errorKind("login-required")
errorKindServiceControl = errorKind("service-control")
errorKindServiceStatus = errorKind("service-status")
errorKindAppControl = errorKind("app-control")
)

type errorValue interface{}
Expand Down
85 changes: 0 additions & 85 deletions usersession/agent/rest_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ import (
"mime"
"net/http"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"time"

"github.com/mvo5/goconfigparser"
Expand All @@ -48,7 +46,6 @@ var restApi = []*Command{
sessionInfoCmd,
serviceControlCmd,
serviceStatusCmd,
appControlCmd,
pendingRefreshNotificationCmd,
finishRefreshNotificationCmd,
}
Expand All @@ -74,11 +71,6 @@ var (
GET: serviceStatus,
}

appControlCmd = &Command{
Path: "/v1/app-control",
POST: postAppControl,
}

pendingRefreshNotificationCmd = &Command{
Path: "/v1/notifications/pending-refresh",
POST: postPendingRefreshNotification,
Expand Down Expand Up @@ -580,80 +572,3 @@ func postRefreshFinishedNotification(c *Command, r *http.Request) Response {
}
return SyncResponse(nil)
}

func collectSnapAppUnits(snapName string, sysd systemd.Systemd) (units []string, err error) {
pattern, err := snap.TransientScopeGlob(snapName)
if err != nil {
return nil, err
}

return sysd.ListUnits(pattern)
}

func appKill(inst *client.AppInstruction, sysd systemd.Systemd) Response {
// TODO: Use inst.Reason as a hint to explain to users what is happening
if inst.Signal != syscall.SIGKILL {
return BadRequest("only signal SIGKILL is supported")
}

var units []string
for _, snapName := range inst.Snaps {
if err := snap.ValidateInstanceName(snapName); err != nil {
return BadRequest("invalid snap instance name %q: %v", snapName, err)
}
snapAppUnits, err := collectSnapAppUnits(snapName, sysd)
if err != nil {
return InternalError("cannot collect snap app units for %q: %v", snapName, err)
}
units = append(units, snapAppUnits...)
}

killErrors := make(map[string]string)
for _, unit := range units {
signal := strconv.Itoa(int(inst.Signal))
if err := sysd.Kill(unit, signal, "all"); err != nil {
killErrors[unit] = err.Error()
}
}

if len(killErrors) != 0 {
return SyncResponse(&resp{
Type: ResponseTypeError,
Status: 500,
Result: &errorResult{
Message: "some transient units failed to be killed",
Kind: errorKindAppControl,
Value: map[string]interface{}{
"kill-errors": killErrors,
},
},
})
}

return SyncResponse(nil)
}

var appInstructionDispTable = map[string]func(*client.AppInstruction, systemd.Systemd) Response{
"kill": appKill,
}

func postAppControl(c *Command, r *http.Request) Response {
if ok, resp := validateJSONRequest(r); !ok {
return resp
}

decoder := json.NewDecoder(r.Body)
var inst client.AppInstruction
if err := decoder.Decode(&inst); err != nil {
return BadRequest("cannot decode request body into service instruction: %v", err)
}
impl := appInstructionDispTable[inst.Action]
if impl == nil {
return BadRequest("unknown action %s", inst.Action)
}
// Prevent multiple systemd actions from being carried out simultaneously
systemdLock.Lock()
defer systemdLock.Unlock()
sysd := systemd.New(systemd.UserMode, noopReporter{})
return impl(&inst, sysd)
}
Loading

0 comments on commit 6e9df44

Please sign in to comment.