2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2011 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula interface to Python for the Storage Daemon
32 * Kern Sibbald, January MMV
34 * SD Python interface removed 17 December 2011 (KES)
42 #ifdef xxxxHAVE_PYTHON
43 #undef _POSIX_C_SOURCE
46 #include <lib/pythonlib.h>
48 static PyObject *set_job_events(PyObject *self, PyObject *arg);
49 static PyObject *job_write(PyObject *self, PyObject *arg);
51 PyMethodDef JobMethods[] = {
52 {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
53 {"write", job_write, METH_VARARGS, "Write to output"},
54 {NULL, NULL, 0, NULL} /* last item */
63 static struct s_vars getvars[] = {
64 { NT_("Job"), "s"}, /* 0 */
65 { NT_("SDName"), "s"}, /* 1 */
66 { NT_("Level"), "s"}, /* 2 */
67 { NT_("Type"), "s"}, /* 3 */
68 { NT_("JobId"), "i"}, /* 4 */
69 { NT_("Client"), "s"}, /* 5 */
70 { NT_("Pool"), "s"}, /* 6 */
71 { NT_("MediaType"), "s"}, /* 7 */
72 { NT_("JobName"), "s"}, /* 8 */
73 { NT_("JobStatus"), "s"}, /* 9 */
74 { NT_("VolumeName"), "s"}, /* 10 */
75 { NT_("Device"), "s"}, /* 11 */
81 /* Writable variables */
82 static struct s_vars setvars[] = {
83 { NT_("JobReport"), "s"},
89 /* Return Job variables */
90 PyObject *job_getattr(PyObject *self, char *attrname)
98 Dmsg1(100, "In job_getattr=%s\n", attrname);
99 jcr = get_jcr_from_PyObject(self);
101 bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
105 for (i=0; getvars[i].name; i++) {
106 if (strcmp(getvars[i].name, attrname) == 0) {
112 /* Try our methods */
113 return Py_FindMethod(JobMethods, self, attrname);
117 return Py_BuildValue((char *)getvars[i].fmt, jcr->job_name); /* Non-unique name */
118 case 1: /* SD's name */
119 return Py_BuildValue((char *)getvars[i].fmt, my_name);
121 return Py_BuildValue((char *)getvars[i].fmt, job_level_to_str(jcr->getJobLevel()));
123 return Py_BuildValue((char *)getvars[i].fmt, job_type_to_str(jcr->getJobType()));
125 return Py_BuildValue((char *)getvars[i].fmt, jcr->JobId);
127 return Py_BuildValue((char *)getvars[i].fmt, jcr->client_name);
129 return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->pool_name);
130 case 7: /* MediaType */
131 return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->media_type);
132 case 8: /* JobName */
133 return Py_BuildValue((char *)getvars[i].fmt, jcr->Job);
134 case 9: /* JobStatus */
136 buf[0] = jcr->JobStatus;
137 return Py_BuildValue((char *)getvars[i].fmt, buf);
139 return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->VolumeName);
141 return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->dev_name);
143 bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
145 PyErr_SetString(PyExc_AttributeError, errmsg);
149 int job_setattr(PyObject *self, char *attrname, PyObject *value)
158 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
159 if (value == NULL) { /* Cannot delete variables */
160 bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
164 jcr = get_jcr_from_PyObject(self);
166 errmsg = _("Job pointer not found.");
170 /* Find attribute name in list */
171 for (i=0; setvars[i].name; i++) {
172 if (strcmp(setvars[i].name, attrname) == 0) {
180 /* Get argument value ***FIXME*** handle other formats */
181 if (setvars[i].fmt != NULL) {
182 if (!PyArg_Parse(value, (char *)setvars[i].fmt, &strval)) {
183 PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
188 case 0: /* JobReport */
189 Jmsg(jcr, M_INFO, 0, "%s", strval);
193 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
196 PyErr_SetString(PyExc_AttributeError, errmsg);
201 static PyObject *set_job_events(PyObject *self, PyObject *arg)
206 Dmsg0(100, "In set_job_events.\n");
207 if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
208 Pmsg0(000, _("Error in ParseTuple\n"));
211 jcr = get_jcr_from_PyObject(self);
212 Py_XDECREF((PyObject *)jcr->Python_events);
214 jcr->Python_events = (void *)eObject;
219 static PyObject *job_write(PyObject *self, PyObject *args)
223 if (!PyArg_ParseTuple(args, "s:write", &text)) {
224 Pmsg0(000, _("Parse tuple error in job_write\n"));
228 Jmsg(NULL, M_INFO, 0, "%s", text);
235 int generate_job_event(JCR *jcr, const char *event)
237 PyObject *method = NULL;
238 PyObject *Job = (PyObject *)jcr->Python_job;
239 PyObject *events = (PyObject *)jcr->Python_events;
240 PyObject *result = NULL;
243 if (!Job || !events) {
248 // PyEval_AcquireLock();
250 method = find_method(events, method, event);
255 bstrncpy(jcr->event, event, sizeof(jcr->event));
256 result = PyObject_CallFunction(method, (char *)"O", Job);
257 jcr->event[0] = 0; /* no event in progress */
258 if (result == NULL) {
259 if (PyErr_Occurred()) {
261 Dmsg1(000, _("Error in Python method %s\n"), event);
270 // PyEval_ReleaseLock();
277 /* Dummy if Python not configured */
278 int generate_job_event(JCR *jcr, const char *event)
282 #endif /* xxxxHAVE_PYTHON */