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: parallel snap install #5561

Merged
merged 22 commits into from Aug 16, 2018

Conversation

bboozzoo
Copy link
Collaborator

A set of changes to snapstate that add support for parallel snap installation. The PR will currently conflict with #5452 regarding SnapAction struct fields. Once #5452 lands I'll update this PR as needed.

There is also a branch with changes to snapstate.InstallPath() right here https://github.com/bboozzoo/snapd/commits/bboozzoo/parallel-install-daemon I'll push those changes as a separate PR.

Feel free to indicate where more testing is needed.

@bboozzoo bboozzoo requested a review from pedronis July 26, 2018 12:09
@codecov-io
Copy link

codecov-io commented Jul 26, 2018

Codecov Report

Merging #5561 into master will decrease coverage by <.01%.
The diff coverage is 97.67%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5561      +/-   ##
==========================================
- Coverage   78.96%   78.95%   -0.01%     
==========================================
  Files         522      522              
  Lines       39694    39711      +17     
==========================================
+ Hits        31343    31355      +12     
- Misses       5805     5809       +4     
- Partials     2546     2547       +1
Impacted Files Coverage Δ
overlord/snapstate/check_snap.go 81.13% <100%> (+0.48%) ⬆️
overlord/snapstate/snapstate.go 81.5% <100%> (+0.18%) ⬆️
overlord/snapstate/backend/setup.go 52.63% <100%> (+1.28%) ⬆️
overlord/snapstate/handlers.go 71.88% <80%> (+0.02%) ⬆️
cmd/snap/cmd_aliases.go 91.37% <0%> (-1.73%) ⬇️
overlord/hookstate/hookmgr.go 73.55% <0%> (-0.97%) ⬇️
overlord/ifacestate/handlers.go 64.88% <0%> (-0.4%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3fdeae0...d07429f. Read the comment docs.

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>
@bboozzoo bboozzoo force-pushed the bboozzoo/parallel-install-overlord branch from 18d926e to 912b03d Compare July 27, 2018 08:41
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems there's a real issue with download bits or test confusion.

Also not sure if alias code bits don't need changes or they are not here and will be in a follow up?

The SnapSetup construction in applyAutoAliasesDelta looks wrong for sure, missing InstanceKey.

Channel: channel,
SideInfo: snapst.CurrentSideInfo(),
Channel: channel,
InstanceKey: snapst.InstanceKey,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change tested? I see tests for most changes here, but not this one

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a run through test for switch.


_, s.InstanceKey = snap.SplitInstanceName(instanceName)

// TODO parallel-install: enforce snap.Info.SnapName() == snap name from instanceName
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems slightly late to do that here though, it would go earlier in checkSnap

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a PR with some changes to snap.Validate() that will catch this. OTOH it's no harm to check it in snapstate as well.

@@ -142,7 +142,7 @@ func (f *fakeStore) SnapInfo(spec store.SnapSpec, user *auth.UserState) (*snap.I
f.pokeStateLock()

sspec := snapSpec{
Name: spec.Name,
Name: snap.InstanceSnap(spec.Name),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused, here we don't need this, we need to check that Name doesn't have an instance-key, this code might also be unused right now though

},
{
op: "storesvc-download",
name: "some-snap_instance",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like a real bug or test confusion, download shouldn't receive an instance name. I don't think we changed store to support that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either way, we probably should add a check about that in the fake download code

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rechecked download uses the name only for errors afaict, on the other end some of those would be strange with the instance name, like the ones about paid snaps (you pay once, not per instance), something to think about

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll tweak the code to use snap name instead. Also will record target path in the tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as I wrote, the question is whether to pass instance-name or snap-name to Download, it matters mostly for error messages but some might be confusing with instance-name, and some might be better with, I don't know if it means we should teach it about instance-name and splitting. Easiest for a start would be to pass snap-name

…pInfo

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>
@pedronis
Copy link
Collaborator

pedronis commented Jul 30, 2018

The SnapSetup construction in applyAutoAliasesDelta looks wrong for sure, missing InstanceKey.

could you add at least a general TODO about alias code there?

@pedronis pedronis dismissed their stale review July 30, 2018 12:34

punctual issues have been addressed, won't be able to do a full deep 2nd pass

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>
…file

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
@@ -208,6 +208,13 @@ func checkSnap(st *state.State, snapFilePath string, si *snap.SideInfo, curInfo
return err
}

snapName, instanceKey := snap.SplitInstanceName(instanceName)
if instanceKey != "" && snapName != s.SnapName() {
return fmt.Errorf("cannot install snap %q using instance name %q", s.SnapName(), instanceName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we only error here if instanceKey != ""?

Copy link
Collaborator Author

@bboozzoo bboozzoo Aug 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After going a bit back and forth with this one, I've moved the check down, after all callbacks are executed. The assumption is that the callbacks are likely to yield more detailed errors (if any), as for instance happens with checkGadgetOrKernel() which returns cannot replace gadget snap with a different one while the snap name check would return cannot install snap "zgadget" using instance name "gadget". I'm happy to adjust it further if needed,

Oh and dropped instanceKey != "" too.

Copy link
Contributor

@stolowski stolowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's a massive change! First pass, just some minors.

if len(split) >= 2 {
// <snap>_<rev>.snap
// <snap>_<instance-key>_<rev>.snap
name = split[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the logic of SplitInstanceName helper, can you use it instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid it might be a bit confusing as the input is not an instance name but a file name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks.

err = s.state.Get("snaps", &snaps)
c.Assert(err, IsNil)

snapst := snaps["some-snap_instance"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add c.Assert(snapst, NotNil) before other checks? Will give quicker diagnosis if something breaks, instead of panic'ing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Add support for opening snaps from directory (as in snap try). Otherwise snap
info is populated with incorrect data and snap name checks will fail.

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Tweak the handling of snap name in snap cheks. Allow registered callbacks to run
first as they may return more precise/informative errors.

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Copy link
Contributor

@stolowski stolowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good (but probably still needs review from Samuele). Thanks!

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, couple of comments left

for _, check := range checkSnapCallbacks {
err := check(st, s, curInfo, flags)
if err != nil {
return err
}
}

if snapName != s.SnapName() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a test for this when instanceKey == ""

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test added.

@@ -843,6 +845,7 @@ func applyAutoAliasesDelta(st *state.State, delta map[string][]string, op string

snapsup := &SnapSetup{
SideInfo: &snap.SideInfo{RealName: snapName},
// TODO parallel-install: include instance key
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably want a more general TODO about the whole alias code vs instate keys and parallel installs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tweaked the comment a little bit.

@bboozzoo bboozzoo merged commit 8f466e4 into snapcore:master Aug 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants