chore(runner): add new register command

Signed-off-by: Bo-Yi.Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi.Wu 2022-10-15 16:12:32 +08:00 committed by Jason Song
parent cce60d466b
commit a503f7429f
9 changed files with 128 additions and 42 deletions

View File

@ -7,8 +7,9 @@ Act runner is a runner for Forges supports Github Actions protocol.
create a new file as name `.env` create a new file as name `.env`
```sh ```sh
GITEA_RUNNER_NAME=foobar GITEA_RUNNER_NAME=
GITEA_RUNNER_URL=http://localhost:3000/foo/bar GITEA_RPC_PROTO=http
GITEA_RPC_HOST=localhost:3001
GITEA_RUNNER_TOKEN=1234567890abcde GITEA_RUNNER_TOKEN=1234567890abcde
GITEA_RUNNER_LABELS=foo,bar GITEA_RUNNER_LABELS=foo,bar
``` ```

View File

@ -94,11 +94,6 @@ func runDaemon(ctx context.Context, task *runtime.Task) func(cmd *cobra.Command,
WithField("arch", cfg.Platform.Arch). WithField("arch", cfg.Platform.Arch).
Infoln("polling the remote server") Infoln("polling the remote server")
// register new runner
if err := poller.Register(ctx, cfg.Runner); err != nil {
return err
}
// update runner status to idle // update runner status to idle
log.Infoln("update runner status to idle") log.Infoln("update runner status to idle")
if _, err := cli.UpdateRunner( if _, err := cli.UpdateRunner(

88
cmd/register.go Normal file
View File

@ -0,0 +1,88 @@
package cmd
import (
"context"
"time"
"gitea.com/gitea/act_runner/client"
"gitea.com/gitea/act_runner/config"
"gitea.com/gitea/act_runner/poller"
"gitea.com/gitea/act_runner/runtime"
pingv1 "gitea.com/gitea/proto-go/ping/v1"
"github.com/bufbuild/connect-go"
"github.com/joho/godotenv"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
func runRegister(ctx context.Context, task *runtime.Task) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
log.Infoln("Starting runner daemon")
_ = godotenv.Load(task.Input.EnvFile)
cfg, err := config.FromEnviron()
if err != nil {
log.WithError(err).
Fatalln("invalid configuration")
}
initLogging(cfg)
cli := client.New(
cfg.Client.Address,
cfg.Client.Secret,
client.WithSkipVerify(cfg.Client.SkipVerify),
client.WithGRPC(cfg.Client.GRPC),
client.WithGRPCWeb(cfg.Client.GRPCWeb),
)
for {
_, err := cli.Ping(ctx, connect.NewRequest(&pingv1.PingRequest{
Data: cfg.Runner.Name,
}))
select {
case <-ctx.Done():
return nil
default:
}
if ctx.Err() != nil {
break
}
if err != nil {
log.WithError(err).
Errorln("cannot ping the remote server")
// TODO: if ping failed, retry or exit
time.Sleep(time.Second)
} else {
log.Infoln("successfully connected the remote server")
break
}
}
runner := &runtime.Runner{
Client: cli,
Machine: cfg.Runner.Name,
Environ: cfg.Runner.Environ,
}
poller := poller.New(
cli,
runner.Run,
&client.Filter{
OS: cfg.Platform.OS,
Arch: cfg.Platform.Arch,
Labels: cfg.Runner.Labels,
},
)
// register new runner
if err := poller.Register(ctx, cfg.Runner); err != nil {
return err
}
log.Infoln("successfully registered new runner")
return nil
}
}

View File

@ -52,12 +52,21 @@ func Execute(ctx context.Context) {
// ./act_runner daemon // ./act_runner daemon
daemonCmd := &cobra.Command{ daemonCmd := &cobra.Command{
Aliases: []string{"daemon"}, Aliases: []string{"daemon"},
Use: "daemon [event name to run]\nIf no event name passed, will default to \"on: push\"", Use: "execute runner daemon",
Short: "Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
RunE: runDaemon(ctx, task), RunE: runDaemon(ctx, task),
} }
rootCmd.AddCommand(daemonCmd)
// ./act_runner daemon
registerCmd := &cobra.Command{
Aliases: []string{"register"},
Use: "register new runner",
Args: cobra.MaximumNArgs(1),
RunE: runRegister(ctx, task),
}
// add all command
rootCmd.AddCommand(daemonCmd, registerCmd)
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
os.Exit(1) os.Exit(1)

View File

@ -2,7 +2,6 @@ package config
import ( import (
"fmt" "fmt"
"net/url"
"os" "os"
"runtime" "runtime"
@ -32,19 +31,17 @@ type (
Runner struct { Runner struct {
Name string `envconfig:"GITEA_RUNNER_NAME"` Name string `envconfig:"GITEA_RUNNER_NAME"`
URL string `envconfig:"GITEA_RUNNER_URL" required:"true"`
Token string `envconfig:"GITEA_RUNNER_TOKEN" required:"true"` Token string `envconfig:"GITEA_RUNNER_TOKEN" required:"true"`
Capacity int `envconfig:"GITEA_RUNNER_CAPACITY" default:"1"` Capacity int `envconfig:"GITEA_RUNNER_CAPACITY" default:"1"`
File string `envconfig:"GITEA_RUNNER_FILE" default:".runner"`
Environ map[string]string `envconfig:"GITEA_RUNNER_ENVIRON"` Environ map[string]string `envconfig:"GITEA_RUNNER_ENVIRON"`
EnvFile string `envconfig:"GITEA_RUNNER_ENV_FILE"` EnvFile string `envconfig:"GITEA_RUNNER_ENV_FILE"`
Labels []string `envconfig:"GITEA_RUNNER_LABELS"` Labels []string `envconfig:"GITEA_RUNNER_LABELS"`
} }
Platform struct { Platform struct {
OS string `envconfig:"GITEA_PLATFORM_OS"` OS string `envconfig:"GITEA_PLATFORM_OS"`
Arch string `envconfig:"GITEA_PLATFORM_ARCH"` Arch string `envconfig:"GITEA_PLATFORM_ARCH"`
Kernel string `envconfig:"GITEA_PLATFORM_KERNEL"`
Variant string `envconfig:"GITEA_PLATFORM_VARIANT"`
} }
) )
@ -55,14 +52,6 @@ func FromEnviron() (Config, error) {
return cfg, err return cfg, err
} }
// check runner remote url
u, err := url.Parse(cfg.Runner.URL)
if err != nil {
return cfg, err
}
cfg.Client.Proto = u.Scheme
cfg.Client.Host = u.Host
cfg.Client.Secret = cfg.Runner.Token cfg.Client.Secret = cfg.Runner.Token
// runner config // runner config
@ -97,5 +86,5 @@ func FromEnviron() (Config, error) {
} }
} }
return cfg, err return cfg, nil
} }

