3 * Bacula interface to Python for the Storage Daemon
5 * Kern Sibbald, January MMV
12 Copyright (C) 2005 Kern Sibbald
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of
17 the License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public
25 License along with this program; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
35 #undef _POSIX_C_SOURCE
38 extern JCR *get_jcr_from_PyObject(PyObject *self);
39 extern PyObject *find_method(PyObject *eventsObject, PyObject *method,
42 static PyObject *set_job_events(PyObject *self, PyObject *arg);
43 static PyObject *job_write(PyObject *self, PyObject *arg);
45 PyMethodDef JobMethods[] = {
46 {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
47 {"write", job_write, METH_VARARGS, "Write to output"},
48 {NULL, NULL, 0, NULL} /* last item */
57 static struct s_vars getvars[] = {
58 { N_("Job"), "s"}, /* 0 */
59 { N_("SDName"), "s"}, /* 1 */
60 { N_("Level"), "s"}, /* 2 */
61 { N_("Type"), "s"}, /* 3 */
62 { N_("JobId"), "i"}, /* 4 */
63 { N_("Client"), "s"}, /* 5 */
64 { N_("Pool"), "s"}, /* 6 */
65 { N_("MediaType"), "s"}, /* 7 */
66 { N_("JobName"), "s"}, /* 8 */
67 { N_("JobStatus"), "s"}, /* 9 */
68 { N_("VolumeName"), "s"}, /* 10 */
69 { N_("Device"), "s"}, /* 11 */
75 /* Writable variables */
76 static struct s_vars setvars[] = {
77 { N_("JobReport"), "s"},
83 /* Return Job variables */
84 PyObject *job_getattr(PyObject *self, char *attrname)
92 Dmsg1(100, "In job_getattr=%s\n", attrname);
93 jcr = get_jcr_from_PyObject(self);
95 bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
99 for (i=0; getvars[i].name; i++) {
100 if (strcmp(getvars[i].name, attrname) == 0) {
106 /* Try our methods */
107 return Py_FindMethod(JobMethods, self, attrname);
111 return Py_BuildValue(getvars[i].fmt, jcr->job_name); /* Non-unique name */
112 case 1: /* SD's name */
113 return Py_BuildValue(getvars[i].fmt, my_name);
115 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
117 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
119 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
121 return Py_BuildValue(getvars[i].fmt, jcr->client_name);
123 return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
124 case 7: /* MediaType */
125 return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
126 case 8: /* JobName */
127 return Py_BuildValue(getvars[i].fmt, jcr->Job);
128 case 9: /* JobStatus */
130 buf[0] = jcr->JobStatus;
131 return Py_BuildValue(getvars[i].fmt, buf);
133 return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
135 return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
137 bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
139 PyErr_SetString(PyExc_AttributeError, errmsg);
143 int job_setattr(PyObject *self, char *attrname, PyObject *value)
152 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
153 if (value == NULL) { /* Cannot delete variables */
154 bsnprintf(buf, sizeof(buf), "Cannot delete attribute %s", attrname);
158 jcr = get_jcr_from_PyObject(self);
160 errmsg = "Job pointer not found.";
164 /* Find attribute name in list */
165 for (i=0; setvars[i].name; i++) {
166 if (strcmp(setvars[i].name, attrname) == 0) {
174 /* Get argument value ***FIXME*** handle other formats */
175 if (setvars[i].fmt != NULL) {
176 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
177 PyErr_SetString(PyExc_TypeError, "Read-only attribute");
182 case 0: /* JobReport */
183 Jmsg(jcr, M_INFO, 0, "%s", strval);
187 bsnprintf(buf, sizeof(buf), "Cannot find attribute %s", attrname);
190 PyErr_SetString(PyExc_AttributeError, errmsg);
195 static PyObject *set_job_events(PyObject *self, PyObject *arg)
200 Dmsg0(100, "In set_job_events.\n");
201 if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
202 Dmsg0(000, "Error in ParseTuple\n");
205 jcr = get_jcr_from_PyObject(self);
206 Py_XDECREF((PyObject *)jcr->Python_events);
208 jcr->Python_events = (void *)eObject;
213 static PyObject *job_write(PyObject *self, PyObject *args)
217 if (!PyArg_ParseTuple(args, "s:write", &text)) {
218 Dmsg0(000, "Parse tuple error in job_write\n");
222 Jmsg(NULL, M_INFO, 0, "%s", text);
229 int generate_job_event(JCR *jcr, const char *event)
231 PyObject *method = NULL;
232 PyObject *Job = (PyObject *)jcr->Python_job;
233 PyObject *events = (PyObject *)jcr->Python_events;
234 PyObject *result = NULL;
237 if (!Job || !events) {
241 PyEval_AcquireLock();
243 method = find_method(events, method, event);
248 bstrncpy(jcr->event, event, sizeof(jcr->event));
249 result = PyObject_CallFunction(method, "O", Job);
250 jcr->event[0] = 0; /* no event in progress */
251 if (result == NULL) {
252 if (PyErr_Occurred()) {
254 Dmsg1(000, "Error in Python method %s\n", event);
262 PyEval_ReleaseLock();
269 /* Dummy if Python not configured */
270 int generate_job_event(JCR *jcr, const char *event)
274 #endif /* HAVE_PYTHON */