woodpecker/server/main.go

194 lines
5.2 KiB
Go
Raw Normal View History

2014-06-04 21:25:38 +00:00
package main
import (
"database/sql"
"flag"
"fmt"
2014-06-04 21:25:38 +00:00
"net/http"
"os"
"strings"
2014-06-04 21:25:38 +00:00
"github.com/drone/config"
2014-09-29 01:36:24 +00:00
"github.com/drone/drone/server/middleware"
2014-09-30 07:43:50 +00:00
"github.com/drone/drone/server/pubsub"
"github.com/drone/drone/server/router"
2014-06-12 19:44:19 +00:00
"github.com/drone/drone/shared/build/log"
2014-06-04 21:25:38 +00:00
2014-09-30 07:43:50 +00:00
"github.com/GeertJohan/go.rice"
2014-07-13 02:01:58 +00:00
2014-09-29 01:36:24 +00:00
"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"
2014-09-28 03:36:11 +00:00
"github.com/drone/drone/plugin/remote/gogs"
2014-09-29 01:36:24 +00:00
"github.com/drone/drone/server/blobstore"
"github.com/drone/drone/server/datastore"
"github.com/drone/drone/server/datastore/database"
2014-09-29 03:21:02 +00:00
"github.com/drone/drone/server/worker/director"
"github.com/drone/drone/server/worker/docker"
"github.com/drone/drone/server/worker/pool"
2014-06-04 21:25:38 +00:00
)
const (
2015-07-06 01:06:54 +00:00
DockerTLSWarning = `WARNING: Docker TLS cert or key not given, this may cause a build errors`
)
2014-06-04 21:25:38 +00:00
var (
2014-10-11 21:30:51 +00:00
// commit sha for the current build, set by
// the compile process.
2015-01-12 13:51:54 +00:00
version string
2014-06-04 21:25:38 +00:00
revision string
2014-10-11 21:30:51 +00:00
)
2014-10-11 21:30:51 +00:00
var (
// Database driver configuration. Defaults to sqlite
// when no database configuration specified.
datasource = config.String("database-datasource", "drone.sqlite")
2014-10-11 21:30:51 +00:00
driver = config.String("database-driver", "sqlite3")
2014-10-11 21:30:51 +00:00
// HTTP Server settings.
port = config.String("server-port", ":8000")
sslcrt = config.String("server-ssl-cert", "")
sslkey = config.String("server-ssl-key", "")
assets_folder = config.String("server-assets-folder", "")
2014-10-11 21:30:51 +00:00
workers *pool.Pool
worker *director.Director
pub *pubsub.PubSub
2014-09-30 07:43:50 +00:00
2014-10-11 21:30:51 +00:00
// Docker configuration details.
dockercert = config.String("docker-cert", "")
dockerkey = config.String("docker-key", "")
nodes StringArr
2014-09-29 01:36:24 +00:00
db *sql.DB
2014-06-04 21:25:38 +00:00
)
func main() {
2014-06-12 19:44:19 +00:00
log.SetPriority(log.LOG_NOTICE)
2014-10-11 21:30:51 +00:00
// 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", "", "")
2014-06-04 21:25:38 +00:00
flag.Parse()
config.Var(&nodes, "worker-nodes")
2014-10-11 21:30:51 +00:00
// 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)
}
2014-10-11 21:30:51 +00:00
// 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()
2014-09-28 03:36:11 +00:00
gogs.Register()
2014-09-29 01:36:24 +00:00
// setup the database and cancel all pending
// commits in the system.
2014-10-11 21:30:51 +00:00
db = database.MustConnect(*driver, *datasource)
2014-09-29 01:36:24 +00:00
go database.NewCommitstore(db).KillCommits()
2014-09-29 03:21:02 +00:00
// 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))
}
2014-09-29 03:21:02 +00:00
}
}
pub = pubsub.NewPubSub()
2014-09-29 03:21:02 +00:00
2014-10-11 21:30:51 +00:00
// create handler for static resources
// if we have a configured assets folder it takes precedence over the assets
// bundled to the binary
var assetserve http.Handler
if *assets_folder != "" {
assetserve = http.FileServer(http.Dir(*assets_folder))
} else {
assetserve = http.FileServer(rice.MustFindBox("app").HTTPBox())
}
http.Handle("/robots.txt", assetserve)
2014-09-30 07:43:50 +00:00
http.Handle("/static/", http.StripPrefix("/static", assetserve))
2015-02-06 16:40:59 +00:00
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
r.URL.Path = "/"
assetserve.ServeHTTP(w, r)
})
2014-09-30 07:43:50 +00:00
// create the router and add middleware
mux := router.New()
2014-11-16 06:15:22 +00:00
mux.Use(middleware.Options)
2014-10-11 21:30:51 +00:00
mux.Use(ContextMiddleware)
mux.Use(middleware.SetHeaders)
mux.Use(middleware.SetUser)
http.Handle("/api/", mux)
2014-10-11 21:30:51 +00:00
// 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 {
2014-10-11 21:30:51 +00:00
panic(http.ListenAndServeTLS(*port, *sslcrt, *sslkey, nil))
}
2014-09-29 01:36:24 +00:00
}
// 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))
2014-09-29 03:21:02 +00:00
ctx = pool.NewContext(ctx, workers)
ctx = director.NewContext(ctx, worker)
2014-09-30 07:43:50 +00:00
ctx = pubsub.NewContext(ctx, pub)
2014-09-29 01:36:24 +00:00
// add the context to the goji web context
webcontext.Set(c, ctx)
h.ServeHTTP(w, r)
2014-06-04 21:25:38 +00:00
}
2014-09-29 01:36:24 +00:00
return http.HandlerFunc(fn)
2014-06-04 21:25:38 +00:00
}
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
}