diff --git a/debian/bareos-director-python-plugin.install.in b/debian/bareos-director-python-plugin.install.in index 4abb5c20609..12702a8230c 100644 --- a/debian/bareos-director-python-plugin.install.in +++ b/debian/bareos-director-python-plugin.install.in @@ -1,3 +1,6 @@ @plugindir@/python-dir.so @plugindir@/bareos-dir.py* @plugindir@/bareos_dir_consts.py* +@plugindir@/BareosDirWrapper.py* +@plugindir@/BareosDirPluginBaseclass.py* +@plugindir@/bareos-dir-class-plugin.py* diff --git a/platforms/packaging/bareos.spec b/platforms/packaging/bareos.spec index 3a8c0f11545..4c247f60e76 100644 --- a/platforms/packaging/bareos.spec +++ b/platforms/packaging/bareos.spec @@ -999,7 +999,9 @@ echo "This is a meta package to install a full bareos system" > %{buildroot}%{_d %{plugin_dir}/python-dir.so %{plugin_dir}/bareos-dir.py* %{plugin_dir}/bareos_dir_consts.py* - +%{plugin_dir}/BareosDirPluginBaseclass.py* +%{plugin_dir}/bareos-dir-class-plugin.py* +%{plugin_dir}/BareosDirWrapper.py* %files storage-python-plugin %defattr(-, root, root) diff --git a/src/plugins/dird/BareosDirPluginBaseclass.py b/src/plugins/dird/BareosDirPluginBaseclass.py new file mode 100644 index 00000000000..2b652401f87 --- /dev/null +++ b/src/plugins/dird/BareosDirPluginBaseclass.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# BAREOS - Backup Archiving REcovery Open Sourced +# +# Copyright (C) 2014-2014 Bareos GmbH & Co. KG +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of version three of the GNU Affero General Public +# License as published by the Free Software Foundation, which is +# listed in the file LICENSE. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# Author: Maik Aussendorf +# +# Baseclass for Bareos python plugins +# Functions taken and adapted from bareos-dir.py + +from bareosdir import * +from bareos_dir_consts import * +import os +import time + +class BareosDirPluginBaseclass(object): + + ''' Bareos DIR python plugin base class ''' + + def __init__(self, context, plugindef): + DebugMessage( + context, 100, "Constructor called in module %s\n" % + (__name__)) + events = [] + + events.append(bDirEventType['bDirEventJobStart']); + events.append(bDirEventType['bDirEventJobEnd']); + events.append(bDirEventType['bDirEventJobInit']); + events.append(bDirEventType['bDirEventJobRun']); + RegisterEvents(context, events) + + # get some static Bareos values + self.jobName = GetValue(context, brDirVariable['bDirVarJobName']) + self.jobLevel = chr(GetValue(context, brDirVariable['bDirVarLevel'])) + self.jobType = GetValue(context, brDirVariable['bDirVarType']) + self.jobId = int(GetValue(context, brDirVariable['bDirVarJobId'])) + self.jobClient = GetValue(context, brDirVariable['bDirVarClient']) + self.jobStatus = GetValue(context, brDirVariable['bDirVarJobStatus']) + self.Priority = GetValue(context, brDirVariable['bDirVarPriority']) + + DebugMessage( + context, 100, "JobName = %s - level = %s - type = %s - Id = %s - \ + Client = %s - jobStatus = %s - Priority = %s - BareosDirPluginBaseclass\n" % + (self.jobName,self.jobLevel,self.jobType,self.jobId,self.jobClient,self.jobStatus,self.Priority)) + + def __str__(self): + return "<$%:jobName=%s jobId=%s client=%s>" %(self.__class__, self.jobName,self.jobId,self.Client) + + def parse_plugin_definition(self, context, plugindef): + ''' + Called with the plugin options from the bareos configfiles + 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 + ''' + DebugMessage( + context, 100, "plugin def parser called with %s\n" % + (plugindef)) + # 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 = %s:%s" % (key, val)) + if val == '': + continue + else: + self.options[key] = val + return bRCs['bRC_OK'] + + + def handle_plugin_event(self, context, event): + ''' + This method is called for each of the above registered events + Overload this method to implement your actions for the events, + You may first call this method in your derived class to get the + job attributes read and then only adjust where useful. + ''' + if event == bDirEventType['bDirEventJobInit']: + self.jobInitTime = time.time() + self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); + DebugMessage(context, 100, "bDirEventJobInit event triggered at Unix time %s\n" %self.jobInitTime); + + elif event == bDirEventType['bDirEventJobStart']: + self.jobStartTime = time.time() + self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); + DebugMessage(context, 100, "bDirEventJobStart event triggered at Unix time %s\n" %self.jobStartTime); + + elif event == bDirEventType['bDirEventJobRun']: + # Now the jobs starts running, after eventually waiting some time, e.g for other jobs to finish + self.jobRunTime = time.time() + DebugMessage(context, 100, "bDirEventJobRun event triggered at Unix time %s\n" %self.jobRunTime); + + elif event == bDirEventType['bDirEventJobEnd']: + self.jobEndTime = time.time() + DebugMessage(context, 100, "bDirEventJobEnd event triggered at Unix time %s\n" %self.jobEndTime); + self.jobLevel = chr(GetValue(context, brDirVariable['bDirVarLevel'])); + self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); + self.jobErrors = int(GetValue(context, brDirVariable['bDirVarJobErrors'])); + self.jobBytes = int(GetValue(context, brDirVariable['bDirVarJobBytes'])); + self.jobFiles = int(GetValue(context, brDirVariable['bDirVarJobFiles'])); + self.jobNumVols = int(GetValue(context, brDirVariable['bDirVarNumVols'])); + self.jobPool = GetValue(context, brDirVariable['bDirVarPool']); + self.jobStorage = GetValue(context, brDirVariable['bDirVarStorage']); + self.jobMediaType = GetValue(context, brDirVariable['bDirVarMediaType']); + + self.jobTotalTime = self.jobEndTime - self.jobInitTime; + self.jobRunningTime = self.jobEndTime - self.jobRunTime; + self.throughput = 0 + if self.jobRunningTime > 0: + self.throughput = self.jobBytes / self.jobRunningTime + + return bRCs['bRC_OK']; + + +# vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/src/plugins/dird/BareosDirWrapper.py b/src/plugins/dird/BareosDirWrapper.py new file mode 100644 index 00000000000..e2ce3e840e2 --- /dev/null +++ b/src/plugins/dird/BareosDirWrapper.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# BAREOS - Backup Archiving REcovery Open Sourced +# +# Copyright (C) 2014-2014 Bareos GmbH & Co. KG +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of version three of the GNU Affero General Public +# License as published by the Free Software Foundation, which is +# listed in the file LICENSE. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# Author: Maik Aussendorf +# +# The BareosDirWrapper module. Here is a global object bareos_dir_plugin_object +# and wrapper functions, which are directly called out of the bareos-dir. They +# are intended to pass the call to a method of an object of type +# BareosDirPluginBaseclass (or derived) + +# use this as global plugin object among your python-dir-plugin modules +bareos_dir_plugin_object = None + +def parse_plugin_definition(context, plugindef): + return bareos_dir_plugin_object.parse_plugin_definition(context, plugindef) + +def handle_plugin_event(context, event): + return bareos_dir_plugin_object.handle_plugin_event(context, event) + diff --git a/src/plugins/dird/bareos-dir-class-plugin.py b/src/plugins/dird/bareos-dir-class-plugin.py new file mode 100644 index 00000000000..8eaaad23e9c --- /dev/null +++ b/src/plugins/dird/bareos-dir-class-plugin.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# BAREOS - Backup Archiving REcovery Open Sourced +# +# Copyright (C) 2014-2014 Bareos GmbH & Co. KG +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of version three of the GNU Affero General Public +# License as published by the Free Software Foundation, which is +# listed in the file LICENSE. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# Bareos-dir-local-fileset a simple example for a python Bareos Dir Plugin using +# BareosDirPluginBaseclass. The plugin argument 'filename' is used to read +# all files listed in that file and add it to the fileset +# +# Author: Maik Aussendorf +# + +# Provided by the Bareos Dir Python plugin interface +import bareos_dir_consts + +# This module contains the wrapper functions called by the Bareos-Dir, the +# functions call the corresponding methods from your plugin class +import BareosDirWrapper +from BareosDirWrapper import * + +# This module contains the used plugin class +import BareosDirPluginBaseclass + + +def load_bareos_plugin(context, plugindef): + ''' + This function is called by the Bareos-Dir to load the plugin + We use it to instantiate the plugin class + ''' + # BareosDirWrapper.bareos_dir_plugin_object is the module attribute that + # holds the plugin class object + BareosDirWrapper.bareos_dir_plugin_object = \ + BareosDirPluginBaseclass.BareosDirPluginBaseclass( + context, plugindef) + return bareos_dir_consts.bRCs['bRC_OK'] + +# the rest is done in the Plugin module