Skip to content

Commit

Permalink
seedwriter: check if the optionSnap channel is same as model assert
Browse files Browse the repository at this point in the history
If we define `presence: optional` for an app snap in the model assertion, and the
default channel is `24/stable` for example, then when we pass `--snap=SNAP=24/stable`
to `snap prepare-image` with a model assertion that has model grade higher than
`dangerous`, I will get an error `error: cannot override channels, add devmode snaps,
local snaps, or extra snaps with a model of grade higher than dangerous`

However, I am expecting that snapd should check whether the channel for option snap
is same as the channel defined in model assertion, maybe snapd should only return
error if channel is not the same and the model grade is higher than dangerous

Signed-off-by: Aristo Chen <[email protected]>
  • Loading branch information
AristoChen committed Jun 12, 2024
1 parent 23f572b commit cd8b4f3
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 2 deletions.
15 changes: 13 additions & 2 deletions seed/seedwriter/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,19 @@ func (w *Writer) SetOptionsSnaps(optSnaps []*OptionsSnap) error {
if err != nil {
return fmt.Errorf("cannot use option channel for snap %q: %v", whichSnap, err)
}
if err := w.policy.checkSnapChannel(ch, whichSnap); err != nil {
return err

// Check whether the channel defined in the model assertion
// is same as the option snap(--snap=SNAP_NAME=CHANNEL)
modSnaps, err := w.modSnaps()

Check failure on line 433 in seed/seedwriter/writer.go

View workflow job for this annotation

GitHub Actions / static-checks (latest/stable)

ineffectual assignment to err (ineffassign)
for _, modSnap := range modSnaps {
if sn.Name != modSnap.Name {
continue
}
if sn.Channel != modSnap.DefaultChannel {
if err := w.policy.checkSnapChannel(ch, whichSnap); err != nil {
return err
}
}
}
}
if local {
Expand Down
96 changes: 96 additions & 0 deletions seed/seedwriter/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3316,6 +3316,102 @@ func (s *writerSuite) TestSnapsToDownloadCore20OptionalSnaps(c *C) {
c.Check(snaps[5].SnapName(), Equals, "optional20-b")
}

func (s *writerSuite) TestSnapsToDownloadCore20OptionalSnapsWithSameChannel(c *C) {
model := s.Brands.Model("my-brand", "my-model", map[string]interface{}{
"display-name": "my model",
"architecture": "amd64",
"base": "core20",
"snaps": []interface{}{
map[string]interface{}{
"name": "pc-kernel",
"id": s.AssertedSnapID("pc-kernel"),
"type": "kernel",
"default-channel": "20",
},
map[string]interface{}{
"name": "pc",
"id": s.AssertedSnapID("pc"),
"type": "gadget",
"default-channel": "20",
},
map[string]interface{}{
"name": "optional20-a",
"id": s.AssertedSnapID("optional20-a"),
"presence": "optional",
"default-channel": "20",
},
},
})

// validity
c.Assert(model.Grade(), Equals, asserts.ModelSigned)

s.makeSnap(c, "snapd", "")
s.makeSnap(c, "core20", "")
s.makeSnap(c, "pc-kernel=20", "")
s.makeSnap(c, "pc=20", "")
s.makeSnap(c, "optional20-a", "developerid")

s.opts.Label = "20191122"
w, err := seedwriter.New(model, s.opts)
c.Assert(err, IsNil)

err = w.SetOptionsSnaps([]*seedwriter.OptionsSnap{{Name: "optional20-a", Channel: "20"}})
c.Assert(err, IsNil)

err = w.Start(s.db, s.rf)
c.Assert(err, IsNil)

snaps, err := w.SnapsToDownload()
c.Assert(err, IsNil)
c.Check(snaps, HasLen, 5)
c.Check(snaps[4].SnapName(), Equals, "optional20-a")
}

func (s *writerSuite) TestSnapsToDownloadCore20OptionalSnapsWithDifferentChannel(c *C) {
model := s.Brands.Model("my-brand", "my-model", map[string]interface{}{
"display-name": "my model",
"architecture": "amd64",
"base": "core20",
"snaps": []interface{}{
map[string]interface{}{
"name": "pc-kernel",
"id": s.AssertedSnapID("pc-kernel"),
"type": "kernel",
"default-channel": "20",
},
map[string]interface{}{
"name": "pc",
"id": s.AssertedSnapID("pc"),
"type": "gadget",
"default-channel": "20",
},
map[string]interface{}{
"name": "optional20-a",
"id": s.AssertedSnapID("optional20-a"),
"presence": "optional",
"default-channel": "20",
},
},
})

// validity
c.Assert(model.Grade(), Equals, asserts.ModelSigned)

s.makeSnap(c, "snapd", "")
s.makeSnap(c, "core20", "")
s.makeSnap(c, "pc-kernel=20", "")
s.makeSnap(c, "pc=20", "")
s.makeSnap(c, "optional20-a", "developerid")

s.opts.Label = "20191122"
w, err := seedwriter.New(model, s.opts)
c.Assert(err, IsNil)

err = w.SetOptionsSnaps([]*seedwriter.OptionsSnap{{Name: "optional20-a", Channel: "22"}})
c.Check(err, ErrorMatches, `cannot override channels, add devmode snaps, local snaps, or extra snaps with a model of grade higher than dangerous`)
}

func (s *writerSuite) TestSeedSnapsWriteMetaCore20ExtraSnaps(c *C) {
model := s.Brands.Model("my-brand", "my-model", map[string]interface{}{
"display-name": "my model",
Expand Down

0 comments on commit cd8b4f3

Please sign in to comment.