Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1567)

Unified Diff: scheduler/appengine/apiservers/scheduler.go

Issue 2946343004: scheduler: add rpcs for actions on job and invocation. (Closed)
Patch Set: review Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « scheduler/api/scheduler/v1/scheduler.pb.go ('k') | scheduler/appengine/apiservers/scheduler_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scheduler/appengine/apiservers/scheduler.go
diff --git a/scheduler/appengine/apiservers/scheduler.go b/scheduler/appengine/apiservers/scheduler.go
index 3de1d4e5aed5995af4b3f0770ecc83cce455d774..5bfa0ae8d61740da84a8f1719dae1fbb357d212d 100644
--- a/scheduler/appengine/apiservers/scheduler.go
+++ b/scheduler/appengine/apiservers/scheduler.go
@@ -9,9 +9,12 @@ import (
"github.com/luci/luci-go/scheduler/appengine/catalog"
"github.com/luci/luci-go/scheduler/appengine/engine"
"github.com/luci/luci-go/scheduler/appengine/presentation"
+ "github.com/luci/luci-go/server/auth"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
+
+ "github.com/golang/protobuf/ptypes/empty"
)
// SchedulerServer implements scheduler.Scheduler API.
@@ -24,6 +27,11 @@ var _ scheduler.SchedulerServer = (*SchedulerServer)(nil)
// GetJobs fetches all jobs satisfying JobsRequest and visibility ACLs.
func (s SchedulerServer) GetJobs(ctx context.Context, in *scheduler.JobsRequest) (*scheduler.JobsReply, error) {
+ if in.GetCursor() != "" {
+ // Paging in GetJobs isn't implemented until we have enough jobs to care.
+ // Until then, not empty cursor implies no more jobs to return.
+ return &scheduler.JobsReply{Jobs: []*scheduler.Job{}, NextCursor: ""}, nil
+ }
var ejobs []*engine.Job
var err error
if in.GetProject() == "" {
@@ -42,19 +50,21 @@ func (s SchedulerServer) GetJobs(ctx context.Context, in *scheduler.JobsRequest)
return nil, grpc.Errorf(codes.Internal, "failed to get traits: %s", err)
}
jobs[i] = &scheduler.Job{
- Name: ej.GetJobName(),
- Project: ej.ProjectID,
+ JobRef: &scheduler.JobRef{
+ Project: ej.ProjectID,
+ Job: ej.GetJobName(),
+ },
Schedule: ej.Schedule,
State: &scheduler.JobState{
UiStatus: string(presentation.GetPublicStateKind(ej, traits)),
},
}
}
- return &scheduler.JobsReply{Jobs: jobs}, nil
+ return &scheduler.JobsReply{Jobs: jobs, NextCursor: ""}, nil
}
func (s SchedulerServer) GetInvocations(ctx context.Context, in *scheduler.InvocationsRequest) (*scheduler.InvocationsReply, error) {
- ejob, err := s.Engine.GetJob(ctx, in.GetProject()+"/"+in.GetJob())
+ ejob, err := s.Engine.GetJob(ctx, getJobId(in.GetJobRef()))
if err != nil {
return nil, grpc.Errorf(codes.Internal, "datastore error: %s", err)
}
@@ -74,9 +84,13 @@ func (s SchedulerServer) GetInvocations(ctx context.Context, in *scheduler.Invoc
invs := make([]*scheduler.Invocation, len(einvs))
for i, einv := range einvs {
invs[i] = &scheduler.Invocation{
- Id: einv.ID,
- Job: ejob.GetJobName(),
- Project: ejob.ProjectID,
+ InvocationRef: &scheduler.InvocationRef{
+ JobRef: &scheduler.JobRef{
+ Project: ejob.ProjectID,
+ Job: ejob.GetJobName(),
+ },
+ InvocationId: einv.ID,
+ },
StartedTs: einv.Started.UnixNano() / 1000,
TriggeredBy: string(einv.TriggeredBy),
Status: string(einv.Status),
@@ -90,3 +104,52 @@ func (s SchedulerServer) GetInvocations(ctx context.Context, in *scheduler.Invoc
}
return &scheduler.InvocationsReply{Invocations: invs, NextCursor: cursor}, nil
}
+
+//// Actions.
+
+func (s SchedulerServer) PauseJob(ctx context.Context, in *scheduler.JobRef) (*empty.Empty, error) {
+ return runAction(ctx, in, func() error {
+ return s.Engine.PauseJob(ctx, getJobId(in), auth.CurrentIdentity(ctx))
+ })
+}
+
+func (s SchedulerServer) ResumeJob(ctx context.Context, in *scheduler.JobRef) (*empty.Empty, error) {
+ return runAction(ctx, in, func() error {
+ return s.Engine.ResumeJob(ctx, getJobId(in), auth.CurrentIdentity(ctx))
+ })
+}
+
+func (s SchedulerServer) AbortJob(ctx context.Context, in *scheduler.JobRef) (*empty.Empty, error) {
+ return runAction(ctx, in, func() error {
+ return s.Engine.AbortJob(ctx, getJobId(in), auth.CurrentIdentity(ctx))
+ })
+}
+
+func (s SchedulerServer) AbortInvocation(ctx context.Context, in *scheduler.InvocationRef) (
+ *empty.Empty, error) {
+ return runAction(ctx, in.GetJobRef(), func() error {
+ return s.Engine.AbortInvocation(ctx, getJobId(in.GetJobRef()), in.GetInvocationId(), auth.CurrentIdentity(ctx))
+ })
+}
+
+//// Private helpers.
+
+func runAction(ctx context.Context, jobRef *scheduler.JobRef, action func() error) (*empty.Empty, error) {
+ if !presentation.IsJobOwner(ctx, jobRef.GetProject(), jobRef.GetJob()) {
+ return nil, grpc.Errorf(codes.PermissionDenied, "No permission to execute action")
+ }
+ switch err := action(); {
+ case err == nil:
+ return &empty.Empty{}, nil
+ case err == engine.ErrNoSuchJob:
+ return nil, grpc.Errorf(codes.NotFound, "no such job")
+ case err == engine.ErrNoSuchInvocation:
+ return nil, grpc.Errorf(codes.NotFound, "no such invocation")
+ default:
+ return nil, grpc.Errorf(codes.Internal, "internal error: %s", err)
+ }
+}
+
+func getJobId(jobRef *scheduler.JobRef) string {
+ return jobRef.GetProject() + "/" + jobRef.GetJob()
+}
« no previous file with comments | « scheduler/api/scheduler/v1/scheduler.pb.go ('k') | scheduler/appengine/apiservers/scheduler_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698