2828 Commits

Author SHA1 Message Date
Alfonso Sánchez-Beato
ca4ffa568e daemon: support removing components 2024-07-10 07:49:52 -04:00
Maciej Borzecki
26e8fb456b daemon: fix data race accessing requestedRestart
Data race was picked up in the tests:

==================
WARNING: DATA RACE
Write at 0x00c00041a648 by goroutine 175:
  github.com/snapcore/snapd/daemon.(*Daemon).HandleRestart()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon.go:446 +0x198
  github.com/snapcore/snapd/overlord/restart.(*RestartManager).handleRestart()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/overlord/restart/restart.go:242 +0x10e
  github.com/snapcore/snapd/overlord/restart.Request()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/overlord/restart/restart.go:348 +0xd0
  github.com/snapcore/snapd/overlord/standby.(*StandbyOpinions).Start.func1()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/overlord/standby/standby.go:102 +0xe4

Previous read at 0x00c00041a648 by goroutine 171:
  github.com/snapcore/snapd/daemon.(*Daemon).Stop()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon.go:531 +0x211
  github.com/snapcore/snapd/daemon.(*daemonSuite).TestRestartIntoSocketModeNoNewChanges()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon_test.go:1372 +0x3ed
  runtime.call16()
      /snap/go/10630/src/runtime/asm_amd64.s:770 +0x42
  reflect.Value.Call()
      /snap/go/10630/src/reflect/value.go:380 +0xb5
  gopkg.in/check%2ev1.(*suiteRunner).forkTest.func1()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:775 +0x9c5
  gopkg.in/check%2ev1.(*suiteRunner).forkCall.func1()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:669 +0xe9

Goroutine 175 (running) created at:
  github.com/snapcore/snapd/overlord/standby.(*StandbyOpinions).Start()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/overlord/standby/standby.go:96 +0xfc
  github.com/snapcore/snapd/daemon.(*Daemon).initStandbyHandling()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon.go:320 +0x69c
  github.com/snapcore/snapd/daemon.(*Daemon).Start()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon.go:379 +0x93d
  github.com/snapcore/snapd/daemon.(*daemonSuite).TestRestartIntoSocketModeNoNewChanges()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon_test.go:1359 +0x134
  runtime.call16()
      /snap/go/10630/src/runtime/asm_amd64.s:770 +0x42
  reflect.Value.Call()
      /snap/go/10630/src/reflect/value.go:380 +0xb5
  gopkg.in/check%2ev1.(*suiteRunner).forkTest.func1()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:775 +0x9c5
  gopkg.in/check%2ev1.(*suiteRunner).forkCall.func1()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:669 +0xe9

Goroutine 171 (running) created at:
  gopkg.in/check%2ev1.(*suiteRunner).forkCall()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:666 +0x5ba
  gopkg.in/check%2ev1.(*suiteRunner).forkTest()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:757 +0x155
  gopkg.in/check%2ev1.(*suiteRunner).runTest()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:812 +0x419
  gopkg.in/check%2ev1.(*suiteRunner).run()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/check.go:618 +0x3c6
  gopkg.in/check%2ev1.Run()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/run.go:92 +0x44
  gopkg.in/check%2ev1.RunAll()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/run.go:84 +0x124
  gopkg.in/check%2ev1.TestingT()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/vendor/gopkg.in/check.v1/run.go:72 +0x5d3
  github.com/snapcore/snapd/daemon.Test()
      /home/runner/work/snapd/snapd/src/github.com/snapcore/snapd/daemon/daemon_test.go:63 +0x26
  testing.tRunner()
      /snap/go/10630/src/testing/testing.go:1689 +0x21e
  testing.(*T).Run.gowrap1()
      /snap/go/10630/src/testing/testing.go:1742 +0x44
==================
OK: 682 passed
--- FAIL: Test (71.79s)
    testing.go:1398: race detected during execution of test
