github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/periodic_endpoint.go (about)

     1  package nomad
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/armon/go-metrics"
     8  	"github.com/hashicorp/go-hclog"
     9  	"github.com/hashicorp/go-memdb"
    10  
    11  	"github.com/hashicorp/nomad/acl"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  )
    14  
    15  // Periodic endpoint is used for periodic job interactions
    16  type Periodic struct {
    17  	srv    *Server
    18  	ctx    *RPCContext
    19  	logger hclog.Logger
    20  }
    21  
    22  func NewPeriodicEndpoint(srv *Server, ctx *RPCContext) *Periodic {
    23  	return &Periodic{srv: srv, ctx: ctx, logger: srv.logger.Named("periodic")}
    24  }
    25  
    26  // Force is used to force a new instance of a periodic job
    27  func (p *Periodic) Force(args *structs.PeriodicForceRequest, reply *structs.PeriodicForceResponse) error {
    28  	if done, err := p.srv.forward("Periodic.Force", args, args, reply); done {
    29  		return err
    30  	}
    31  	defer metrics.MeasureSince([]string{"nomad", "periodic", "force"}, time.Now())
    32  
    33  	// Check for write-job permissions
    34  	if aclObj, err := p.srv.ResolveToken(args.AuthToken); err != nil {
    35  		return err
    36  	} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityDispatchJob) && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
    37  		return structs.ErrPermissionDenied
    38  	}
    39  
    40  	// Validate the arguments
    41  	if args.JobID == "" {
    42  		return fmt.Errorf("missing job ID for evaluation")
    43  	}
    44  
    45  	// Lookup the job
    46  	snap, err := p.srv.fsm.State().Snapshot()
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	ws := memdb.NewWatchSet()
    52  	job, err := snap.JobByID(ws, args.RequestNamespace(), args.JobID)
    53  	if err != nil {
    54  		return err
    55  	}
    56  	if job == nil {
    57  		return fmt.Errorf("job not found")
    58  	}
    59  
    60  	if !job.IsPeriodic() {
    61  		return fmt.Errorf("can't force launch non-periodic job")
    62  	}
    63  
    64  	// Force run the job.
    65  	eval, err := p.srv.periodicDispatcher.ForceRun(args.RequestNamespace(), job.ID)
    66  	if err != nil {
    67  		return fmt.Errorf("force launch for job %q failed: %v", job.ID, err)
    68  	}
    69  
    70  	reply.EvalID = eval.ID
    71  	reply.EvalCreateIndex = eval.CreateIndex
    72  	reply.Index = eval.CreateIndex
    73  	return nil
    74  }