-
Notifications
You must be signed in to change notification settings - Fork 42
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
Implement plugin manager #37
Conversation
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.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.
Great to get the baseline in, as we continue to iterate.
cc: @rgnote @shizhMSFT for review. |
plugin/metadata.go
Outdated
Description string `json:"description"` | ||
Version string `json:"version"` | ||
URL string `json:"url"` | ||
SupportedContractVersions []string `json:"supported-contract-versions"` |
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.
supported-contract-versions
Should it be supportedContractVersions
?
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.
Good catch!
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.
Overall, looks solid
plugin/plugin.go
Outdated
// MetadataSubcommandName is the name of the plugin subcommand | ||
// which must be supported by every plugin and returns the | ||
// plugin metadata. | ||
MetadataSubcommandName = "get-plugin-metadata" |
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 discover
?
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.
We changed it to get-plugin-metadata
in notaryproject/specifications#150
plugin/manager.go
Outdated
return cmd.Output() | ||
} | ||
|
||
type rootedFS struct { |
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.
nit: doc comment
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: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
@jaredpar @SteveLasker as the review process is going slower than expected, I've pushed a new batch of commits since. They don't add new functionality but refine the API after the learnings I got using it in notaryproject/notation#168. |
@qmuntal, question for how we can test a set of these changes. |
I like the idea! I'll come with something and share it with you all. |
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.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.
Overall structure and organization looks great, added some comments. Will make another pass tomorrow for some areas I skipped. I'm new to Go, some high level questions.
- Some of these error messages will be presented to users through the CLI, how do we differentiate them, and case and format them correctly with more context.
- We need to support verbose logging through out the library and CLI, is there a standard way to do that in Go? With verbose logging, we can return concise error messages to the user, and they can enable verbose logging for more details/troubleshooting.
plugin/errors.go
Outdated
"fmt" | ||
) | ||
|
||
var ErrUnknownCommand = errors.New("not a plugin command") |
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 need this exported variable? Plugin implementation should ideally return a custom error message that includes the unsupported command 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.
Wops, this variable is an unused leftover, will remove it.
if fsys, ok := fsys.(rootedFS); ok { | ||
return filepath.Join(fsys.root, name, base) | ||
} | ||
return filepath.Join(name, base) |
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 didn't understand what this code achieves, specially line 204. I'm new to Go.
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.
if fsys, ok := fsys.(rootedFS); ok {
this is an interface type cast, being ok
a flag which is true when fsys
can be casted to rootedFS
.
In production fsys
type is always rootedFS
, as this is what NewManager
instantiates, but for testing purposes I'm also supporting generic fsys
types, aka fs.FS
, which are mostly instantiated from testing/fstest
package.
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.
Got it. Should we add a code comment here to make this clearer, that the alternate path is to support testing?
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: qmuntal <qmuntaldiaz@microsoft.com>
Thanks for the review @gokarnm. My take is that What I wouldn't support is verbose levels in the returned errors. It either returns an error or not, leaving to the caller to decide if it should be logged as a debug, info, warning or whatever other level. The build-in |
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
What about the error message casing, error messages which are returned to CLI users should be correctly cased. It seems to be a convention to use small case error messages in Go?
Agreed, I wasn't clear enough. I meant verbose level should log to stdout so that it's visible to in CLI or an upstream caller if they enable verbose logging. The verbose logging will need to be supported in notation-go and notation-core-go, as that's where bulk of the decision paths and validations will be. This need not be implemented right away. |
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 for this iteration. Added a couple of comments to not allow symlinks for plugin dir, that can be addressed in next revision, when we add support for describe-key
.
plugin/manager/manager.go
Outdated
if fi.Mode().Type() != 0 { | ||
// Ignore non-regular files. | ||
return false | ||
} |
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.
We should additionally check if the containing dir ~/.notation/plugins/{plugin-name}/notation-{plugin-name}
is also not a symlink, something that was missed in the spec.
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 exactly what it is being checked here. Non-regular files include symlinks and directories.
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'm bit confused here. Isn't this code only checking that the plugin executable (notation-{plugin-name}
) itself is not a symlink, and not that additionally the enclosing directory is also not a symlink (~/.notation/plugins/{plugin-name}
dir)?
plugin/manager/manager.go
Outdated
if dir == "." || !d.IsDir() { | ||
return 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.
We should skip over plugin dirs that are symlinks, something that was missed in the spec.
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!
There are multiple options to transform and localize text, being https://pkg.go.dev/golang.org/x/text the most common.
If we need to log something from those libraries, which is still not clear to me if we should, we will find the way. For example, http.Server logs error into the optional |
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Yes, that's what I'm looking for, similar to libraries that support emitting verbose logs to aid debugging issues. It would be useful for us to debug user reported errors as the logic in many of these areas, plugin and signature verification logic, is quite complex. |
This PR implements the common code of the plugin-extensibility spec so it will be used by
notary
and others.The
Manager
implementation will probably change once notaryproject/notation#167 is discussed.It also contains unit test and integration tests with ad-hoc plugins. Coverage is around 95%.
@SteveLasker
Signed-off-by: qmuntal qmuntaldiaz@microsoft.com