diff --git a/README.md b/README.md index 298050b..0b91152 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ Act runner is a runner for Forges supports Github Actions protocol. create a new file as name `.env` ```sh -GITEA_RUNNER_NAME=foobar -GITEA_RUNNER_URL=http://localhost:3000/foo/bar +GITEA_RUNNER_NAME= +GITEA_RPC_PROTO=http +GITEA_RPC_HOST=localhost:3001 GITEA_RUNNER_TOKEN=1234567890abcde GITEA_RUNNER_LABELS=foo,bar ``` diff --git a/cmd/daemon.go b/cmd/daemon.go index 62c2fb8..4c58eb3 100644 --- a/cmd/daemon.go +++ b/cmd/daemon.go @@ -94,11 +94,6 @@ func runDaemon(ctx context.Context, task *runtime.Task) func(cmd *cobra.Command, WithField("arch", cfg.Platform.Arch). Infoln("polling the remote server") - // register new runner - if err := poller.Register(ctx, cfg.Runner); err != nil { - return err - } - // update runner status to idle log.Infoln("update runner status to idle") if _, err := cli.UpdateRunner( diff --git a/cmd/register.go b/cmd/register.go new file mode 100644 index 0000000..72aa280 --- /dev/null +++ b/cmd/register.go @@ -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 + } +} diff --git a/cmd/root.go b/cmd/root.go index 09d0312..9fc3dda 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -52,12 +52,21 @@ func Execute(ctx context.Context) { // ./act_runner daemon daemonCmd := &cobra.Command{ Aliases: []string{"daemon"}, - Use: "daemon [event name to run]\nIf no event name passed, will default to \"on: push\"", - Short: "Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.", + Use: "execute runner daemon", Args: cobra.MaximumNArgs(1), 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 { os.Exit(1) diff --git a/config/config.go b/config/config.go index e41e46c..1e97a88 100644 --- a/config/config.go +++ b/config/config.go @@ -2,7 +2,6 @@ package config import ( "fmt" - "net/url" "os" "runtime" @@ -32,19 +31,17 @@ type ( Runner struct { Name string `envconfig:"GITEA_RUNNER_NAME"` - URL string `envconfig:"GITEA_RUNNER_URL" required:"true"` Token string `envconfig:"GITEA_RUNNER_TOKEN" required:"true"` Capacity int `envconfig:"GITEA_RUNNER_CAPACITY" default:"1"` + File string `envconfig:"GITEA_RUNNER_FILE" default:".runner"` Environ map[string]string `envconfig:"GITEA_RUNNER_ENVIRON"` EnvFile string `envconfig:"GITEA_RUNNER_ENV_FILE"` Labels []string `envconfig:"GITEA_RUNNER_LABELS"` } Platform struct { - OS string `envconfig:"GITEA_PLATFORM_OS"` - Arch string `envconfig:"GITEA_PLATFORM_ARCH"` - Kernel string `envconfig:"GITEA_PLATFORM_KERNEL"` - Variant string `envconfig:"GITEA_PLATFORM_VARIANT"` + OS string `envconfig:"GITEA_PLATFORM_OS"` + Arch string `envconfig:"GITEA_PLATFORM_ARCH"` } ) @@ -55,14 +52,6 @@ func FromEnviron() (Config, error) { 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 // runner config @@ -97,5 +86,5 @@ func FromEnviron() (Config, error) { } } - return cfg, err + return cfg, nil } diff --git a/core/runner.go b/core/runner.go new file mode 100644 index 0000000..0ea6559 --- /dev/null +++ b/core/runner.go @@ -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"` +} diff --git a/go.mod b/go.mod index 75f02dc..4fb7716 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gitea.com/gitea/act_runner go 1.18 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/avast/retry-go/v4 v4.1.0 github.com/bufbuild/connect-go v0.5.0 diff --git a/go.sum b/go.sum index 0f7d7bf..bb611a3 100644 --- a/go.sum +++ b/go.sum @@ -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/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-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/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= diff --git a/poller/poller.go b/poller/poller.go index 98f1223..95f914a 100644 --- a/poller/poller.go +++ b/poller/poller.go @@ -9,6 +9,7 @@ import ( "gitea.com/gitea/act_runner/client" "gitea.com/gitea/act_runner/config" + "gitea.com/gitea/act_runner/core" runnerv1 "gitea.com/gitea/proto-go/runner/v1" "github.com/appleboy/com/file" @@ -44,16 +45,9 @@ type Poller struct { errorRetryCounter int } -type runner struct { - id int64 - uuid string - name string - token string -} - func (p *Poller) Register(ctx context.Context, cfg config.Runner) error { // check .runner config exist - if file.IsFile(".runner") { + if file.IsFile(cfg.File) { 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{ Name: cfg.Name, Token: cfg.Token, - Url: cfg.URL, AgentLabels: append(defaultLabels, []string{p.Filter.OS, p.Filter.Arch}...), CustomLabels: p.Filter.Labels, })) @@ -70,21 +63,21 @@ func (p *Poller) Register(ctx context.Context, cfg config.Runner) error { return err } - data := &runner{ - id: resp.Msg.Runner.Id, - uuid: resp.Msg.Runner.Uuid, - name: resp.Msg.Runner.Name, - token: resp.Msg.Runner.Token, + data := &core.Runner{ + ID: resp.Msg.Runner.Id, + UUID: resp.Msg.Runner.Uuid, + Name: resp.Msg.Runner.Name, + Token: resp.Msg.Runner.Token, } - file, err := json.MarshalIndent(data, "", " ") + file, err := json.MarshalIndent(data, "", " ") if err != nil { log.WithError(err).Error("poller: cannot marshal the json input") return err } // 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 {