Skip to content

Commit

Permalink
o/devicestate, o/snapstate, tests: handle components during a remodel
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewphelpsj committed Jan 15, 2025
1 parent 043de81 commit fb52d67
Show file tree
Hide file tree
Showing 11 changed files with 1,675 additions and 83 deletions.
233 changes: 184 additions & 49 deletions overlord/devicestate/devicestate.go

Large diffs are not rendered by default.

1,219 changes: 1,217 additions & 2 deletions overlord/devicestate/devicestate_remodel_test.go

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions overlord/devicestate/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"time"

"github.com/snapcore/snapd/asserts"
"github.com/snapcore/snapd/asserts/snapasserts"
"github.com/snapcore/snapd/boot"
"github.com/snapcore/snapd/gadget"
"github.com/snapcore/snapd/gadget/install"
Expand Down Expand Up @@ -185,6 +186,14 @@ func MockSnapstatePathInstallGoal(mock func(snapstate.PathSnap) snapstate.Instal
return testutil.Mock(&snapstatePathInstallGoal, mock)
}

func MockSnapstateInstallComponents(mock func(ctx context.Context, st *state.State, names []string, info *snap.Info, vsets *snapasserts.ValidationSets, opts snapstate.Options) ([]*state.TaskSet, error)) (restore func()) {
return testutil.Mock(&snapstateInstallComponents, mock)
}

func MockSnapstateInstallComponentPath(mock func(st *state.State, csi *snap.ComponentSideInfo, info *snap.Info, path string, opts snapstate.Options) (*state.TaskSet, error)) (restore func()) {
return testutil.Mock(&snapstateInstallComponentPath, mock)
}

