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

cmd/snap: snap refresh --time with new and legacy schedules #4487

Merged
merged 18 commits into from Jan 30, 2018

Conversation

bboozzoo
Copy link
Collaborator

Add --timer command line switch to snap refresh command. The switch replaces
--time (now hidden). Passing --time switch, the legacy format of the output is
preserved. When using --timer instead, the output clearly indicates that what is
returned is the new time schedule.

Add --timer command line switch to `snap refresh` command. The switch replaces
--time (now hidden). Passing --time switch, the legacy format of the output is
preserved. When using --timer instead, the output clearly indicates that what is
returned is the new time schedule.

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

codecov-io commented Jan 15, 2018

Codecov Report

Merging #4487 into master will decrease coverage by 0.1%.
The diff coverage is 89.65%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4487      +/-   ##
==========================================
- Coverage   78.28%   78.18%   -0.11%     
==========================================
  Files         453      455       +2     
  Lines       32334    32466     +132     
==========================================
+ Hits        25312    25382      +70     
- Misses       4923     4970      +47     
- Partials     2099     2114      +15
Impacted Files Coverage Δ
client/client.go 80.78% <ø> (ø) ⬆️
overlord/snapstate/snapmgr.go 87.72% <100%> (ø) ⬆️
daemon/api.go 74.65% <100%> (+0.04%) ⬆️
overlord/snapstate/autorefresh.go 78.86% <83.33%> (ø) ⬆️
cmd/snap/cmd_snap_op.go 67.63% <85.71%> (+0.33%) ⬆️
interfaces/dbus/backend.go 57.97% <0%> (-4.53%) ⬇️
overlord/hookstate/hookmgr.go 72% <0%> (-1.15%) ⬇️
userd/launcher.go 68.42% <0%> (ø) ⬆️
interfaces/builtin/desktop.go 87.5% <0%> (ø) ⬆️
cmd/snap/cmd_run.go 69.04% <0%> (ø) ⬆️
... and 6 more

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 3b69fca...8d6b922. Read the comment docs.

@mvo5
Copy link
Contributor

mvo5 commented Jan 16, 2018

A bit of a meta-question: shouldn't client.SysInfo() have the data if its the new-style of legacy schedule? Or is this purely about the prefix string (schedule or timer)? I guess I wonder if it makes sense to have something like: schedule: new-style-timer (which will happen with this PR afaict).

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.

LGTM, but please see the little nitpick, +1

