1
1
mirror of https://github.com/go-gitea/gitea synced 2025-11-02 20:38:26 +00:00
Files
gitea/routers/api/bots/runner/runner.go
2022-11-25 17:48:44 +08:00

129 lines
3.3 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package runner
import (
"context"
"errors"
"code.gitea.io/gitea/core"
bots_model "code.gitea.io/gitea/models/bots"
"code.gitea.io/gitea/modules/log"
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
"gitea.com/gitea/proto-go/runner/v1/runnerv1connect"
"github.com/bufbuild/connect-go"
gouuid "github.com/google/uuid"
)
var _ runnerv1connect.RunnerServiceClient = (*Service)(nil)
type Service struct {
Scheduler core.Scheduler
runnerv1connect.UnimplementedRunnerServiceHandler
}
// Register for new runner.
func (s *Service) Register(
ctx context.Context,
req *connect.Request[runnerv1.RegisterRequest],
) (*connect.Response[runnerv1.RegisterResponse], error) {
if req.Msg.Token == "" || req.Msg.Name == "" {
return nil, errors.New("missing runner token or name")
}
runnerToken, err := bots_model.GetRunnerToken(req.Msg.Token)
if err != nil {
return nil, errors.New("runner token not found")
}
if runnerToken.IsActive {
return nil, errors.New("runner token has already activated")
}
// create new runner
runner := &bots_model.Runner{
UUID: gouuid.New().String(),
Name: req.Msg.Name,
OwnerID: runnerToken.OwnerID,
RepoID: runnerToken.RepoID,
Token: req.Msg.Token,
Status: core.StatusOffline,
AgentLabels: req.Msg.AgentLabels,
CustomLabels: req.Msg.CustomLabels,
}
// create new runner
if err := bots_model.NewRunner(ctx, runner); err != nil {
return nil, errors.New("can't create new runner")
}
// update token status
runnerToken.IsActive = true
if err := bots_model.UpdateRunnerToken(ctx, runnerToken, "is_active"); err != nil {
return nil, errors.New("can't update runner token status")
}
res := connect.NewResponse(&runnerv1.RegisterResponse{
Runner: &runnerv1.Runner{
Uuid: runner.UUID,
Token: runner.Token,
Name: runner.Name,
AgentLabels: runner.AgentLabels,
CustomLabels: runner.CustomLabels,
},
})
return res, nil
}
// Request requests the next available build stage for execution.
func (s *Service) FetchTask(
ctx context.Context,
req *connect.Request[runnerv1.FetchTaskRequest],
) (*connect.Response[runnerv1.FetchTaskResponse], error) {
log.Debug("manager: request queue item")
task, err := s.Scheduler.Request(ctx, core.Filter{
OS: req.Msg.Os,
Arch: req.Msg.Arch,
})
if err != nil && ctx.Err() != nil {
log.Debug("manager: context canceled")
return nil, err
}
if err != nil {
log.Warn("manager: request queue item error")
return nil, err
}
// TODO: update task and check data lock
task.Machine = req.Msg.Os
res := connect.NewResponse(&runnerv1.FetchTaskResponse{
Task: task,
})
return res, nil
}
// UpdateTask updates the task status.
func (s *Service) UpdateTask(
ctx context.Context,
req *connect.Request[runnerv1.UpdateTaskRequest],
) (*connect.Response[runnerv1.UpdateTaskResponse], error) {
res := connect.NewResponse(&runnerv1.UpdateTaskResponse{})
return res, nil
}
// UpdateLog uploads log of the task.
func (s *Service) UpdateLog(
ctx context.Context,
req *connect.Request[runnerv1.UpdateLogRequest],
) (*connect.Response[runnerv1.UpdateLogResponse], error) {
res := connect.NewResponse(&runnerv1.UpdateLogResponse{})
return res, nil
}