From 6bcde0ad221e28a1dd652e6542d6031812463ea8 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Thu, 3 Jan 2008 22:24:35 +0000 Subject: [PATCH] ebl New implementation for runscript with multiple command/console git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6193 91ce42f0-d328-0410-95d8-f526ca767f89 --- .../runscript_with_multiple_command.patch | 987 ------------------ .../runscript_with_multiple_command_v2.patch | 88 ++ 2 files changed, 88 insertions(+), 987 deletions(-) create mode 100644 bacula/patches/testing/runscript_with_multiple_command_v2.patch diff --git a/bacula/patches/testing/runscript_with_multiple_command.patch b/bacula/patches/testing/runscript_with_multiple_command.patch index 1d9251afc5..0b7e915d6b 100644 --- a/bacula/patches/testing/runscript_with_multiple_command.patch +++ b/bacula/patches/testing/runscript_with_multiple_command.patch @@ -1,990 +1,3 @@ -Index: patches/testing/runscript_with_multiple_command.patch -=================================================================== ---- patches/testing/runscript_with_multiple_command.patch (révision 6171) -+++ patches/testing/runscript_with_multiple_command.patch (copie de travail) -@@ -1,982 +0,0 @@ --Index: patches/testing/runscript_with_multiple_command.patch --=================================================================== ----- patches/testing/runscript_with_multiple_command.patch (révision 6170) --+++ patches/testing/runscript_with_multiple_command.patch (copie de travail) --@@ -1,483 +0,0 @@ ---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); --Index: src/dird/fd_cmds.c --=================================================================== ----- src/dird/fd_cmds.c (révision 6169) --+++ src/dird/fd_cmds.c (copie de travail) --@@ -527,7 +527,8 @@ -- RUNSCRIPT *cmd; -- bool launch_before_cmd = false; -- POOLMEM *ehost = get_pool_memory(PM_FNAME); --- int result; --+ int result, cmd_type; --+ char *c, *command; -- -- Dmsg0(120, "bdird: sending runscripts to fd\n"); -- --@@ -537,29 +538,33 @@ -- 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); --+ 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 +572,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"); -- } --@@ -1886,7 +1889,7 @@ -- RUNSCRIPT *script = new_runscript(); -- memcpy(script, &res_runscript, sizeof(RUNSCRIPT)); -- 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) */ --@@ -86,19 +85,22 @@ -- -- bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */ -- 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, int *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 */ -- void debug(); --+ void set_job_code_callback(job_code_callback_t job_code_callback); -- --- void set_job_code_callback(job_code_callback_t job_code_callback); --+private: --+ bool run_command(const char *cmd, JCR *job, const char *name=""); -- }; -- -- /* create new RUNSCRIPT (set all value to 0) */ -- RUNSCRIPT *new_runscript(); -- ---/* create new RUNSCRIPT from an other */ --+/* create new RUNSCRIPT from an other (deep copy) */ -- RUNSCRIPT *copy_runscript(RUNSCRIPT *src); -- -- /* launch each script from runscripts*/ --Index: src/lib/runscript.c --=================================================================== ----- src/lib/runscript.c (révision 6169) --+++ src/lib/runscript.c (copie de travail) --@@ -59,15 +59,18 @@ -- -- 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); --+ } --+ delete commands; -- } -- if (free_strings && target) { -- free_pool_memory(target); -- } --- -- target = NULL; --- command = NULL; --+ commands = NULL; -- on_success = true; -- on_failure = false; -- fail_on_error = true; --@@ -83,10 +86,16 @@ -- 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 +104,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 +120,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; -- } --@@ -175,23 +142,31 @@ -- } -- } -- ---/* set this->command to cmd */ ---void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type) --+/* set add cmd to this->commands alist */ --+void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type) -- { --- Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd)); --+ Dmsg2(500, "runscript: setting command = %s type=%i\n", NPRT(cmd), acmd_type); -- -- if (!cmd) { -- 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); -- } -- --+/* command = ( SHELL_CMD | CONSOLE_CMD ) command */ --+void RUNSCRIPT::get_command(const char* command, int *acmd_type, char **cmd) --+{ --+ *acmd_type = (int) command[0]; --+ *cmd = (char *)command + 1; --+} --+ -- /* set this->target to client_name */ -- void RUNSCRIPT::set_target(const POOLMEM *client_name) -- { --@@ -210,14 +185,70 @@ -- -- 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; --+} --+ --+/* run a command from the list */ --+bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name) --+{ -- POOLMEM *ecmd = get_pool_memory(PM_FNAME); --- int status; --+ int status, cmd_type; -- BPIPE *bpipe; --- char line[MAXSTRING]; --+ char line[MAXSTRING], *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 +309,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); Index: src/dird/fd_cmds.c =================================================================== --- src/dird/fd_cmds.c (révision 6169) diff --git a/bacula/patches/testing/runscript_with_multiple_command_v2.patch b/bacula/patches/testing/runscript_with_multiple_command_v2.patch new file mode 100644 index 0000000000..0c5fc63001 --- /dev/null +++ b/bacula/patches/testing/runscript_with_multiple_command_v2.patch @@ -0,0 +1,88 @@ +Index: src/dird/dird_conf.c +=================================================================== +--- src/dird/dird_conf.c (révision 6192) ++++ src/dird/dird_conf.c (copie de travail) +@@ -1678,6 +1678,8 @@ + + /* We build RunScripts items here */ + static RUNSCRIPT res_runscript; ++static alist *res_runscript_cmd; ++static alist *res_runscript_type; + + /* Store a runscript->when in a bit field */ + static void store_runscript_when(LEX *lc, RES_ITEM *item, int index, int pass) +@@ -1731,7 +1733,10 @@ + lex_get_token(lc, T_STRING); + + if (pass == 2) { +- ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code); ++ POOLMEM *c = get_pool_memory(PM_FNAME); ++ pm_strcpy(c, lc->str); ++ res_runscript_cmd->prepend(c); ++ res_runscript_type->prepend((void*) item->code); + } + scan_to_eol(lc); + } +@@ -1833,7 +1838,8 @@ + */ + static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass) + { +- int token, i; ++ char *c; ++ int token, i, t; + alist **runscripts = (alist **)(item->value) ; + + Dmsg1(200, "store_runscript: begin store_runscript pass=%i\n", pass); +@@ -1846,6 +1852,11 @@ + scan_err1(lc, _("Expecting open brace. Got %s"), lc->str); + } + ++ if (pass == 2) { ++ res_runscript_cmd = New(alist(10, not_owned_by_alist)); ++ res_runscript_type = New(alist(10, not_owned_by_alist)); ++ } ++ + while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) { + if (token == T_EOB) { + break; +@@ -1873,26 +1884,26 @@ + } + + if (pass == 2) { +- if (res_runscript.command == NULL) { +- scan_err2(lc, _("%s item is required in %s resource, but not found.\n"), +- "command", "runscript"); +- } +- + /* run on client by default */ + if (res_runscript.target == NULL) { + res_runscript.set_target("%c"); + } +- +- RUNSCRIPT *script = new_runscript(); +- memcpy(script, &res_runscript, sizeof(RUNSCRIPT)); +- script->set_job_code_callback(job_code_callback_filesetname); +- + if (*runscripts == NULL) { +- *runscripts = New(alist(10, not_owned_by_alist)); ++ *runscripts = New(alist(10, not_owned_by_alist)); + } +- +- (*runscripts)->append(script); +- script->debug(); ++ while ((c=(char*)res_runscript_cmd->pop()) != NULL) { ++ t = (int) res_runscript_type->pop(); ++ RUNSCRIPT *script = new_runscript(); ++ memcpy(script, &res_runscript, sizeof(RUNSCRIPT)); ++ script->set_job_code_callback(job_code_callback_filesetname); ++ script->command = c; ++ script->cmd_type = t; ++ ++ (*runscripts)->append(script); ++ script->debug(); ++ } ++ delete res_runscript_type; ++ delete res_runscript_cmd; + } + + scan_to_eol(lc); -- 2.39.5