This repository has been archived on 2025-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
Files
drone-runner-podman/command/daemon/daemon.go
2019-10-19 11:39:16 -07:00

216 lines
4.8 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Polyform License
// that can be found in the LICENSE file.
package daemon
import (
"context"
"time"
"github.com/drone-runners/drone-runner-docker/engine"
"github.com/drone-runners/drone-runner-docker/engine/compiler"
"github.com/drone-runners/drone-runner-docker/engine/linter"
"github.com/drone-runners/drone-runner-docker/engine/resource"
"github.com/drone-runners/drone-runner-docker/internal/match"
"github.com/drone-runners/drone-runner-docker/runtime"
"github.com/drone/runner-go/client"
"github.com/drone/runner-go/handler/router"
"github.com/drone/runner-go/logger"
loghistory "github.com/drone/runner-go/logger/history"
"github.com/drone/runner-go/pipeline/history"
"github.com/drone/runner-go/pipeline/remote"
"github.com/drone/runner-go/secret"
"github.com/drone/runner-go/server"
"github.com/drone/signal"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
"gopkg.in/alecthomas/kingpin.v2"
)
// empty context.
var nocontext = context.Background()
type daemonCommand struct {
envfile string
}
func (c *daemonCommand) run(*kingpin.ParseContext) error {
// load environment variables from file.
godotenv.Load(c.envfile)
// load the configuration from the environment
config, err := fromEnviron()
if err != nil {
return err
}
// setup the global logrus logger.
setupLogger(config)
cli := client.New(
config.Client.Address,
config.Client.Secret,
config.Client.SkipVerify,
)
if config.Client.Dump {
cli.Dumper = logger.StandardDumper(
config.Client.DumpBody,
)
}
cli.Logger = logger.Logrus(
logrus.NewEntry(
logrus.StandardLogger(),
),
)
engine, err := engine.New(config.Keypair.Public, config.Keypair.Private)
if err != nil {
return err
}
remote := remote.New(cli)
tracer := history.New(remote)
hook := loghistory.New()
logrus.AddHook(hook)
poller := &runtime.Poller{
Client: cli,
Runner: &runtime.Runner{
Client: cli,
Machine: config.Runner.Name,
Reporter: tracer,
Linter: linter.New(),
Match: match.Func(
config.Limit.Repos,
config.Limit.Events,
config.Limit.Trusted,
),
Compiler: &compiler.Compiler{
Environ: nil,
Labels: nil,
Privileged: nil,
Networks: nil,
Volumes: nil,
// Resources: nil,
Registry: nil,
Secret: secret.External(
config.Secret.Endpoint,
config.Secret.Token,
config.Secret.SkipVerify,
),
},
Execer: runtime.NewExecer(
tracer,
remote,
engine,
config.Runner.Procs,
),
},
Filter: &client.Filter{
Kind: resource.Kind,
Type: resource.Type,
Labels: config.Runner.Labels,
},
}
ctx, cancel := context.WithCancel(nocontext)
defer cancel()
// listen for termination signals to gracefully shutdown
// the runner daemon.
ctx = signal.WithContextFunc(ctx, func() {
println("received signal, terminating process")
cancel()
})
var g errgroup.Group
server := server.Server{
Addr: config.Server.Port,
Handler: router.New(tracer, hook, router.Config{
Username: config.Dashboard.Username,
Password: config.Dashboard.Password,
Realm: config.Dashboard.Realm,
}),
}
logrus.WithField("addr", config.Server.Port).
Infoln("starting the server")
g.Go(func() error {
return server.ListenAndServe(ctx)
})
// Ping the server and block until a successful connection
// to the server has been established.
for {
err := cli.Ping(ctx, config.Runner.Name)
select {
case <-ctx.Done():
return nil
default:
}
if ctx.Err() != nil {
break
}
if err != nil {
logrus.WithError(err).
Errorln("cannot ping the remote server")
time.Sleep(time.Second)
} else {
logrus.Infoln("successfully pinged the remote server")
break
}
}
g.Go(func() error {
logrus.WithField("capacity", config.Runner.Capacity).
WithField("endpoint", config.Client.Address).
WithField("kind", resource.Kind).
WithField("type", resource.Type).
Infoln("polling the remote server")
poller.Poll(ctx, config.Runner.Capacity)
return nil
})
err = g.Wait()
if err != nil {
logrus.WithError(err).
Errorln("shutting down the server")
}
return err
}
// helper function configures the global logger from
// the loaded configuration.
func setupLogger(config Config) {
logger.Default = logger.Logrus(
logrus.NewEntry(
logrus.StandardLogger(),
),
)
if config.Debug {
logrus.SetLevel(logrus.DebugLevel)
}
if config.Trace {
logrus.SetLevel(logrus.TraceLevel)
}
}
// Register the daemon command.
func Register(app *kingpin.Application) {
c := new(daemonCommand)
cmd := app.Command("daemon", "starts the runner daemon").
Default().
Action(c.run)
cmd.Arg("envfile", "load the environment variable file").
Default("").
StringVar(&c.envfile)
}