]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/runscript_with_multiple_command.patch
ebl First patch that pass regress scripts
[bacula/bacula] / bacula / patches / testing / runscript_with_multiple_command.patch
1 Index: src/dird/fd_cmds.c
2 ===================================================================
3 --- src/dird/fd_cmds.c  (révision 6169)
4 +++ src/dird/fd_cmds.c  (copie de travail)
5 @@ -537,29 +537,35 @@
6           Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
7  
8           if (strcmp(ehost, jcr->client->name()) == 0) {
9 -            pm_strcpy(msg, cmd->command);
10 -            bash_spaces(msg);
11 +            char *c;
12 +            char *command, cmd_type;
13 +            foreach_alist(c, cmd->commands) {
14 +               cmd->get_command(c, &cmd_type, &command);
15 +               if (cmd_type == SHELL_CMD) {
16 +                  pm_strcpy(msg, command);
17 +                  bash_spaces(msg);
18  
19 -            Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
20 +                  Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
21              
22 -            /* TODO: remove this with bacula 1.42 */
23 -            if (cmd->old_proto) {
24 -               result = send_runscript_with_old_proto(jcr, cmd->when, msg);
25 +                  /* TODO: remove this with bacula 1.42 */
26 +                  if (cmd->old_proto) {
27 +                     result = send_runscript_with_old_proto(jcr, cmd->when, msg);
28 +                     
29 +                  } else {
30 +                     fd->fsend(runscript, cmd->on_success, 
31 +                                          cmd->on_failure,
32 +                                          cmd->fail_on_error,
33 +                                          cmd->when,
34 +                                          msg);
35  
36 -            } else {
37 -               fd->fsend(runscript, cmd->on_success, 
38 -                                    cmd->on_failure,
39 -                                    cmd->fail_on_error,
40 -                                    cmd->when,
41 -                                    msg);
42 -
43 -               result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
44 -               launch_before_cmd = true;
45 +                     result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
46 +                     launch_before_cmd = true;
47 +                  }
48 +                  if (!result) {
49 +                     goto bail_out;
50 +                  }
51 +               }
52              }
53 -            
54 -            if (!result) {
55 -               goto bail_out;
56 -            }
57           }
58           /* TODO : we have to play with other client */
59           /*
60 @@ -567,7 +573,7 @@
61             send command to an other client
62             }
63           */
64 -      }        
65 +      }
66     } 
67  
68     /* Tell the FD to execute the ClientRunBeforeJob */
69 Index: src/dird/dird_conf.c
70 ===================================================================
71 --- src/dird/dird_conf.c        (révision 6169)
72 +++ src/dird/dird_conf.c        (copie de travail)
73 @@ -651,16 +651,19 @@
74           }
75        }
76        if (res->res_job.RunScripts) {
77 -        RUNSCRIPT *script;
78 -        foreach_alist(script, res->res_job.RunScripts) {
79 -           sendit(sock, _(" --> RunScript\n"));
80 -           sendit(sock, _("  --> Command=%s\n"), NPRT(script->command));
81 -           sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
82 -           sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
83 -           sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
84 -           sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
85 -           sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
86 -        }
87 +         char *c;
88 +         RUNSCRIPT *script;
89 +         foreach_alist(script, res->res_job.RunScripts) {
90 +            sendit(sock, _(" --> RunScript\n"));
91 +            foreach_alist(c, script->commands) {
92 +               sendit(sock, _("  --> Command=%s\n"), NPRT(c));
93 +            }
94 +            sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
95 +            sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
96 +            sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
97 +            sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
98 +            sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
99 +         }
100        }
101        if (res->res_job.pool) {
102           sendit(sock, _("  --> "));
103 @@ -1724,14 +1727,14 @@
104  }
105  
106  /*
107 - * Store a runscript->command as a string
108 + * Store a runscript->commands as a alist(char + string)
109   */
110  static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
111  {
112     lex_get_token(lc, T_STRING);
113  
114     if (pass == 2) {
115 -      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
116 +      ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
117     }
118     scan_to_eol(lc);
119  }
120 @@ -1745,7 +1748,7 @@
121        RUNSCRIPT *script = new_runscript();
122        script->set_job_code_callback(job_code_callback_filesetname);
123  
124 -      script->set_command(lc->str);
125 +      script->add_command(lc->str);
126  
127        /* TODO: remove all script->old_proto with bacula 1.42 */
128  
129 @@ -1873,7 +1876,7 @@
130     }
131  
132     if (pass == 2) {
133 -      if (res_runscript.command == NULL) {
134 +      if (res_runscript.commands == NULL) {
135           scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
136                     "command", "runscript");
137        }
138 @@ -1883,10 +1886,11 @@
139           res_runscript.set_target("%c");
140        }
141  
142 -      RUNSCRIPT *script = new_runscript();
143 -      memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
144 +      RUNSCRIPT *script = copy_runscript(&res_runscript);
145 +      res_runscript.reset_default(true);
146 +
147        script->set_job_code_callback(job_code_callback_filesetname);
148 -      
149 +
150        if (*runscripts == NULL) {
151          *runscripts = New(alist(10, not_owned_by_alist));
152        }
153 Index: src/filed/job.c
154 ===================================================================
155 --- src/filed/job.c     (révision 6169)
156 +++ src/filed/job.c     (copie de travail)
157 @@ -481,7 +481,7 @@
158  
159     /* Run the command now */
160     script = new_runscript();
161 -   script->set_command(cmd);
162 +   script->add_command(cmd);
163     script->when = SCRIPT_Before;
164     ok = script->run(jcr, "ClientRunBeforeJob");
165     free_runscript(script);
166 @@ -529,7 +529,7 @@
167     unbash_spaces(msg);
168  
169     cmd = new_runscript();
170 -   cmd->set_command(msg);
171 +   cmd->add_command(msg);
172     cmd->on_success = true;
173     cmd->on_failure = false;
174     cmd->when = SCRIPT_After;
175 @@ -567,7 +567,7 @@
176     cmd->fail_on_error = fail_on_error;
177     unbash_spaces(msg);
178  
179 -   cmd->set_command(msg);
180 +   cmd->add_command(msg);
181     cmd->debug();
182     jcr->RunScripts->append(cmd);
183  
184 Index: src/lib/runscript.h
185 ===================================================================
186 --- src/lib/runscript.h (révision 6169)
187 +++ src/lib/runscript.h (copie de travail)
188 @@ -62,8 +62,8 @@
189  };
190  
191  enum {
192 -   SHELL_CMD   = 1,
193 -   CONSOLE_CMD = 2 
194 +   SHELL_CMD   = '|',
195 +   CONSOLE_CMD = '@' 
196  };
197  
198  /*
199 @@ -71,10 +71,9 @@
200   */
201  class RUNSCRIPT {
202  public:
203 -   POOLMEM *command;            /* command string */
204 +   alist *commands;             /* list of command/console string */
205     POOLMEM *target;             /* host target */
206     int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
207 -   int  cmd_type;               /* Command type -- Shell, Console */
208     char level;                  /* Base|Full|Incr...|All (NYI) */
209     bool on_success;             /* execute command on job success (After) */
210     bool on_failure;             /* execute command on job failure (After) */
211 @@ -85,8 +84,10 @@
212                                  /* Optional callback function passed to edit_job_code */
213  
214     bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
215 +   bool run_command(const char *cmd, JCR *job, const char *name="");
216     bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
217 -   void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
218 +   void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
219 +   void get_command(const char *cmd, char *cmd_type, char **cmd);
220     void set_target(const POOLMEM *client_name);
221     void reset_default(bool free_string = false);
222     bool is_local();             /* true if running on local host */
223 Index: src/lib/runscript.c
224 ===================================================================
225 --- src/lib/runscript.c (révision 6169)
226 +++ src/lib/runscript.c (copie de travail)
227 @@ -59,15 +59,20 @@
228  
229  void RUNSCRIPT::reset_default(bool free_strings)
230  {
231 -   if (free_strings && command) {
232 -     free_pool_memory(command);
233 +   char *c;
234 +   if (free_strings && commands) {
235 +      foreach_alist(c, commands) {
236 +         free_pool_memory(c);
237 +      }
238     }
239     if (free_strings && target) {
240       free_pool_memory(target);
241     }
242 -   
243     target = NULL;
244 -   command = NULL;
245 +   if (commands) {
246 +      delete commands;
247 +      commands = NULL;
248 +   }
249     on_success = true;
250     on_failure = false;
251     fail_on_error = true;
252 @@ -76,17 +81,23 @@
253     job_code_callback = NULL;
254  }
255  
256 -RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
257 +Runscript *copy_runscript(RUNSCRIPT *src)
258  {
259     Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
260  
261     RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
262     memcpy(dst, src, sizeof(RUNSCRIPT));
263  
264 -   dst->command = NULL;
265 +   dst->commands =  New(alist(5, not_owned_by_alist));
266 +   char *c;
267 +   POOLMEM *m;
268 +   foreach_alist(c, src->commands) {
269 +      m = get_pool_memory(PM_FNAME);
270 +      pm_strcpy(m, c);
271 +      dst->commands->append(m);
272 +   }
273 +
274     dst->target = NULL;
275 -
276 -   dst->set_command(src->command, src->cmd_type);
277     dst->set_target(src->target);
278  
279     return dst;   
280 @@ -95,9 +106,12 @@
281  void free_runscript(RUNSCRIPT *script)
282  {
283     Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
284 -
285 -   if (script->command) {
286 -      free_pool_memory(script->command);
287 +   POOLMEM *c;
288 +   if (script->commands) {
289 +      foreach_alist(c, script->commands) {
290 +         free_pool_memory(c);
291 +      }
292 +      delete script->commands;
293     }
294     if (script->target) {
295        free_pool_memory(script->target);
296 @@ -108,60 +122,15 @@
297  int run_scripts(JCR *jcr, alist *runscripts, const char *label)
298  {
299     Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
300 -   
301 -   RUNSCRIPT *script;
302 -   bool runit;
303  
304 -   int when;
305 -
306 -   if (strstr(label, NT_("Before"))) {
307 -      when = SCRIPT_Before;
308 -   } else {
309 -      when = SCRIPT_After;
310 -   }
311 -
312     if (runscripts == NULL) {
313        Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
314        return 0;
315     }
316 -
317 +   
318 +   RUNSCRIPT *script;
319     foreach_alist(script, runscripts) {
320 -      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
321 -      runit = false;
322 -
323 -      if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
324 -         if ((script->on_success 
325 -            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
326 -            || (script->on_failure && job_canceled(jcr))
327 -            )
328 -         {
329 -            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
330 -                  script->command, script->on_success, script->on_failure,
331 -                  jcr->JobStatus );
332 -            runit = true;
333 -         }
334 -      }
335 -
336 -      if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
337 -         if ((script->on_success && (jcr->JobStatus == JS_Terminated))
338 -             || (script->on_failure && job_canceled(jcr))
339 -            )
340 -         {
341 -            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
342 -                  script->command, script->on_success, script->on_failure,
343 -                  jcr->JobStatus );
344 -            runit = true;
345 -         }
346 -      }
347 -
348 -      if (!script->is_local()) {
349 -         runit = false;
350 -      }
351 -
352 -      /* we execute it */
353 -      if (runit) {
354 -         script->run(jcr, label);
355 -      }
356 +      script->run(jcr, label);
357     }
358     return 1;
359  }
360 @@ -176,7 +145,7 @@
361  }
362  
363  /* set this->command to cmd */
364 -void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
365 +void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
366  {
367     Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
368  
369 @@ -184,14 +153,21 @@
370        return;
371     }
372  
373 -   if (!command) {
374 -      command = get_pool_memory(PM_FNAME);
375 +   if (!commands) {
376 +      commands = New(alist(5, not_owned_by_alist)); 
377     }
378  
379 -   pm_strcpy(command, cmd);
380 -   cmd_type = acmd_type;
381 +   POOLMEM *c = get_pool_memory(PM_FNAME);
382 +   Mmsg(c, "%c%s", acmd_type, cmd);
383 +   commands->append(c);
384  }
385  
386 +void RUNSCRIPT::get_command(const char* command, char *acmd_type, char **cmd)
387 +{
388 +   *acmd_type = command[0];
389 +   *cmd = (char *)command + 1;
390 +}
391 +
392  /* set this->target to client_name */
393  void RUNSCRIPT::set_target(const POOLMEM *client_name)
394  {
395 @@ -210,14 +186,71 @@
396  
397  bool RUNSCRIPT::run(JCR *jcr, const char *name)
398  {
399 -   Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
400 +   char *c;
401 +   bool runit;
402 +
403 +   int when;
404 +
405 +   if (strstr(name, NT_("Before"))) {
406 +      when = SCRIPT_Before;
407 +   } else {
408 +      when = SCRIPT_After;
409 +   }
410 +
411 +   foreach_alist(c, this->commands) {
412 +      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
413 +      runit = false;
414 +
415 +      if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
416 +         if ((this->on_success 
417 +            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
418 +            || (this->on_failure && job_canceled(jcr))
419 +            )
420 +         {
421 +            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
422 +                  c, this->on_success, this->on_failure,
423 +                  jcr->JobStatus );
424 +            runit = true;
425 +         }
426 +      }
427 +
428 +      if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
429 +         if ((this->on_success && (jcr->JobStatus == JS_Terminated))
430 +             || (this->on_failure && job_canceled(jcr))
431 +            )
432 +         {
433 +            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
434 +                  c, this->on_success, this->on_failure,
435 +                  jcr->JobStatus );
436 +            runit = true;
437 +         }
438 +      }
439 +
440 +      if (!this->is_local()) {
441 +         runit = false;
442 +      }
443 +
444 +      /* we execute it */
445 +      if (runit) {
446 +         this->run_command(c, jcr, name);
447 +      }
448 +   }
449 +   return 1;
450 +}
451 +
452 +bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
453 +{
454     POOLMEM *ecmd = get_pool_memory(PM_FNAME);
455     int status;
456     BPIPE *bpipe;
457     char line[MAXSTRING];
458 +   char cmd_type;
459 +   char *cmd;
460  
461 -   ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
462 -   Dmsg1(100, "runscript: running '%s'...\n", ecmd);
463 +   this->get_command(command, &cmd_type, &cmd);
464 +   ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
465 +
466 +   Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
467     Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), 
468          cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
469  
470 @@ -278,9 +311,12 @@
471  
472  void RUNSCRIPT::debug()
473  {
474 +   char *c;
475     Dmsg0(200, "runscript: debug\n");
476     Dmsg0(200,  _(" --> RunScript\n"));
477 -   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
478 +   foreach_alist(c, commands) {
479 +      Dmsg1(200,  _("  --> Command=%s\n"), NPRT(c));
480 +   }
481     Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
482     Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
483     Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);