runner/runtime/runtime.go

75 lines
2.0 KiB
Go

package runtime
import (
"context"
"strings"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
"codeberg.org/forgejo/runner/artifactcache"
"codeberg.org/forgejo/runner/client"
log "github.com/sirupsen/logrus"
)
// Runner runs the pipeline.
type Runner struct {
Machine string
Version string
ForgeInstance string
Environ map[string]string
Client client.Client
Labels []string
Network string
CacheHandler *artifactcache.Handler
}
// Run runs the pipeline stage.
func (s *Runner) Run(ctx context.Context, task *runnerv1.Task) error {
env := map[string]string{}
for k, v := range s.Environ {
env[k] = v
}
if s.CacheHandler != nil {
env["ACTIONS_CACHE_URL"] = s.CacheHandler.ExternalURL() + "/"
}
return NewTask(task.Id, s.Client, env, s.Network, s.platformPicker).Run(ctx, task, s.Machine, s.Version)
}
func (s *Runner) platformPicker(labels []string) string {
platforms := make(map[string]string, len(s.Labels))
for _, l := range s.Labels {
label, schema, arg, err := ParseLabel(l)
if err != nil {
log.Errorf("invaid label %q: %v", l, err)
continue
}
switch schema {
case "docker":
// TODO "//" will be ignored, maybe we should use 'ubuntu-18.04:docker:node:16-buster' instead
platforms[label] = strings.TrimPrefix(arg, "//")
case "host":
platforms[label] = "-self-hosted"
default:
// It should not happen, because ParseLabel has checked it.
continue
}
}
for _, label := range labels {
if v, ok := platforms[label]; ok {
return v
}
}
// TODO: support multiple labels
// like:
// ["ubuntu-22.04"] => "ubuntu:22.04"
// ["with-gpu"] => "linux:with-gpu"
// ["ubuntu-22.04", "with-gpu"] => "ubuntu:22.04_with-gpu"
// return default.
// So the runner receives a task with a label that the runner doesn't have,
// it happens when the user have edited the label of the runner in the web UI.
return "node:16-bullseye" // TODO: it may be not correct, what if the runner is used as host mode only?
}