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