@@ -93,7 +93,7 @@ Arguments:
9393
9494 // Override "exec" field if specified on the CLI.
9595 if args1 != nil {
96- c .Config .Exec = strings .Join (args1 , " " )
96+ c .Config .Exec = ExecConfigSlice {{ Cmd : strings .Join (args1 , " " )}}
9797 }
9898
9999 // Override "debug" field if specified on the CLI.
@@ -260,8 +260,11 @@ func (c *MountCommand) Run(ctx context.Context) (err error) {
260260 }
261261
262262 // Execute subcommand, if specified in config.
263- if err := c .execCmd (ctx ); err != nil {
264- return fmt .Errorf ("cannot exec: %w" , err )
263+ // Exit if no subcommand specified.
264+ if len (c .Config .Exec ) > 0 {
265+ if err := c .execCmds (ctx ); err != nil {
266+ return fmt .Errorf ("cannot exec: %w" , err )
267+ }
265268 }
266269
267270 return nil
@@ -384,21 +387,56 @@ func (c *MountCommand) initProxyServer(ctx context.Context) error {
384387 return nil
385388}
386389
387- func (c * MountCommand ) execCmd (ctx context.Context ) error {
388- // Exit if no subcommand specified.
389- if c .Config .Exec == "" {
390- return nil
390+ // execCmds sequentially executes the commands in the "exec" config.
391+ // The last command is run asynchronously and will send its exit to the execCh.
392+ func (c * MountCommand ) execCmds (ctx context.Context ) error {
393+ for i , config := range c .Config .Exec {
394+ args , err := shellwords .Parse (config .Cmd )
395+ if err != nil {
396+ return fmt .Errorf ("cannot parse exec command[%d]: %w" , i , err )
397+ }
398+ cmd , args := args [0 ], args [1 :]
399+
400+ // Skip if command should only run on candidate nodes and this is a non-candidate.
401+ if config .IfCandidate && ! c .Store .Candidate () {
402+ log .Printf ("node is not a candidate, skipping command execution: %s %v" , cmd , args )
403+ continue
404+ }
405+
406+ // Execute all commands synchronously except for the last one.
407+ // This is to support migration commands that occur before the app start.
408+ if i < len (c .Config .Exec )- 1 {
409+ if err := c .execSyncCmd (ctx , cmd , args ); err != nil {
410+ return fmt .Errorf ("sync cmd: %w" , err )
411+ }
412+ } else {
413+ if err := c .execBackgroundCmd (ctx , cmd , args ); err != nil {
414+ return fmt .Errorf ("background cmd: %w" , err )
415+ }
416+ }
391417 }
392418
393- // Execute subcommand process.
394- args , err := shellwords .Parse (c .Config .Exec )
395- if err != nil {
396- return fmt .Errorf ("cannot parse exec command: %w" , err )
419+ return nil
420+ }
421+
422+ func (c * MountCommand ) execSyncCmd (ctx context.Context , cmd string , args []string ) error {
423+ log .Printf ("executing command: %s %v" , cmd , args )
424+
425+ c .cmd = exec .CommandContext (ctx , cmd , args ... )
426+ c .cmd .Env = os .Environ ()
427+ c .cmd .Stdout = os .Stdout
428+ c .cmd .Stderr = os .Stderr
429+ if err := c .cmd .Run (); err != nil {
430+ return fmt .Errorf ("cannot run command: %w" , err )
397431 }
398432
399- log .Printf ("starting subprocess: %s %v" , args [0 ], args [1 :])
433+ return nil
434+ }
435+
436+ func (c * MountCommand ) execBackgroundCmd (ctx context.Context , cmd string , args []string ) error {
437+ log .Printf ("starting background subprocess: %s %v" , cmd , args )
400438
401- c .cmd = exec .CommandContext (ctx , args [ 0 ] , args [ 1 :] ... )
439+ c .cmd = exec .CommandContext (ctx , cmd , args ... )
402440 c .cmd .Env = os .Environ ()
403441 c .cmd .Stdout = os .Stdout
404442 c .cmd .Stderr = os .Stderr
0 commit comments