3d78433564
Fix #64 (incompletely). It's still not ideal. It makes more sense to use the gateway IP address of container network as outbound IP of cache server. However, this requires act to cooperate, some think like: - act creates the network for new container, and returns the network to runner. - runner extracts the gateway IP in the network. - runner uses the gateway IP as outbound IP, and pass it to act as cache server endpoint. - act It continues to create the container with the created network. Reviewed-on: https://gitea.com/gitea/act_runner/pulls/74 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
121 lines
2.7 KiB
Go
121 lines
2.7 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/mattn/go-isatty"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
"codeberg.org/forgejo/runner/artifactcache"
|
|
"codeberg.org/forgejo/runner/client"
|
|
"codeberg.org/forgejo/runner/config"
|
|
"codeberg.org/forgejo/runner/engine"
|
|
"codeberg.org/forgejo/runner/poller"
|
|
"codeberg.org/forgejo/runner/runtime"
|
|
)
|
|
|
|
func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, args []string) error {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
log.Infoln("Starting runner daemon")
|
|
|
|
_ = godotenv.Load(envFile)
|
|
cfg, err := config.FromEnviron()
|
|
if err != nil {
|
|
log.WithError(err).
|
|
Fatalln("invalid configuration")
|
|
}
|
|
|
|
initLogging(cfg)
|
|
|
|
// require docker if a runner label uses a docker backend
|
|
needsDocker := false
|
|
for _, l := range cfg.Runner.Labels {
|
|
_, schema, _, _ := runtime.ParseLabel(l)
|
|
if schema == "docker" {
|
|
needsDocker = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if needsDocker {
|
|
// try to connect to docker daemon
|
|
// if failed, exit with error
|
|
if err := engine.Start(ctx); err != nil {
|
|
log.WithError(err).Fatalln("failed to connect docker daemon engine")
|
|
}
|
|
}
|
|
|
|
var g errgroup.Group
|
|
|
|
cli := client.New(
|
|
cfg.Client.Address,
|
|
cfg.Client.Insecure,
|
|
cfg.Runner.UUID,
|
|
cfg.Runner.Token,
|
|
version,
|
|
)
|
|
|
|
runner := &runtime.Runner{
|
|
Client: cli,
|
|
Machine: cfg.Runner.Name,
|
|
ForgeInstance: cfg.Client.Address,
|
|
Environ: cfg.Runner.Environ,
|
|
Labels: cfg.Runner.Labels,
|
|
Version: version,
|
|
}
|
|
|
|
if handler, err := artifactcache.NewHandler(); err != nil {
|
|
log.Errorf("cannot init cache server, it will be disabled: %v", err)
|
|
} else {
|
|
log.Infof("cache handler listens on: %v", handler.ExternalURL())
|
|
runner.CacheHandler = handler
|
|
}
|
|
|
|
poller := poller.New(
|
|
cli,
|
|
runner.Run,
|
|
cfg.Runner.Capacity,
|
|
)
|
|
|
|
g.Go(func() error {
|
|
l := log.WithField("capacity", cfg.Runner.Capacity).
|
|
WithField("endpoint", cfg.Client.Address).
|
|
WithField("os", cfg.Platform.OS).
|
|
WithField("arch", cfg.Platform.Arch)
|
|
l.Infoln("polling the remote server")
|
|
|
|
if err := poller.Poll(ctx); err != nil {
|
|
l.Errorf("poller error: %v", err)
|
|
}
|
|
poller.Wait()
|
|
return nil
|
|
})
|
|
|
|
err = g.Wait()
|
|
if err != nil {
|
|
log.WithError(err).
|
|
Errorln("shutting down the server")
|
|
}
|
|
return err
|
|
}
|
|
}
|
|
|
|
// initLogging setup the global logrus logger.
|
|
func initLogging(cfg config.Config) {
|
|
isTerm := isatty.IsTerminal(os.Stdout.Fd())
|
|
log.SetFormatter(&log.TextFormatter{
|
|
DisableColors: !isTerm,
|
|
FullTimestamp: true,
|
|
})
|
|
|
|
if cfg.Debug {
|
|
log.SetLevel(log.DebugLevel)
|
|
}
|
|
if cfg.Trace {
|
|
log.SetLevel(log.TraceLevel)
|
|
}
|
|
}
|