9
core/runner.go Normal file
View File

@ -0,0 +1,9 @@
package core
// Runner struct
type Runner struct {
ID int64 `json:"id"`
UUID string `json:"uuid"`
Name string `json:"name"`
Token string `json:"token"`
}

2
go.mod
View File

@ -3,7 +3,7 @@ module gitea.com/gitea/act_runner
go 1.18 go 1.18
require ( require (
gitea.com/gitea/proto-go v0.0.0-20221013073523-69d53451957a gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b
github.com/appleboy/com v0.1.6 github.com/appleboy/com v0.1.6
github.com/avast/retry-go/v4 v4.1.0 github.com/avast/retry-go/v4 v4.1.0
github.com/bufbuild/connect-go v0.5.0 github.com/bufbuild/connect-go v0.5.0

2
go.sum
View File

@ -27,6 +27,8 @@ gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa h1:HHqlvfIvqFlny3sgJgAM1B
gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa/go.mod h1:9W/Nz16tjfnWp7O5DUo3EjZBnZFBI/5rlWstX4o7+hU= gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa/go.mod h1:9W/Nz16tjfnWp7O5DUo3EjZBnZFBI/5rlWstX4o7+hU=
gitea.com/gitea/proto-go v0.0.0-20221013073523-69d53451957a h1:WHNPcbDR2vw2a17Ml06+n4MC0UwsyD/F3WeVteaXWMI= gitea.com/gitea/proto-go v0.0.0-20221013073523-69d53451957a h1:WHNPcbDR2vw2a17Ml06+n4MC0UwsyD/F3WeVteaXWMI=
gitea.com/gitea/proto-go v0.0.0-20221013073523-69d53451957a/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y= gitea.com/gitea/proto-go v0.0.0-20221013073523-69d53451957a/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y=
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b h1:TSz7VRHfnM/5JwGPgIAjSlDIvcr4pTGfuRMtgMxttmg=
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=

View File

@ -9,6 +9,7 @@ import (
"gitea.com/gitea/act_runner/client" "gitea.com/gitea/act_runner/client"
"gitea.com/gitea/act_runner/config" "gitea.com/gitea/act_runner/config"
"gitea.com/gitea/act_runner/core"
runnerv1 "gitea.com/gitea/proto-go/runner/v1" runnerv1 "gitea.com/gitea/proto-go/runner/v1"
"github.com/appleboy/com/file" "github.com/appleboy/com/file"
@ -44,16 +45,9 @@ type Poller struct {
errorRetryCounter int errorRetryCounter int
} }
type runner struct {
id int64
uuid string
name string
token string
}
func (p *Poller) Register(ctx context.Context, cfg config.Runner) error { func (p *Poller) Register(ctx context.Context, cfg config.Runner) error {
// check .runner config exist // check .runner config exist
if file.IsFile(".runner") { if file.IsFile(cfg.File) {
return nil return nil
} }
@ -61,7 +55,6 @@ func (p *Poller) Register(ctx context.Context, cfg config.Runner) error {
resp, err := p.Client.Register(ctx, connect.NewRequest(&runnerv1.RegisterRequest{ resp, err := p.Client.Register(ctx, connect.NewRequest(&runnerv1.RegisterRequest{
Name: cfg.Name, Name: cfg.Name,
Token: cfg.Token, Token: cfg.Token,
Url: cfg.URL,
AgentLabels: append(defaultLabels, []string{p.Filter.OS, p.Filter.Arch}...), AgentLabels: append(defaultLabels, []string{p.Filter.OS, p.Filter.Arch}...),
CustomLabels: p.Filter.Labels, CustomLabels: p.Filter.Labels,
})) }))
@ -70,21 +63,21 @@ func (p *Poller) Register(ctx context.Context, cfg config.Runner) error {
return err return err
} }
data := &runner{ data := &core.Runner{
id: resp.Msg.Runner.Id, ID: resp.Msg.Runner.Id,
uuid: resp.Msg.Runner.Uuid, UUID: resp.Msg.Runner.Uuid,
name: resp.Msg.Runner.Name, Name: resp.Msg.Runner.Name,
token: resp.Msg.Runner.Token, Token: resp.Msg.Runner.Token,
} }
file, err := json.MarshalIndent(data, "", " ") file, err := json.MarshalIndent(data, "", " ")
if err != nil { if err != nil {
log.WithError(err).Error("poller: cannot marshal the json input") log.WithError(err).Error("poller: cannot marshal the json input")
return err return err
} }
// store runner config in .runner file // store runner config in .runner file
return os.WriteFile(".runner", file, 0o644) return os.WriteFile(cfg.File, file, 0o644)
} }
func (p *Poller) Poll(ctx context.Context, n int) error { func (p *Poller) Poll(ctx context.Context, n int) error {