-
Notifications
You must be signed in to change notification settings - Fork 113
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
Runtime Plugins: Design & integration #1814
Comments
Just to initiate the discussion, here are my initial thoughts: Plugin PackageFirstly, in order to facilitate the plugins, we would require an extra
The plugin package gives the services, "ready to use" implementation of the driver. Each service should use this package to get their respective drivers. The plugins package should be called by the services. (authprovider, userprovider, storageprovider etc). Unlike earlier, wherein the services fetch the drivers from the in-memory registry, the services should now fetch the drivers (or rather, the implementation) from the plugins package. DriversEach driver needs to expose an interface for the plugins to implement. I think we already have interfaces for each drivers in their respective packages. Now, along with the exposed interfaces, each driver package should also have hashicorp's func GRPCServer() // returns grpc server
func GRPCClient() // returns grpc client These methods are responsible for starting the gRPC/RPC (based on the protocol) server/client. The host i.e reva core acts as an rpc client, whereas the plugin acs as an rpc server. The rpc server needs to be started by the plugin code whereas the rpc client, is started by the plugins package (in reva codebase). Thoughts? |
In order to get more clearer understanding, I tried to write a small "POC" for the plugins package. I've added the code in my local branch here: https://github.com/cs3org/reva/compare/master...jimil749:runtime-plugins?expand=1 And I have the plugin code as a github gist setup here: https://gist.github.com/jimil749/e439e8ebdbb5c8b82d122311b42b92f3. I've added an extra type pluginConfig struct{
driver string
location string // location of the plugin binary
users string // plugin configuration
} Also, just a question: do we want to parse the plugin configurations at the service level and pass them to the plugins or have plugins parse the configurations (just pass |
@jimil749 I would like this, to ensure backwards compatiblity:
The plugin creation should also take the |
@labkode sure, that makes sense! Plugins should take in the
PS: Do we want to support loading plugins from the in-memory registry (which is initialized at the init stage), after addition of runtime plugins? |
@jimil749 I think the logic could be: if Yes, we still need to be able to load plugins from the in-memory registry as these are core plugins that come out of the box with Reva |
Sure, that'll work. Thanks for the clarification! So, i think for the most part the configuration (toml file) would not involve any major changes. The inputs can be processed as suggested. The next part that I wanted to discuss was the protocol that we'll be using. We have a choice b/w rpc and grpc. The only issues with grpc is that we need to generate new protobuf binding, with the added |
Hi Jimil. Sorry for the delay.
Totally agreed
I'm not sure 100% sure about this. We can support this as well but this shouldn't be the primary method in which we access runtime drivers. The whole binary management should be taken care of by the plugins pkg. You specify something like
I think rpc should be good enough as discussed. I want to avoid having two versions of almost similar bindings. Defining the request and response types for the individual calls like you did should work. I'll also look into yaegi today to see if we can figure out the protobuf issue. Also, please create a PR once you start with the implementation and then we can continue on that; makes reviewing easier. |
Agreed. So we'd just need to point towards the source code. The plugins pkg should be responsible for "compiling" and then loading the binary. And yes, we could add a flag to choose b/w in-memory registry or the other way. That makes sense! 👍
Sure! Sounds good.
Will do that. I'll start with implementing the plugins package, and try to move the userprovider |
Perfect! |
Also, @ishank011, yaegi does not support cgo, (traefik/yaegi#780), this can cause issues with some drivers. |
Ah! Let's not waste time on it then, there might be even more surprises |
There is another requirement, we need to be able to load a compiled plugin already (we won't have access to source code). |
Just a query here @ishank011, if we add a global "plugin" flag to indicate whether we want to use the registry or external plugins, wouldn't that enforce all the services to use runtime drivers? |
Ah okay, we should support that as well then
Yep, that's the plan for the long term. For the time being, you can use workarounds for testing |
The reason for this one comes from ownCloud. |
Continuing the discussion with compilation of plugins: |
Yep that should work but first, let's take care of local drivers. For such drivers, the plugins should be generated at runtime (once we reach the hot-reloading stage) or compile time for now. |
Okay, so as for the local drivers, we need to have a pre-defined directory (maybe we could have As for the compilation part:
Also @ishank011,
here you mentioned that when we specify |
Yep, sounds good. We can use Regarding just specifying the plugin driver name, the motivation is to have backward compatibility with the way we currently configure it. If we were sure that all the locally present userprovider drivers were in the same parent pkg, we could have added this part to where we register the userprovider plugin, but this is not the case. So yeah, we can specify the full path, but switching between the plugin and prod mode will be a pain. Try to think of a way around this, I will as well. |
@ishank011, by switching b/w plugin and prod mode, do you refer to switching b/w compiling and loading the plugins, and loading the provided binary? Or are you referring to switching between the registry mode (like it happens now) and plugin mode? For the former, one solution can be (this may sound trivial) to have another |
So when
and when
My point is that when switching the plugin flag, we'd have to change the path even if we want to use the same package (from json to pkg/user/json) and this will have to be done for all packages, which is not the most ideal thing. Makes sense? |
We can consider starting a watcher over existing binaries as well |
Yep, this makes sense. Thanks for the elaborate description. So whenever we have the |
So @ishank011, in an ideal world we'd want to have the same configuration i.e |
Yep |
@ishank011, this is a tricky situation. If we think from the user perspective, shouldn't it be a bit convenient to provide the path to source code instead of just having the name of the driver? |
@ishank011 talking about the "fetching" stage (getting plugins from github) I tested the working of hashicorp's go-getter package. It seems to suitable for our use case. I had a small question about the same. Do we download the source code into some |
So I was trying to add the go-getter library in the |
As discussed, this issues is opened to have discussions on how to implement the
plugins
pkg into the reva codebase. The primary candidate for plugin system is the hashicorp go-plugin, which supports plugins over RPC and gRPC.The text was updated successfully, but these errors were encountered: