Skip to content

Commit

Permalink
Implementation of Python Director Plugin
Browse files Browse the repository at this point in the history
Implement a plugin that makes it possible to write Director plugins in Python.

Stub plugin function is available that loads a python interpreter per plugin
instance. Need to link the plugin events to Python methods and allow the Python
code to call the plugin code do read and write plugin variables.

Fixes #12: Implementation of Python Director Plugin
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent ef167c7 commit 950e8ba
Show file tree
Hide file tree
Showing 7 changed files with 826 additions and 150 deletions.
285 changes: 156 additions & 129 deletions src/dird/dir_plugins.c
Expand Up @@ -29,7 +29,7 @@
#include "dird.h"
#include "dir_plugins.h"

const int dbglvl = 50;
const int dbglvl = 150;
const char *plugin_type = "-dir.so";

static alist *dird_plugin_list;
Expand Down Expand Up @@ -360,150 +360,164 @@ void free_plugins(JCR *jcr)
*/
static bRC bareosGetValue(bpContext *ctx, brDirVariable var, void *value)
{
JCR *jcr;
JCR *jcr = NULL;
bRC ret = bRC_OK;

if (!ctx) {
return bRC_Error;
}
jcr = ((b_plugin_ctx *)ctx->bContext)->jcr;
if (!jcr) {
return bRC_Error;
}
if (!value) {
return bRC_Error;
}
switch (var) {
case bDirVarJobId:
*((int *)value) = jcr->JobId;
Dmsg1(dbglvl, "dir-plugin: return bDirVarJobId=%d\n", jcr->JobId);
break;
case bDirVarJobName:
*((char **)value) = jcr->Job;
Dmsg1(dbglvl, "BAREOS: return Job name=%s\n", jcr->Job);
break;
case bDirVarJob:
*((char **)value) = jcr->res.job->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarJob=%s\n", jcr->res.job->hdr.name);
break;
case bDirVarLevel:
*((int *)value) = jcr->getJobLevel();
Dmsg1(dbglvl, "BAREOS: return bDirVarLevel=%c\n", jcr->getJobLevel());
break;
case bDirVarType:
*((int *)value) = jcr->getJobType();
Dmsg1(dbglvl, "BAREOS: return bDirVarType=%c\n", jcr->getJobType());
break;
case bDirVarClient:
*((char **)value) = jcr->res.client->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarClient=%s\n", jcr->res.client->hdr.name);
break;
case bDirVarNumVols:
POOL_DBR pr;
memset(&pr, 0, sizeof(pr));
bstrncpy(pr.Name, jcr->res.pool->hdr.name, sizeof(pr.Name));
if (!db_get_pool_record(jcr, jcr->db, &pr)) {
ret=bRC_Error;
}
*((int *)value) = pr.NumVols;
Dmsg1(dbglvl, "BAREOS: return bDirVarNumVols=%d\n", pr.NumVols);
break;
case bDirVarPool:
*((char **)value) = jcr->res.pool->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarPool=%s\n", jcr->res.pool->hdr.name);
break;
case bDirVarStorage:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->hdr.name;
} else if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarStorage=%s\n", NPRT(*((char **)value)));

switch (var) { /* General variables, no need of ctx */
case bDirVarPluginDir:
*((char **)value) = me->plugin_directory;
Dmsg1(dbglvl, "dir-plugin: return bDirVarPluginDir=%s\n", me->plugin_directory);
break;
case bDirVarWriteStorage:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
default:
if (!ctx) {
return bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarWriteStorage=%s\n", NPRT(*((char **)value)));
break;
case bDirVarReadStorage:
if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
jcr = ((b_plugin_ctx *)ctx->bContext)->jcr;
if (!jcr) {
return bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarReadStorage=%s\n", NPRT(*((char **)value)));
break;
case bDirVarCatalog:
*((char **)value) = jcr->res.catalog->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarCatalog=%s\n", jcr->res.catalog->hdr.name);
break;
case bDirVarMediaType:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->media_type;
} else if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->media_type;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}

if (jcr) {
switch (var) {
case bDirVarJobId:
*((int *)value) = jcr->JobId;
Dmsg1(dbglvl, "dir-plugin: return bDirVarJobId=%d\n", jcr->JobId);
break;
case bDirVarJobName:
*((char **)value) = jcr->Job;
Dmsg1(dbglvl, "BAREOS: return Job name=%s\n", jcr->Job);
break;
case bDirVarJob:
*((char **)value) = jcr->res.job->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarJob=%s\n", jcr->res.job->hdr.name);
break;
case bDirVarLevel:
*((int *)value) = jcr->getJobLevel();
Dmsg1(dbglvl, "BAREOS: return bDirVarLevel=%c\n", jcr->getJobLevel());
break;
case bDirVarType:
*((int *)value) = jcr->getJobType();
Dmsg1(dbglvl, "BAREOS: return bDirVarType=%c\n", jcr->getJobType());
break;
case bDirVarClient:
*((char **)value) = jcr->res.client->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarClient=%s\n", jcr->res.client->hdr.name);
break;
case bDirVarNumVols:
POOL_DBR pr;
memset(&pr, 0, sizeof(pr));
bstrncpy(pr.Name, jcr->res.pool->hdr.name, sizeof(pr.Name));
if (!db_get_pool_record(jcr, jcr->db, &pr)) {
ret=bRC_Error;
}
*((int *)value) = pr.NumVols;
Dmsg1(dbglvl, "BAREOS: return bDirVarNumVols=%d\n", pr.NumVols);
break;
case bDirVarPool:
*((char **)value) = jcr->res.pool->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarPool=%s\n", jcr->res.pool->hdr.name);
break;
case bDirVarStorage:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->hdr.name;
} else if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarStorage=%s\n", NPRT(*((char **)value)));
break;
case bDirVarWriteStorage:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarWriteStorage=%s\n", NPRT(*((char **)value)));
break;
case bDirVarReadStorage:
if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->hdr.name;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarReadStorage=%s\n", NPRT(*((char **)value)));
break;
case bDirVarCatalog:
*((char **)value) = jcr->res.catalog->hdr.name;
Dmsg1(dbglvl, "BAREOS: return bDirVarCatalog=%s\n", jcr->res.catalog->hdr.name);
break;
case bDirVarMediaType:
if (jcr->res.wstore) {
*((char **)value) = jcr->res.wstore->media_type;
} else if (jcr->res.rstore) {
*((char **)value) = jcr->res.rstore->media_type;
} else {
*((char **)value) = NULL;
ret=bRC_Error;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarMediaType=%s\n", NPRT(*((char **)value)));
break;
case bDirVarJobStatus:
*((int *)value) = jcr->JobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarJobStatus=%c\n", jcr->JobStatus);
break;
case bDirVarPriority:
*((int *)value) = jcr->JobPriority;
Dmsg1(dbglvl, "BAREOS: return bDirVarPriority=%d\n", jcr->JobPriority);
break;
case bDirVarVolumeName:
*((char **)value) = jcr->VolumeName;
Dmsg1(dbglvl, "BAREOS: return bDirVarVolumeName=%s\n", jcr->VolumeName);
break;
case bDirVarCatalogRes:
ret = bRC_Error;
break;
case bDirVarJobErrors:
*((int *)value) = jcr->JobErrors;
Dmsg1(dbglvl, "BAREOS: return bDirVarErrors=%d\n", jcr->JobErrors);
break;
case bDirVarJobFiles:
*((int *)value) = jcr->JobFiles;
Dmsg1(dbglvl, "BAREOS: return bDirVarFiles=%d\n", jcr->JobFiles);
break;
case bDirVarSDJobFiles:
*((int *)value) = jcr->SDJobFiles;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDFiles=%d\n", jcr->SDJobFiles);
break;
case bDirVarSDErrors:
*((int *)value) = jcr->SDErrors;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDErrors=%d\n", jcr->SDErrors);
break;
case bDirVarFDJobStatus:
*((int *)value) = jcr->FDJobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarFDJobStatus=%c\n", jcr->FDJobStatus);
break;
case bDirVarSDJobStatus:
*((int *)value) = jcr->SDJobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDJobStatus=%c\n", jcr->SDJobStatus);
break;
default:
break;
}
Dmsg1(dbglvl, "BAREOS: return bDirVarMediaType=%s\n", NPRT(*((char **)value)));
break;
case bDirVarJobStatus:
*((int *)value) = jcr->JobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarJobStatus=%c\n", jcr->JobStatus);
break;
case bDirVarPriority:
*((int *)value) = jcr->JobPriority;
Dmsg1(dbglvl, "BAREOS: return bDirVarPriority=%d\n", jcr->JobPriority);
break;
case bDirVarVolumeName:
*((char **)value) = jcr->VolumeName;
Dmsg1(dbglvl, "BAREOS: return bDirVarVolumeName=%s\n", jcr->VolumeName);
break;
case bDirVarCatalogRes:
ret = bRC_Error;
break;
case bDirVarJobErrors:
*((int *)value) = jcr->JobErrors;
Dmsg1(dbglvl, "BAREOS: return bDirVarErrors=%d\n", jcr->JobErrors);
break;
case bDirVarJobFiles:
*((int *)value) = jcr->JobFiles;
Dmsg1(dbglvl, "BAREOS: return bDirVarFiles=%d\n", jcr->JobFiles);
break;
case bDirVarSDJobFiles:
*((int *)value) = jcr->SDJobFiles;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDFiles=%d\n", jcr->SDJobFiles);
break;
case bDirVarSDErrors:
*((int *)value) = jcr->SDErrors;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDErrors=%d\n", jcr->SDErrors);
break;
case bDirVarFDJobStatus:
*((int *)value) = jcr->FDJobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarFDJobStatus=%c\n", jcr->FDJobStatus);
break;
case bDirVarSDJobStatus:
*((int *)value) = jcr->SDJobStatus;
Dmsg1(dbglvl, "BAREOS: return bDirVarSDJobStatus=%c\n", jcr->SDJobStatus);
break;
default:
break;
}

return ret;
}

static bRC bareosSetValue(bpContext *ctx, bwDirVariable var, void *value)
{
JCR *jcr;

if (!value || !ctx) {
return bRC_Error;
}
Expand All @@ -513,8 +527,21 @@ static bRC bareosSetValue(bpContext *ctx, bwDirVariable var, void *value)
return bRC_Error;
}
// Dmsg1(dbglvl, "BAREOS: jcr=%p\n", jcr);
/* Nothing implemented yet */
Dmsg1(dbglvl, "dir-plugin: bareosSetValue var=%d\n", var);
switch (var) {
case bwDirVarVolumeName:
pm_strcpy(jcr->VolumeName, ((char *)value));
break;
case bwDirVarPriority:
jcr->JobPriority = *((int *)value);
break;
case bwDirVarJobLevel:
jcr->setJobLevel(*((int *)value));
break;
default:
break;
}

return bRC_OK;
}

