-
Notifications
You must be signed in to change notification settings - Fork 574
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
o/snapstate: account for remodeling when installing prereqs as well as updating them #14137
o/snapstate: account for remodeling when installing prereqs as well as updating them #14137
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it feels that we need some matching unit test(s) to capture these behaviors, that would have avoided the regression being surface only by spread?
There are still lots of failures in spread tests related to remodel. |
…hat might be getting updated during a remodel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for the fix, but the function is a bit strangely named now. It'd be nice to clean it up a bit but not a blocker for this PR
overlord/snapstate/handlers.go
Outdated
@@ -346,28 +355,17 @@ func (m *SnapManager) installOneBaseOrRequired(t *state.Task, snapName string, c | |||
} | |||
|
|||
// other kind of dependency, check if it's in progress | |||
if ok, err := inProgress(snapName); err != nil { | |||
if _, err := shouldAttemptInstall(snapName); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit weird now. It's inside a isInstalled
case but we run a shouldAttemptInstall
check? It's also inconsistent with the comment above it.
Tbh the original is also not great, since it has more logic to it than than just checking if the snap is running
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the name isn't good. Unfortunately I haven't been able to come up with something better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering whether the code can't be simplified further now
overlord/snapstate/handlers.go
Outdated
@@ -346,28 +355,17 @@ func (m *SnapManager) installOneBaseOrRequired(t *state.Task, snapName string, c | |||
} | |||
|
|||
// other kind of dependency, check if it's in progress | |||
if ok, err := inProgress(snapName); err != nil { | |||
if _, err := shouldAttemptInstall(snapName); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we actually need this code inside the "if" now? wouldn't the code outside the "if" do the same in practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it can be dropped here to just always return err
, regardless if nil or not.
overlord/snapstate/handlers.go
Outdated
// downloads during a remodel happen prior to snap installation. thus, | ||
// we cannot wait for snaps to be installed here. see remodelTasks for | ||
// more information on how the tasks are ordered. | ||
if deviceCtx.ForRemodeling() { | ||
return false, nil | ||
} | ||
|
||
// snap is being installed, retry later |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this comment making sense in all cases now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to account for the refresh case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did another pass, some questions/comments
overlord/snapstate/handlers.go
Outdated
// tasks are ordered by the remodeling code. specifically, all snap | ||
// downloads during a remodel happen prior to snap installation. thus, | ||
// we cannot wait for snaps to be installed here. see remodelTasks for | ||
// more information on how the tasks are ordered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wont' this be a problem also for updatePrereqIfOutdated code? doesn't it mean we should simply check this before all other checks and return early? instead of doing the check here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spoke to Miguel about this earlier, because I was also confused about the ordering of the original code:
Those are mutually exclusive, unless I'm misunderstanding the question. The first if runs when the prerequisite is a default provider and the rest runs if it's another type of dependency (base, snapd). So that checks doesn't run after updating. Also the updatePrereqIfOutdated has code to check if its already being updated so it would catch a conflict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify, that comment was about the inProgress
check vs the updatePrereqIfOutdated
call which was the code snippet in the link. It wasn't about the remodel check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I see I was conflating them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I misunderstood the question, my bad
overlord/snapstate/handlers.go
Outdated
// snap is being installed, retry later | ||
return true, nil | ||
// snap is either being installed or updated | ||
return false, onInFlight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that return directly onInFlight is helpful here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I return onInFlight
here to distinguish between when we are remodeling or when we aren't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworked how this looks in the most recent commit. Since we don't actually want to go into updatePrereqIfOutdated
during a remodel since it tries to reach out to the store (we should have already downloaded all the snaps needed for the remodel, cc @MiguelPires to make sure I'm not lying), I think we can just move the check for remodeling earlier in the function.
overlord/snapstate/handlers.go
Outdated
@@ -324,19 +324,28 @@ func (m *SnapManager) installOneBaseOrRequired(t *state.Task, snapName string, c | |||
return nil, err | |||
} | |||
|
|||
inProgress := func(snapName string) (bool, error) { | |||
shouldAttemptInstall := func(snapName string) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe then this name can go back to the old one? it's really a bit confusing for the usage inside if isInstalled
… want to update prereqs during a remodel anyways
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
@@ -403,6 +403,76 @@ func (s *prereqSuite) TestDoPrereqRetryWhenBaseInFlight(c *C) { | |||
c.Check(chg.Status(), Equals, state.DoneStatus) | |||
} | |||
|
|||
func (s *prereqSuite) TestDoPrereqNoRetryWhenBaseInFlightDuringRemodel(c *C) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could have other variants (skips when there's a install in progress, a possible update of a prereq, a missing base, etc) but maybe it's not worth it to add those right now since we want this merged soon
overlord/snapstate/handlers.go
Outdated
// tasks are ordered by the remodeling code. specifically, all snap | ||
// downloads during a remodel happen prior to snap installation. thus, | ||
// we cannot wait for snaps to be installed here. see remodelTasks for | ||
// more information on how the tasks are ordered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I misunderstood the question, my bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
In #14088 I broke
tests/nested/manual/hybrid-remodel
when attempting to fix a different bug. By moving the remodeling check, I accidentally omitted checking for remodeling when updating a prereq. This change makes sure that we check for remodeling when installing and updating prereqs.