github.com/manicqin/nomad@v0.9.5/command/job_periodic_force.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/nomad/api"
     8  	"github.com/posener/complete"
     9  )
    10  
    11  type JobPeriodicForceCommand struct {
    12  	Meta
    13  }
    14  
    15  func (c *JobPeriodicForceCommand) Help() string {
    16  	helpText := `
    17  Usage: nomad job periodic force <job id>
    18  
    19    This command is used to force the creation of a new instance of a periodic job.
    20    This is used to immediately run a periodic job, even if it violates the job's
    21    prohibit_overlap setting.
    22  
    23  General Options:
    24  
    25    ` + generalOptionsUsage() + `
    26  
    27  Periodic Force Options:
    28  
    29    -detach
    30      Return immediately instead of entering monitor mode. After the force,
    31      the evaluation ID will be printed to the screen, which can be used to
    32      examine the evaluation using the eval-status command.
    33  
    34    -verbose
    35      Display full information.
    36  `
    37  
    38  	return strings.TrimSpace(helpText)
    39  }
    40  
    41  func (c *JobPeriodicForceCommand) Synopsis() string {
    42  	return "Force the launch of a periodic job"
    43  }
    44  
    45  func (c *JobPeriodicForceCommand) AutocompleteFlags() complete.Flags {
    46  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    47  		complete.Flags{
    48  			"-detach":  complete.PredictNothing,
    49  			"-verbose": complete.PredictNothing,
    50  		})
    51  }
    52  
    53  func (c *JobPeriodicForceCommand) AutocompleteArgs() complete.Predictor {
    54  	return complete.PredictFunc(func(a complete.Args) []string {
    55  		client, err := c.Meta.Client()
    56  		if err != nil {
    57  			return nil
    58  		}
    59  
    60  		resp, _, err := client.Jobs().PrefixList(a.Last)
    61  		if err != nil {
    62  			return []string{}
    63  		}
    64  
    65  		// filter this by periodic jobs
    66  		matches := make([]string, 0, len(resp))
    67  		for _, job := range resp {
    68  			if job.Periodic {
    69  				matches = append(matches, job.ID)
    70  			}
    71  		}
    72  		return matches
    73  	})
    74  }
    75  
    76  func (c *JobPeriodicForceCommand) Name() string { return "job periodic force" }
    77  
    78  func (c *JobPeriodicForceCommand) Run(args []string) int {
    79  	var detach, verbose bool
    80  
    81  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    82  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    83  	flags.BoolVar(&detach, "detach", false, "")
    84  	flags.BoolVar(&verbose, "verbose", false, "")
    85  
    86  	if err := flags.Parse(args); err != nil {
    87  		return 1
    88  	}
    89  
    90  	// Check that we got exactly one argument
    91  	args = flags.Args()
    92  	if l := len(args); l != 1 {
    93  		c.Ui.Error("This command takes one argument: <job id>")
    94  		c.Ui.Error(commandErrorText(c))
    95  		return 1
    96  	}
    97  
    98  	// Truncate the id unless full length is requested
    99  	length := shortId
   100  	if verbose {
   101  		length = fullId
   102  	}
   103  
   104  	// Get the HTTP client
   105  	client, err := c.Meta.Client()
   106  	if err != nil {
   107  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
   108  		return 1
   109  	}
   110  
   111  	// Check if the job exists
   112  	jobID := args[0]
   113  	jobs, _, err := client.Jobs().PrefixList(jobID)
   114  	if err != nil {
   115  		c.Ui.Error(fmt.Sprintf("Error forcing periodic job: %s", err))
   116  		return 1
   117  	}
   118  	// filter non-periodic jobs
   119  	periodicJobs := make([]*api.JobListStub, 0, len(jobs))
   120  	for _, j := range jobs {
   121  		if j.Periodic {
   122  			periodicJobs = append(periodicJobs, j)
   123  		}
   124  	}
   125  	if len(periodicJobs) == 0 {
   126  		c.Ui.Error(fmt.Sprintf("No periodic job(s) with prefix or id %q found", jobID))
   127  		return 1
   128  	}
   129  	if len(periodicJobs) > 1 {
   130  		c.Ui.Error(fmt.Sprintf("Prefix matched multiple periodic jobs\n\n%s", createStatusListOutput(periodicJobs)))
   131  		return 1
   132  	}
   133  	jobID = periodicJobs[0].ID
   134  
   135  	// force the evaluation
   136  	evalID, _, err := client.Jobs().PeriodicForce(jobID, nil)
   137  	if err != nil {
   138  		c.Ui.Error(fmt.Sprintf("Error forcing periodic job %q: %s", jobID, err))
   139  		return 1
   140  	}
   141  
   142  	if detach {
   143  		c.Ui.Output("Force periodic successful")
   144  		c.Ui.Output("Evaluation ID: " + evalID)
   145  		return 0
   146  	}
   147  
   148  	// Detach was not specified, so start monitoring
   149  	mon := newMonitor(c.Ui, client, length)
   150  	return mon.monitor(evalID, false)
   151  }