From: Kern Sibbald Date: Sun, 5 Dec 2004 10:45:31 +0000 (+0000) Subject: Implement run command in Python X-Git-Tag: Release-1.38.0~720 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=0162361e5875bc80b6f90e027c648ab34a9fa457;p=bacula%2Fbacula Implement run command in Python git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1744 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index f5c9362494..96cbe0726f 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -24,7 +24,7 @@ Major Changes: 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 @@ -33,21 +33,28 @@ Major Changes: 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: @@ -58,6 +65,10 @@ def EndJob(j): 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 ==== diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 711c97c99a..af56034169 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -62,7 +62,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp); /* 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); @@ -70,7 +70,7 @@ extern int send_level_command(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); @@ -97,7 +97,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* 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); @@ -149,28 +149,28 @@ JCR *new_control_jcr(const char *base_name, int job_type); 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); @@ -190,3 +190,6 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr); /* 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); diff --git a/bacula/src/dird/python.c b/bacula/src/dird/python.c index d539bd4fa6..dc188d0766 100644 --- a/bacula/src/dird/python.c +++ b/bacula/src/dird/python.c @@ -39,12 +39,14 @@ bool run_module(const char *module); 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 */ }; @@ -151,4 +153,26 @@ PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw) 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 */ diff --git a/bacula/src/dird/ua.h b/bacula/src/dird/ua.h index 82818f9a47..ac3b02dbea 100644 --- a/bacula/src/dird/ua.h +++ b/bacula/src/dird/ua.h @@ -48,6 +48,7 @@ struct UAContext { 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 */ }; diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 57f99e5ac2..09620551ac 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -52,7 +52,6 @@ extern int autodisplay_cmd(UAContext *ua, const char *cmd); 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); diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 69ea42d1fa..d9eed92902 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -73,7 +73,7 @@ int autodisplay_cmd(UAContext *ua, const char *cmd) } /* - * Turn gui processing on/off + * Turn batch processing on/off */ int gui_cmd(UAContext *ua, const char *cmd) { @@ -84,9 +84,11 @@ 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: diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 9f06fd33f7..7f0d5eb8a4 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -38,7 +38,6 @@ /* Imported functions */ -extern int run_cmd(UAContext *ua, const char *cmd); extern void print_bsr(UAContext *ua, RBSR *bsr); /* Imported variables */ diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 52aeff5a55..89c0e200f6 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -42,6 +42,9 @@ extern struct s_kw ReplaceOptions[]; * For Restore Jobs * run jobid=nn * + * Returns: 0 on error + * JobId if OK + * */ int run_cmd(UAContext *ua, const char *cmd) { @@ -116,7 +119,7 @@ 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; @@ -124,7 +127,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 1: /* JobId */ if (jid) { bsendmsg(ua, _("JobId specified twice.\n")); - return 1; + return 0; } jid = ua->argv[i]; kw_ok = true; @@ -133,7 +136,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 3: /* fd */ if (client_name) { bsendmsg(ua, _("Client specified twice.\n")); - return 1; + return 0; } client_name = ua->argv[i]; kw_ok = true; @@ -141,7 +144,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 4: /* fileset */ if (fileset_name) { bsendmsg(ua, _("FileSet specified twice.\n")); - return 1; + return 0; } fileset_name = ua->argv[i]; kw_ok = true; @@ -149,7 +152,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 5: /* level */ if (level_name) { bsendmsg(ua, _("Level specified twice.\n")); - return 1; + return 0; } level_name = ua->argv[i]; kw_ok = true; @@ -158,7 +161,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 7: /* sd */ if (store_name) { bsendmsg(ua, _("Storage specified twice.\n")); - return 1; + return 0; } store_name = ua->argv[i]; kw_ok = true; @@ -166,7 +169,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 8: /* pool */ if (pool_name) { bsendmsg(ua, _("Pool specified twice.\n")); - return 1; + return 0; } pool_name = ua->argv[i]; kw_ok = true; @@ -174,7 +177,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 9: /* where */ if (where) { bsendmsg(ua, _("Where specified twice.\n")); - return 1; + return 0; } where = ua->argv[i]; kw_ok = true; @@ -182,7 +185,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 10: /* bootstrap */ if (bootstrap) { bsendmsg(ua, _("Bootstrap specified twice.\n")); - return 1; + return 0; } bootstrap = ua->argv[i]; kw_ok = true; @@ -190,7 +193,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 11: /* replace */ if (replace) { bsendmsg(ua, _("Replace specified twice.\n")); - return 1; + return 0; } replace = ua->argv[i]; kw_ok = true; @@ -198,7 +201,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 12: /* When */ if (when) { bsendmsg(ua, _("When specified twice.\n")); - return 1; + return 0; } when = ua->argv[i]; kw_ok = true; @@ -206,7 +209,7 @@ int run_cmd(UAContext *ua, const char *cmd) case 13: /* Priority */ if (Priority) { bsendmsg(ua, _("Priority specified twice.\n")); - return 1; + return 0; } Priority = atoi(ua->argv[i]); if (Priority <= 0) { @@ -221,7 +224,7 @@ int run_cmd(UAContext *ua, const char *cmd) 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; @@ -255,7 +258,7 @@ int run_cmd(UAContext *ua, const char *cmd) 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 */ @@ -267,7 +270,7 @@ int run_cmd(UAContext *ua, const char *cmd) catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name); if (catalog == NULL) { bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name); - return 1; + return 0; } } @@ -287,11 +290,11 @@ int run_cmd(UAContext *ua, const char *cmd) 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) { @@ -310,7 +313,7 @@ int run_cmd(UAContext *ua, const char *cmd) } 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) { @@ -325,11 +328,11 @@ int run_cmd(UAContext *ua, const char *cmd) 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) { @@ -344,11 +347,11 @@ int run_cmd(UAContext *ua, const char *cmd) 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) { @@ -361,11 +364,11 @@ int run_cmd(UAContext *ua, const char *cmd) 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) { @@ -460,7 +463,7 @@ try_again: } /* Run without prompting? */ - if (find_arg(ua, _("yes")) > 0) { + if (ua->batch || find_arg(ua, _("yes")) > 0) { goto start_job; } @@ -847,7 +850,7 @@ start_job: } else { bsendmsg(ua, _("Job started. JobId=%u\n"), JobId); } - return 1; + return JobId; } bail_out: diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index c8dd2a7711..4ea140929d 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -693,6 +693,12 @@ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, 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]); diff --git a/bacula/src/version.h b/bacula/src/version.h index a17049247a..7f7d5ebdf9 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #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