Creating Custom Backup Backend Plugin

Navigation:  Backup Providers Integration >

Creating Custom Backup Backend Plugin

Previous pageReturn to chapter overviewNext page

Creating Module


To create a plugin for a particular backup backend a python module should be created in backup_backends folder. The plugin will be registered automatically when a function backend(name) from backup_backends module is called.

If the plugin should be used only in some appropriate systems environment is_suitable function could be implemented, which should return Boolean. It will be called during backend(name) from backup_backends function call and if is_suitable False, then BackendNonApplicableError exception will be raised.


Here is an example of is_suitable function for DirectAdmin module:


def is_suitable():

return os.path.isfile('/usr/local/directadmin/directadmin')



Defining Classes


There are two mandatory classes that have to be implemented in the plugin.


Backup Class


This class represents a backup. It can have any name since it is not directly referenced to from the outside of the module. It can either be inherited from




which already have some features (e.g. comparison) implemented or it can be written from scratch. The class must define a method file_data that returns a FileData object (described below). Objects of this class should also be comparable by the date created as if they were actual backups.


FileData Class


The second class that has to be implemented is FileData which represents a file in a backup. It must have file size, modify time and a method restore.


Implementing API Functions


There are 3 functions in the plugin, but only one of them is mandatory - backups. This function returns a list of Backup instances. Optional functions are init, cleanup and info that are responsible for the initialization, cleanup and getting some information of the plugin respectively.


def init(*args):


def backups(until=None):


def cleanup():


def info():



Depending on the features of the backend being integrated, the plugin might have one or more classes and functions responsible to authorise on the backup server and retrieve data from it, however only functions init, backups, cleanup and info are called from the outside of the module.


To check that the plugin works as intended try passing your plugin name to the CLI for example like this:


restore_infected <your_backend_name> list


To be used in asynchronous libraries ‘async_restore_infected’ routine has been added. Typical use case:


import logging

from restore_infected import backup_backends

from restore_infected.restore import async_restore_infected

from defence360agent.malscan.scanner import MalwareScanner


async def _custom_scan_function(files):

    if not files:

        return []

    still_infected = []

    scanner = MalwareScanner().scan_filelist()


    result = await scanner.async_wait()

    if result['results']:

        still_infected = list(result['results'].keys())

    return still_infected


class DummyDumper:


    async def do_restore(cls, files):

        backend = backup_backends.backend('cpanel')

        return await async_restore_infected(

            backend, files, scan_func=_custom_scan_function)



For Acronis backup two restore modes are available:

Download mode - a file to be restored is simply pulled by HTTP from backup server;

Recovery mode - restore_infected just sends command to backup server and then waits for the file to be restored is actually placed to expected folder. Its size is equal to expected one.

Recovery mode is used by default because it restores file owner and permissions, too. Though downloading mode can be enabled with passing ‘use_download’ option to restore_infected function. The second optional parameter - timeout - can be passed to restore_infected function to change the default waiting time (time to wait while a file to be restored is being pulled by recovery agent). By default timeout is 600 seconds.