Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FD python plugin baseclass and sample plugins
Signed-off-by: Marco van Wieringen <marco.van.wieringen@bareos.com>
- Loading branch information
Maik Aussendorf
authored and
Marco van Wieringen
committed
Apr 14, 2014
1 parent
ee96b58
commit c96b8a9
Showing
5 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Baseclass for Bareos python plugins | ||
# Functions taken and adapted from bareos-fd.py | ||
# (c) Bareos GmbH & Co. KG, Maik Aussendorf | ||
# AGPL v.3 | ||
|
||
from bareosfd import * | ||
from bareos_fd_consts import * | ||
from os import O_WRONLY, O_CREAT | ||
|
||
class BareosFdPluginBaseclass: | ||
''' Bareos python plugin base class ''' | ||
def __init__(self, context, plugindef): | ||
DebugMessage(context, 100, "Constructor called in module " + __name__ + "\n"); | ||
events = []; | ||
events.append(bEventType['bEventJobEnd']); | ||
events.append(bEventType['bEventEndBackupJob']); | ||
events.append(bEventType['bEventEndFileSet']); | ||
events.append(bEventType['bEventHandleBackupFile']); | ||
RegisterEvents(context, events); | ||
# get some static Bareos values | ||
self.fdname = GetValue(context, bVariable['bVarFDName']); | ||
self.jobId = GetValue(context, bVariable['bVarJobId']); | ||
self.client = GetValue(context, bVariable['bVarClient']); | ||
self.level = GetValue(context, bVariable['bVarLevel']); | ||
self.jobName = GetValue(context, bVariable['bVarJobName']); | ||
self.workingdir = GetValue(context, bVariable['bVarWorkingDir']); | ||
DebugMessage(context, 100, "FDName = " + self.fdname + " - BareosFdPluginBaseclass\n"); | ||
DebugMessage(context, 100, "WorkingDir = " + self.workingdir + " jobId: " + str(self.jobId) + "\n"); | ||
|
||
def parse_plugin_definition(self,context, plugindef): | ||
DebugMessage(context, 100, "plugin def parser called with " + plugindef + "\n"); | ||
# Parse plugin options into a dict | ||
self.options = dict(); | ||
plugin_options = plugindef.split(":"); | ||
for current_option in plugin_options: | ||
key,sep,val = current_option.partition("="); | ||
DebugMessage(context, 100, "key:val: " + key + ':' + val + "\n"); | ||
if val == '': | ||
continue; | ||
else: | ||
self.options[key] = val; | ||
# you should overload this method with your own and do option checking here, return bRCs['bRC_Error'], if options are not ok | ||
# or better call super.parse_plugin_definition in your own class and make sanity check on self.options afterwards | ||
return bRCs['bRC_OK']; | ||
|
||
|
||
def plugin_io(self, context, IOP): | ||
DebugMessage(context, 100, "plugin_io called with " + str(IOP) + "\n"); | ||
|
||
FNAME = IOP.fname; | ||
if IOP.func == bIOPS['IO_OPEN']: | ||
try: | ||
if IOP.flags & (O_CREAT | O_WRONLY): | ||
self.file = open(FNAME, 'wb'); | ||
else: | ||
self.file = open(FNAME, 'rb'); | ||
except: | ||
IOP.status = -1; | ||
return bRCs['bRC_Error']; | ||
|
||
return bRCs['bRC_OK']; | ||
|
||
elif IOP.func == bIOPS['IO_CLOSE']: | ||
self.file.close(); | ||
return bRCs['bRC_OK']; | ||
|
||
elif IOP.func == bIOPS['IO_SEEK']: | ||
return bRCs['bRC_OK']; | ||
|
||
elif IOP.func == bIOPS['IO_READ']: | ||
IOP.buf = bytearray(IOP.count); | ||
IOP.status = self.file.readinto(IOP.buf); | ||
IOP.io_errno = 0 | ||
return bRCs['bRC_OK']; | ||
|
||
elif IOP.func == bIOPS['IO_WRITE']: | ||
IOP.status = self.file.write(IOP.buf); | ||
IOP.io_errno = 0 | ||
return bRCs['bRC_OK']; | ||
|
||
|
||
def handle_plugin_event(self, context, event): | ||
if event == bEventType['bEventJobEnd']: | ||
DebugMessage(context, 100, "handle_plugin_event called with bEventJobEnd\n"); | ||
|
||
elif event == bEventType['bEventEndBackupJob']: | ||
DebugMessage(context, 100, "handle_plugin_event called with bEventEndBackupJob\n"); | ||
|
||
elif event == bEventType['bEventEndFileSet']: | ||
DebugMessage(context, 100, "handle_plugin_event called with bEventEndFileSet\n"); | ||
|
||
else: | ||
DebugMessage(context, 100, "handle_plugin_event called with event" + str(event) + "\n"); | ||
|
||
return bRCs['bRC_OK']; | ||
|
||
|
||
def start_backup_file(self,context, savepkt): | ||
DebugMessage(context, 100, "start_backup called\n"); | ||
# Base method, we do not add anything, overload this method with your implementation to add files to backup fileset | ||
return bRCs['bRC_Skip']; | ||
|
||
|
||
def end_backup_file(self, context): | ||
DebugMessage(context, 100, "end_backup_file() entry point in Python called\n") | ||
return bRCs['bRC_OK']; | ||
|
||
def start_restore_file(self, context, cmd): | ||
DebugMessage(context, 100, "start_restore_file() entry point in Python called with" + str(cmd) + "\n") | ||
return bRCs['bRC_OK']; | ||
|
||
def end_restore_file(self,context): | ||
DebugMessage(context, 100, "end_restore_file() entry point in Python called\n") | ||
return bRCs['bRC_OK']; | ||
|
||
def restore_object_data(self, context, ROP): | ||
DebugMessage(context, 100, "restore_object_data called with " + str(ROP) + "\n"); | ||
return bRCs['bRC_OK']; | ||
|
||
def create_file(self,context, restorepkt): | ||
DebugMessage(context, 100, "create_file() entry point in Python called with" + str(restorepkt) + "\n") | ||
restorepkt.create_status = bCFs['CF_EXTRACT']; | ||
return bRCs['bRC_OK']; | ||
|
||
def check_file(self,context, fname): | ||
DebugMessage(context, 100, "check_file() entry point in Python called with" + str(fname) + "\n") | ||
return bRCs['bRC_OK']; | ||
|
||
def handle_backup_file(self,context, savepkt): | ||
DebugMessage(context, 100, "handle_backup_file called with " + str(savepkt) + "\n"); | ||
return bRCs['bRC_OK']; | ||
|
||
# vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Bareos python plugins class that adds files from a local list to the backup fileset | ||
# (c) Bareos GmbH & Co. KG | ||
# AGPL v.3 | ||
# Author: Maik Aussendorf | ||
|
||
from bareosfd import * | ||
from bareos_fd_consts import * | ||
import os | ||
from BareosFdPluginBaseclass import * | ||
import BareosFdWrapper | ||
|
||
|
||
class BareosFdPluginLocalFileset (BareosFdPluginBaseclass): | ||
''' | ||
Simple Bareos-FD-Plugin-Class that parses a file and backups all files listed there | ||
Filename is taken from plugin argument 'filename' | ||
''' | ||
|
||
def parse_plugin_definition(self,context, plugindef): | ||
''' | ||
Parses the plugin argmuents and reads files from file given by argument 'filename' | ||
''' | ||
BareosFdPluginBaseclass.parse_plugin_definition(self, context, plugindef); | ||
if (not 'filename' in self.options): | ||
DebugMessage(context, 100, "Option \'filename\' not defined.\n"); | ||
return bRCs['bRC_Error']; | ||
DebugMessage(context, 100, "Using " + self.options['filename'] + " to search for local files\n"); | ||
if os.path.exists (self.options['filename']): | ||
try: | ||
config_file = open (self.options['filename'],'rb'); | ||
except: | ||
DebugMessage(context, 100, "Could not open file " + self.options['filename'] + "\n"); | ||
return bRCs['bRC_Error']; | ||
else: | ||
DebugMessage(context, 100, "File " + self.options['filename'] + " does not exist\n"); | ||
return bRCs['bRC_Error']; | ||
self.files_to_backup = config_file.read().splitlines(); | ||
return bRCs['bRC_OK']; | ||
|
||
|
||
def start_backup_file(self,context, savepkt): | ||
''' | ||
Defines the file to backup and creates the savepkt. In this example only files (no directories) | ||
are allowed | ||
''' | ||
DebugMessage(context, 100, "start_backup called\n"); | ||
if not self.files_to_backup: | ||
DebugMessage(context, 100, "No files to backup\n"); | ||
return bRCs['bRC_Skip']; | ||
|
||
file_to_backup = self.files_to_backup.pop(); | ||
DebugMessage(context, 100, "file: " + file_to_backup + "\n"); | ||
|
||
statp = StatPacket(); | ||
savepkt.statp = statp; | ||
savepkt.fname = file_to_backup; | ||
savepkt.type = bFileType['FT_REG']; | ||
|
||
JobMessage(context, bJobMessageType['M_INFO'], "Starting backup of " + file_to_backup + "\n"); | ||
return bRCs['bRC_OK']; | ||
|
||
def end_backup_file(self, context): | ||
''' | ||
Here we return 'bRC_More' as long as our list files_to_backup is not empty and | ||
bRC_OK when we are done | ||
''' | ||
DebugMessage(context, 100, "end_backup_file() entry point in Python called\n") | ||
if self.files_to_backup: | ||
return bRCs['bRC_More']; | ||
else: | ||
return bRCs['bRC_OK']; | ||
|
||
|
||
# vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# The BareosFdWrapper module. Here is a global object bareos_fd_plugin_object and wrapper functions, which | ||
# are directly called out of the bareos-fd. They are intended to pass the call to a method of an | ||
# object of type BareosFdPluginBaseclass (or derived) | ||
|
||
# use this as global plugin object among your python-fd-plugin modules | ||
bareos_fd_plugin_object=None | ||
|
||
def parse_plugin_definition(context, plugindef): | ||
return bareos_fd_plugin_object.parse_plugin_definition(context, plugindef); | ||
|
||
def handle_plugin_event(context, event): | ||
return bareos_fd_plugin_object.handle_plugin_event(context, event); | ||
|
||
def start_backup_file(context, savepkt): | ||
return bareos_fd_plugin_object.start_backup_file(context, savepkt); | ||
|
||
def end_backup_file(context): | ||
return bareos_fd_plugin_object.end_backup_file(context); | ||
|
||
def start_restore_file(context, cmd): | ||
return bareos_fd_plugin_object.start_restore_file(context,cmd); | ||
|
||
def end_restore_file(context): | ||
return bareos_fd_plugin_object.end_restore_file(context); | ||
|
||
def restore_object_data(context, ROP): | ||
return bareos_fd_plugin_object.restore_object_data(context, ROP); | ||
|
||
def plugin_io(context, IOP): | ||
return bareos_fd_plugin_object.plugin_io(context, IOP); | ||
|
||
def create_file(context, restorepkt): | ||
return bareos_fd_plugin_object.create_file(context, restorepkt) | ||
|
||
def check_file(context, fname): | ||
return bareos_fd_plugin_object.check_file(context, fname) | ||
|
||
def handle_backup_file(context, savepkt): | ||
return bareos_fd_plugin_object.handle_backup_file(context, savepkt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# Bareos-fd-local-fileset a simple example for a python Bareos FD Plugin using BareosFdPluginLocalFileset | ||
# The plugin argument 'filename' is used to read all files listed in that file and add it to the fileset | ||
|
||
# Provided by the Bareos FD Python plugin interface | ||
from bareosfd import * | ||
from bareos_fd_consts import * | ||
|
||
# This module contains the wrapper functions called by the Bareos-FD, the functions call the corresponding | ||
# methods from your plugin class | ||
from BareosFdWrapper import * | ||
|
||
# This module contains the used plugin class | ||
from BareosFdPluginLocalFileset import * | ||
|
||
def load_bareos_plugin(context, plugindef): | ||
''' | ||
This function is called by the Bareos-FD to load the plugin | ||
We use it to instantiate the plugin class | ||
''' | ||
# BareosFdWrapper.bareos_fd_plugin_object is the module attribute that holds the plugin class object | ||
BareosFdWrapper.bareos_fd_plugin_object = BareosFdPluginLocalFileset (context, plugindef); | ||
return bRCs['bRC_OK']; | ||
|
||
# the rest is done in the Plugin module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# Bareos-fd-mock-test a simple example for a python Bareos FD Plugin using the baseclass | ||
# and doing nothing | ||
# You may take this as a skeleton for your plugin | ||
|
||
from bareosfd import * | ||
from bareos_fd_consts import * | ||
from os import O_WRONLY, O_CREAT | ||
|
||
from BareosFdPluginBaseclass import * | ||
from BareosFdWrapper import * | ||
|
||
def load_bareos_plugin(context, plugindef): | ||
DebugMessage(context, 100, "------ Plugin loader called with " + plugindef + "\n"); | ||
BareosFdWrapper.plugin_object = BareosFdPluginBaseclass (context, plugindef); | ||
return bRCs['bRC_OK']; | ||
|
||
# the rest is done in the Plugin module |