-
Notifications
You must be signed in to change notification settings - Fork 524
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
RFC: New registry provider extensibility model #2033
Comments
Thank you, @bwateratmsft, for putting together this document. Here are my suggestions--HTH! OverviewMy assumption is this document is a design proposal and not just an invitation for brainstorming. As such it should be addressed to the person(s) who does registry provider implementation (registry extension author). It should tell them what can be accomplished, and how. What "we" (VS Code Docker extension owners) think, or need to do, is only relevant to the extent that it facilitates the job of the registry extension author. Everything else is unnecessary. Also, if a facility is necessary, don't say "we would need to create X". Say "Docker extension provides X" instead. Do not say "we most likely would include X". Say "the public API package includes X".
We should enumerate what commands will be provided by the Docker extension, and briefly describe their semantics. Registering a registry providerIn this section I would expect to learn what specific VS Code event(s) the registry provider author will have to handle to register themselves with the Docker extension. A code snippet, or a reference to an example would be very helpful. Provider pick listI suggest that the spec just guarantees that if the registry provider is registered with Docker extension, the corresponding registry type will be available as a choice for the user that is attempting to connect to a Docker registry. That is all. Precisely how this will happen, what UI is involved, the manifest, and the tagging, are all user experience & implementation details that are both not fully worked out, and not very important from the registry provider perspective. RegistryTreeItem interface
I would say that
So what is it? Why would a
Left-clicked? Can you elaborate? Other interfaces
|
I think Mike already made the decision for us that the above (including manifest) is final. Since provider authors who want to be discovered will need to update the manifest, they need to know about it.
It would be an ID unique to the specific node, and authors may want it for contextual information when executing commands.
Here's the text from the VSCode API doc:
When you left-click a tree node, if this command is defined, it will be executed. Within that command you also define the arguments, if any. As an example, our
I'm not sure I understand exactly what you mean. |
I agree with @karolz-ms regarding the "cached" functions; exposing parallel sets of functions in the interface is confusing and feels like it pushes requirements onto implementations that may not have such concerns. If what we're really trying to convey is whether the user explicitly refreshed a node (vs. normal navigation), then I think that's more easily done with a flag (e.g. |
Heheh, TBH I like that better as well, which is why I did it that way originally. Implementers have the flexibility to cache or not, but clear instruction if they are caching when they should drop it. I think caching should be as invisible to a caller as possible. In this case, the caller needs the authority to invalidate the cache, so a simple boolean flag works. The rest can be invisible behind one method. |
While I understand the reasoning behind making I wonder if we can use a model where a |
That sounds like a good candidate for something we'll implement if we actually find we have need of it. Command calls will get the |
There is little semantic difference between having |
In general, I wonder whether we can make the "simple" registry provider more of a proper subset (in terms of interface implementations) of the "custom" registry provider, rather than having two completely different provider implementations (with a somewhat complex/confusing set of optional functions in that base provider interface). What I'm thinking of is have every registry provider be a "custom" one, but provide helper/factory functions that allow extensions to create simple implementations with minimal fuss. I'm also thinking that this would help in cases where a "custom" provider is really just a simple one with, perhaps an extra layer of parent nodes. In that case, the current proposal seems to drop them into a "implement everything yourself" rather than a model where they can add their one layer, then use helpers to generate the rest. |
@karolz-ms So is your suggestion to have a |
The idea being that you can subsequently call |
@philliphoff interesting idea, but I am worried that it might make the contract significantly more complicated |
I agree; I feel like a "simple" way to just add a layer of nodes would actually be much more complicated. In terms of implementation, here's how I plan to do Azure, which might help make more sense why I did it this way.
With this approach you can "add a layer" of nodes, without making for a confusing implementation of the contract for those who want to stick with the basics. I like the extreme simplicity of the basic implementation--you literally cannot make something any simpler than |
I guess I'm just trying to avoid the awkwardness of the semantics of Something like: export interface RegistryTreeItem<T> {
// Mirror vscode.TreeItem properties
readonly context?: T;
} |
Or explicitly define a property on the callback node containing their original object? The wrapping |
But |
No, which is why almost all of the properties on
Yes, derive from the generic Registry V2 provider I will also be writing, and if your registry isn't V2 compliant, find a new registry 😉 |
So there will be a generic registry provider that as part of this API that extensions can derive from (or otherwise extend)? Can we make sure that's part of this proposal/design? Will you have to derive from that generic provider in whole or can one, for example, just take certain node types from it and reuse them from one's own provider? (Is this the what the Azure registry provider will be based on?) |
Yes and yes!
It will be split-up-able, which is what Azure will be doing. In fact, I'm planning on implementing two layers, basically--a generic caching provider that takes care of Memento and keytar storage, so that you don't have to think about permanent caching (or, in-memory caching, or secret storage), and then a RegistryV2 extension of that which can talk to V2 registries. Azure will be an extension of the latter with some extra layers, Docker Hub of the former. GitLab will also be the former. |
Good, I'm eager to see what that looks like and will wait before making any further comments. I feel like, once written down, it will end up being very similar to my idea of factory/helper functions that allow extensions to easily create parts of the tree they don't care to customize, which I think will make it clearer how to support both "simple" and "(semi-)custom" providers without having to support two completely different provider interfaces. (E.g. a provider simply returns a root |
JFrog with Artifactory - used by SAP, all enterprises which use SAP, Finance, Helth services .... because its security is approved by certain agencies. |
Closing since there hasn't been much engagement. We're planning to work on #869 this semester. |
Docker Registry Provider Extensibility Model
Motivation
Several concerns around registry providers have motivated us to explore a better extensibility model for supplying additional providers. These include:
In order to alleviate these concerns it is necessary to establish a better extensibility model.
Overview
Adding a registry provider would involve creating an extension, which can communicate with the Docker extension to provide a view into a given registry. Optionally, the extension could also implement context and palette commands. With the correct context values on nodes, the existing context and palette commands will also work. These commands include:
vscode-docker.registries.copyImageDigest
vscode-docker.registries.deleteImage
vscode-docker.registries.disconnectRegistry
vscode-docker.registries.logInToDockerCli
vscode-docker.registries.logOutOfDockerCli
vscode-docker.registries.pullImage
vscode-docker.registries.pullRepository
vscode-docker.registries.reconnectRegistry
vscode-docker.images.push
(indirectly, this depends onDockerRegistry.baseImagePath
)// TODO: this feels out of place in the Overview section
// TODO: List the right context values in source
A Node package (
vscode-docker-registries
) contains the interfaces necessary to properly implement the provider, and also includes a generic V2 provider, since most providers would be little more than a slim inheriting implementation on top of that.Implementing a registry provider
In order to connect to a given registry, the provider author must write the necessary code to authenticate and query their offering, and implement the necessary provider interfaces (alluded to above and described in detail below).
There are two ways to do this:
1. Strict registry structure
An extension implements three primary methods (and some additional supporting methods):
Implementing a registry provider this way is very simple, but additional features (like ACR's subscriptions, tasks) are not possible.
2. Show arbitrary tree structure
An extension gives a tree object which will show anything they wish. It is more difficult to implement but offers greater flexibility.
Registering a registry provider
The Docker extension implements an interface (see below) allowing for registry providers to register themselves with the extension. The extensions need to call this registration method every time the Docker extension is activated, and can accomplish this by setting an activation event on the command
vscode-docker.registries.providerActivation
. Inpackage.json
:Upon activation, the provider extension must call the Docker extension to register. The
registerDockerRegistryProvider
method returns aDisposable
which should be pushed to the extension activation context's subscriptions.Showing up in the provider pick list
In order to be used, an extension needs to show up in the quick pick list for registry providers. The list will consist of:
Optionally, the Docker extension may also establish a tag that can be used by provider extensions to easily filter for them on the marketplace, and a link/command/etc. within the Docker extension to open the marketplace with that filter.
Interfaces
Docker extension
DockerExtension
:Note: "register...Registry" is a bit of a tongue twister, but all of the VSCode API's similar methods use "register*"; consistency is good.
Basic registry provider
RegistryTreeItem
:DockerRegistryProviderBase
:BasicDockerRegistryProvider
:DockerRegistry
:DockerRepository
:DockerTag
:Custom registry provider
CustomDockerRegistryProvider
:ParentTreeItem
:Others
DockerCredentials
:CommandContext
:The text was updated successfully, but these errors were encountered: