2019-02-19 23:56:41 +00:00
|
|
|
// Copyright 2019 Drone IO, Inc.
|
2018-03-21 13:02:17 +00:00
|
|
|
//
|
2018-02-19 22:24:10 +00:00
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
2018-03-21 13:02:17 +00:00
|
|
|
//
|
2018-02-19 22:24:10 +00:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2018-03-21 13:02:17 +00:00
|
|
|
//
|
2018-02-19 22:24:10 +00:00
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2017-06-29 22:51:22 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2019-02-19 23:56:41 +00:00
|
|
|
"context"
|
|
|
|
"flag"
|
2017-06-29 22:51:22 +00:00
|
|
|
"fmt"
|
|
|
|
|
2019-02-19 23:56:41 +00:00
|
|
|
"github.com/drone/drone/cmd/drone-server/bootstrap"
|
|
|
|
"github.com/drone/drone/cmd/drone-server/config"
|
|
|
|
"github.com/drone/drone/core"
|
2019-03-05 07:16:53 +00:00
|
|
|
"github.com/drone/drone/metric/sink"
|
2019-02-19 23:56:41 +00:00
|
|
|
"github.com/drone/drone/operator/runner"
|
2020-06-05 02:15:30 +00:00
|
|
|
"github.com/drone/drone/service/canceler/reaper"
|
2019-02-19 23:56:41 +00:00
|
|
|
"github.com/drone/drone/server"
|
|
|
|
"github.com/drone/drone/trigger/cron"
|
|
|
|
"github.com/drone/signal"
|
2017-06-29 22:51:22 +00:00
|
|
|
|
2019-02-19 23:56:41 +00:00
|
|
|
"github.com/joho/godotenv"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
|
_ "github.com/lib/pq"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
2017-06-29 22:51:22 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2019-02-19 23:56:41 +00:00
|
|
|
var envfile string
|
|
|
|
flag.StringVar(&envfile, "env-file", ".env", "Read in a file of environment variables")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
godotenv.Load(envfile)
|
|
|
|
config, err := config.Environ()
|
|
|
|
if err != nil {
|
|
|
|
logger := logrus.WithError(err)
|
|
|
|
logger.Fatalln("main: invalid configuration")
|
|
|
|
}
|
|
|
|
|
|
|
|
initLogging(config)
|
|
|
|
ctx := signal.WithContext(
|
|
|
|
context.Background(),
|
|
|
|
)
|
|
|
|
|
|
|
|
// if trace level logging is enabled, output the
|
|
|
|
// configuration parameters.
|
|
|
|
if logrus.IsLevelEnabled(logrus.TraceLevel) {
|
|
|
|
fmt.Println(config.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
app, err := InitializeApplication(config)
|
|
|
|
if err != nil {
|
|
|
|
logger := logrus.WithError(err)
|
|
|
|
logger.Fatalln("main: cannot initialize server")
|
|
|
|
}
|
|
|
|
|
|
|
|
// optionally bootstrap the system with administrative or
|
|
|
|
// machine users configured in the environment.
|
|
|
|
err = bootstrap.New(app.users).Bootstrap(ctx, &core.User{
|
|
|
|
Login: config.Users.Create.Username,
|
|
|
|
Machine: config.Users.Create.Machine,
|
|
|
|
Admin: config.Users.Create.Admin,
|
|
|
|
Hash: config.Users.Create.Token,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
logger := logrus.WithError(err)
|
|
|
|
logger.Fatalln("cannot bootstrap user account")
|
|
|
|
}
|
|
|
|
|
|
|
|
g := errgroup.Group{}
|
|
|
|
g.Go(func() error {
|
|
|
|
logrus.WithFields(
|
|
|
|
logrus.Fields{
|
|
|
|
"proto": config.Server.Proto,
|
|
|
|
"host": config.Server.Host,
|
|
|
|
"port": config.Server.Port,
|
|
|
|
"url": config.Server.Addr,
|
|
|
|
"acme": config.Server.Acme,
|
|
|
|
},
|
|
|
|
).Infoln("starting the http server")
|
|
|
|
return app.server.ListenAndServe(ctx)
|
|
|
|
})
|
|
|
|
|
2019-03-05 07:16:53 +00:00
|
|
|
// launches the datadog sink in a goroutine. If the sink
|
|
|
|
// is disabled, the goroutine exits immediately without error.
|
|
|
|
g.Go(func() (err error) {
|
|
|
|
if !config.Datadog.Enabled {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return app.sink.Start(ctx)
|
|
|
|
})
|
|
|
|
|
2019-02-19 23:56:41 +00:00
|
|
|
// launches the cron runner in a goroutine. If the cron
|
|
|
|
// runner is disabled, the goroutine exits immediately
|
|
|
|
// without error.
|
|
|
|
g.Go(func() (err error) {
|
|
|
|
if config.Cron.Disabled {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
logrus.WithField("interval", config.Cron.Interval.String()).
|
|
|
|
Infoln("starting the cron scheduler")
|
|
|
|
return app.cron.Start(ctx, config.Cron.Interval)
|
|
|
|
})
|
|
|
|
|
2020-06-05 02:15:30 +00:00
|
|
|
// launches the reaper in a goroutine. If the reaper
|
|
|
|
// is disabled, the goroutine exits immediately
|
|
|
|
// without error.
|
|
|
|
g.Go(func() (err error) {
|
|
|
|
if config.Cleanup.Disabled {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
logrus.WithField("interval", config.Cleanup.Interval.String()).
|
|
|
|
Infoln("starting the zombie build reaper")
|
|
|
|
return app.reaper.Start(ctx, config.Cleanup.Interval)
|
|
|
|
})
|
|
|
|
|
2019-02-19 23:56:41 +00:00
|
|
|
// launches the build runner in a goroutine. If the local
|
|
|
|
// runner is disabled (because nomad or kubernetes is enabled)
|
|
|
|
// then the goroutine exits immediately without error.
|
|
|
|
g.Go(func() (err error) {
|
|
|
|
if app.runner == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
logrus.WithField("threads", config.Runner.Capacity).
|
|
|
|
Infoln("main: starting the local build runner")
|
|
|
|
return app.runner.Start(ctx, config.Runner.Capacity)
|
|
|
|
})
|
|
|
|
|
|
|
|
if err := g.Wait(); err != nil {
|
|
|
|
logrus.WithError(err).Fatalln("program terminated")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 01:27:15 +00:00
|
|
|
// helper function configures the logging.
|
2019-02-19 23:56:41 +00:00
|
|
|
func initLogging(c config.Config) {
|
|
|
|
if c.Logging.Debug {
|
|
|
|
logrus.SetLevel(logrus.DebugLevel)
|
|
|
|
}
|
|
|
|
if c.Logging.Trace {
|
|
|
|
logrus.SetLevel(logrus.TraceLevel)
|
|
|
|
}
|
|
|
|
if c.Logging.Text {
|
|
|
|
logrus.SetFormatter(&logrus.TextFormatter{
|
|
|
|
ForceColors: c.Logging.Color,
|
|
|
|
DisableColors: !c.Logging.Color,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
logrus.SetFormatter(&logrus.JSONFormatter{
|
|
|
|
PrettyPrint: c.Logging.Pretty,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// application is the main struct for the Drone server.
|
|
|
|
type application struct {
|
|
|
|
cron *cron.Scheduler
|
2020-06-05 02:15:30 +00:00
|
|
|
reaper *reaper.Reaper
|
2019-03-05 07:16:53 +00:00
|
|
|
sink *sink.Datadog
|
2019-02-19 23:56:41 +00:00
|
|
|
runner *runner.Runner
|
|
|
|
server *server.Server
|
|
|
|
users core.UserStore
|
|
|
|
}
|
|
|
|
|
|
|
|
// newApplication creates a new application struct.
|
|
|
|
func newApplication(
|
|
|
|
cron *cron.Scheduler,
|
2020-06-05 02:15:30 +00:00
|
|
|
reaper *reaper.Reaper,
|
2019-03-05 07:16:53 +00:00
|
|
|
sink *sink.Datadog,
|
2019-02-19 23:56:41 +00:00
|
|
|
runner *runner.Runner,
|
|
|
|
server *server.Server,
|
|
|
|
users core.UserStore) application {
|
|
|
|
return application{
|
|
|
|
users: users,
|
|
|
|
cron: cron,
|
2019-03-05 07:16:53 +00:00
|
|
|
sink: sink,
|
2019-02-19 23:56:41 +00:00
|
|
|
server: server,
|
|
|
|
runner: runner,
|
2020-06-05 02:15:30 +00:00
|
|
|
reaper: reaper,
|
2017-06-29 22:51:22 +00:00
|
|
|
}
|
|
|
|
}
|