From cbcd15d6037ae494ab65900b5951a98deadddc59 Mon Sep 17 00:00:00 2001 From: Steve Kriss Date: Tue, 28 Nov 2017 13:45:22 -0800 Subject: [PATCH] add/update documentation for plugins Signed-off-by: Steve Kriss --- README.md | 10 +++++++ docs/plugins.md | 35 +++++++++++++++++++++++++ pkg/backup/item_action.go | 9 ++++--- pkg/cloudprovider/storage_interfaces.go | 17 +++++++----- pkg/restore/item_action.go | 8 +++++- 5 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 docs/plugins.md diff --git a/README.md b/README.md index 98373051d..021164aff 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,14 @@ Looking at a specific example--an `ark backup create test-backup` command trigge 5. By default, Ark also makes disk snapshots of any persistent volumes, using the appropriate cloud service API. (This can be disabled via the option `--snapshot-volumes=false`) +## Extensibility + +Ark has multiple mechanisms for extending the core functionality to meet your individual backup/restore needs: + +* [Hooks][27] allow you to specify commands to be executed within running pods during a backup. This is useful if you need to run a workload-specific command prior to taking a backup (for example, to flush disk buffers or to freeze a database). +* [Plugins][28] enable you to develop custom object/block storage back-ends or per-item backup/restore actions that can execute arbitrary logic, including modifying the items being backed up/restored. Plugins can be used by Ark without needing to be compiled into the core Ark binary. + + ## Further documentation To learn more about Heptio Ark operations and their applications, see the [`/docs` directory][3]. @@ -210,3 +218,5 @@ See [the list of releases][6] to find out about feature changes. [24]: http://j.hept.io/ark-list [25]: http://slack.kubernetes.io/ [26]: https://github.com/heptio/ark/releases +[27]: /docs/hooks.md +[28]: /docs/plugins.md \ No newline at end of file diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 000000000..df4f4496b --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,35 @@ +# Plugins + +Heptio Ark has a plugin architecture that allows users to add their own custom functionality to Ark backups & restores +without having to modify/recompile the core Ark binary. To add custom functionality, users simply create their own binary +containing an implementation of one of Ark's plugin kinds (described below), plus a small amount of boilerplate code to +expose the plugin implementation to Ark. This binary is added to a container image that serves as an init container for +the Ark server pod and copies the binary into a shared emptyDir volume for the Ark server to access. + +A fully-functional [sample plugin repository][1] is provided to serve as a convenient starting point for plugin authors. + +## Plugin Kinds + +Ark currently supports the following kinds of plugins: + +- **Object Store** - persists and retrieves backups, backup logs and restore logs +- **Block Store** - creates volume snapshots (during backup) and restores volumes from snapshots (during restore) +- **Backup Item Action** - executes arbitrary logic for individual items prior to storing them in a backup file +- **Restore Item Action** - executes arbitrary logic for individual items prior to restoring them into a cluster + +## Plugin Naming + +Ark relies on a naming convention to identify plugins. Each plugin binary should be named `ark--`, +where `plugin-kind` is one of `objectstore`, `blockstore`, `backupitemaction`, or `restoreitemaction`, and `name` is +unique within the plugin kind. + +## Plugin Logging + +Ark provides a [logger][2] that can be used by plugins to log structured information to the main Ark server log or +per-backup/restore logs. See the [sample repository][1] for an example of how to instantiate and use the logger +within your plugin. + + + +[1]: https://github.com/heptio/ark-plugin-example +[2]: https://github.com/heptio/ark/blob/master/pkg/plugin/logger.go \ No newline at end of file diff --git a/pkg/backup/item_action.go b/pkg/backup/item_action.go index ab01794e5..14ddaaad6 100644 --- a/pkg/backup/item_action.go +++ b/pkg/backup/item_action.go @@ -26,11 +26,14 @@ import ( // ItemAction is an actor that performs an operation on an individual item being backed up. type ItemAction interface { // AppliesTo returns information about which resources this action should be invoked for. + // An ItemAction's Execute function will only be invoked on items that match the returned + // selector. A zero-valued ResourceSelector matches all resources. AppliesTo() (ResourceSelector, error) - // Execute allows the ItemAction to perform arbitrary logic with the item being backed up. - // Implementations may return additional ResourceIdentifiers that indicate specific items - // that also need to be backed up. + // Execute allows the ItemAction to perform arbitrary logic with the item being backed up, + // including mutating the item itself prior to backup. The item (unmodified or modified) + // should be returned, along with an optional slice of ResourceIdentifiers specifying + // additional related items that should be backed up. Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []ResourceIdentifier, error) } diff --git a/pkg/cloudprovider/storage_interfaces.go b/pkg/cloudprovider/storage_interfaces.go index 4c4286b57..922c9756a 100644 --- a/pkg/cloudprovider/storage_interfaces.go +++ b/pkg/cloudprovider/storage_interfaces.go @@ -40,14 +40,16 @@ type ObjectStore interface { GetObject(bucket string, key string) (io.ReadCloser, error) // ListCommonPrefixes gets a list of all object key prefixes that come - // before the provided delimiter (this is often used to simulate a directory - // hierarchy in object storage). + // before the provided delimiter. For example, if the bucket contains + // the keys "foo-1/bar", "foo-1/baz", and "foo-2/baz", and the delimiter + // is "/", this will return the slice {"foo-1", "foo-2"}. ListCommonPrefixes(bucket string, delimiter string) ([]string, error) - // ListObjects gets a list of all objects in bucket that have the same prefix. + // ListObjects gets a list of all keys in the specified bucket + // that have the given prefix. ListObjects(bucket, prefix string) ([]string, error) - // DeleteObject removes object with the specified key from the given + // DeleteObject removes the object with the specified key from the given // bucket. DeleteObject(bucket string, key string) error @@ -63,7 +65,8 @@ type BlockStore interface { // cannot be initialized from the provided config. Init(config map[string]string) error - // CreateVolumeFromSnapshot creates a new block volume, initialized from the provided snapshot, + // CreateVolumeFromSnapshot creates a new block volume in the specified + // availability zone, initialized from the provided snapshot, // and with the specified type and IOPS (if using provisioned IOPS). CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) @@ -73,8 +76,8 @@ type BlockStore interface { // SetVolumeID sets the cloud provider specific identifier for the PersistentVolume. SetVolumeID(pv runtime.Unstructured, volumeID string) (runtime.Unstructured, error) - // GetVolumeInfo returns the type and IOPS (if using provisioned IOPS) for a specified block - // volume. + // GetVolumeInfo returns the type and IOPS (if using provisioned IOPS) for + // the specified block volume in the given availability zone. GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) // IsVolumeReady returns whether the specified volume is ready to be used. diff --git a/pkg/restore/item_action.go b/pkg/restore/item_action.go index 16f437b4c..1fa4d8c9f 100644 --- a/pkg/restore/item_action.go +++ b/pkg/restore/item_action.go @@ -25,9 +25,15 @@ import ( // ItemAction is an actor that performs an operation on an individual item being restored. type ItemAction interface { // AppliesTo returns information about which resources this action should be invoked for. + // An ItemAction's Execute function will only be invoked on items that match the returned + // selector. A zero-valued ResourceSelector matches all resources. AppliesTo() (ResourceSelector, error) - // Execute allows the ItemAction to perform arbitrary logic with the item being restored. + // Execute allows the ItemAction to perform arbitrary logic with the item being restored, + // including mutating the item itself prior to restore. The item (unmodified or modified) + // should be returned, along with a warning (which will be logged but will not prevent + // the item from being restored) or error (which will be logged and will prevent the item + // from being restored) if applicable. Execute(obj runtime.Unstructured, restore *api.Restore) (res runtime.Unstructured, warning error, err error) }