Once the Python script gets control, it can have access to Bacula
variables by doing:
- import bacula
+ import bacula
The script is called with one argument, typically called j. This
argument *must* be passed unchanged to each bacula function. The
Bacula variables can be read with:
- bacula.get(j, "Variable-name")
+ bacula.get(j, "Variable-name")
- where j is the argument passed to the function, and Variable-name
- is on of the following:
+ where j is the argument passed to the function, and Variable-name
+ is on of the following:
- JoId, Client, Pool, Storage, Catalog, MediaType, NumVols, DirName,
- Level, Type, Job, JobName, JobStatus
+ JobId, Client, Pool, Storage, Catalog, MediaType, NumVols, DirName,
+ Level, Type, Job, JobName, JobStatus
Bacula varibles can be set using Python keyword arguments:
- bacula.set(jcr=j, VolumeName="xyz")
+ bacula.set(jcr=j, VolumeName="xyz")
- The two currently implemented writable "variables" are:
+ The two currently implemented writable "variables" are:
- VolumeName and JobReport
+ VolumeName and JobReport
+
+ It is possible to submit a Bacula run command with the following:
+
+ bacula.run(j, "run kernsave client=Matou storage=File")
+
+ this function returns the JobId of the job that was started. If
+ there is an error, the return value is zero.
Example:
jobid = bacula.get(j, "JobId")
client = bacula.get(j, "Client")
bacula.set(jcr=j, JobReport="EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+ if (jobid < 5) :
+ startid = bacula.run(j, "run kernsave")
+ print "Python started jobid=", startid
+
return 1
====
/* fd_cmds.c */
extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int send_include_list(JCR *jcr);
extern int send_exclude_list(JCR *jcr);
extern int send_bootstrap_file(JCR *jcr);
extern int get_attributes_and_put_in_catalog(JCR *jcr);
extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
- char *link, char *attr, int stream);
+ char *link, char *attr, int stream);
extern void get_level_since_time(JCR *jcr, char *since, int since_len);
extern int send_run_before_and_after_commands(JCR *jcr);
/* msgchan.c */
extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int start_storage_daemon_job(JCR *jcr);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int bget_dirmsg(BSOCK *bs);
void free_ua_context(UAContext *ua);
/* ua_select.c */
-STORE *select_storage_resource(UAContext *ua);
-JOB *select_job_resource(UAContext *ua);
-JOB *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE *select_storage_resource(UAContext *ua);
+JOB *select_job_resource(UAContext *ua);
+JOB *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
FILESET *select_fileset_resource(UAContext *ua);
-int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void start_prompt(UAContext *ua, const char *msg);
-void add_prompt(UAContext *ua, const char *prompt);
-int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
-CAT *get_catalog_resource(UAContext *ua);
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void start_prompt(UAContext *ua, const char *msg);
+void add_prompt(UAContext *ua, const char *prompt);
+int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
+CAT *get_catalog_resource(UAContext *ua);
STORE *get_storage_resource(UAContext *ua, int use_default);
-int get_media_type(UAContext *ua, char *MediaType, int max_media);
-bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int get_media_type(UAContext *ua, char *MediaType, int max_media);
+bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
POOL *get_pool_resource(UAContext *ua);
POOL *select_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
-int get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
int find_arg_keyword(UAContext *ua, const char **list);
int find_arg(UAContext *ua, const char *keyword);
/* ua_purge.c */
int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr);
+
+/* ua_run.c */
+extern int run_cmd(UAContext *ua, const char *cmd);
PyObject *bacula_get(PyObject *self, PyObject *args);
PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw);
+PyObject *bacula_run(PyObject *self, PyObject *args);
/* 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."},
+ {"run", (PyCFunction)bacula_run, METH_VARARGS, "Run a Bacula command."},
{NULL, NULL, 0, NULL} /* last item */
};
return Py_BuildValue("i", 1);
}
+/* Run a Bacula command */
+PyObject *bacula_run(PyObject *self, PyObject *args)
+{
+ PyObject *CObject;
+ JCR *jcr;
+ char *item;
+ int stat;
+
+ if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) {
+ return NULL;
+ }
+ jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
+ UAContext *ua = new_ua_context(jcr);
+ ua->batch = true;
+ pm_strcpy(ua->cmd, item); /* copy command */
+ parse_ua_args(ua); /* parse command */
+ stat = run_cmd(ua, ua->cmd);
+ free_ua_context(ua);
+ return Py_BuildValue("i", stat);
+}
+
+
#endif /* HAVE_PYTHON */
bool automount; /* if set, mount after label */
bool quit; /* if set, quit */
bool verbose; /* set for normal UA verbosity */
+ bool batch; /* set for non-interactive mode */
uint32_t pint32_val; /* positive integer */
int32_t int32_val; /* positive/negative */
};
extern int gui_cmd(UAContext *ua, const char *cmd);
extern int sqlquerycmd(UAContext *ua, const char *cmd);
extern int querycmd(UAContext *ua, const char *cmd);
-extern int run_cmd(UAContext *ua, const char *cmd);
extern int retentioncmd(UAContext *ua, const char *cmd);
extern int prunecmd(UAContext *ua, const char *cmd);
extern int purgecmd(UAContext *ua, const char *cmd);
}
/*
- * Turn gui processing on/off
+ * Turn batch processing on/off
*/
int gui_cmd(UAContext *ua, const char *cmd)
{
switch (find_arg_keyword(ua, kw)) {
case 0:
+ ua->batch = true;
ua->jcr->gui = true;
break;
case 1:
+ ua->batch = false;
ua->jcr->gui = false;
break;
default:
/* Imported functions */
-extern int run_cmd(UAContext *ua, const char *cmd);
extern void print_bsr(UAContext *ua, RBSR *bsr);
/* Imported variables */
* For Restore Jobs
* run <job-name> jobid=nn
*
+ * Returns: 0 on error
+ * JobId if OK
+ *
*/
int run_cmd(UAContext *ua, const char *cmd)
{
case 0: /* job */
if (job_name) {
bsendmsg(ua, _("Job name specified twice.\n"));
- return 1;
+ return 0;
}
job_name = ua->argv[i];
kw_ok = true;
case 1: /* JobId */
if (jid) {
bsendmsg(ua, _("JobId specified twice.\n"));
- return 1;
+ return 0;
}
jid = ua->argv[i];
kw_ok = true;
case 3: /* fd */
if (client_name) {
bsendmsg(ua, _("Client specified twice.\n"));
- return 1;
+ return 0;
}
client_name = ua->argv[i];
kw_ok = true;
case 4: /* fileset */
if (fileset_name) {
bsendmsg(ua, _("FileSet specified twice.\n"));
- return 1;
+ return 0;
}
fileset_name = ua->argv[i];
kw_ok = true;
case 5: /* level */
if (level_name) {
bsendmsg(ua, _("Level specified twice.\n"));
- return 1;
+ return 0;
}
level_name = ua->argv[i];
kw_ok = true;
case 7: /* sd */
if (store_name) {
bsendmsg(ua, _("Storage specified twice.\n"));
- return 1;
+ return 0;
}
store_name = ua->argv[i];
kw_ok = true;
case 8: /* pool */
if (pool_name) {
bsendmsg(ua, _("Pool specified twice.\n"));
- return 1;
+ return 0;
}
pool_name = ua->argv[i];
kw_ok = true;
case 9: /* where */
if (where) {
bsendmsg(ua, _("Where specified twice.\n"));
- return 1;
+ return 0;
}
where = ua->argv[i];
kw_ok = true;
case 10: /* bootstrap */
if (bootstrap) {
bsendmsg(ua, _("Bootstrap specified twice.\n"));
- return 1;
+ return 0;
}
bootstrap = ua->argv[i];
kw_ok = true;
case 11: /* replace */
if (replace) {
bsendmsg(ua, _("Replace specified twice.\n"));
- return 1;
+ return 0;
}
replace = ua->argv[i];
kw_ok = true;
case 12: /* When */
if (when) {
bsendmsg(ua, _("When specified twice.\n"));
- return 1;
+ return 0;
}
when = ua->argv[i];
kw_ok = true;
case 13: /* Priority */
if (Priority) {
bsendmsg(ua, _("Priority specified twice.\n"));
- return 1;
+ return 0;
}
Priority = atoi(ua->argv[i]);
if (Priority <= 0) {
case 15: /* Verify Job */
if (verify_job_name) {
bsendmsg(ua, _("Verify Job specified twice.\n"));
- return 1;
+ return 0;
}
verify_job_name = ua->argv[i];
kw_ok = true;
Dmsg1(200, "Set jobname=%s\n", job_name);
} else {
bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
- return 1;
+ return 0;
}
}
} /* end argc loop */
catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
if (catalog == NULL) {
bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
- return 1;
+ return 0;
}
}
job = select_job_resource(ua);
}
if (!job) {
- return 1;
+ return 0;
} else if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
bsendmsg(ua, _("No authorization. Job \"%s\".\n"),
job->hdr.name);
- return 1;
+ return 0;
}
if (store_name) {
} else if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
bsendmsg(ua, _("No authorization. Storage \"%s\".\n"),
store->hdr.name);
- return 1;
+ return 0;
}
if (pool_name) {
pool = job->pool; /* use default */
}
if (!pool) {
- return 1;
+ return 0;
} else if (!acl_access_ok(ua, Pool_ACL, store->hdr.name)) {
bsendmsg(ua, _("No authorization. Pool \"%s\".\n"),
pool->hdr.name);
- return 1;
+ return 0;
}
if (client_name) {
client = job->client; /* use default */
}
if (!client) {
- return 1;
+ return 0;
} else if (!acl_access_ok(ua, Client_ACL, store->hdr.name)) {
bsendmsg(ua, _("No authorization. Client \"%s\".\n"),
client->hdr.name);
- return 1;
+ return 0;
}
if (fileset_name) {
fileset = job->fileset; /* use default */
}
if (!fileset) {
- return 1;
+ return 0;
} else if (!acl_access_ok(ua, FileSet_ACL, store->hdr.name)) {
bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"),
fileset->hdr.name);
- return 1;
+ return 0;
}
if (verify_job_name) {
}
/* Run without prompting? */
- if (find_arg(ua, _("yes")) > 0) {
+ if (ua->batch || find_arg(ua, _("yes")) > 0) {
goto start_job;
}
} else {
bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
}
- return 1;
+ return JobId;
}
bail_out:
bsendmsg(ua, _("Automatically selected %s: %s\n"), automsg, ua->prompt[1]);
goto done;
}
+ /* If running non-interactive, bail out */
+ if (ua->batch) {
+ bsendmsg(ua, _("Cannot select %s in batch mode.\n"), automsg);
+ item = -1;
+ goto done;
+ }
bsendmsg(ua, ua->prompt[0]);
for (i=1; i < ua->num_prompts; i++) {
bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
/* */
#undef VERSION
#define VERSION "1.37.1"
-#define BDATE "03 December 2004"
-#define LSMDATE "03Dec04"
+#define BDATE "05 December 2004"
+#define LSMDATE "05Dec04"
/* Debug flags */
#undef DEBUG