FAIL
FAIL	github.com/snapcore/snapd/daemon	72.143s

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-07-03 12:06:11 +01:00
Maciej Borzecki
61d7eba0cd daemon, cmd/snapd: propagate context (#14130)
* daemon: establish a cancelation chain for incoming API requests

Establish a cancelation chain for incoming API requests, to ensure orderly
shutdown. This prevents a situation in which an API request, such as notices
wait can block snapd shtudown for a long time.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: return 500 when the request context gets canceled

Request's can be canceled based on the code actually issuing a cancel on the
associted context, hence an Internal Server Error seems more appropriate.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* o/snapstate: leave TODOs about using caller provided context

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: pass down request context where possible

Pass the context from the API request further down.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: set context in snap instruction for many-snap operation

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: pass context as an explicit parameter to request handlers

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: pass context

Thanks to @ZeyadYasser

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: comment on Start() taking a context.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: add unit tests targeting context passed to Start()

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: drop unit test for hijacked context

The test isn't very useful. Another option to trigger this would be to call
Stop() without a prior call to Start(), but this segfaults on
d.standbyOpinions.Stop(), so it'c clear this needs a followup fix or callign
Stop() this way isn't supported.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

---------

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-06-28 14:54:52 +02:00
Alfonso Sánchez-Beato
d4167958aa daemon: set only component information in returned api data
if only components are going to be installed.
2024-06-23 23:22:14 +01:00
Zygmunt Krynicki
64aee549b5 daemon: fix racy tests caused by copy-pasted variable
The test creates two symbolic links but reuses some information about them by
passing the same variable. Use the proper variable to avoid being sensitive to
symlink mtime differences on fast enough systems.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-06-19 13:34:45 +02:00
Maciej Borzecki
336ec014f8 daemon: ensure stability of components list in snap info
Information about components of a snap is repacked from a map to a list. Since
map iteration does not guarantee stability, we need to sort the list of
components to keep the tests reliable.

Fixes the following failure:

FAIL: api_snaps_test.go:1611: snapsSuite.TestMapLocalFieldsWithComponents

api_snaps_test.go:1809:
    c.Check(daemon.MapLocal(about, nil), check.DeepEquals, expected)
... obtained *client.Snap = &client.Snap{...}
... expected *client.Snap = &client.Snap{...}
... Difference:
...     Components[2].Name: "comp-4" != "comp-3"
...     Components[2].Summary: "" != "summary 3"
...     Components[2].Description: "" != "description 3"
...     Components[3].Name: "comp-3" != "comp-4"
...     Components[3].Summary: "summary 3" != ""
...     Components[3].Description: "description 3" != ""

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-06-19 08:56:31 +02:00
Alfonso Sánchez-Beato
13284fccb4 daemon: send components information on GET /v2/snaps 2024-06-18 18:31:42 +01:00
Alfonso Sánchez-Beato
2c60c18d01 daemon: fix some messages produced on component installation 2024-06-18 18:31:42 +01:00
Miguel Pires
8128ed20bb many: rename aspect/bundle to view/registry
This changes the naming of the aspects feature to be "registry" instead
of bundle (i.e., a configuration space backed with its own storage) and
"view" instead of aspect. Once this lands, anyone that has this enabled
needs to unset the experimental flag and rename the state entry before
refreshing snapd and then re-enable.

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
2024-06-17 17:16:57 +02:00
Andrew Phelps
06082e1fd5 many: add Provenance field to ComponentInfo (#14067)
Add a Provenance to snap.ComponentInfo. This allows snap pack to work with components that define a provenance in their component.yaml file.

* snap, interfaces, daemon: add Provenance field to ComponentInfo

* s/pack: test packing component with provenance

* snap: validate provenance when parsing component.yaml
2024-06-13 09:35:30 +02:00
Andrew Phelps
5c788ad1f9 many: replace interfaces.Repository.AddSnap with AddAppSet (#13772)
* many: replace interfaces.Repo.AddSnap with AddAppSet

* interfaces: remove repo.RemovePlug since it is unused

* interfaces: simplify check for a snap's presence in interfaces repo

* interfaces: update doc comment on Repository.AddAppSet

* o/ifacestate: fix duplicate init of app set following refactor in master

* o/snapstate: fix bug that caused implicit slots to be added to core and snapd snaps
2024-06-11 19:05:38 +01:00
Sergio Costas
1e0d03f761 api-snaps: add refresh-observe access to /v2/snaps/{name} (#13931)
Access to /v2/snaps/{name} is required for snap-refresh-observe
because it is needed to get the path for the XXXXX.desktop file,
which is needed for the icon and the visible name.

It should not be a problem because /v2/snaps is already
enabled.
2024-06-05 12:46:07 +02:00
Andrew Phelps
13676e7402 many: update snap.ReadComponentInfoFromContainer to take in an optional snap.ComponentSideInfo that contains the component revision (#13979)
* many: update snap.ReadComponentInfoFromContainer to take in an optional snap.ComponentSideInfo that contains the component revision

* snap: add back NewComponentInfo function

* daemon, snap, interfaces: replace manual creation of ComponentInfo with usage of NewComponentInfo
2024-06-03 17:27:23 +02:00
Andrew Phelps
e532d3f8ae daemon: make sure to re-pin validation sets that were already pinned when enforcing new validation sets (#13989)
* daemon: make sure to re-pin validation sets that were already pinned when enforcing new validation sets

* tests: update snap-refresh-enforce to verify that validation sets do not become unpinned when enforcing new sets
2024-06-03 17:26:59 +02:00
Maciej Borzecki
9e2e5e206a o/snapstate: handling of unexpected runtime restart (#14002)
* o/snapstate: when invoked for rollback, check for any changes related to snapd

When the snapd.service unit fails to be activated, an OnFailure handler will
execute snap-failure which in turn starts the snapd process from the previous
revision of the snap with SNAPD_REVERT_TO_REV set in its environment. It may
happen that the snapd unit fails at runtime without an associated change to the
snapd snap, however snap-failure is not able to detect such case, and so the
snapd process started in its context would continue to run. Avoid this by
extending the logic within snapd to check it if has been started by snap-failure
with the intention of handling a rollback, and so whether there is a change
related to snapd snap in the state. When the conditions have not been met, snapd
exits and snap-failure continues to restart the snapd service.

Related issues: SNAPDENG-21605

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* tests/core/snapd-failover: account for improved snap-failure behavior

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* overlord: add Is() to startup error

Add Is() support to startupError, so that error can be introspected at runtime.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* o/snapstate: return an explicit error from StartUp() when no recovery was detected

When snapd is invoked in a context of recovery but the state does not reflect
this, return an explicit error indicating that further startup should be carried out.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* daemon: return an explicit error when startup in recovery context was aborted

Return an explicit error when startup in failure recovery context was aborted
due to lack of operations in the state which may have triggered it.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* cmd/snapd: handle unnecessary failure recovery

Gracefully handle unnecessary failure recovery but exiting with 0 status, so
that snap-failure may continue with cleanup and restart.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* o/snapstate: improve the check for asserting if restart was warranted

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* overlord: add managers test for handling of runtime restart with failure handling

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* many: tweak names and comments

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* o/snapstate: tweak unit test names

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* cmd/snapd: use fmt.Fprintln

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

* overlord/snapstate: tweak naming

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

---------

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-06-03 15:18:49 +02:00
Zeyad Yasser
c182ed01ff daemon: attach affected-snaps data to tasks (#13953)
* o/snapstate: export affectedSnaps, so it can be used by daemon package

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>

* daemon: attach affected-snaps data to tasks

This allows API caller to associate each task with the
relevant snaps which is useful in the case change progress
tracking when a change is associated with multiple snaps.

This exact use case is needed by snapd-desktop-integration.

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>

---------

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
2024-05-31 17:36:17 +02:00
Andrew Phelps
5b5b54f146 daemon, o/snapstate, snap: add hooks to snap.ComponentInfo (#13771)
* daemon, o/snapstate, snap: add hook information to snap.ComponentInfo

* snap: add functions for helping with snap component instances

* snap: return correct security tags from hook if it is a component hook

* s/snaptest: add function for mocking an installed component

* snap: add functions to help with hook and component locations

* snap: add test for ReadComponentInfoFromContainer where component is not found in provided snap.Info

* snap, o/snapstate: move component and snap consistency checks into snap.ReadComponentInfoFromContainer

* snap: remove unneeded json tag

* snap: log if we ignore an unsuppported implicit component hook

* snap: reorder addAndBindImplicitComponentHooksFromContainer args to be more consistent

* snap: add extra component hook to test

* snap: reorder ComponentHooksDir args and implement it using ComponentMountDir

* snap: correct doc comment on SnapComponentName

* snap: use two spaces for indentation in yaml literals

* snap: upgrade debug log for unsupported hook to notice
2024-04-17 15:56:41 +02:00
Sergio Costas
11d242dada tests: Ensure that parseOptionalTime honors nanoseconds (#13819)
* tests: Ensure that parseOptionalTime honors nanoseconds

This PR adds a test for parseOptionalTime, which checks whether
it honors nanoseconds in a RFC3339 date/time or not.

* Fix package name

* Update daemon/request_test.go

Co-authored-by: Zeyad Yasser <zeyady98@gmail.com>

* Move exports into exports_test.go

---------

Co-authored-by: Zeyad Yasser <zeyady98@gmail.com>
2024-04-16 09:30:46 +02:00
Maciej Borzecki
25c9e7de42 daemon: fix notices API tests on non Ubuntu (#13823)
Snap mount location is hardcoded, but os-release is not mocked, so host paths
are assumed.

Failed like so:

```
----------------------------------------------------------------------
FAIL: api_notices_test.go:947: noticesSuite.TestAddNoticesSnapCmdReexecCore

api_notices_test.go:948:
    s.testAddNoticesSnapCmd(c, "/snap/core/12/usr/bin/snap", false)
api_base_test.go:648:
    c.Assert(rsp.Type, check.Equals, daemon.ResponseTypeSync, check.Commentf("expected sync resp: %#v, result: %+v", rsp, rsp.Result))
... obtained daemon.ResponseType = "error"
... expected daemon.ResponseType = "sync"
... expected sync resp: &daemon.respJSON{Type:"error", Status:403, StatusText:"", Result:(*daemon.errorResult)(0xc0007911d0), Change:"", Sources:[]string(nil), SuggestedCurrency:"", WarningTimestamp:<nil>, WarningCount:0, Maintenance:(*daemon.errorResult)(nil)}, result: &{Message:only snap command can record notices Kind:login-required Value:<nil>}
... Difference:
...     "error" != "sync"

```

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
2024-04-12 16:04:58 +02:00
Philip Meulengracht
81309e59a9 daemon,cmd/snap: support for user services in snap services (#13381)
* daemon,cmd/snap: support for user services in snap services

* NEWS: update news to reflect this functionality

* cmd/snap: add missing unit tests

* many: use interface instead for StatusDecorator to allow for unit testing

* daemon: fix a static check for a range loop where a variable could be omitted

* daemon,cmd/snap: support user-service status of the root user with a --user switch

* t/main/services-user: add a case for root user

* t/main/services-user: fix wrong filename

* cmd/snap: fix TestAppStatus unit test failing

* cmd/snap: extend help for "snap services" to describe the new --global and --user switches

remove errors on redundant switches, remove unneeded argument, move validation of arguments closer to entry of Execute

* cmd/snap: refer directly to fields in the help docs
2024-04-11 12:45:48 +02:00
Zeyad Gouda
57624c4ae9 o/state,daemon: add snap-run-inhibit notice
* daemon: remove polkit check from POST /v2/notices (thanks @olivercalder)
* o/state: update snap-run-inhibit notice doc comment
* daemon: allow snap command only to add snap-run-inhibit notices
	Check that the call to /v2/notices to create snap-run-inhibit notices
	is coming from an expected source by checking the symlink target of
	/proc/<PID>/exe is one of the known locations:
	- /usr/bin/snap
	- /snap/snapd/current/usr/bin/snap
	- /snap/core/current/usr/bin/snap
* daemon/api_notices_test.go: fix typo (thanks @olivercalder)
* daemon: address review comments
* daemon: extract validation out of postNotices
* o/state,daemon: use common notice validation (thanks @Meulengracht)
* p/state,daemon: s/attempted to/cannot/ in notice validation errors (thanks @pedronis)
* daemon: use wildcard matching for snap binary location (thanks @bboozzoo)
* daemon: simplify snap-run-inhibit snap validation
* daemon: remove unused snapInstanceExists

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
2024-04-10 10:27:07 +02:00
Miguel Pires
79c5ac14b2 many: remove usages of deprecated io/ioutil package (#13768)
* many: remove usages of deprecated io/ioutil package

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

* .golangci.yml: remove errcheck ignore rule for io/ioutil

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

* run-checks: prevent new usages of io/ioutil

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>

---------

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
2024-04-03 23:23:24 +02:00
Oliver Calder
22113fd27c o/i/a/common: test that CheckAccess attaches all interface to remoteAddr
Signed-off-by: Oliver Calder <oliver.calder@canonical.com>
2024-04-03 13:26:36 +02:00
Oliver Calder
5a9ca3b23e daemon: allow multiple interfaces in interface{Open,Authenticated}Access
Some endpoints needs to be accessible to snaps via more than one
interface. This change turns the `Interface string` field of
`interface{Open,Authenticated}Access` into `Interfaces []string`.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>
2024-04-02 14:32:49 -05:00
Oliver Calder
f1baf9b7cd daemon: make ucrednet support multiple interfaces idempotently
The `RemoteAddr` of a request can now store more than one interface:
`...;iface=foo&bar&baz;` includes the interfaces "foo", "bar", and "baz".

Importantly, `ucrednetAttachInterface` is now idempotent. No matter how
many times it is called with the same interface, once the interface is
in the list, it is not added again.

Also, the corresponding `ucrednetGetWithInterface` now returns a slice
of interfaces instead of a single one. This slice is obtained by
splitting the value of the `iface=` field on `'&'` characters.

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

daemon: refactor ucrednetAttachInterface to use raddrRegexp

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

daemon: add comments about ucrednet remote address regexp groups

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

daemon: deduplicate types in notices filter and test types for multiple interfaces

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

daemon: add duplicate type to notices types filter test

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>

daemon: rename ucrednetGetWithInterface to ucrednetGetWithInterfaces

Signed-off-by: Oliver Calder <oliver.calder@canonical.com>
2024-04-02 14:32:49 -05:00