-
Notifications
You must be signed in to change notification settings - Fork 879
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
Make libnetwork understand pluginv2. #1472
Conversation
Companion PR to moby/moby#26860. |
a392cf7
to
a18957e
Compare
@@ -163,7 +165,7 @@ type initializer struct { | |||
} | |||
|
|||
// New creates a new instance of network controller. | |||
func New(cfgOptions ...config.Option) (NetworkController, error) { | |||
func New(getter getter.PluginGetter, cfgOptions ...config.Option) (NetworkController, 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.
getter.PluginGetter
can be one of the config.Option. That will save the New
API from changing.
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.
Agree, please see if you can pass the plugin getter via a config option setter.
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.
@@ -144,7 +144,7 @@ func newDriver() *driver { | |||
} | |||
|
|||
// Init registers a new instance of bridge driver | |||
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { | |||
func Init(dc driverapi.DriverCallback, ps interface{}, config map[string]interface{}) 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.
why is this an interface{} ? why cant it be the concrete 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.
plugingetter is only used in remote driver code. So it can be abstracted from other code paths. i.e bridge code doesnt need to know about a plugingetter, since it doesnt use it.
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. Can you instead use the above DriverCallback
for this purpose ?
You can return the plugingetter as a GetPluginGetter API as part of DriverCallback.
BTW, Controller
implements DriverCallback
and hence you can get this done cleanly without having to change the Init
API signature.
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.
PluginGetter naturally falls in DriverRegistry rather than the Controller. I've made necessary updates.
} | ||
}) | ||
} else { | ||
plugins.Handle(driverapi.NetworkPluginEndpointType, func(name string, client *plugins.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.
The callback function seems identical. Can you pls reuse it instead of duplicating it here ?
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.
}) | ||
} else { | ||
plugins.Handle(ipamapi.PluginEndpointType, func(name string, client *plugins.Client) { | ||
a := newAllocator(name, 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.
Same here.
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.
@anusha-ragunathan thanks for the vendor updates. Are these changes done to be in sync with docker/docker ? |
@mavenugo : vendor update has 2 fold reason. 1. get the |
a18957e
to
c626c8a
Compare
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.
Thanks for the vendor update again :-)
@aboch can u pls check if the vendoring work is fine ?
@@ -144,7 +144,7 @@ func newDriver() *driver { | |||
} | |||
|
|||
// Init registers a new instance of bridge driver | |||
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { | |||
func Init(dc driverapi.DriverCallback, ps interface{}, config map[string]interface{}) 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.
got it. Can you instead use the above DriverCallback
for this purpose ?
You can return the plugingetter as a GetPluginGetter API as part of DriverCallback.
BTW, Controller
implements DriverCallback
and hence you can get this done cleanly without having to change the Init
API signature.
CI failure on
The test is not on the gh open issues and looks unrelated to the PR. I can open an issue if necessary. |
@anusha-ragunathan thats alright. can u pls address the comments ? I will check what is going on with the test failure. |
@anusha-ragunathan
Run |
@aboch : I did, before opening the PR, but ran into errors modprobing |
There were 2 libnetwork test containers that were stuck causing modprobe, ipvsadm PATH errors. Removing those fixed the issue, but now modprobe is unable to open modules.dep.bin. Rebooting host doesnt help. File exists on host.
RUN TestGetFamily === RUN TestService === RUN TestDestination
|
@anusha-ragunathan For now, do not worry for the local make failures, just take care of the compiling issues in macvlan test code, and re-push. If you want to run the CI locally, run |
}) | ||
func Init(dc driverapi.DriverCallback, ps interface{}, config map[string]interface{}) error { | ||
// Unit test code is unaware of a true PluginStore. So we fall back to v1 plugins. | ||
if ps != 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.
Please define a local function pointer which will point to ps.(plugingetter.PluginGetter)
if ps != nil
, plugins.Handle()
otherwise
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.
@@ -37,7 +37,7 @@ type DrvRegistry struct { | |||
// Functors definition | |||
|
|||
// InitFunc defines the driver initialization function signature. | |||
type InitFunc func(driverapi.DriverCallback, map[string]interface{}) error | |||
type InitFunc func(driverapi.DriverCallback, interface{}, map[string]interface{}) 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.
Would it make sense to have the plugin getter be a member of DrvRegistry
?
At the end all the remote drivers register with the registry, he can hold the plugin getter for them to be called in the init function.
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.
Yes, DrvRegistry is where PluginGetter belongs. Updated.
@@ -192,12 +195,12 @@ func New(cfgOptions ...config.Option) (NetworkController, error) { | |||
dcfg = c.makeDriverConfig(i.ntype) | |||
} | |||
|
|||
if err := drvRegistry.AddDriver(i.ntype, i.fn, dcfg); err != nil { | |||
if err := drvRegistry.AddDriver(i.ntype, i.fn, dcfg, c.plugingetter); err != 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.
If you store the plugin getter in the drvRegistry
, AddDriver()
does prototype does not need to change
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. I've also split the PR into godep vendoring and plugin related code, so its easier to review.
Signed-off-by: Anusha Ragunathan <anusha@docker.com>
90c8a63
to
2fcee1c
Compare
@@ -1074,7 +1078,7 @@ func (c *controller) loadDriver(networkType string) error { | |||
} | |||
|
|||
func (c *controller) loadIPAMDriver(name string) error { | |||
if _, err := plugins.Get(name, ipamapi.PluginEndpointType); err != nil { | |||
if _, err := c.plugingetter.Get(name, ipamapi.PluginEndpointType, getter.LOOKUP); err != 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.
Here we can modify to c.driverRegistry.GetPluginGetter().
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.
c has to implement a GetPluginGetter
to satisy DriverAPICallback
which is a wrapper to drvRegistry.GetPluginGetter()
. So this will be c.GetPluginGetter()
@@ -154,6 +155,7 @@ type controller struct { | |||
agentInitDone chan struct{} | |||
keys []*types.EncryptionKey | |||
clusterConfigAvailable bool | |||
plugingetter getter.PluginGetter |
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 think we no longer need this member in controller
, rather we can just keep it confined to drvRegistry
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.
Yes indeed
@@ -29,7 +29,15 @@ func newDriver(name string, client *plugins.Client) driverapi.Driver { | |||
// Init makes sure a remote driver is registered when a network driver | |||
// plugin is activated. | |||
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { | |||
plugins.Handle(driverapi.NetworkPluginEndpointType, func(name string, client *plugins.Client) { | |||
var handleFunc func(string, func(string, *plugins.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.
I think you could just rewrite the whole block as:
handleFunc := plugins.Handle
if pg := dc.GetPluginGetter(); pg != nil {
handleFunc = pg.Handle
}
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.
ipamDrivers ipamTable | ||
dfn DriverNotifyFunc | ||
ifn IPAMNotifyFunc | ||
plugingetter getter.PluginGetter |
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.
Please follow the camel case convention as in ipamDrivers
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.
Yikes! Done.
2fcee1c
to
fa0a5a1
Compare
@@ -30,7 +30,15 @@ func newAllocator(name string, client *plugins.Client) ipamapi.Ipam { | |||
|
|||
// Init registers a remote ipam when its plugin is activated | |||
func Init(cb ipamapi.Callback, l, g interface{}) error { | |||
plugins.Handle(ipamapi.PluginEndpointType, func(name string, client *plugins.Client) { | |||
var handleFunc func(string, func(string, *plugins.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.
Same here, you should be able to reduce the footprint of this change, make it less verbose.
fa0a5a1
to
9e8e375
Compare
CI failure on #1385 |
As part of daemon init, network and ipam drivers are passed a pluginstore object that implements the plugin/getter interface. Use this interface methods in libnetwork to interact with network plugins. This interface provides the new and improved pluginv2 functionality and falls back to pluginv1 (legacy) if necessary. Signed-off-by: Anusha Ragunathan <anusha@docker.com>
9e8e375
to
7b26d7e
Compare
LGTM |
@anusha-ragunathan thanks for taking care of all the comments. LGTM |
As part of daemon init, network and ipam drivers are passed a
pluginstore object that implements the plugin/getter interface. Use this
interface methods in libnetwork to interact with network plugins. This
interface provides the new and improved pluginv2 functionality and falls
back to pluginv1 (legacy) if necessary.
Signed-off-by: Anusha Ragunathan anusha@docker.com