-
Notifications
You must be signed in to change notification settings - Fork 611
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
[WIP] Re-enable plugin filter #1517
Conversation
Current coverage is 55.12% (diff: 0.00%)@@ master #1517 diff @@
==========================================
Files 102 102
Lines 16940 16945 +5
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 9340 9341 +1
+ Misses 6438 6434 -4
- Partials 1162 1170 +8
|
Isn't the issue that there's a catch-22? I'm not sure my memory is correct, but I thought requiring a certain plugin wouldn't schedule the task on a node until the plugin was loaded on that node, but the plugin might not get loaded until a task which uses it runs there. |
@aaronlehmann I wasn't aware of this catch-22 situation. I was under the impression that a plugin is loaded externally on a node (say by an operator) and has nothing to do with SwarmKit. I'll try to get this clarified. |
The preconditions for adding this back are in the
I think the problem is that there are cases where the plugin isn't reported until it is actually in use. What testing have we done to confirm this works? |
8bddc81
to
fdce868
Compare
Welp @tiborvass @vieux |
fdce868
to
60c85b2
Compare
After some discussion with @vieux, here's an update: There are two caveats though
WDYT @aluzzardi @stevvooe @aaronlehmann? |
@nishanttotla : PluginsV2 can be queried using PluginList API endpoint. Also pluginsV2 will be stable in 1.13, so you dont need to worry about experimental support only. |
@anusha-ragunathan thanks! Is there a PR to track, that's moving PluginsV2 out of experimental? We can then update this PR and merge after that one is. |
@nishanttotla : There's no PR yet, but an issue tracking it. moby/moby#26760 |
60c85b2
to
4b52408
Compare
Also related: #1545 |
4b52408
to
1525602
Compare
Picking this up again, after moby/moby#28226 was merged. I will update this PR using |
In 1.13, we will support pluginv1 (where plugins are queried via |
@anusha-ragunathan thanks for the heads up. In the case of Swarm mode though, v1 plugins are tricky because they won't show up in So we might have to stick to v2 plugins for Swarm mode. |
What about the case where the v1 plugin was loaded and running before the node joined the swarm? Node had some containers using the plugin. So plugin was loaded and running and |
@anusha-ragunathan you're right, I hadn't considered that case. Fortunately, it won't be hard to support both, so I will update the PR accordingly. |
1525602
to
95d591a
Compare
95d591a
to
c6abcf8
Compare
e30d3b3
to
b2ae871
Compare
Are these test failures related? @LK4D4 |
Looks similar to #1662 It is unrelated. |
b2ae871
to
2ac4be6
Compare
addPlugins("Volume", info.Plugins.Volume) | ||
// Add builtin driver "overlay" (the only builtin multi-host driver) to | ||
// the plugin list by default. | ||
addPlugins("Network", append([]string{"overlay"}, info.Plugins.Network...)) | ||
addPlugins("Authorization", info.Plugins.Authorization) | ||
|
||
// retrieve v2 plugins |
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.
/cc @tiborvass @vieux @anusha-ragunathan
Could you please take a look at this logic?
@nishanttotla This needs testing (at the very least manual). e.g. install a plugin on a machine and then deploy a service using that plugin (and make sure it gets deployed ONLY to that machine) |
for _, plgn := range v2plugins { | ||
for _, typ := range plgn.Config.Interface.Types { | ||
plugins[api.PluginDescription{ | ||
Type: typ.String(), |
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.
typ.String()
will return something of the format docker/VolumeDriver:1.0
. However, test code in scheduler_test.go: L1404 still sets the type to be Volume
. Where are the changes in swarmkit to accomodate this new format?
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.
Is this new microformat documented anywhere?
Do plugins no long have a type?
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.
b7d2cd2
to
9a5c348
Compare
@tiborvass @stevvooe @anusha-ragunathan Updated the PR to save plugins based on driver type. PTAL. |
@@ -41,12 +41,35 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) { | |||
} | |||
} | |||
|
|||
// add v1 plugins to 'plugins' | |||
addPlugins("Volume", info.Plugins.Volume) |
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.
@anusha-ragunathan do we want to add v2 plugins to docker info
or not? If we do, then info.Plugins.Volume
will contain both built-in local
driver, v1 plugins, and v2 plugins.
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 dont feel strongly towards adding v2 plugins to docker info
.
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 feels weird not to add them imho. Why would only built-in drivers + v1 plugins appear there?
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.
There's already a way to query them from docker using docker plugin ls
and hence there's no reason to duplicate the info.
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.
Right, but now there is a field called Plugins
in docker info, that is essentially deprecated without being deprecated. Anyway, not sure what's the best solution.
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.
The reason docker info
historically had a Plugins
section is because, there was no other way to query for that information through docker. Now that plugins are a first-class docker citizen, we should not continue down a legacy path of exposing that info.
We should document that Plugins
in docker info
lists only pluginsv1 and to query for pluginsv2 use docker plugin ls
. When pluginsv1 is deprecated, we should consider removing Plugins
from docker info
.
// add v2 plugins to 'plugins' | ||
for _, plgn := range v2plugins { | ||
for _, typ := range plgn.Config.Interface.Types { | ||
plgnTyp := typ.Capability |
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.
you need to also verify that typ.Prefix == "docker"
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.
for _, typ := range plgn.Config.Interface.Types { | ||
plgnTyp := typ.Capability | ||
if typ.Capability == "volumedriver" { | ||
plgnTyp = "Volume" |
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.
@nishanttotla what happens if we remove these ifs ? The capability is volumedriver
. I actually wonder if it shouldn't even be the whole type: docker/volumedriver:1.0
. cc @anusha-ragunathan
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.
My understanding is that we want to rename it to Volume
here because of this line that was shipped in 1.12: https://github.com/docker/swarmkit/pull/1517/files#diff-0c043559989dc54f88aaac9214b99260R45
which in turn was there because that's the nomenclature in docker info
.
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.
@tiborvass Not exactly. The way I understand, the reason is in filter.go
. Notice the Check()
function for PluginFilter
// Check returns true if the task can be scheduled into the given node.
func (f *PluginFilter) Check(n *NodeInfo) bool {
// Get list of plugins on the node
nodePlugins := n.Description.Engine.Plugins
// Check if all volume plugins required by task are installed on node
container := f.t.Spec.GetContainer()
if container != nil {
for _, mount := range container.Mounts {
if mount.VolumeOptions != nil && mount.VolumeOptions.DriverConfig != nil {
if !f.pluginExistsOnNode("Volume", mount.VolumeOptions.DriverConfig.Name, nodePlugins) {
return false
}
}
}
}
// Check if all network plugins required by task are installed on node
for _, tn := range f.t.Networks {
if !f.pluginExistsOnNode("Network", tn.Network.DriverState.Name, nodePlugins) {
return false
}
}
return true
}
In particular, I'm pointing out to the fact that volumes are stored as mounts, and networks stored separately, and we check if the corresponding Driver exists on that node. This is why I wanted to store with a simple "Volume" or "Network" key, instead of the longer form returned by type.String()
. For other plugins, this PR is storing the long form version.
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.
On that note, the issue that we don't have a way of storing arbitrary plugins in the TaskSpec, from which to match them against the node on which PluginFilter
is applied. For volumes and networks, this happens via a separate code path that allows for attaching to networks or mounting volumes. This is something we might want to build to support general plugins, and will require proto changes. This PR will work for volume and network v2 plugins.
cc @stevvooe
94a85f7
to
1651614
Compare
I think there may be fundamental problems with the plugin data model that need to be worked out before going forward with this. For example, the plugin list reported via NodeDescription is actually a list of drivers (we should probably rename this), but the new plugin model creates "capabilities". What are these capabilities? How do they work? I have seen a few examples in discussion but the results look foreign. Do we have a list of capabilities for a plugin? For this to work properly, we really need a feedback loop of installation of a plugin to whatever the result is for a running plugin. This only lists the plugins and reports them, and doesn't provide any indication if they are the right state or the correct plugin. |
|
||
// add v2 plugins to 'plugins' | ||
for _, plgn := range v2plugins { | ||
for _, typ := range plgn.Config.Interface.Types { |
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 be looking for enabled (aka running) plugins. For this, use plgn.Enabled
.
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 was addressed.
@nishanttotla @aluzzardi : Any updates on this? Are you blocked on something? Is there something I can help with. We need this PR for 1.13-rc5. |
Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
1651614
to
d9fd705
Compare
v2plugins, err := e.client.PluginList(ctx) | ||
if err != nil { | ||
return nil, err | ||
} |
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 should be changed not to make Describe
error out if the error contains "plugins are not supported on this platform".
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.
Actually, I'm going to make it ignore all errors. This will also fail against daemons that are too old to support this endpoint.
I am going to carry this PR. I've fixed some of the outstanding issues, but I've discovered a big problem that prevents this from being practically useful for volumes.
This is tricky to get right. We should be consistent in the way we refer to plugins. We shouldn't just strip the tag off, because that loses information. We also need to make sure that we handle other cases like What we probably need as a starting point is a canonical function that compares plugin references, adding a default tag where necessary and handling digest cases properly. However, even this won't fix (1), since the volume code is where this comparison is happening, and it does a simple string comparison on the volume driver name, which already had the tag included. I'm not sure what the right solution to this is. |
Discussed with @anusha-ragunathan and @tonistiigi and learned that digests will never be used in plugin naming. The canonical name of a plugin is I will fix (1) in I will fix (2) in this PR (or a carried version) by comparing tags in the plugin filter, and assuming |
Carried in #1808 |
[Carry #1517] Support v2 plugins; re-enable scheduler plugin filter
Fix #1231. It was disabled in #1224, due to lazy loading by the engine.
Using the plugins API, it is possible to list installed plugins.
One issue is that we don't have a way of storing arbitrary plugins in the TaskSpec, from which to match them against the node on which
PluginFilter
is applied. For volumes and networks, this happens via a separate code path that allows for attaching to networks or mounting volumes. This is something we might want to build to support general plugins, and will require proto changes. This PR will work for volume and network v2 plugins.Signed-off-by: Nishant Totla nishanttotla@gmail.com