Expand Down
3 changes: 2 additions & 1 deletion src/dird/dir_plugins.h
Expand Up @@ -79,7 +79,8 @@ typedef enum {
bDirVarSDJobFiles = 20,
bDirVarSDErrors = 21,
bDirVarFDJobStatus = 22,
bDirVarSDJobStatus = 23
bDirVarSDJobStatus = 23,
bDirVarPluginDir = 24
} brDirVariable;

/*
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/dird/Makefile.in
Expand Up @@ -33,7 +33,7 @@ example-plugin-dir.la: Makefile \
example-plugin-dir$(DEFAULT_OBJECT_TYPE)
$(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared example-plugin-dir.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version

python-dir.lo: python-dir.c
python-dir.lo: python-dir.c python-dir.h
$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) $(PYTHON_CPPFLAGS) -c $<

python-dir.la: Makefile \
Expand Down
32 changes: 32 additions & 0 deletions src/plugins/dird/bareos-dir.py
@@ -0,0 +1,32 @@
from bareosdir import *
from bareos_dir_consts import *

def load_bareos_plugin(context):
DebugMessage(context, 100, "load_bareos_plugin called\n");
events = [];
events.append(bDirEventType['bDirEventJobStart']);
events.append(bDirEventType['bDirEventJobEnd']);
events.append(bDirEventType['bDirEventJobInit']);
events.append(bDirEventType['bDirEventJobRun']);
RegisterEvents(context, events);
return bRCs['bRC_OK'];

def handle_plugin_event(context, event):
if event == bDirEventType['bDirEventJobStart']:
DebugMessage(context, 100, "bDirEventJobStart event triggered\n");
jobname = GetValue(context, brDirVariable['bDirVarJobName']);
DebugMessage(context, 100, "Job " + jobname + " starting\n");

elif event == bDirEventType['bDirEventJobEnd']:
DebugMessage(context, 100, "bDirEventJobEnd event triggered\n");
jobname = GetValue(context, brDirVariable['bDirVarJobName']);
DebugMessage(context, 100, "Job " + jobname + " stopped\n");

elif event == bDirEventType['bDirEventJobInit']:
DebugMessage(context, 100, "bDirEventJobInit event triggered\n");

elif event == bDirEventType['bDirEventJobRun']:
DebugMessage(context, 100, "bDirEventJobRun event triggered\n");

return bRCs['bRC_OK'];

0 comments on commit 950e8ba

Please sign in to comment.