3 * Bacula interface to Python for the Director
5 * Kern Sibbald, November MMIV
12 Copyright (C) 2004-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 int set_job_events(PyObject *self, PyObject *arg);
43 static int job_run(PyObject *self, PyObject *arg);
50 /* Read-only variables */
51 static struct s_vars getvars[] = {
53 { N_("DirName"), "s"},
58 { N_("NumVols"), "i"},
60 { N_("Storage"), "s"},
61 { N_("Catalog"), "s"},
62 { N_("MediaType"), "s"},
63 { N_("JobName"), "s"},
64 { N_("JobStatus"), "s"},
69 /* Writable variables */
70 static struct s_vars setvars[] = {
71 { N_("set_events"), NULL},
73 { N_("JobReport"), "s"},
75 { N_("VolumeName") , "s"},
81 /* Return Job variables */
82 /* Returns: NULL if error
83 * PyObject * return value if OK
85 PyObject *job_getattr(PyObject *self, char *attrname)
93 Dmsg0(100, "In job_getattr.\n");
94 jcr = get_jcr_from_PyObject(self);
96 bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
99 for (i=0; getvars[i].name; i++) {
100 if (strcmp(getvars[i].name, attrname) == 0) {
110 return Py_BuildValue(getvars[i].fmt, jcr->job->hdr.name);
111 case 1: /* Director's name */
112 return Py_BuildValue(getvars[i].fmt, my_name);
114 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
116 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
118 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
120 return Py_BuildValue(getvars[i].fmt, jcr->client->hdr.name);
121 case 6: /* NumVols */
122 return Py_BuildValue(getvars[i].fmt, jcr->NumVols);
124 return Py_BuildValue(getvars[i].fmt, jcr->pool->hdr.name);
125 case 8: /* Storage */
126 return Py_BuildValue(getvars[i].fmt, jcr->store->hdr.name);
128 return Py_BuildValue(getvars[i].fmt, jcr->catalog->hdr.name);
129 case 10: /* MediaType */
130 return Py_BuildValue(getvars[i].fmt, jcr->store->media_type);
131 case 11: /* JobName */
132 return Py_BuildValue(getvars[i].fmt, jcr->Job);
133 case 12: /* JobStatus */
135 buf[0] = jcr->JobStatus;
136 return Py_BuildValue(getvars[i].fmt, buf);
139 bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
141 PyErr_SetString(PyExc_AttributeError, errmsg);
146 /* Set Job variables */
150 int job_setattr(PyObject *self, char *attrname, PyObject *value)
157 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
158 if (value == NULL) { /* Cannot delete variables */
161 jcr = get_jcr_from_PyObject(self);
166 /* Find attribute name in list */
167 for (i=0; setvars[i].name; i++) {
168 if (strcmp(setvars[i].name, attrname) == 0) {
176 /* Get argument value ***FIXME*** handle other formats */
177 if (setvars[i].fmt != NULL) {
178 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
179 PyErr_SetString(PyExc_TypeError, "Read-only attribute");
184 case 0: /* set_events */
185 return set_job_events(self, value);
187 return job_run(self, value);
188 case 2: /* JobReport */
190 Jmsg(jcr, M_INFO, 0, "%s", strval);
192 case 4: /* VolumeName */
193 /* Make sure VolumeName is valid and we are in VolumeName event */
194 if (strcmp("NewVolume", jcr->event) == 0 &&
195 is_volume_name_legal(NULL, strval)) {
196 pm_strcpy(jcr->VolumeName, strval);
197 Dmsg1(100, "Set Vol=%s\n", strval);
200 jcr->VolumeName[0] = 0;
204 PyErr_SetString(PyExc_AttributeError, attrname);
209 static int set_job_events(PyObject *self, PyObject *arg)
214 Dmsg0(100, "In set_job_events.\n");
215 if (!PyArg_Parse(arg, "O", &eObject)) {
218 jcr = get_jcr_from_PyObject(self);
219 Py_XDECREF((PyObject *)jcr->Python_events);
221 jcr->Python_events = (void *)eObject;
222 return 0; /* good return */
225 /* Run a Bacula command */
226 static int job_run(PyObject *self, PyObject *arg)
232 if (!PyArg_Parse(arg, "s", &item)) {
235 jcr = get_jcr_from_PyObject(self);
236 UAContext *ua = new_ua_context(jcr);
238 pm_strcpy(ua->cmd, item); /* copy command */
239 parse_ua_args(ua); /* parse command */
240 stat = run_cmd(ua, ua->cmd);
242 /* ***FIXME*** check stat */
247 int generate_job_event(JCR *jcr, const char *event)
249 PyObject *method = NULL;
250 PyObject *Job = (PyObject *)jcr->Python_job;
251 PyObject *result = NULL;
258 PyEval_AcquireLock();
260 PyObject *events = (PyObject *)jcr->Python_events;
261 method = find_method(events, method, event);
266 bstrncpy(jcr->event, event, sizeof(jcr->event));
267 result = PyObject_CallFunction(method, "O", Job);
268 jcr->event[0] = 0; /* no event in progress */
269 if (result == NULL) {
270 if (PyErr_Occurred()) {
272 Dmsg1(000, "Error in Python method %s\n", event);
280 PyEval_ReleaseLock();
284 bool python_set_prog(JCR*, char const*) { return false; }
288 /* Dummy if Python not configured */
289 int generate_job_event(JCR *jcr, const char *event) { return 1; }
292 #endif /* HAVE_PYTHON */