e4a017ce06
Co-authored-by: Francesco Renzi <rentziass@github.com> Co-authored-by: Nikola Jokic <jokicnikola07@gmail.com>
142 lines
3.5 KiB
Go
142 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/actions/scaleset"
|
|
)
|
|
|
|
type Config struct {
|
|
RegistrationURL string
|
|
MaxRunners int
|
|
MinRunners int
|
|
ScaleSetName string
|
|
Labels []string
|
|
RunnerGroup string
|
|
GitHubApp scaleset.GitHubAppAuth
|
|
Token string
|
|
RunnerImage string
|
|
LogLevel string
|
|
LogFormat string
|
|
}
|
|
|
|
func (c *Config) defaults() {
|
|
if c.RunnerGroup == "" {
|
|
c.RunnerGroup = scaleset.DefaultRunnerGroup
|
|
}
|
|
if c.RunnerImage == "" {
|
|
c.RunnerImage = "ghcr.io/actions/actions-runner:latest"
|
|
}
|
|
}
|
|
|
|
func (c *Config) Validate() error {
|
|
c.defaults()
|
|
|
|
if _, err := url.ParseRequestURI(c.RegistrationURL); err != nil {
|
|
return fmt.Errorf("invalid registration URL: %w, it should be the full URL of where you want to register your scale set, e.g. 'https://github.com/org/repo'", err)
|
|
}
|
|
|
|
appError := c.GitHubApp.Validate()
|
|
if c.Token == "" && appError != nil {
|
|
return fmt.Errorf("no credentials provided: either GitHub App (client id, installation id and private key) (recommended) or a Personal Access Token are required")
|
|
}
|
|
|
|
if c.ScaleSetName == "" {
|
|
return fmt.Errorf("scale set name is required")
|
|
}
|
|
for i, label := range c.Labels {
|
|
if strings.TrimSpace(label) == "" {
|
|
return fmt.Errorf("label at index %d is empty", i)
|
|
}
|
|
}
|
|
if c.MaxRunners < c.MinRunners {
|
|
return fmt.Errorf("max runners cannot be less than min-runners")
|
|
}
|
|
if c.RunnerGroup == "" {
|
|
return fmt.Errorf("runner group is required")
|
|
}
|
|
if c.RunnerImage == "" {
|
|
return fmt.Errorf("runner image is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// systemInfo serves as a base system info
|
|
func systemInfo(scaleSetID int) scaleset.SystemInfo {
|
|
return scaleset.SystemInfo{
|
|
System: "dockerscaleset",
|
|
Subsystem: "dockerscaleset",
|
|
CommitSHA: "NA", // You can leverage build flags to set commit SHA
|
|
Version: "0.1.0", // You can leverage build flags to set version
|
|
ScaleSetID: scaleSetID,
|
|
}
|
|
}
|
|
|
|
func (c *Config) ScalesetClient() (*scaleset.Client, error) {
|
|
if err := c.GitHubApp.Validate(); err == nil {
|
|
return scaleset.NewClientWithGitHubApp(
|
|
scaleset.ClientWithGitHubAppConfig{
|
|
GitHubConfigURL: c.RegistrationURL,
|
|
GitHubAppAuth: c.GitHubApp,
|
|
SystemInfo: systemInfo(0),
|
|
},
|
|
)
|
|
}
|
|
|
|
return scaleset.NewClientWithPersonalAccessToken(
|
|
scaleset.NewClientWithPersonalAccessTokenConfig{
|
|
GitHubConfigURL: c.RegistrationURL,
|
|
PersonalAccessToken: c.Token,
|
|
SystemInfo: systemInfo(0),
|
|
},
|
|
)
|
|
}
|
|
|
|
func (c *Config) Logger() *slog.Logger {
|
|
var lvl slog.Level
|
|
switch strings.ToLower(c.LogLevel) {
|
|
case "debug":
|
|
lvl = slog.LevelDebug
|
|
case "info":
|
|
lvl = slog.LevelInfo
|
|
case "warn":
|
|
lvl = slog.LevelWarn
|
|
case "error":
|
|
lvl = slog.LevelError
|
|
default:
|
|
lvl = slog.LevelInfo
|
|
}
|
|
|
|
switch c.LogFormat {
|
|
case "json":
|
|
return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
|
AddSource: true,
|
|
Level: lvl,
|
|
}))
|
|
case "text":
|
|
return slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
|
AddSource: true,
|
|
Level: lvl,
|
|
}))
|
|
default:
|
|
return slog.New(slog.DiscardHandler)
|
|
}
|
|
}
|
|
|
|
// BuildLabels returns the labels to use for the runner scale set.
|
|
// If custom labels are provided, those are used; otherwise, the scale set name is used as the label.
|
|
func (c *Config) BuildLabels() []scaleset.Label {
|
|
if len(c.Labels) > 0 {
|
|
labels := make([]scaleset.Label, len(c.Labels))
|
|
for i, name := range c.Labels {
|
|
labels[i] = scaleset.Label{Name: strings.TrimSpace(name)}
|
|
}
|
|
return labels
|
|
}
|
|
return []scaleset.Label{{Name: c.ScaleSetName}}
|
|
}
|