if x.asksForMode() || x.asksForChannel() {
return errors.New(i18n.G("--time does not take mode nor channel flags"))
err := errors.New(i18n.G("--timer does not take mode nor channel flags"))
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: no need for err variable, just:

if x.Time
    return errors.New(...)
}
return errors.New(...) // --timer error
'''

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed, thanks

Copy link
Collaborator

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
@@ -599,7 +599,8 @@ type cmdRefresh struct {

Revision string `long:"revision"`
List bool `long:"list"`
Time bool `long:"time"`
Time bool `long:"time" hidden:"yes"`
Timer bool `long:"timer"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at the PR, there's a gut feeling that this is error prone. The difference between "time" and "timer" is too subtle, and people will end up using one or the other without realizing, and getting weird behavior. I suggest just introducing the new behavior, and only displaying schedule if one is indeed set and no timer is set.

There's a very small chance that this will break someone that was trying to get the old schedule even when nothing was set, but this risk is one-off and better than the risk of having error prone behavior forever.

…y format

Let the callers know whether the refresh schedule was defined using a legacy
format.

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…ules

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Adjust refresh info returned in sysinfo endpoint depending on the use of the
modern 'refresh.timer' or the legacy 'refresh.schedule' settings. When the new
refresh.timer setting is used only the 'timer' field will be sent. Similarly,
when the legacy setting is in effect, the 'timer' field will not be sent and
'schedule' will be send instead.

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…h info

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
@bboozzoo bboozzoo changed the title cmd/snap: snap refresh --timer, hide --time cmd/snap: snap refresh --time with new and legacy schedules Jan 24, 2018
timerOrSchedulePrefix = "schedule"
timerOrSchedule = sysinfo.Refresh.Schedule
}
fmt.Fprintf(Stdout, "%s: %s\n", timerOrSchedulePrefix, timerOrSchedule)
Copy link
Contributor

Choose a reason for hiding this comment

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

That's quite verbose for what's essentially this:

if sysinfo.Refresh.Schedule != "" {
        fmt.Fprintf(Stdout, "schedule: %s", sysinfo.Refresh.Schedule
} else {
        fmt.Fprintf(Stdout, "timer: %s", sysinfo.Refresh.Timer)
}

Note that the server should never send a schedule if timer is set, or the reverse.

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

@zyga zyga left a comment

Choose a reason for hiding this comment

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

Tests need adjustments:

+ '[' true = false ']'
+ snap install test-snapd-control-consumer
test-snapd-control-consumer 1.0 from 'testrootorg' installed
Snap test-snapd-control-consumer is no longer tracking stable.
+ snap interfaces
Slot                      Plug
[snip]
:snapd-control            test-snapd-control-consumer,test-snapd-control-consumer:snapd-control-with-manage
+ echo 'When the snapd-control-with-manage plug is connected'
When the snapd-control-with-manage plug is connected
+ snap connect test-snapd-control-consumer:snapd-control-with-manage
+ echo 'Then the system knows it can be set to managed'
Then the system knows it can be set to managed
+ snap debug can-manage-refreshes
+ MATCH true
+ echo 'Then the core refresh.schedule can be set to '\''managed'\'''
Then the core refresh.schedule can be set to 'managed'
+ snap set core refresh.schedule=managed
+ journalctl -u snapd
+ grep 'cannot parse "managed"'
+ snap refresh --time
+ MATCH 'schedule: managed'
error: pattern not found, got:
timer: managed
last: 2018-01-24T15:50:00Z
next: 2018-01-25T19:22:00Z

…figuration setting

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

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

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

Thanks for this update! Looks good, I put some nitpicks inside but really no blockers, feel free to ignore.

client/client.go Outdated
Schedule string `json:"schedule"`
// Schedule contains the legacy refresh.schedule setting. The field is
// omitted when the legacy setting is not used.
Schedule string `json:"schedule,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

(nitpick^10) I would put schedule and timer close to each other, probably move schedule at the end (under timer).

@@ -665,7 +665,11 @@ func (x *cmdRefresh) showRefreshTimes() error {
return err
}

fmt.Fprintf(Stdout, "schedule: %s\n", sysinfo.Refresh.Schedule)
if sysinfo.Refresh.Schedule != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

(nitpick^2) I wonder if this should be the other way around (even though it does not make a practical difference I suppose). I.e. to make clear that sysinfo.Refresh.Timer is the thing that always wins if it is set?

We should also probably show an (internal) error if no refresh schedule is set at all (and add a test for this).

// RefreshSchedule will return a user visible string with the current schedule
// for the automatic refreshes and a flag indicating whether the schedule is a
// legacy one.
func (m *autoRefresh) RefreshSchedule() (string, bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would name the return values now to make clear what the "bool" stands for, something like func ... (schedule string, legacy bool, err error)

Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
…schedule are empty

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

@niemeyer niemeyer left a comment

Choose a reason for hiding this comment

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

LGTM with just trivials, thanks!

} else if sysinfo.Refresh.Schedule != "" {
fmt.Fprintf(Stdout, "schedule: %s\n", sysinfo.Refresh.Schedule)
} else {
return errors.New("internal error, both refresh.timer and refresh.schedule are empty")
Copy link
Contributor

Choose a reason for hiding this comment

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

Either this is incorrect, or the documentation on the fields above is incorrect, since they disagree. The documentation for the fields says that for both fields, the value is omitted if not in use. That seems to imply that it is possible for them both to be empty if the user hasn't set either.

As an aside, in those cases I think we use a colon after internal error ("internal error: ...").

Next: formatRefreshTime(nextRefresh),
}
if !legacySchedule {
refreshInfo.Timer = refreshScheduleStr
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks good. Seems to be the field documentation that is wrong. I suggest just dropping the "The field is omitted" part of both comments. The desired intention there seems to be implied by omitempty already.

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

Is this good to be merged?

Copy link
Collaborator

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM with one word change, feel free to push in another branch if you want.

@@ -366,10 +366,10 @@ func (m *SnapManager) LastRefresh() (time.Time, error) {
return m.autoRefresh.LastRefresh()
}

// RefreshSchedule returns the current refresh schedule as a string
// suitable to display to a user.
// RefreshSchedule returns the current refresh schedule as a string suitable to
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nitpick: suitable for

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

merge?

@zyga zyga merged commit 2dd7827 into snapcore:master Jan 30, 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
6 participants