From a01a64c3826ba3b677c0f5210c686fd5b23eeb08 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Mon, 31 Dec 2007 19:07:15 +0000 Subject: [PATCH] ebl First patch that pass regress scripts git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6170 91ce42f0-d328-0410-95d8-f526ca767f89 --- .../runscript_with_multiple_command.patch | 483 ++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 bacula/patches/testing/runscript_with_multiple_command.patch diff --git a/bacula/patches/testing/runscript_with_multiple_command.patch b/bacula/patches/testing/runscript_with_multiple_command.patch new file mode 100644 index 0000000000..98eea8231d --- /dev/null +++ b/bacula/patches/testing/runscript_with_multiple_command.patch @@ -0,0 +1,483 @@ +Index: src/dird/fd_cmds.c +=================================================================== +--- src/dird/fd_cmds.c (révision 6169) ++++ src/dird/fd_cmds.c (copie de travail) +@@ -537,29 +537,35 @@ + Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost); + + if (strcmp(ehost, jcr->client->name()) == 0) { +- pm_strcpy(msg, cmd->command); +- bash_spaces(msg); ++ char *c; ++ char *command, cmd_type; ++ foreach_alist(c, cmd->commands) { ++ cmd->get_command(c, &cmd_type, &command); ++ if (cmd_type == SHELL_CMD) { ++ pm_strcpy(msg, command); ++ bash_spaces(msg); + +- Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command); ++ Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command); + +- /* TODO: remove this with bacula 1.42 */ +- if (cmd->old_proto) { +- result = send_runscript_with_old_proto(jcr, cmd->when, msg); ++ /* TODO: remove this with bacula 1.42 */ ++ if (cmd->old_proto) { ++ result = send_runscript_with_old_proto(jcr, cmd->when, msg); ++ ++ } else { ++ fd->fsend(runscript, cmd->on_success, ++ cmd->on_failure, ++ cmd->fail_on_error, ++ cmd->when, ++ msg); + +- } else { +- fd->fsend(runscript, cmd->on_success, +- cmd->on_failure, +- cmd->fail_on_error, +- cmd->when, +- msg); +- +- result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR); +- launch_before_cmd = true; ++ result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR); ++ launch_before_cmd = true; ++ } ++ if (!result) { ++ goto bail_out; ++ } ++ } + } +- +- if (!result) { +- goto bail_out; +- } + } + /* TODO : we have to play with other client */ + /* +@@ -567,7 +573,7 @@ + send command to an other client + } + */ +- } ++ } + } + + /* Tell the FD to execute the ClientRunBeforeJob */ +Index: src/dird/dird_conf.c +=================================================================== +--- src/dird/dird_conf.c (révision 6169) ++++ src/dird/dird_conf.c (copie de travail) +@@ -651,16 +651,19 @@ + } + } + if (res->res_job.RunScripts) { +- RUNSCRIPT *script; +- foreach_alist(script, res->res_job.RunScripts) { +- sendit(sock, _(" --> RunScript\n")); +- sendit(sock, _(" --> Command=%s\n"), NPRT(script->command)); +- sendit(sock, _(" --> Target=%s\n"), NPRT(script->target)); +- sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success); +- sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure); +- sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error); +- sendit(sock, _(" --> RunWhen=%u\n"), script->when); +- } ++ char *c; ++ RUNSCRIPT *script; ++ foreach_alist(script, res->res_job.RunScripts) { ++ sendit(sock, _(" --> RunScript\n")); ++ foreach_alist(c, script->commands) { ++ sendit(sock, _(" --> Command=%s\n"), NPRT(c)); ++ } ++ sendit(sock, _(" --> Target=%s\n"), NPRT(script->target)); ++ sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success); ++ sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure); ++ sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error); ++ sendit(sock, _(" --> RunWhen=%u\n"), script->when); ++ } + } + if (res->res_job.pool) { + sendit(sock, _(" --> ")); +@@ -1724,14 +1727,14 @@ + } + + /* +- * Store a runscript->command as a string ++ * Store a runscript->commands as a alist(char + string) + */ + static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass) + { + lex_get_token(lc, T_STRING); + + if (pass == 2) { +- ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code); ++ ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code); + } + scan_to_eol(lc); + } +@@ -1745,7 +1748,7 @@ + RUNSCRIPT *script = new_runscript(); + script->set_job_code_callback(job_code_callback_filesetname); + +- script->set_command(lc->str); ++ script->add_command(lc->str); + + /* TODO: remove all script->old_proto with bacula 1.42 */ + +@@ -1873,7 +1876,7 @@ + } + + if (pass == 2) { +- if (res_runscript.command == NULL) { ++ if (res_runscript.commands == NULL) { + scan_err2(lc, _("%s item is required in %s resource, but not found.\n"), + "command", "runscript"); + } +@@ -1883,10 +1886,11 @@ + res_runscript.set_target("%c"); + } + +- RUNSCRIPT *script = new_runscript(); +- memcpy(script, &res_runscript, sizeof(RUNSCRIPT)); ++ RUNSCRIPT *script = copy_runscript(&res_runscript); ++ res_runscript.reset_default(true); ++ + script->set_job_code_callback(job_code_callback_filesetname); +- ++ + if (*runscripts == NULL) { + *runscripts = New(alist(10, not_owned_by_alist)); + } +Index: src/filed/job.c +=================================================================== +--- src/filed/job.c (révision 6169) ++++ src/filed/job.c (copie de travail) +@@ -481,7 +481,7 @@ + + /* Run the command now */ + script = new_runscript(); +- script->set_command(cmd); ++ script->add_command(cmd); + script->when = SCRIPT_Before; + ok = script->run(jcr, "ClientRunBeforeJob"); + free_runscript(script); +@@ -529,7 +529,7 @@ + unbash_spaces(msg); + + cmd = new_runscript(); +- cmd->set_command(msg); ++ cmd->add_command(msg); + cmd->on_success = true; + cmd->on_failure = false; + cmd->when = SCRIPT_After; +@@ -567,7 +567,7 @@ + cmd->fail_on_error = fail_on_error; + unbash_spaces(msg); + +- cmd->set_command(msg); ++ cmd->add_command(msg); + cmd->debug(); + jcr->RunScripts->append(cmd); + +Index: src/lib/runscript.h +=================================================================== +--- src/lib/runscript.h (révision 6169) ++++ src/lib/runscript.h (copie de travail) +@@ -62,8 +62,8 @@ + }; + + enum { +- SHELL_CMD = 1, +- CONSOLE_CMD = 2 ++ SHELL_CMD = '|', ++ CONSOLE_CMD = '@' + }; + + /* +@@ -71,10 +71,9 @@ + */ + class RUNSCRIPT { + public: +- POOLMEM *command; /* command string */ ++ alist *commands; /* list of command/console string */ + POOLMEM *target; /* host target */ + int when; /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/ +- int cmd_type; /* Command type -- Shell, Console */ + char level; /* Base|Full|Incr...|All (NYI) */ + bool on_success; /* execute command on job success (After) */ + bool on_failure; /* execute command on job failure (After) */ +@@ -85,8 +84,10 @@ + /* Optional callback function passed to edit_job_code */ + + bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */ ++ bool run_command(const char *cmd, JCR *job, const char *name=""); + bool can_run_at_level(int JobLevel) { return true;}; /* TODO */ +- void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD); ++ void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD); ++ void get_command(const char *cmd, char *cmd_type, char **cmd); + void set_target(const POOLMEM *client_name); + void reset_default(bool free_string = false); + bool is_local(); /* true if running on local host */ +Index: src/lib/runscript.c +=================================================================== +--- src/lib/runscript.c (révision 6169) ++++ src/lib/runscript.c (copie de travail) +@@ -59,15 +59,20 @@ + + void RUNSCRIPT::reset_default(bool free_strings) + { +- if (free_strings && command) { +- free_pool_memory(command); ++ char *c; ++ if (free_strings && commands) { ++ foreach_alist(c, commands) { ++ free_pool_memory(c); ++ } + } + if (free_strings && target) { + free_pool_memory(target); + } +- + target = NULL; +- command = NULL; ++ if (commands) { ++ delete commands; ++ commands = NULL; ++ } + on_success = true; + on_failure = false; + fail_on_error = true; +@@ -76,17 +81,23 @@ + job_code_callback = NULL; + } + +-RUNSCRIPT *copy_runscript(RUNSCRIPT *src) ++Runscript *copy_runscript(RUNSCRIPT *src) + { + Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n"); + + RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT)); + memcpy(dst, src, sizeof(RUNSCRIPT)); + +- dst->command = NULL; ++ dst->commands = New(alist(5, not_owned_by_alist)); ++ char *c; ++ POOLMEM *m; ++ foreach_alist(c, src->commands) { ++ m = get_pool_memory(PM_FNAME); ++ pm_strcpy(m, c); ++ dst->commands->append(m); ++ } ++ + dst->target = NULL; +- +- dst->set_command(src->command, src->cmd_type); + dst->set_target(src->target); + + return dst; +@@ -95,9 +106,12 @@ + void free_runscript(RUNSCRIPT *script) + { + Dmsg0(500, "runscript: freeing RUNSCRIPT object\n"); +- +- if (script->command) { +- free_pool_memory(script->command); ++ POOLMEM *c; ++ if (script->commands) { ++ foreach_alist(c, script->commands) { ++ free_pool_memory(c); ++ } ++ delete script->commands; + } + if (script->target) { + free_pool_memory(script->target); +@@ -108,60 +122,15 @@ + int run_scripts(JCR *jcr, alist *runscripts, const char *label) + { + Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus); +- +- RUNSCRIPT *script; +- bool runit; + +- int when; +- +- if (strstr(label, NT_("Before"))) { +- when = SCRIPT_Before; +- } else { +- when = SCRIPT_After; +- } +- + if (runscripts == NULL) { + Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n"); + return 0; + } +- ++ ++ RUNSCRIPT *script; + foreach_alist(script, runscripts) { +- Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command)); +- runit = false; +- +- if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) { +- if ((script->on_success +- && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created)) +- || (script->on_failure && job_canceled(jcr)) +- ) +- { +- Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", +- script->command, script->on_success, script->on_failure, +- jcr->JobStatus ); +- runit = true; +- } +- } +- +- if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) { +- if ((script->on_success && (jcr->JobStatus == JS_Terminated)) +- || (script->on_failure && job_canceled(jcr)) +- ) +- { +- Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", +- script->command, script->on_success, script->on_failure, +- jcr->JobStatus ); +- runit = true; +- } +- } +- +- if (!script->is_local()) { +- runit = false; +- } +- +- /* we execute it */ +- if (runit) { +- script->run(jcr, label); +- } ++ script->run(jcr, label); + } + return 1; + } +@@ -176,7 +145,7 @@ + } + + /* set this->command to cmd */ +-void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type) ++void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type) + { + Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd)); + +@@ -184,14 +153,21 @@ + return; + } + +- if (!command) { +- command = get_pool_memory(PM_FNAME); ++ if (!commands) { ++ commands = New(alist(5, not_owned_by_alist)); + } + +- pm_strcpy(command, cmd); +- cmd_type = acmd_type; ++ POOLMEM *c = get_pool_memory(PM_FNAME); ++ Mmsg(c, "%c%s", acmd_type, cmd); ++ commands->append(c); + } + ++void RUNSCRIPT::get_command(const char* command, char *acmd_type, char **cmd) ++{ ++ *acmd_type = command[0]; ++ *cmd = (char *)command + 1; ++} ++ + /* set this->target to client_name */ + void RUNSCRIPT::set_target(const POOLMEM *client_name) + { +@@ -210,14 +186,71 @@ + + bool RUNSCRIPT::run(JCR *jcr, const char *name) + { +- Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type); ++ char *c; ++ bool runit; ++ ++ int when; ++ ++ if (strstr(name, NT_("Before"))) { ++ when = SCRIPT_Before; ++ } else { ++ when = SCRIPT_After; ++ } ++ ++ foreach_alist(c, this->commands) { ++ Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c)); ++ runit = false; ++ ++ if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) { ++ if ((this->on_success ++ && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created)) ++ || (this->on_failure && job_canceled(jcr)) ++ ) ++ { ++ Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", ++ c, this->on_success, this->on_failure, ++ jcr->JobStatus ); ++ runit = true; ++ } ++ } ++ ++ if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) { ++ if ((this->on_success && (jcr->JobStatus == JS_Terminated)) ++ || (this->on_failure && job_canceled(jcr)) ++ ) ++ { ++ Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", ++ c, this->on_success, this->on_failure, ++ jcr->JobStatus ); ++ runit = true; ++ } ++ } ++ ++ if (!this->is_local()) { ++ runit = false; ++ } ++ ++ /* we execute it */ ++ if (runit) { ++ this->run_command(c, jcr, name); ++ } ++ } ++ return 1; ++} ++ ++bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name) ++{ + POOLMEM *ecmd = get_pool_memory(PM_FNAME); + int status; + BPIPE *bpipe; + char line[MAXSTRING]; ++ char cmd_type; ++ char *cmd; + +- ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback); +- Dmsg1(100, "runscript: running '%s'...\n", ecmd); ++ this->get_command(command, &cmd_type, &cmd); ++ ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback); ++ ++ Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type); + Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), + cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd); + +@@ -278,9 +311,12 @@ + + void RUNSCRIPT::debug() + { ++ char *c; + Dmsg0(200, "runscript: debug\n"); + Dmsg0(200, _(" --> RunScript\n")); +- Dmsg1(200, _(" --> Command=%s\n"), NPRT(command)); ++ foreach_alist(c, commands) { ++ Dmsg1(200, _(" --> Command=%s\n"), NPRT(c)); ++ } + Dmsg1(200, _(" --> Target=%s\n"), NPRT(target)); + Dmsg1(200, _(" --> RunOnSuccess=%u\n"), on_success); + Dmsg1(200, _(" --> RunOnFailure=%u\n"), on_failure); -- 2.39.5