-
Notifications
You must be signed in to change notification settings - Fork 651
daemon,overlord: add subcommand handling to snapctl #1718
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
daemon,overlord: add subcommand handling to snapctl #1718
Conversation
Add some more logic and subcommands to snapctl. Stub out initial set command. This should allow other subcommands to be easily added (e.g. for interface hooks). Updates: #1586465 Signed-off-by: Kyle Fazzari <kyle@canonical.com>
overlord/hookstate/handler.go
Outdated
|
|
||
| // Generate a secure, random ID for this handler | ||
| idBytes := make([]byte, 32) | ||
| _, err := rand.Read(idBytes) |
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 this block for any amount of time?
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.
It uses getrandom(), which by default uses /dev/urandom, which shouldn't block.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
c708671 to
4aaded3
Compare
…kmanager_snapctl Signed-off-by: Kyle Fazzari <kyle@canonical.com>
overlord/hookstate/hookmgr.go
Outdated
| state: s, | ||
| runner: runner, | ||
| repository: newRepository(), | ||
| activeHandlers: newHandlerCollection(), |
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/activeHandlers/handlers/ (we don't have any inactive ones)
I've mentioned this in earlier reviews: it doesn't feel like the additional abstraction there is gaining us much. As a thought experiment, try to inline a map and a simple mutex here, and see how much code you need to write here, vs. how much code you drop.
That said, I believe what we really want here is a map of context, not handlers. The reason being that context is a concrete and common implementation, and it would be simple and convenient to introduce a HookHandler method on context to navigate from a context into its handler. Doing that in the opposite direction is boring, because every single handler will need to reimplement the same method to return its context.
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.
Done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
daemon/api.go
Outdated
| return BadRequest("cannot run snapctl: %s", err) | ||
| } | ||
|
|
||
| stdout, stderr, err := ctlcmd.RunCommand(context, snapctlRequest.Args) |
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 one might be just ctlcmd.Run now that we have cmd in the package name.
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.
Done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
client/snapctl.go
Outdated
|
|
||
| // RunSnapctl requests a snapctl run for the given options. | ||
| func (client *Client) RunSnapctl(options SnapCtlOptions) (stdout, stderr []byte, err error) { | ||
| func (client *Client) RunSnapctl(options hookstate.SnapCtlRequest) (stdout, stderr []byte, err 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.
Options was right on this end, per other similar methods. If the point is reusing the same type, it's okay to keep it as options everywhere.
This should also be received as a pointer, as the other option values in client.
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.
Also note that, as we agreed before, when reusing such types we should have them inside client rather than inside the other internal package, so it's obvious when we're adding code that makes no sense for the client end.
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.
Moved this back to client.SnapCtlOptions, and used that throughout for consistency.
|
LGTM with these last few points sorted. |
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
| exit 1 | ||
| fi | ||
|
|
||
| if [[ ! "$output" =~ .*"no context for ID: \"foo\"".* ]]; then |
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.
Spread test still broken here. I'd suggest the more usual:
echo "$output" | grep -q 'no context for ID: "foo"'
No need for ifs or the extra message here. Note that English sentence below is a direct translation of the code, which in this specific case is more clear.
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.
Or alternatively, using the bash expression syntax, but simply:
[[ "$output" =~ 'no context for ID: "foo"' ]]
I've just confirmed that it traces properly as well, and actually better than echo+grep.
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.
Ah, and the problem is actually on the former line:
error: cannot run snapctl: cannot run snapctl: no context for ID: "foo"
+ output='Running snapctl. It should be in my PATH and not cause denials.'
+ [[ ! Running snapctl. It should be in my PATH and not cause denials. =~ .*no context for ID: "foo".* ]]
Need something like output="$(snap ... 2>&1 >/dev/null)" to capture only stderr.
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.
Oops, good catch, thanks! Passing now.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
|
|
||
| // NewMockHandler returns a new MockHandler. | ||
| func NewMockHandler() *MockHandler { | ||
| return &MockHandler{ |
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.
Pardon my ignorance here, but given goes default policy of zeroing values, why explicatively init them here? Or am I missing something?
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, you're not missing anything, I'm being dumb. Fixed now, thanks!
|
Looks good, just one question inline |
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Make some more progress on LP: #1586465 by adding some more logic and subcommands to
snapctl. Stub out initialsetcommand. This should allow other subcommands to be easily added (e.g. for interface hooks).