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

Push metadata to the Store. #1634

Merged
merged 11 commits into from
Nov 27, 2017
Merged

Push metadata to the Store. #1634

merged 11 commits into from
Nov 27, 2017

Conversation

facundobatista
Copy link
Contributor

This is to fulfill first part of design discussed in this forum post.

Copy link
Contributor

@kalikiana kalikiana left a comment

Choose a reason for hiding this comment

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

@facundobatista Note the store tests are failing on Travis.

@@ -364,6 +364,18 @@ def get_assertion(self, snap_id, endpoint):
def sign_developer_agreement(self, latest_tos_accepted=False):
return self.sca.sign_developer_agreement(latest_tos_accepted)

def update_metadata(self, snap_name, metadata, arch, force):
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the purpose of arch here? It only seems to be used for the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly! The idea is to maintain the detail level of the rest of SnapNotFoundError messages.

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. It just strikes me as odd that the method would use a value in the error that isn't needed to do the actual work. As in, the error is providing more detail than is relevant to the failure. I might be missing something, though.

for field_name, error in sorted(conflicts):
sent = metadata.get(field_name)
parts.extend((
"Conflict in {!r} field:".format(field_name),
Copy link
Contributor

Choose a reason for hiding this comment

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

The error should probably say something like You can use --force-metadata to update anyway?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And repeat this message in ALL conflict lines, you say?

Maybe it's better to add a line (in case of conflicts) after all conflicts, saying something like "You can repeat the command with --force-metadata to force the local values into the Store"?

What do you think? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that sounds great!

@facundobatista
Copy link
Contributor Author

Oh, Travis failed because a CLA check: The command "./tools/travis/run_cla_check.sh" exited with 1., but I already signed the CLA.

Looks like failed the CLA check on @jocave ([email protected]), but I don't know why he is related to my branch :(

@facundobatista
Copy link
Contributor Author

@kalikiana there I did the changes we talked about, thanks!

Copy link
Contributor

@kalikiana kalikiana left a comment

Choose a reason for hiding this comment

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

Grand, thanks! I like it!


If only_metadata is True it will just send the metadata; otherwise the
whole process is done (including sending the metadata after sending the
snap binary).
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 please document the force_metadata arg?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks!

\b
Examples:
snapcraft push my-snap_0.1_amd64.snap
snapcraft push my-snap_0.1_amd64.snap --only-metadata
Copy link
Collaborator

Choose a reason for hiding this comment

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

hey @matthewpaulthomas or @evandandrea do you think --only-metadata is correct here, it feels strange to me even though it is technically correct. Should this be --metadata or something else?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think --only-metadata is self-explanatory. The option should reflect the developer's intention, not what happens internally (the metadata is sent, the snap is not).

I would be more explicit and use --overwrite-metadata.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note however that "overwrite metadata" is not what it does, unless you also pass "force metadata", because pushing metadata can result in conflicts if you modified those fields through the web UI.

Also, these names are stablished in the proper forum post, should discuss these there?

snapcraft push my-snap_0.2_amd64.snap --release edge
snapcraft push my-snap_0.3_amd64.snap --release candidate,beta
"""
if release and only_metadata:
raise click.UsageError(
"--only-metadata and --release are mutually exclusive")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't this be done with click itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -115,7 +129,7 @@ def push(snap_file, release):
'After pushing, an attempt to release to {} '
'will be made'.format(channel_list))

snapcraft.push(snap_file, channel_list)
snapcraft.push(snap_file, channel_list, only_metadata, force_metadata)
Copy link
Collaborator

Choose a reason for hiding this comment

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

instead of passing the logic over to push, can we handle the logic to call update_metadata from here? The printing with logger in that method should also be brought over here (it is a bit hard with some of the current logic we have but most of this stuff should be easily movable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can be moved, but conceptually "it's a push" (complete, or only metadata).

Another drawback of moving it to here is the need to call the private '_get_data_from_snap_file' from the private '_store".

I could start to move stuff around and/or make it public if you insist (but probably it would be better to do that in a separate branch, which I can commit to do if we decide this path)

@sergiusens sergiusens added this to the 2.36 milestone Oct 26, 2017
@facundobatista
Copy link
Contributor Author

Well, Travis now failed again with a weird message: "The job exceeded the maximum time limit for jobs, and has been terminated."

How can I trigger a new Travis check?

@kalikiana
Copy link
Contributor

I re-triggered it for you.

@facundobatista
Copy link
Contributor Author

Thanks! It worked ok now...


__FMT_NOT_REGISTERED = (
'Sorry, try `snapcraft register {snap_name}` before trying to '
'update metadata.')
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm getting this error when I try to push --only-metadata without having pushed the snap first.
We should catch when the snapcraft is registered but not pushed, and recommend to call without --only-metadata. Is that possible?

Copy link
Contributor

@come-maiz come-maiz Nov 9, 2017

Choose a reason for hiding this comment

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

Following @matthewpaulthomas's suggestion, the error messages should say what happened, why, and how to fix it.
What do you think of something like: "Failed to update metadata: snap not registered. Run first snapcraft register {snap_name} and then snapcraft push {snap_file}". ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will change, taking also Sergio's recommendation below

" In the Store: {!r}".format(error['message']),
))
parts.extend((
"You can repeat the command with --force-metadata",
Copy link
Contributor

Choose a reason for hiding this comment

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

This comma introduces a weird new line in the middle of the message. We generally don't wrap the messages, and if we do, we probably should do it in a single place. So, I think it would be better to add a single string.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also related to this message, "You can repeat the command with --force-metadata" seems confusing when you get this error while pushing a new revision. Note that in that case the revision is correctly uploaded, so re-uploading it won't work (so you would need to do a --only-metadata + --force-metadata instead).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regarding the comma, I was doing that on purpose, I'll fix it to have a single string.

And will improve the message.

Copy link
Contributor

@come-maiz come-maiz left a comment

Choose a reason for hiding this comment

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

@facundobatista sorry for the late late review.
This looks very good to me, I've just left a few comments, please let me know what do you think about them.

Also, it would be nice to have at least one integation_test for the happy update of the metadata. On that test it will be hard to verify if the update succeeded, which makes me think that we need a command to get the current values in the store. Something like snapcraft metadata <snap-name>.

Also it seems not possible to test the conflict in an integration_test against the staging server, right? In that case, documenting in manual_tests.md a test that makes a push, goes to the store, changes values, and tries to push again would be good.

@sergiusens
Copy link
Collaborator

sergiusens commented Nov 9, 2017 via email

@facundobatista
Copy link
Contributor Author

@ElOpio thanks for the comments, there I answered them. Also I'll add an integration test, and describe in the manual file how to test the situation of the conflict (as you said, this can not be done automatically)

@sergiusens I'll like your suggestion for the message. Also will check that we don't say "metadata" in any human text

@facundobatista
Copy link
Contributor Author

@ElOpio @sergiusens did the changes as discussed/reviewed, thanks!

Copy link
Collaborator

@sergiusens sergiusens left a comment

Choose a reason for hiding this comment

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

Given this
"""
10:43 mpt Facu sorry my head works in mysterious ways... I don't know where I got my references from; but starting from scratch, does snapcraft push-metadata feel more straightforward and understandable than snapcraft push --only-metadata?
10:43 sergiusens, to me, yes
"""

I think we should just move over the command and make these minimal UI layer changes and we should be good to go

@@ -364,6 +364,18 @@ def get_assertion(self, snap_id, endpoint):
def sign_developer_agreement(self, latest_tos_accepted=False):
return self.sca.sign_developer_agreement(latest_tos_accepted)

def update_metadata(self, snap_name, metadata, force):
Copy link
Collaborator

Choose a reason for hiding this comment

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

From conversations on IRC, can you call this push_metadata?

@@ -609,6 +621,21 @@ def snap_push_metadata(self, snap_name, updown_data,

return StatusTracker(response.json()['status_details_url'])

def update_metadata(self, snap_id, snap_name, metadata, force):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please rename to push_metadata

Copy link
Collaborator

@sergiusens sergiusens left a comment

Choose a reason for hiding this comment

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

Thanks a but for your contribution! It looks really good and the team really appreciates your patience!

I have two minor comments about printing that should be super simple to address.


logger.info("The metadata has been updated")
logger.info("The metadata has been pushed")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just one minor nit, can you remove this from here and put it under

snapcraft.push_metadata(snap_file, force)

in snapcraft.cli.store?

If force=True it will force the local metadata into the Store,
ignoring any possible conflict.
"""
logger.info("Pushing metadata to the Store (force=%s)", force)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mind removing this line or making it .debug or we will get a double print on regular runs?

@facundobatista
Copy link
Contributor Author

Pushed requested change

@sergiusens sergiusens merged commit 2f61ad0 into canonical:master Nov 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants