3 Bacula interface to Python
5 Kern Sibbald, November MMIV
7 Copyright (C) 2004 Kern Sibbald
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of
12 the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public
20 License along with this program; if not, write to the Free
21 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 #include "../dird/dird_conf.h"
28 #define DIRECTOR_DAEMON 1
29 #include "../cats/cats.h"
36 bool run_module(const char *module);
38 static PyObject *bacula_get(PyObject *self, PyObject *args);
39 static PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw);
41 /* Define Bacula entry points */
42 static PyMethodDef BaculaMethods[] = {
43 {"get", bacula_get, METH_VARARGS, "Get Bacula variables."},
44 {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS,
45 "Set Bacula variables."},
46 {NULL, NULL, 0, NULL} /* last item */
50 /* Return Bacula variables */
52 bacula_get(PyObject *self, PyObject *args)
57 if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) {
60 jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
61 /* ***FIXME*** put this in a table */
62 if (strcmp(item, "JobId") == 0) {
63 return Py_BuildValue("i", jcr->JobId);
64 } else if (strcmp(item, "Client") == 0) {
65 return Py_BuildValue("s", jcr->client->hdr.name);
66 } else if (strcmp(item, "Pool") == 0) {
67 return Py_BuildValue("s", jcr->pool->hdr.name);
68 } else if (strcmp(item, "Storage") == 0) {
69 return Py_BuildValue("s", jcr->store->hdr.name);
70 } else if (strcmp(item, "Catalog") == 0) {
71 return Py_BuildValue("s", jcr->catalog->hdr.name);
72 } else if (strcmp(item, "MediaType") == 0) {
73 return Py_BuildValue("s", jcr->store->media_type);
74 } else if (strcmp(item, "NumVols") == 0) {
75 return Py_BuildValue("i", jcr->NumVols);
76 } else if (strcmp(item, "DirName") == 0) {
77 return Py_BuildValue("s", my_name);
78 } else if (strcmp(item, "Level") == 0) {
79 return Py_BuildValue("s", job_level_to_str(jcr->JobLevel));
80 } else if (strcmp(item, "Type") == 0) {
81 return Py_BuildValue("s", job_type_to_str(jcr->JobType));
82 } else if (strcmp(item, "Job") == 0) {
83 return Py_BuildValue("s", jcr->job->hdr.name);
84 } else if (strcmp(item, "JobName") == 0) {
85 return Py_BuildValue("s", jcr->Job);
90 /* Set Bacula variables */
92 bacula_set(PyObject *self, PyObject *args, PyObject *keyw)
97 char *VolumeName = NULL;
98 static char *kwlist[] = {"jcr", "JobReport", "VolumeName", NULL};
99 if (!PyArg_ParseTupleAndKeywords(args, keyw, "O|ss:set", kwlist,
100 &CObject, &msg, &VolumeName)) {
103 jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
105 Jmsg(jcr, M_INFO, 0, "%s", msg);
108 pm_strcpy(jcr->VolumeName, VolumeName);
110 return Py_BuildValue("i", 1);
114 void init_python_interpreter(char *progname)
116 Py_SetProgramName(progname);
118 PyEval_InitThreads();
119 Py_InitModule("bacula", BaculaMethods);
120 PyRun_SimpleString("import sys\n"
121 "sys.path.append('.')\n");
122 PyEval_ReleaseLock();
125 void term_python_interpreter()
132 * Generate and process a Bacula event by importing a Python
133 * module and running it.
135 * Returns: 0 if Python not configured or module not found
139 int generate_event(JCR *jcr, const char *event)
141 PyObject *pName, *pModule, *pDict, *pFunc;
142 PyObject *pArgs, *pValue;
144 pName = PyString_FromString(event);
146 Jmsg(jcr, M_ERROR, 0, "Could not convert \"%s\" to Python string.\n", event);
147 return -1; /* Could not convert string */
150 pModule = PyImport_Import(pName);
151 Py_DECREF(pName); /* release pName */
153 if (pModule != NULL) {
154 pDict = PyModule_GetDict(pModule);
155 /* pDict is a borrowed reference */
157 pFunc = PyDict_GetItemString(pDict, (char *)event);
158 /* pFun: Borrowed reference */
160 if (pFunc && PyCallable_Check(pFunc)) {
161 /* Create JCR argument to send to function */
162 pArgs = PyTuple_New(1);
163 pValue = PyCObject_FromVoidPtr((void *)jcr, NULL);
167 Jmsg(jcr, M_ERROR, 0, "Could not convert JCR to Python CObject.\n");
168 return -1; /* Could not convert JCR to CObject */
170 /* pValue reference stolen here: */
171 PyTuple_SetItem(pArgs, 0, pValue);
173 /* Finally, we call the module here */
174 pValue = PyObject_CallObject(pFunc, pArgs);
176 if (pValue != NULL) {
181 Jmsg(jcr, M_ERROR, 0, "Error running Python module: %s\n", event);
182 return 0; /* error running function */
184 /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
186 Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found in module.\n", event);
187 return -1; /* function not found */
191 return 0; /* Module not present */
199 * No Python configured
202 int generate_event(JCR *jcr, const char *event) { return 0; }
203 void init_python_interpreter(char *progname) { }
204 void term_python_interpreter() { }
207 #endif /* HAVE_PYTHON */