Package: backwork
backworkBackup simplified.backworkis a toolkit that simplifies the process of backing up and restoring databases. It
handles the backup process itself as well as upload, download, restoration, and error notification.PrerequisitesPython 2.7InstallingYou can installbackworkusingpip:$pipinstallbackworkRunningAfter installing you should have abackworkcommand available.$ backwork --help
usage: backwork [-h] [-n NOTIFIERS] {backup,restore,upload,download} ...

positional arguments:
  {backup,restore,upload,download}

optional arguments:
  -h, --help            show this help message and exit
  -n NOTIFIERS, --notify NOTIFIERS
                        enable a notifier, it can be used multiple timesPlug-insJust havingbackworkis not enough. You will need to the plug-ins that
suit your needs. You can install plug-ins by running:$pipinstall<plug-in_name>You can discover available plug-ins byviewing thebackwork-plugintopic on Github.Plug-ins are divided into three categories:BackupBackup plug-ins are responsible for connecting to databases and doing the
actual backup process, as well as the restore process for the backups.
You can discover available backup plug-ins byviewing thebackwork-plugin-backuptopic on Github.Once you install a backup plug-in it will be available via thebackwork backupandbackwork restorecommands:$backworkbackup--help
usage:backworkbackup[-h][-U]{mongo}...

Performdatabasebackups.Run`backworkbackup{database_type}-h`formore
detailsoneachsupporteddatabase.

positionalarguments:{mongo}optionalarguments:-h,--helpshowthishelpmessageandexit-U,--uploadoutputbackupdatatostdouttoallowpipingittoanuploadcommandusage: backwork restore [-h] [-U] {mongo} ...

Perform database restores. Run `backwork restore {database_type} -h` for more
details on each supported database.

positional arguments:
  {mongo}

optional arguments:
  -h, --help    show this help message and exitAvailable plug-ins:backwork-backup-mongoUploadUpload plug-ins store and retrieve your backup files securely from remote storage.
You can discover available upload plug-ins byviewing thebackwork-plugin-uploadtopic on Github.You can use them with thebackwork upload,backwork show, andbackwork downloadcommands:$backworkupload--help
usage:backworkupload[-h]{softlayer}...

Uploadafiletoremoteservice.Run`backworkupload{service}-h`formore
detailsoneachsupportedservice.

positionalarguments:{softlayer}optionalarguments:-h,--helpshowthishelpmessageandexit$backworkshow--help
usage:backworkshow[-h]{cos}...

Showsavailablebackupsonaremoteservice.Run`backworkshow{service}-h`formoredetailsoneachsupportedservice.

positionalarguments:{cos}optionalarguments:-h,--helpshowthishelpmessageandexit$backworkdownload--help
usage:backworkdownload[-h]{softlayer}...

Downloadafilefromaremoteservice.Run`backworkupload{service}-h`formore
detailsoneachsupportedservice.

positionalarguments:{softlayer}optionalarguments:-h,--helpshowthishelpmessageandexitAvailable plug-ins:backwork-upload-softlayerNotifiersNotifiers tell you when things go wrong. More important than having a backup
process configured is knowing when this process fails.
You can discover available notifier plug-ins byviewing thebackwork-plugin-notifiertopic on Github.Notifiers are enabled on thebackworkcommand using the-nor--notifyarguments. They may also require some extra values, such API keys.$backwork--help
usage:backwork[-h][-nNOTIFIERS][--sentry-dsnSENTRY_DSN]{backup,upload}...

