Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overlord/snapstate: keep current track if only risk is specified #7199

Merged
merged 7 commits into from Aug 13, 2019
Merged
21 changes: 17 additions & 4 deletions overlord/snapstate/snapstate.go
Expand Up @@ -1193,11 +1193,24 @@ func resolveChannel(st *state.State, snapName, newChannel string, deviceCtx Devi
model := deviceCtx.Model()

var pinnedTrack, which string
if snapName == model.Kernel() && model.KernelTrack() != "" {
switch {
case snapName == model.Kernel() && model.KernelTrack() != "":
pinnedTrack, which = model.KernelTrack(), "kernel"
}
if snapName == model.Gadget() && model.GadgetTrack() != "" {
case snapName == model.Gadget() && model.GadgetTrack() != "":
pinnedTrack, which = model.GadgetTrack(), "gadget"
default:
var snapst SnapState
err := Get(st, snapName, &snapst)
if err != nil && err != state.ErrNoState {
return "", err
}
if snapst.IsInstalled() && snapst.Channel != "" {
ch, err := snap.ParseChannel(snapst.Channel, "")
if err != nil {
return "", err
}
pinnedTrack = ch.Track
}
}

if pinnedTrack == "" {
Expand All @@ -1216,7 +1229,7 @@ func resolveChannel(st *state.State, snapName, newChannel string, deviceCtx Devi
// risk/branch) within the pinned track
return pinnedTrack + "/" + newChannel, nil
}
if nch.Track != "" && nch.Track != pinnedTrack {
if nch.Track != "" && nch.Track != pinnedTrack && which != "" {
// switching to a different track is not allowed
return "", fmt.Errorf("cannot switch from %s track %q as specified for the (device) model to %q", which, pinnedTrack, nch.Clean().String())

Expand Down
21 changes: 21 additions & 0 deletions overlord/snapstate/snapstate_test.go
Expand Up @@ -14510,6 +14510,7 @@ func (s *snapmgrTestSuite) TestResolveChannelPinnedTrack(c *C) {
exp string
kernelTrack string
gadgetTrack string
snapChannel string
err string
}{
// neither kernel nor gadget
Expand Down Expand Up @@ -14547,6 +14548,13 @@ func (s *snapmgrTestSuite) TestResolveChannelPinnedTrack(c *C) {
// risk only defaults to pinned kernel track
{snap: "kernel", new: "stable", exp: "17/stable", kernelTrack: "17"},
{snap: "kernel", new: "edge", exp: "17/edge", kernelTrack: "17"},
// risk only with regular snap defaults to pinned track
{snap: "some-snap", new: "stable", exp: "3.0/stable", snapChannel: "3.0/edge"},
{snap: "some-snap", new: "4.0/stable", exp: "4.0/stable", snapChannel: "3.0/edge"},
bboozzoo marked this conversation as resolved.
Show resolved Hide resolved
{snap: "some-snap", new: "latest/stable", exp: "latest/stable", snapChannel: "3.0/edge"},
// risk only with kernel/gadget defaults to pinned track from channel in snap state if not pinned by model
{snap: "kernel", new: "stable", exp: "2.0/stable", snapChannel: "2.0/edge"},
{snap: "brand-gadget", new: "stable", exp: "2.0/stable", snapChannel: "2.0/edge"},
} {
c.Logf("tc: %+v", tc)
if tc.kernelTrack != "" && tc.gadgetTrack != "" {
Expand All @@ -14563,6 +14571,19 @@ func (s *snapmgrTestSuite) TestResolveChannelPinnedTrack(c *C) {
}
deviceCtx := &snapstatetest.TrivialDeviceContext{DeviceModel: model}
s.state.Lock()
if tc.snapChannel != "" {
snapstate.Set(s.state, tc.snap, &snapstate.SnapState{
Active: true,
Channel: tc.snapChannel,
Sequence: []*snap.SideInfo{{
RealName: tc.snap,
Revision: snap.R(1),
SnapID: "some-id",
}},
Current: snap.R(1)})
} else {
snapstate.Set(s.state, tc.snap, nil)
}
ch, err := snapstate.ResolveChannel(s.state, tc.snap, tc.new, deviceCtx)
s.state.Unlock()
if tc.err != "" {
Expand Down