You can modify the behavior of Kiwi with adding a plug-in in the software. Plug-ins can perform actions at predefined moments:
When the app starts
When a backup is launched
When a backup process iterates on a file
When a backup ends
Writing a plug-in¶
Create a plug-in on your own is pretty simple. Plug-ins are stored in your `data directory`_. under the plugins/[your plugin name] directory.
The plug-in can act at four moments in the code, and there are the four functions that you can write corresponding to these four moments. The backup process shares data about the current backup to plug-ins, and a plug-in itself could change this data. This is how a plug-in can really interact with the backup process.
When app starts¶
def on_server_start(): """Launched when the backup is started"""
When backup starts/stops¶
def on_backup_start(context): """Launched when backup starts :param context: shared context of the backup """
def on_backup_stop(context): """Launched when backup stops :param context: shared context of the backup """
When backup iterates on a file¶
def on_file(kfile, context): """Launched when backup stops :param kfile: kfile of the current iteration :param context: shared context of the backup """
This example is a very simple plug-in that executes a script file at a backup start or stop. The execution is cross-platform. There can be a lot of improvements (asynchronous/synchronous, arguments to script …) but let’s begin with an easy one. You must create a file in your plugin directory with the name “__init__.py” with the following code:
import kclient from kclient import bos import os import subprocess from logging import getLogger logger = getLogger('kclient.runner') PLUGIN_ROOT = os.path.join(kclient.bos.getPluginsDir(), os.path.dirname(os.path.realpath(__file__))) def launch_script(filepath): """ Cross-platform script launching """ if kclient.bos.isWin32(): filepath += '.bat' elif kclient.bos.isLinux() or kclient.bos.isOsX(): filepath += '.sh' script_fullpath = os.path.join(PLUGIN_ROOT, filepath) if os.path.exists(script_fullpath): logger.warning('execute %s', script_fullpath) subprocess.call(script_fullpath) return True else: logger.error('cannot execute missing script %s', script_fullpath) return False def on_start_backup(context): if not launch_script('pre_backup'): logger.error('can not launch pre-backup script') def on_stop_backup(context): if not launch_script('post_backup'): logger.error('can not launch pre-backup script')
In your data directory, under plugins/script-launcher, put two files: (post|pre)_backup.(bat|sh). If there is no script the plug-in will log it and the backup will continue.
Database state handling¶
Imagine you have a database that you need to save. This database holds a lot of very sensitive data. Because the database is open, you can not save it. So you need to manually close it before going to bed and re-open it at 2:00 AM when the backup is done (because data is very important to the functionality of your site).
If you are in the case above, here is an example of how useful this example is in case you use mysql.
The first script below executed before the backup starts closes the database. The second one re-open it at the end.
#! /bin/sh service mysql stop
#! /bin/sh service mysql start