From: Kern Sibbald Date: Mon, 29 Nov 2004 11:08:17 +0000 (+0000) Subject: First cut Python support X-Git-Tag: Release-1.38.0~737 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5b6c0dcb6a7aa5e2136fd890562e779892ad459f;p=bacula%2Fbacula First cut Python support git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1727 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index b15a1b8a8f..f80d9e531e 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -516,15 +516,15 @@ AC_ARG_WITH(python, install directory, default is to search through a number of common places for the Python files.], [ - PYTHON_INCDIR=. + PYTHON_INCDIR= PYTHON_LIBS= if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/include/python2.2/Python.h; then - PYTHON_INCDIR=/usr/include/python2.2 + PYTHON_INCDIR=-I/usr/include/python2.2 PYTHON_LIBS="-L/usr/lib/python2.2/config -lpython2.2 -lutil -ldl" elif test -f $prefix/include/Python.h; then - PYTHON_INCDIR=$prefix/include + PYTHON_INCDIR=-I$prefix/include PYTHON_LIBS="-L$prefix/lib/config -lpython -lutil -ldl" else AC_MSG_RESULT(no) @@ -532,10 +532,10 @@ AC_ARG_WITH(python, fi else if test -f $withval/Python.h; then - PYTHON_INCDIR=$withval + PYTHON_INCDIR=-I$withval PYTHON_LIBS="-L$withval/config -lpython -lutil -ldl" elif test -f $withval/include/Python.h; then - PYTHON_INCDIR=$withval/include + PYTHON_INCDIR=-I$withval/include PYTHON_LIBS="-L$withval/lib/config -lpython -lutil -ldl" else AC_MSG_RESULT(no) diff --git a/bacula/configure b/bacula/configure index 99bb88fd91..511162cac9 100755 --- a/bacula/configure +++ b/bacula/configure @@ -6896,15 +6896,15 @@ echo $ECHO_N "checking for Python support... $ECHO_C" >&6 if test "${with_python+set}" = set; then withval="$with_python" - PYTHON_INCDIR=. + PYTHON_INCDIR= PYTHON_LIBS= if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/include/python2.2/Python.h; then - PYTHON_INCDIR=/usr/include/python2.2 + PYTHON_INCDIR=-I/usr/include/python2.2 PYTHON_LIBS="-L/usr/lib/python2.2/config -lpython2.2 -lutil -ldl" elif test -f $prefix/include/Python.h; then - PYTHON_INCDIR=$prefix/include + PYTHON_INCDIR=-I$prefix/include PYTHON_LIBS="-L$prefix/lib/config -lpython -lutil -ldl" else echo "$as_me:$LINENO: result: no" >&5 @@ -6915,10 +6915,10 @@ echo "$as_me: error: Unable to find Python.h in standard locations" >&2;} fi else if test -f $withval/Python.h; then - PYTHON_INCDIR=$withval + PYTHON_INCDIR=-I$withval PYTHON_LIBS="-L$withval/config -lpython -lutil -ldl" elif test -f $withval/include/Python.h; then - PYTHON_INCDIR=$withval/include + PYTHON_INCDIR=-I$withval/include PYTHON_LIBS="-L$withval/lib/config -lpython -lutil -ldl" else echo "$as_me:$LINENO: result: no" >&5 diff --git a/bacula/src/dird/Makefile.in b/bacula/src/dird/Makefile.in index 4374f63c4c..487913c77e 100644 --- a/bacula/src/dird/Makefile.in +++ b/bacula/src/dird/Makefile.in @@ -19,6 +19,7 @@ thisdir = src/dird DEBUG=@DEBUG@ PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_INC = @PYTHON_INCDIR@ first_rule: all dummy: @@ -30,6 +31,7 @@ SVRSRCS = dird.c admin.c authenticate.c \ fd_cmds.c getmsg.c inc_conf.c job.c \ jobq.c mac.c \ mountreq.c msgchan.c next_vol.c newvol.c \ + python.c \ recycle.c restore.c run_conf.c \ scheduler.c sql_cmds.c \ ua_acl.c ua_cmds.c ua_dotcmds.c \ @@ -44,6 +46,7 @@ SVROBJS = dird.o admin.o authenticate.o \ fd_cmds.o getmsg.o inc_conf.o job.o \ jobq.o mac.o \ mountreq.o msgchan.o next_vol.o newvol.o \ + python.o \ recycle.o restore.o run_conf.o \ scheduler.o sql_cmds.o \ ua_acl.o ua_cmds.o ua_dotcmds.o \ @@ -62,7 +65,7 @@ EXTRAOBJS = @OBJLIST@ # inference rules .c.o: - $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< #------------------------------------------------------------------------- all: Makefile bacula-dir @STATIC_DIR@ @echo "==== Make of dird is good ====" @@ -134,7 +137,7 @@ depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile - @$(CXX) -S -M $(CPPFLAGS) $(XINC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile + @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index c032ade304..b5a4647b00 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -223,7 +223,7 @@ int main (int argc, char *argv[]) init_console_msg(working_directory); - init_python_interpreter(director->hdr.name); + init_python_interpreter(director->hdr.name, "."); set_thread_concurrency(director->MaxConcurrentJobs * 2 + 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */); diff --git a/bacula/src/dird/python.c b/bacula/src/dird/python.c new file mode 100644 index 0000000000..1c8488059e --- /dev/null +++ b/bacula/src/dird/python.c @@ -0,0 +1,113 @@ +/* + * + * Bacula interface to Python for the Director + * + * Kern Sibbald, November MMIV + * + * Version $Id$ + * + */ + +/* + + Copyright (C) 2004 Kern Sibbald + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + */ + +#include "bacula.h" +#include "dird.h" + +#ifdef HAVE_PYTHON +#include + +bool run_module(const char *module); + +PyObject *bacula_get(PyObject *self, PyObject *args); +PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); + +/* Define Bacula entry points */ +PyMethodDef BaculaMethods[] = { + {"get", bacula_get, METH_VARARGS, "Get Bacula variables."}, + {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS, + "Set Bacula variables."}, + {NULL, NULL, 0, NULL} /* last item */ +}; + + +/* Return Bacula variables */ +PyObject *bacula_get(PyObject *self, PyObject *args) +{ + PyObject *CObject; + JCR *jcr; + char *item; + if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) { + return NULL; + } + jcr = (JCR *)PyCObject_AsVoidPtr(CObject); + /* ***FIXME*** put this in a table */ + if (strcmp(item, "JobId") == 0) { + return Py_BuildValue("i", jcr->JobId); + } else if (strcmp(item, "Client") == 0) { + return Py_BuildValue("s", jcr->client->hdr.name); + } else if (strcmp(item, "Pool") == 0) { + return Py_BuildValue("s", jcr->pool->hdr.name); + } else if (strcmp(item, "Storage") == 0) { + return Py_BuildValue("s", jcr->store->hdr.name); + } else if (strcmp(item, "Catalog") == 0) { + return Py_BuildValue("s", jcr->catalog->hdr.name); + } else if (strcmp(item, "MediaType") == 0) { + return Py_BuildValue("s", jcr->store->media_type); + } else if (strcmp(item, "NumVols") == 0) { + return Py_BuildValue("i", jcr->NumVols); + } else if (strcmp(item, "DirName") == 0) { + return Py_BuildValue("s", my_name); + } else if (strcmp(item, "Level") == 0) { + return Py_BuildValue("s", job_level_to_str(jcr->JobLevel)); + } else if (strcmp(item, "Type") == 0) { + return Py_BuildValue("s", job_type_to_str(jcr->JobType)); + } else if (strcmp(item, "Job") == 0) { + return Py_BuildValue("s", jcr->job->hdr.name); + } else if (strcmp(item, "JobName") == 0) { + return Py_BuildValue("s", jcr->Job); + } + return NULL; +} + +/* Set Bacula variables */ +PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) +{ + PyObject *CObject; + JCR *jcr; + char *msg = NULL; + char *VolumeName = NULL; + static char *kwlist[] = {"jcr", "JobReport", "VolumeName", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keyw, "O|ss:set", kwlist, + &CObject, &msg, &VolumeName)) { + return NULL; + } + jcr = (JCR *)PyCObject_AsVoidPtr(CObject); + if (msg) { + Jmsg(jcr, M_INFO, 0, "%s", msg); + } + if (VolumeName) { + pm_strcpy(jcr->VolumeName, VolumeName); + } + return Py_BuildValue("i", 1); +} + +#endif /* HAVE_PYTHON */ diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index 3a43fe3a49..fa6349e9bb 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -101,7 +101,7 @@ Makefile: $(srcdir)/Makefile.in $(topdir)/config.status && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status python.o: python.c - $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(python) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< + $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(python) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< rwlock_test: rm -f rwlock.o @@ -149,7 +149,7 @@ depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile - @$(CXX) -S -M $(CPPFLAGS) $(XINC) -I$(python) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile + @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(python) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index d859f48c24..356500f665 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -174,7 +174,8 @@ char *getgroup (gid_t gid); void free_getgroup_cache(); /* python.c */ -void init_python_interpreter(char *progname); +void init_python_interpreter(char *progname, char *scripts); +void term_python_interpreter(); int generate_event(JCR *jcr, const char *event); /* signal.c */ diff --git a/bacula/src/lib/python.c b/bacula/src/lib/python.c index aea7ff571a..2a14bfd8d9 100644 --- a/bacula/src/lib/python.c +++ b/bacula/src/lib/python.c @@ -1,9 +1,14 @@ /* - - Bacula interface to Python - - Kern Sibbald, November MMIV + * + * Bacula common code library interface to Python + * + * Kern Sibbald, November MMIV + * + * Version $Id$ + * + */ +/* Copyright (C) 2004 Kern Sibbald This program is free software; you can redistribute it and/or @@ -24,101 +29,29 @@ */ #include "bacula.h" -#include "../dird/dird_conf.h" -#define DIRECTOR_DAEMON 1 -#include "../cats/cats.h" -#include "jcr.h" - #ifdef HAVE_PYTHON #include -bool run_module(const char *module); - -static PyObject *bacula_get(PyObject *self, PyObject *args); -static PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); - -/* Define Bacula entry points */ -static PyMethodDef BaculaMethods[] = { - {"get", bacula_get, METH_VARARGS, "Get Bacula variables."}, - {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS, - "Set Bacula variables."}, - {NULL, NULL, 0, NULL} /* last item */ -}; +PyObject *bacula_get(PyObject *self, PyObject *args); +PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw); -/* Return Bacula variables */ -static PyObject* -bacula_get(PyObject *self, PyObject *args) -{ - PyObject *CObject; - JCR *jcr; - char *item; - if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) { - return NULL; - } - jcr = (JCR *)PyCObject_AsVoidPtr(CObject); - /* ***FIXME*** put this in a table */ - if (strcmp(item, "JobId") == 0) { - return Py_BuildValue("i", jcr->JobId); - } else if (strcmp(item, "Client") == 0) { - return Py_BuildValue("s", jcr->client->hdr.name); - } else if (strcmp(item, "Pool") == 0) { - return Py_BuildValue("s", jcr->pool->hdr.name); - } else if (strcmp(item, "Storage") == 0) { - return Py_BuildValue("s", jcr->store->hdr.name); - } else if (strcmp(item, "Catalog") == 0) { - return Py_BuildValue("s", jcr->catalog->hdr.name); - } else if (strcmp(item, "MediaType") == 0) { - return Py_BuildValue("s", jcr->store->media_type); - } else if (strcmp(item, "NumVols") == 0) { - return Py_BuildValue("i", jcr->NumVols); - } else if (strcmp(item, "DirName") == 0) { - return Py_BuildValue("s", my_name); - } else if (strcmp(item, "Level") == 0) { - return Py_BuildValue("s", job_level_to_str(jcr->JobLevel)); - } else if (strcmp(item, "Type") == 0) { - return Py_BuildValue("s", job_type_to_str(jcr->JobType)); - } else if (strcmp(item, "Job") == 0) { - return Py_BuildValue("s", jcr->job->hdr.name); - } else if (strcmp(item, "JobName") == 0) { - return Py_BuildValue("s", jcr->Job); - } - return NULL; -} - -/* Set Bacula variables */ -static PyObject* -bacula_set(PyObject *self, PyObject *args, PyObject *keyw) -{ - PyObject *CObject; - JCR *jcr; - char *msg = NULL; - char *VolumeName = NULL; - static char *kwlist[] = {"jcr", "JobReport", "VolumeName", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keyw, "O|ss:set", kwlist, - &CObject, &msg, &VolumeName)) { - return NULL; - } - jcr = (JCR *)PyCObject_AsVoidPtr(CObject); - if (msg) { - Jmsg(jcr, M_INFO, 0, "%s", msg); - } - if (VolumeName) { - pm_strcpy(jcr->VolumeName, VolumeName); - } - return Py_BuildValue("i", 1); -} +/* Pull in Bacula entry points */ +extern PyMethodDef BaculaMethods[]; -void init_python_interpreter(char *progname) +/* Start the interpreter */ +void init_python_interpreter(char *progname, char *scripts) { + char buf[MAXSTRING]; Py_SetProgramName(progname); Py_Initialize(); PyEval_InitThreads(); Py_InitModule("bacula", BaculaMethods); - PyRun_SimpleString("import sys\n" - "sys.path.append('.')\n"); + bsnprintf(buf, sizeof(buf), "import sys\n" + "sys.path.append('%s')\n", scripts); + PyRun_SimpleString(buf); PyEval_ReleaseLock(); } @@ -177,12 +110,17 @@ int generate_event(JCR *jcr, const char *event) Py_DECREF(pValue); } else { Py_DECREF(pModule); - PyErr_Print(); - Jmsg(jcr, M_ERROR, 0, "Error running Python module: %s\n", event); + if (PyErr_Occurred()) { + PyErr_Print(); + Jmsg(jcr, M_ERROR, 0, "Error running Python module: %s\n", event); + } return 0; /* error running function */ } /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */ } else { + if (PyErr_Occurred()) { + PyErr_Print(); + } Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found in module.\n", event); return -1; /* function not found */ }