positionalarguments:{backup,upload}optionalarguments:-h,--helpshowthishelpmessageandexit-nNOTIFIERS,--notifyNOTIFIERSenableanotifier,itcanbeusedmultipletimes--sentry-dsnSENTRY_DSNSentryDSNtobeusedfornotifications.Itcanalsobesetwiththeevironmentvariable$SENTRY_DSN.You can enable as many notifiers as you want on a command.Available plug-ins:backwork-notify-sentryExamplesBackup a MongoDB database running locally$backworkbackupmongo2017-01-1503:58:15,270backup.mongoINFOstartingmongobackup...2017-01-1503:58:15,270backup.mongoINFOsavingfileto/Users/laoqui/Projects/backwork/dumps/mongo_backup_20170115-035815.archive.gz2017-01-1503:58:15,350backup.mongoINFOoutput:2017-01-15T03:58:15.342-0500writingapp.productstoarchive'/Users/laoqui/Projects/backwork/dumps/mongo_backup_20170115-035815.archive.gz'2017-01-15T03:58:15.347-0500donedumpingapp.products(1document)2017-01-1503:58:15,350backup.mongoINFObackupcompleteThis will create an archived backup, compressed and timestamped, and stored in a
folder calleddumpsin the current directory.Backup remote MongoDB database$backworkbackupmongo-h<HOSTIP>:<PORT>-u<USER>-p<PASSWORD>Backup a MongoDB to a specific folder and file name$backworkbackupmongo-o/var/backups--archive=mongo_backup.archiveUpload a backup file to Softlayer ObjectStorage$backworkuploadsoftayer-u<USERNAME>-p<APIKEY>-d<DATACENTER>-c<CONTAINER>/path/to/file/remote/path/locationUser Sentry to receive error messages$backwork-nsentry--sentry-dsn<SENTRYDSN>backupmongo-o/var/backups--archive=mongo_backup.archiveMore infoCheck the--helpinformation for each of the commands for more details.ExtendingThe best way to extendbackworkis by creating new plugi-ins. They are simple
Python packages that implement a few set of methods. Here are some base classes
you can use as a starting point:classBackupBase(object):"""Base class that describes the interface a backup command must implement.Attributes:command     the value used in the command line to invoke this command,usually is the name of the database (e.g.: mongo, mysql)"""command=""def__init__(self,args,extra):"""Initialize a backup command given the arguments passed to CLI"""self.args=argsself.extra=extra@classmethoddefparse_args(cls,subparsers):"""Parse CLI arguments specific to this subcommand"""raiseNotImplementedError("Base method not overriden.")defbackup(self):"""Backup a database given the arguments specified.All the values passed via the CLI are available at `self.args` and`self.extra`. The first object stores known arguments that have beenexplicitly parsed. The second object is a list of arguments that areunkown to the parser and can be useful for invoking other commandswithouht having to re-define its parser's arguments.This method should raise exceptions in case of errors so any activenotifier can hadle it."""raiseNotImplementedError("Base method not overriden.")classUploadBase(object):"""Base class that describes the interface an upload command must implement.Attributes:command     the value used in the command line to invoke this command,usually is the name of the service (e.g.: softlayer, s3)"""command=""def__init__(self,args,extra):"""Initialize an upload command given the arguments passed to CLI"""self.args=argsself.extra=extra@classmethoddefparse_args(cls,subparsers):"""Parse CLI arguments specific to this subcommand"""raiseNotImplementedError("Base method not overriden.")defupload(self):"""Upload a file to the remote service.All the values passed via the CLI are available at `self.args` and`self.extra`. The first object stores known arguments that have beenexplicitly parsed. The second object is a list of arguments that areunkown to the parser and can be useful for invoking other commandswithouht having to re-define its parser's arguments.This method should raise exceptions in case of errors so any activenotifier can hadle it."""raiseNotImplementedError("Base method not overriden.")classNotifierBase(object):"""Base class for notifiersNotifiers are responsible for sending messages to external services toreport relevant events that may happen during the execution of a command.Attributes:command     the value used to enable a notifier in the command line,e.g.: `backwork -n {command}`"""command=""def__init__(self,args,extra):self.args=argsself.extra=extra@classmethoddefparse_args(cls,parser):"""Add command line argument parsing rules relevant to the notifier.This method is not required to be implemented as it might not benecessary to add more arguments to the parser in some cases."""passdefnotify(self,msg=""):"""Handle an incoming message.The `msg` object could be either a `string` or an `Exception`. You maywant to handle them differently with something like:if issubclass(msg.__class__, Exception):handle_exception(msg)else:handle_string(msg)If `msg` is an exception, the call to this method will be in the contextof an `except`, meaning you will be able to access `sys.exc_info()`."""raiseNotImplementedError("Base method not overriden.")To make your package visible tobackworkyou will also need to declare anentry_pointin yoursetup.pyfile.Each plug-in type has a differententry_pointkey:Backups:setup(...entry_points={"backwork.backups":["<COMMAND NAME>":"module:BackupClass"],"backwork.restores":["<COMMAND NAME>":"module:RestoreClass"]},...Uploads:setup(...entry_points={"backwork.uploads":["<COMMAND NAME>":"module:UploadClass"],"backwork.shows":["<COMMAND NAME>":"module:ShowClass"]"backwork.downloads":["<COMMAND NAME>":"module:DownloadClass"]},...Notifiers:setup(...entry_points={"backwork.notifiers":["<COMMAND NAME>":"module:NotifierClass"]},...Once your plug-in is ready you can usepipto install it and it should be
available to be used bebackwork.Future workAdd support for more databases, storage services and notifiersHandle backup schedulingSupport more environment variables