func MockSnapstateDownload(f func(ctx context.Context, st *state.State, name string, components []string, blobDirectory string, revOpts snapstate.RevisionOptions, opts snapstate.Options) (*state.TaskSet, *snap.Info, error)) (restore func()) {
r := testutil.Backup(&snapstateDownload)
snapstateDownload = f
Expand Down
46 changes: 30 additions & 16 deletions overlord/snapstate/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@ func InstallComponents(
// TODO:COMPS: verify validation sets here

snapsup := SnapSetup{
Base: info.Base,
SideInfo: &info.SideInfo,
Channel: info.Channel,
Flags: opts.Flags.ForSnapSetup(),
Type: info.Type(),
Version: info.Version,
PlugsOnly: len(info.Slots) == 0,
InstanceKey: info.InstanceKey,
Base: info.Base,
SideInfo: &info.SideInfo,
Channel: info.Channel,
Flags: opts.Flags.ForSnapSetup(),
Type: info.Type(),
Version: info.Version,
PlugsOnly: len(info.Slots) == 0,
InstanceKey: info.InstanceKey,
ComponentExclusiveSetup: true,
}

setupSecurity := st.NewTask("setup-profiles",
Expand Down Expand Up @@ -264,14 +265,15 @@ func InstallComponentPath(st *state.State, csi *snap.ComponentSideInfo, info *sn
}

snapsup := SnapSetup{
Base: info.Base,
SideInfo: &info.SideInfo,
Channel: info.Channel,
Flags: opts.Flags.ForSnapSetup(),
Type: info.Type(),
Version: info.Version,
PlugsOnly: len(info.Slots) == 0,
InstanceKey: info.InstanceKey,
Base: info.Base,
SideInfo: &info.SideInfo,
Channel: info.Channel,
Flags: opts.Flags.ForSnapSetup(),
Type: info.Type(),
Version: info.Version,
PlugsOnly: len(info.Slots) == 0,
InstanceKey: info.InstanceKey,
ComponentExclusiveSetup: true,
}
compSetup := ComponentSetup{
CompSideInfo: csi,
Expand All @@ -289,6 +291,18 @@ func InstallComponentPath(st *state.State, csi *snap.ComponentSideInfo, info *sn
}

ts := componentTS.taskSet()

// TODO:COMPS: instead of doing this, we should convert this function to
// operate on multiple components so that it works like InstallComponents.
// this would improve performance, especially in the case of kernel module
// components.
begin, err := ts.Edge(BeginEdge)
if err != nil {
return nil, fmt.Errorf("internal error: cannot find begin edge on component install task set: %v", err)
}

begin.Set("component-setup-tasks", []string{componentTS.compSetupTaskID})

ts.JoinLane(generateLane(st, opts))

return ts, nil
Expand Down
2 changes: 2 additions & 0 deletions overlord/snapstate/component_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ func (s *snapmgrTestSuite) TestInstallComponentPathForParallelInstall(c *C) {
var snapsup snapstate.SnapSetup
c.Assert(ts.Tasks()[0].Get("snap-setup", &snapsup), IsNil)
c.Assert(snapsup.InstanceKey, Equals, snapKey)
c.Assert(snapsup.ComponentExclusiveSetup, Equals, true)
}

func (s *snapmgrTestSuite) TestInstallComponentPathWrongSnap(c *C) {
Expand Down Expand Up @@ -1052,6 +1053,7 @@ func (s *snapmgrTestSuite) testInstallComponents(c *C, opts testInstallComponent
snapsup, err := snapstate.TaskSnapSetup(prepareKmodComps)
c.Assert(err, IsNil)
c.Assert(snapsup, NotNil)
c.Assert(snapsup.ComponentExclusiveSetup, Equals, true)

for _, ts := range tss[0 : len(tss)-1] {
task := ts.Tasks()[0]
Expand Down
4 changes: 4 additions & 0 deletions overlord/snapstate/snapmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ type SnapSetup struct {
// case of an undo. Note that this cannot be tagged as omitempty, since we
// need to distinguish between empty and nil.
PreUpdateKernelModuleComponents []*snap.ComponentSideInfo `json:"pre-update-kernel-module-components"`

// ComponentExclusiveSetup is set if this SnapSetup exists only to deal with
// components, and not the snap itself.
ComponentExclusiveSetup bool `json:"component-exclusive-setup,omitempty"`
}

// ConfdbID identifies a confdb.
Expand Down
25 changes: 13 additions & 12 deletions overlord/snapstate/snapstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -1641,18 +1641,19 @@ func downloadTasks(
}

snapsup := &SnapSetup{
Channel: revOpts.Channel,
Base: info.Base,
UserID: opts.UserID,
Flags: opts.Flags.ForSnapSetup(),
DownloadInfo: &info.DownloadInfo,
SideInfo: &info.SideInfo,
Type: info.Type(),
Version: info.Version,
InstanceKey: info.InstanceKey,
CohortKey: revOpts.CohortKey,
ExpectedProvenance: info.SnapProvenance,
DownloadBlobDir: downloadDir,
Channel: revOpts.Channel,
Base: info.Base,
UserID: opts.UserID,
Flags: opts.Flags.ForSnapSetup(),
DownloadInfo: &info.DownloadInfo,
SideInfo: &info.SideInfo,
Type: info.Type(),
Version: info.Version,
InstanceKey: info.InstanceKey,
CohortKey: revOpts.CohortKey,
ExpectedProvenance: info.SnapProvenance,
DownloadBlobDir: downloadDir,
ComponentExclusiveSetup: skipSnapDownload,
}

if sar.RedirectChannel != "" {
Expand Down
13 changes: 9 additions & 4 deletions overlord/snapstate/snapstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10176,7 +10176,8 @@ func (s *snapmgrTestSuite) TestDownloadWithComponents(c *C) {
c.Assert(begin, NotNil)
c.Check(begin.Kind(), Equals, "download-snap")

verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir)
const componentExclusive = false
verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir, componentExclusive)
}

func (s *snapmgrTestSuite) TestDownloadWithComponentsWithMismatchValidationSets(c *C) {
Expand Down Expand Up @@ -10388,7 +10389,8 @@ func (s *snapmgrTestSuite) TestDownloadWithComponentsWithValidationSets(c *C) {
c.Assert(begin, NotNil)
c.Check(begin.Kind(), Equals, "download-snap")

verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir)
const componentExclusive = false
verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir, componentExclusive)
}

func (s *snapmgrTestSuite) TestDownloadComponents(c *C) {
Expand Down Expand Up @@ -10463,10 +10465,11 @@ func (s *snapmgrTestSuite) TestDownloadComponents(c *C) {
c.Assert(begin, NotNil)
c.Check(begin.Kind(), Equals, "download-component")

verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir)
const componentExclusive = true
verifySnapAndComponentSetupsForDownload(c, begin, ts, downloadDir, componentExclusive)
}

func verifySnapAndComponentSetupsForDownload(c *C, begin *state.Task, ts *state.TaskSet, downloadDir string) {
func verifySnapAndComponentSetupsForDownload(c *C, begin *state.Task, ts *state.TaskSet, downloadDir string, componentExclusive bool) {
var snapsup snapstate.SnapSetup
err := begin.Get("snap-setup", &snapsup)
c.Assert(err, IsNil)
Expand All @@ -10482,6 +10485,8 @@ func verifySnapAndComponentSetupsForDownload(c *C, begin *state.Task, ts *state.
fmt.Sprintf("%s_%s.snap", snapsup.InstanceName(), snapsup.Revision()),
))

c.Assert(snapsup.ComponentExclusiveSetup, Equals, componentExclusive)

var compsupTaskIDs []string
err = begin.Get("component-setup-tasks", &compsupTaskIDs)
c.Assert(err, IsNil)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"type": "model",
"authority-id": "developer1",
"series": "16",
"brand-id": "developer1",
"model": "my-model",
"revision": "1",
"architecture": "amd64",
"timestamp": "2024-04-24T00:00:00+00:00",
"grade": "dangerous",
"base": "core24",
"serial-authority": ["generic"],
"snaps": [
{
"default-channel": "24/edge",
"id": "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH",
"name": "pc",
"type": "gadget"
},
{
"default-channel": "24/edge",
"id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza",
"name": "pc-kernel",
"type": "kernel"
},
{
"default-channel": "latest/edge",
"id": "dwTAh7MZZ01zyriOZErqd1JynQLiOGvM",
"name": "core24",
"type": "base"
},
{
"default-channel": "latest/edge",
"id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4",
"name": "snapd",
"type": "snapd"
}
]
}
42 changes: 42 additions & 0 deletions tests/lib/assertions/test-snapd-component-remodel-new-pc-24.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"type": "model",
"authority-id": "developer1",
"series": "16",
"brand-id": "developer1",
"model": "my-model",
"revision": "2",
"architecture": "amd64",
"timestamp": "2024-04-24T00:00:00+00:00",
"grade": "dangerous",
"base": "core24",
"serial-authority": ["generic"],
"snaps": [
{
"default-channel": "24/edge",
"id": "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH",
"name": "pc",
"type": "gadget"
},
{
"default-channel": "24/edge",
"id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza",
"name": "pc-kernel",
"type": "kernel",
"components": {
"wifi-comp": "required"
}
},
{
"default-channel": "latest/edge",
"id": "dwTAh7MZZ01zyriOZErqd1JynQLiOGvM",
"name": "core24",
"type": "base"
},
{
"default-channel": "latest/edge",
"id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4",
"name": "snapd",
"type": "snapd"
}
]
}
Loading

0 comments on commit fb52d67

Please sign in to comment.