-
Notifications
You must be signed in to change notification settings - Fork 56
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
Merge snapcore/snapd/state changes #259
Merge snapcore/snapd/state changes #259
Conversation
State: - Add WaitStatus support that allows a task to wait until further action to continue its execution. The WaitStatus is treated mostly as DoneStatus, except it is not a ready status. - Add CopyState function. - Add Change.AbortUnreadyLanes. - Add Change.CheckTaskDependencies to check if tasks have circular dependencies. - Add task and change callbacks invoked on a status change. - Implement timings.GetSaver interface in state.State. Note, however, the snapcore/snapd/timings package that provides the interface is not included in this PR. pebble has a similar "timing" package. It might be reasonable to introduce "timings" separately to replace the "timing" package to keep concerns (state and timings) separated. State engine: - Add StateStarterUp interface to perform possible expensive initialisation in a separate StartUp method. Overlord: - Implement the StateStarterUp interface Daemon: - Call Overlord StartUp during the start process to complete its initialisation. Note, that there is no obvious requirement to introduce this separation for pebble. It can still initialise Overlord in New(). The separation was mimicked to maintain better compatibility with possible future mergers of the snapcore/snapd/overlord/* changes. Misc: - Add jsonutil package required by the new state's CopyState function. - Rename osutil.CanStat to osutil.FileExist. - Rename task.FakeTime to task.MockTime. - Add testutil.ErrorIs and testutil.DeepUnsortedMatches checkers.
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.
Enormous amount of work, thank you.
I have a couple of first pass comments added with a few questions here:
- I found that some changes pulled in here belong to commits with additional changes and comments providing the original context. It is extremely difficult for me to review some of the code without the original context explained. I wonder if some of the groups of changes would be better to cherry-pick from the original commit as a whole, e.g:
commit 4815875ea89eace1349d30fe863371e251e08ebd
overlord: only initialize loopTomb when needed
-
I would break this PR up into smaller logical commits. It makes reviewing easier as one can select only on commit, and use that as context to understand which files are impacted?
-
I wonder if some things like jsonutil and testutil could be moved to
x-go
to prevent this exercise from repeating itself on those common code areas?
err = d.Start() | ||
if err != nil { | ||
return err | ||
} |
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 think we can simplify this for error only returns to mimic d.Init()
?
if err := d.Start(); err != nil {
return err
}
func (d *Daemon) Overlord() *overlord.Overlord { | ||
return d.overlord | ||
} | ||
|
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.
Currently, daemon
tests are bundled as part of the same package (not daemon_test
). There are currently roughly 68 occurrences of d.overlord.xxx
obtaining the overlord instance directly using the private struct field.
I think we should either stick to the earlier scheme, or update all the d.overlord
references in tests.
} | ||
if d.overlord == nil { | ||
panic("internal error: no Overlord") | ||
} | ||
|
||
d.StartTime = time.Now() | ||
|
||
// now perform expensive overlord/manages initialization |
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 think the comment intends to read:
// now perform expensive overlord/manager initialization
=> "manager"
// -*- Mode: Go; indent-tabs-mode: t -*- | ||
|
||
/* | ||
* Copyright (C) 2015-2018 Canonical Ltd |
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.
-
From a previous comment I've received in Pebble, I think the preference is to drop the formatting hint, as this is mostly not needed anymore today.
-
It looks like we could update the copyright date to current, as the patch moved it backwards actually.
Please consider everywhere.
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.
An observation: testutil
according to my investigation depends only on reaper
and logger
. It seems like this package and deps could be moved to x-go relatively easily, removing the need for future cross-project maintenance.
// It may return false on permission issues. | ||
func CanStat(path string) bool { | ||
func FileExists(path string) bool { |
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 would group this rename (and the subsequent changes) in its own commit in the PR. It makes it very easy to review such a change in isolation of the rest of the PR by selecting only one commit at a time.
} | ||
|
||
// StartUp proceeds to run any expensive Overlord or managers initialization. | ||
// After this is done once it is a noop. |
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.
// After this is done once,
it is a noop.
if o.loopTomb == nil { | ||
o.loopTomb = new(tomb.Tomb) | ||
} |
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.
Could you add some context for this? However, it does not seem to include the whole feature for lazy overlord startup.
This appears to be related to:
commit 4815875ea89eace1349d30fe863371e251e08ebd
Author: Alberto Mardegan <[email protected]>
Date: Mon Dec 6 10:25:07 2021 +0300
overlord: only initialize loopTomb when needed
@@ -1,7 +1,7 @@ | |||
// -*- Mode: Go; indent-tabs-mode: t -*- | |||
|
|||
/* | |||
* Copyright (c) 2016 Canonical Ltd | |||
* Copyright (C) 2016-2023 Canonical Ltd |
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 think lower case (c) 2023 Canonical Ltd
is the norm ? New copyright notices drop the starting date.
@@ -157,7 +181,6 @@ type marshalledChange struct { | |||
Clean bool `json:"clean,omitempty"` | |||
Data map[string]*json.RawMessage `json:"data,omitempty"` | |||
TaskIDs []string `json:"task-ids,omitempty"` | |||
Lanes int `json:"lanes,omitempty"` |
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 safe for us to just remove? What will be the impact for current systems ?
Hi @benhoyt , @flotter (cc @niemeyer). After a discussion with @flotter over the comments above, it is suggested to try the following approach for this PR instead:
Thus, the changesets I imagine this PR to be divided into (roughly):
Please give me your thoughts on the above. If it looks reasonable, I can go ahead, cancel this PR and send changes in stages. |
Yes, that looks very reasonable to me, thanks @dmitry-lyfar. Some specifics:
|
We talked about this today in our call and agreed to break it down. Some more detailed feedback:
Sounds good, thank you.
Yes, we should go the opposite direction: snapd still needs to move towards Fake* terminology. It was mixed, and when it was moved to Pebble it was standardized.
We do want to do this. The change in snapd was actually made on my request precisely after Pebble was split, because it makes little sense for machine start/restart logic to live inside a package that is responsible for general state management and work dispatch. So let's please integrate this change too, ideally on its own PR like is being proposed for everything else.
Why would we not introduce it? As I remember, we're not making extensive use of timers yet, but this is a nice feature that would be nice to have avaialble, and the fact we're not using this extensively makes the job easier supposedly.
From those descriptions it's not clear what is being proposed that is a feature that does not exist in snapd itself and what is a feature that is just being migrated. So it's harder to agree/disagree. In general: what is being ported from snapd in support of general state logic is good. What is being created inside Pebble itself, or that is being ported from snapd but is unrelated to the state package itself, not so great but we can talk about it. Feel free to provide more details so we can consider specific changes, either in their own PR or in our calls. For now, I suggest closing this PR. |
Ack.
The interface implementation itself is tiny as it stores/retrieves raw data to the state. It is largerly used by the independent timings package which I was thinking makes sense to merge with some changes that would use it as it is not directly related to the state management. I will add the GetSaver implementation now so it can be used later when someone introduces timings and their usage in Pebble later on.
Sounds good, closing this one now. |
This PR is made in preparation to merge the latest snapd state package changes into pebble as per the plan discussed in #259. Both ErrorIs and DeepUnsortedMatches checkers are used by the latest state package test suites. These are cherry-picked from the snapd repository with some minor changes (fixed Pebble linter's warnings, updated license header).
Hello there! As discussed with @niemeyer, the latest changes in snapd's state management were merged into Pebble. Please find the summary below:
State:
State engine:
Overlord:
Daemon:
Misc:
Unit-testing:
Pebble's unit tests fail occasionally if ran as:
go test ./... -count 10
This PR does not appear to introduce any regression to the current tests' behaviour.