1
0
mirror of https://github.com/woodpecker-ci/woodpecker.git synced 2024-12-30 10:11:23 +02:00
woodpecker/server/main.go
Matt Bostock 307aed12bc Move open registration setting into remote plugins
...so that it's possible to enable or disable open registration on a
per-remote basis.

For example, the `DRONE_REGISTRATION_OPEN` environment variable now
becomes `DRONE_GITHUB_OPEN` when using GitHub as a remote.

The default for open registration in this commit is `false` (disabled),
which matches the existing behaviour.

This is useful if you need to support both public and private remotes,
e.g. GitHub.com and GitHub Enterprise, where you trust all of the
private users and want to allow open registration for those but would
not want all GitHub.com users to run builds on your server.

Tested with GitHub and GitLab.
2015-01-16 22:04:24 +00:00

190 lines
5.1 KiB
Go

package main
import (
"database/sql"
"flag"
"fmt"
"net/http"
"os"
"strings"
"github.com/drone/config"
"github.com/drone/drone/server/middleware"
"github.com/drone/drone/server/pubsub"
"github.com/drone/drone/server/router"
"github.com/drone/drone/shared/build/log"
"github.com/GeertJohan/go.rice"
"code.google.com/p/go.net/context"
webcontext "github.com/goji/context"
"github.com/zenazn/goji/web"
_ "github.com/drone/drone/plugin/notify/email"
"github.com/drone/drone/plugin/remote/bitbucket"
"github.com/drone/drone/plugin/remote/github"
"github.com/drone/drone/plugin/remote/gitlab"
"github.com/drone/drone/plugin/remote/gogs"
"github.com/drone/drone/server/blobstore"
"github.com/drone/drone/server/capability"
"github.com/drone/drone/server/datastore"
"github.com/drone/drone/server/datastore/database"
"github.com/drone/drone/server/worker/director"
"github.com/drone/drone/server/worker/docker"
"github.com/drone/drone/server/worker/pool"
)
const (
DockerTLSWarning = `WARINING: Docker TLS cert or key not given, this may cause a build errors`
)
var (
// commit sha for the current build, set by
// the compile process.
version string
revision string
)
var (
// Database driver configuration. Defaults to sqlite
// when no database configuration specified.
datasource = config.String("database-datasource", "drone.sqlite")
driver = config.String("database-driver", "sqlite3")
// HTTP Server settings.
port = config.String("server-port", ":8000")
sslcrt = config.String("server-ssl-cert", "")
sslkey = config.String("server-ssl-key", "")
workers *pool.Pool
worker *director.Director
pub *pubsub.PubSub
// Docker configuration details.
dockercert = config.String("docker-cert", "")
dockerkey = config.String("docker-key", "")
nodes StringArr
db *sql.DB
caps map[string]bool
)
func main() {
log.SetPriority(log.LOG_NOTICE)
// Parses flags. The only flag that can be passed into the
// application is the location of the configuration (.toml) file.
var conf string
flag.StringVar(&conf, "config", "", "")
flag.Parse()
config.Var(&nodes, "worker-nodes")
// Parses config data. The config data can be stored in a config
// file (.toml format) or environment variables, or a combo.
config.SetPrefix("DRONE_")
err := config.Parse(conf)
if err != nil {
log.Errf("Unable to parse config: %v", err)
os.Exit(1)
}
// Setup the remote services. We need to execute these to register
// the remote plugins with the system.
//
// NOTE: this cannot be done via init() because they need to be
// executed after config.Parse
bitbucket.Register()
github.Register()
gitlab.Register()
gogs.Register()
caps = map[string]bool{}
// setup the database and cancel all pending
// commits in the system.
db = database.MustConnect(*driver, *datasource)
go database.NewCommitstore(db).KillCommits()
// Create the worker, director and builders
workers = pool.New()
worker = director.New()
if nodes == nil || len(nodes) == 0 {
workers.Allocate(docker.New())
workers.Allocate(docker.New())
} else {
for _, node := range nodes {
if strings.HasPrefix(node, "unix://") {
workers.Allocate(docker.NewHost(node))
} else if *dockercert != "" && *dockerkey != "" {
workers.Allocate(docker.NewHostCertFile(node, *dockercert, *dockerkey))
} else {
fmt.Println(DockerTLSWarning)
workers.Allocate(docker.NewHost(node))
}
}
}
pub = pubsub.NewPubSub()
// create handler for static resources
assets := rice.MustFindBox("app").HTTPBox()
assetserve := http.FileServer(rice.MustFindBox("app").HTTPBox())
http.Handle("/robots.txt", assetserve)
http.Handle("/static/", http.StripPrefix("/static", assetserve))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write(assets.MustBytes("index.html"))
})
// create the router and add middleware
mux := router.New()
mux.Use(middleware.Options)
mux.Use(ContextMiddleware)
mux.Use(middleware.SetHeaders)
mux.Use(middleware.SetUser)
http.Handle("/api/", mux)
// start the http server in either http or https mode,
// depending on whether a certificate was provided.
if len(*sslcrt) == 0 {
panic(http.ListenAndServe(*port, nil))
} else {
panic(http.ListenAndServeTLS(*port, *sslcrt, *sslkey, nil))
}
}
// ContextMiddleware creates a new go.net/context and
// injects into the current goji context.
func ContextMiddleware(c *web.C, h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
var ctx = context.Background()
ctx = datastore.NewContext(ctx, database.NewDatastore(db))
ctx = blobstore.NewContext(ctx, database.NewBlobstore(db))
ctx = pool.NewContext(ctx, workers)
ctx = director.NewContext(ctx, worker)
ctx = pubsub.NewContext(ctx, pub)
ctx = capability.NewContext(ctx, caps)
// add the context to the goji web context
webcontext.Set(c, ctx)
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
type StringArr []string
func (s *StringArr) String() string {
return fmt.Sprint(*s)
}
func (s *StringArr) Set(value string) error {
for _, str := range strings.Split(value, ",") {
str = strings.TrimSpace(str)
*s = append(*s, str)
}
return nil
}