-
Notifications
You must be signed in to change notification settings - Fork 562
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/devicestate, overlord/snapstate: add task for updating kernel command lines from gadget #10148
overlord/devicestate, overlord/snapstate: add task for updating kernel command lines from gadget #10148
Conversation
…from gadget Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…kernel command line Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…le secure boot. fix races, enable debugs Also verify that boot chains exist Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…ate-gadget-cmdline-tasks
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.
a couple nitpicks about the logging, but otherwise the main code and the spread test looks good to me. I didn't finish reviewing the unit tests yet however
var seeded bool | ||
err := st.Get("seeded", &seeded) | ||
if err != nil && err != state.ErrNoState { | ||
fmt.Printf("not needed\n") |
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.
fmt.Printf("not needed\n") |
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.
Hah, thanks for catching that.
return err | ||
} | ||
if !updated { | ||
t.Logf("no kernel command line update from gadget") |
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.
t.Logf("no kernel command line update from gadget") | |
t.Debugf("no kernel command line update from gadget") |
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.
+1
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've updated the code here and at the place of the other comment to use logger.Debugf()
return err | ||
} | ||
if !updated { | ||
t.Logf("no kernel command line update to undo") |
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.
t.Logf("no kernel command line update to undo") | |
t.Debugf("no kernel command line update to undo") |
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.
+1
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.
And there should be a return nil
here right after the log too.
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.
thanks for this, I did a first pass, mostly minor comments but a question about reboots
// not using trusted boot assets, bootloader config is not | ||
// managed and command line can be manipulated externally | ||
return update, 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.
so we understand, what's the situation here, grub is used but FDE is not enabled?
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.
Yes, the scenario is no FDE, in which case we do not track the trusted boot assets, but that unnecessarily gated the command line handling in bootstate.
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.
Added a test case for this.
// and system bootloader, indicating that the command line is | ||
// not being tracked | ||
return m, 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.
I think these changes in boot needs new unit tests for the new scenarios, no?
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.
Added a test for this too. The scenario is basically a uc20 device which does not have the trusted assets bootloader, so kernel command lines will not be populated, and we do not expect a command line for it anyway.
|
||
func (m *DeviceManager) doUpdateGadgetCommandLine(t *state.Task, _ *tomb.Tomb) error { | ||
if release.OnClassic { | ||
return fmt.Errorf("cannot run update gadget kernel command line task on a classic system") |
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 is an internal 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.
Updated this and the other place
|
||
func (m *DeviceManager) undoUpdateGadgetCommandLine(t *state.Task, _ *tomb.Tomb) error { | ||
if release.OnClassic { | ||
return fmt.Errorf("cannot run update gadget kernel command line task on a classic system") |
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.
same
return err | ||
} | ||
if !updated { | ||
t.Logf("no kernel command line update from gadget") |
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.
+1
overlord/managers_test.go
Outdated
size: 500M | ||
` | ||
|
||
func (s *mgrsSuite) testGadgetKernelCommandLine(c *C, snapPath string, si *snap.SideInfo, bl bootloader.Bootloader, currentFiles [][]string, currentModeenvCmdline string, commandLineAfterReboot string, update 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.
s/snapPath/gadgetPath/ and s/si/gadgetSideInfo/ for a bit more clarity?
overlord/snapstate/snapstate.go
Outdated
@@ -263,6 +263,12 @@ func doInstall(st *state.State, snapst *SnapState, snapsup *SnapSetup, flags int | |||
addTask(gadgetUpdate) | |||
prev = gadgetUpdate | |||
} | |||
if !release.OnClassic && snapsup.Type == snap.TypeGadget { | |||
// XXX: kernel command line from gadget is for core systems only |
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.
why the XXX?
overlord/devicestate/devicemgr.go
Outdated
@@ -160,6 +160,8 @@ func Manager(s *state.State, hookManager *hookstate.HookManager, runner *state.T | |||
// config assets are assumed to be always backwards compatible. | |||
runner.AddHandler("update-managed-boot-config", m.doUpdateManagedBootConfig, 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.
I don't think we want this blank line, maybe just have a trivial comment if the issue with having nothing is the confusion with the previous comment
if !updated { | ||
t.Logf("no kernel command line update to undo") | ||
} | ||
t.Logf("kernel command line update undone") |
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.
"reverted kernel command line", to be more similar to the Do case?
t.SetStatus(state.DoneStatus) | ||
|
||
// kernel command line was updated, request a reboot to make it effective | ||
st.RequestRestart(state.RestartSystem) |
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 risk to reboot twice if there was an assets update from update-managed-boot-config as well? can we do something if that's the 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.
Yes, there is a change to require 2 reboots. One the one hand it is an inconvenience, on the other happens only when both the assets and the command line is changed in the new revision.
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.
can you leave a TODO about thinking further about this? I have some ideas but probably not worth pursuing immediately
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.
Sure, I'll push it after the current spread run finishes
Thanks to @pedronis and @anonymouse64 for suggestions. Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…ne was not changed Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…ate-gadget-cmdline-tasks
Add test cases for compatibility scenarios: - a UC20 device with a bootloader that isn't the trusted assets one - a UC20 device with trusted assets bootloader, but no assets are tracked (as happens when FDE isn't used) Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
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.
thanks, small question/nitpick
} | ||
t.Logf("kernel command line update undone") | ||
t.Logf("Reverted kernel command line change") |
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.
isn't this checked in tests like the do case?
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
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, some super nitpicky comment suggestions
boot/boot_test.go
Outdated
"snapd_recovery_mode=run panic=-1", | ||
"snapd_recovery_mode=run candidate panic=-1", | ||
}) | ||
// without encryption, the trusted assets are no tracked in the modeenv, |
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.
// without encryption, the trusted assets are no tracked in the modeenv, | |
// without encryption, the trusted assets are not tracked in the modeenv, |
} | ||
|
||
func (s *deviceMgrGadgetSuite) TestUpdateGadgetCommandlineWithNewArgs(c *C) { | ||
// no command line arguments prior to the gadget up |
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 command line arguments prior to the gadget up | |
// no command line arguments prior to the gadget update |
} | ||
|
||
func (s *deviceMgrGadgetSuite) TestUpdateGadgetCommandlineUnchanged(c *C) { | ||
// no command line arguments prior to the gadget up |
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 command line arguments prior to the gadget up | |
// no command line arguments prior to the gadget update |
|
||
t.SetStatus(state.DoneStatus) | ||
|
||
// TODO: consider optimization to avoid double reboot when the gadget |
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.
thanks for this comment
func (s *mgrsSuite) testGadgetKernelCommandLine(c *C, gadgetPath string, gadgetSideInfo *snap.SideInfo, | ||
bl bootloader.Bootloader, currentFiles [][]string, currentModeenvCmdline string, | ||
commandLineAfterReboot string, update 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.
oh boy that's quite the signature :-)
overlord/managers_test.go
Outdated
{"meta/gadget.yaml", pcGadgetYaml}, | ||
{"cmdline.extra", "args from old gadget"}, | ||
} | ||
// add new gadget snap kernel command line drop-in file |
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.
// add new gadget snap kernel command line drop-in file | |
// add new gadget snap kernel command line without the file |
Thanks to @anonymouse64 for suggestions Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
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.
Thanks, some nitpicks inside but looks good.
// pre UC20 system, do nothing | ||
return false, nil | ||
} | ||
// but when undoing, we use the current gadget which should have |
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.
Hm, this comment starts with // but ...
- what does the "but" refers to? Should this maybe read just "when undoing, we use the current gadget which should have been restored"
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 this move into the "else" below? It seems we only need currentGadgetData inside this else condition?
logger.Debugf("no kernel command line update from gadget") | ||
return nil | ||
} | ||
t.Logf("Updated kernel command line") |
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.
Thanks for adding this
} | ||
|
||
func (s *mgrsSuite) TestGadgetKernelCommandLineAddCmdline(c *C) { | ||
mabloader := bootloadertest.Mock("mock", c.MkDir()).WithTrustedAssets() |
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.
Would it make sense to have a "gadgetMgrsSuite" or something that does this bootloader setup in a single place? it seems like it's the same across the tests(?)
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 can try to do that in a followup
@@ -5339,6 +5341,7 @@ func (s *snapmgrTestSuite) TestStopSnapServicesFirstSavesSnapSetupLastActiveDisa | |||
}, | |||
Current: snap.R(11), | |||
Active: true, | |||
// gofmt |
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 expand this a little bit? I assuem you add it to avoid indent?
# wait for previous change to finish before proceeding | ||
nested_exec sudo snap watch "$REMOTE_CHG_ID" | ||
|
||
# TODO: enable once full command line override is supported |
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 will be enabled once #10160 landed, yes?
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.
Yes
Thanks to @mvo5 for suggestions Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
@mvo5 can you land this PR? the failure in |
Stacked on top of #10143.The relevant commits are in the overlord package and subpackages, start with 1351e70 and then subsequent ones.