diff --git a/docs/cli-reference/ark_server.md b/docs/cli-reference/ark_server.md index baeedb519..46bf223cd 100644 --- a/docs/cli-reference/ark_server.md +++ b/docs/cli-reference/ark_server.md @@ -14,8 +14,9 @@ ark server [flags] ### Options ``` - -h, --help help for server - --log-level the level at which to log. Valid values are debug, info, warning, error, fatal, panic. (default info) + -h, --help help for server + --log-level the level at which to log. Valid values are debug, info, warning, error, fatal, panic. (default info) + --plugin-dir string directory containing Ark plugins (default "/plugins") ``` ### Options inherited from parent commands diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index abb9cc4c5..5d19215f6 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -65,6 +65,7 @@ func NewCommand() *cobra.Command { var ( sortedLogLevels = getSortedLogLevels() logLevelFlag = flag.NewEnum(logrus.InfoLevel.String(), sortedLogLevels...) + pluginDir = "/plugins" ) var command = &cobra.Command{ @@ -101,7 +102,7 @@ func NewCommand() *cobra.Command { } namespace := getServerNamespace(namespaceFlag) - s, err := newServer(namespace, fmt.Sprintf("%s-%s", c.Parent().Name(), c.Name()), logger) + s, err := newServer(namespace, fmt.Sprintf("%s-%s", c.Parent().Name(), c.Name()), pluginDir, logger) cmd.CheckError(err) @@ -110,6 +111,7 @@ func NewCommand() *cobra.Command { } command.Flags().Var(logLevelFlag, "log-level", fmt.Sprintf("the level at which to log. Valid values are %s.", strings.Join(sortedLogLevels, ", "))) + command.Flags().StringVar(&pluginDir, "plugin-dir", pluginDir, "directory containing Ark plugins") return command } @@ -175,7 +177,7 @@ type server struct { pluginManager plugin.Manager } -func newServer(namespace, baseName string, logger *logrus.Logger) (*server, error) { +func newServer(namespace, baseName, pluginDir string, logger *logrus.Logger) (*server, error) { clientConfig, err := client.Config("", "", baseName) if err != nil { return nil, err @@ -191,7 +193,7 @@ func newServer(namespace, baseName string, logger *logrus.Logger) (*server, erro return nil, errors.WithStack(err) } - pluginManager, err := plugin.NewManager(logger, logger.Level) + pluginManager, err := plugin.NewManager(logger, logger.Level, pluginDir) if err != nil { return nil, err } diff --git a/pkg/plugin/manager.go b/pkg/plugin/manager.go index 80bc1594d..7bd6a637a 100644 --- a/pkg/plugin/manager.go +++ b/pkg/plugin/manager.go @@ -74,8 +74,6 @@ const ( // PluginKindRestoreItemAction is the Kind string for // a Restore ItemAction plugin. PluginKindRestoreItemAction PluginKind = "restoreitemaction" - - pluginDir = "/plugins" ) var AllPluginKinds = []PluginKind{ @@ -132,15 +130,17 @@ type manager struct { logLevel logrus.Level pluginRegistry *registry clientStore *clientStore + pluginDir string } // NewManager constructs a manager for getting plugin implementations. -func NewManager(logger logrus.FieldLogger, level logrus.Level) (Manager, error) { +func NewManager(logger logrus.FieldLogger, level logrus.Level, pluginDir string) (Manager, error) { m := &manager{ logger: logger, logLevel: level, pluginRegistry: newRegistry(), clientStore: newClientStore(), + pluginDir: pluginDir, } if err := m.registerPlugins(); err != nil { @@ -176,26 +176,28 @@ func getPluginInstance(client *plugin.Client, kind PluginKind) (interface{}, err } func (m *manager) registerPlugins() error { + arkCommand := os.Args[0] + // first, register internal plugins for _, provider := range []string{"aws", "gcp", "azure"} { - m.pluginRegistry.register(provider, "/ark", []string{"run-plugin", "cloudprovider", provider}, PluginKindObjectStore, PluginKindBlockStore) + m.pluginRegistry.register(provider, arkCommand, []string{"run-plugin", "cloudprovider", provider}, PluginKindObjectStore, PluginKindBlockStore) } - m.pluginRegistry.register("pv", "/ark", []string{"run-plugin", string(PluginKindBackupItemAction), "pv"}, PluginKindBackupItemAction) - m.pluginRegistry.register("backup-pod", "/ark", []string{"run-plugin", string(PluginKindBackupItemAction), "pod"}, PluginKindBackupItemAction) + m.pluginRegistry.register("pv", arkCommand, []string{"run-plugin", string(PluginKindBackupItemAction), "pv"}, PluginKindBackupItemAction) + m.pluginRegistry.register("backup-pod", arkCommand, []string{"run-plugin", string(PluginKindBackupItemAction), "pod"}, PluginKindBackupItemAction) - m.pluginRegistry.register("job", "/ark", []string{"run-plugin", string(PluginKindRestoreItemAction), "job"}, PluginKindRestoreItemAction) - m.pluginRegistry.register("restore-pod", "/ark", []string{"run-plugin", string(PluginKindRestoreItemAction), "pod"}, PluginKindRestoreItemAction) - m.pluginRegistry.register("svc", "/ark", []string{"run-plugin", string(PluginKindRestoreItemAction), "svc"}, PluginKindRestoreItemAction) + m.pluginRegistry.register("job", arkCommand, []string{"run-plugin", string(PluginKindRestoreItemAction), "job"}, PluginKindRestoreItemAction) + m.pluginRegistry.register("restore-pod", arkCommand, []string{"run-plugin", string(PluginKindRestoreItemAction), "pod"}, PluginKindRestoreItemAction) + m.pluginRegistry.register("svc", arkCommand, []string{"run-plugin", string(PluginKindRestoreItemAction), "svc"}, PluginKindRestoreItemAction) // second, register external plugins (these will override internal plugins, if applicable) - if _, err := os.Stat(pluginDir); err != nil { + if _, err := os.Stat(m.pluginDir); err != nil { if os.IsNotExist(err) { return nil } return err } - files, err := ioutil.ReadDir(pluginDir) + files, err := ioutil.ReadDir(m.pluginDir) if err != nil { return err } @@ -207,9 +209,9 @@ func (m *manager) registerPlugins() error { } if kind == PluginKindCloudProvider { - m.pluginRegistry.register(name, filepath.Join(pluginDir, file.Name()), nil, PluginKindObjectStore, PluginKindBlockStore) + m.pluginRegistry.register(name, filepath.Join(m.pluginDir, file.Name()), nil, PluginKindObjectStore, PluginKindBlockStore) } else { - m.pluginRegistry.register(name, filepath.Join(pluginDir, file.Name()), nil, kind) + m.pluginRegistry.register(name, filepath.Join(m.pluginDir, file.Name()), nil, kind) } }