// TODO this has gotten a bit out of hand. refactor input params func run(path, identity, dockerhost, dockercert, dockerkey string, publish, deploy, privileged bool) (int, error) { dockerClient, err := docker.NewHostCertFile(dockerhost, dockercert, dockerkey) if err != nil { log.Err(err.Error()) return EXIT_STATUS, err } // parse the private environment variables envs := getParamMap("DRONE_ENV_") // parse the Drone yml file s, err := script.ParseBuildFile(path, envs) if err != nil { log.Err(err.Error()) return EXIT_STATUS, err } // inject private environment variables into build script for key, val := range envs { s.Env = append(s.Env, key+"="+val) } if deploy == false { s.Deploy = nil } if publish == false { s.Publish = nil } // get the repository root directory dir := filepath.Dir(path) code := repo.Repo{ Name: filepath.Base(dir), Branch: "HEAD", // should we do this? Path: dir, } // does the local repository match the // $GOPATH/src/{package} pattern? This is // important so we know the target location // where the code should be copied inside // the container. if gopath, ok := getRepoPath(dir); ok { code.Dir = gopath } else if gopath, ok := getGoPath(dir); ok { // in this case we found a GOPATH and // reverse engineered the package path code.Dir = gopath } else { // otherwise just use directory name code.Dir = filepath.Base(dir) } // this is where the code gets uploaded to the container // TODO move this code to the build package code.Dir = filepath.Join("/var/cache/drone/src", filepath.Clean(code.Dir)) // ssh key to import into container var key []byte if len(identity) != 0 { key, err = ioutil.ReadFile(identity) if err != nil { fmt.Printf("[Error] Could not find or read identity file %s\n", identity) return EXIT_STATUS, err } } // loop through and create builders builder := build.New(dockerClient) builder.Build = s builder.Repo = &code builder.Key = key builder.Stdout = os.Stdout builder.Timeout = 300 * time.Minute builder.Privileged = privileged // execute the build if err := builder.Run(); err != nil { log.Errf("Error executing build: %s", err.Error()) return EXIT_STATUS, err } fmt.Printf("\nDrone Build Results \033[90m(%s)\033[0m\n", dir) // loop through and print results build := builder.Build res := builder.BuildState duration := time.Duration(res.Finished - res.Started) switch { case builder.BuildState.ExitCode == 0: fmt.Printf(" \033[32m\u2713\033[0m %v \033[90m(%v)\033[0m\n", build.Name, humanizeDuration(duration*time.Second)) case builder.BuildState.ExitCode != 0: fmt.Printf(" \033[31m\u2717\033[0m %v \033[90m(%v)\033[0m\n", build.Name, humanizeDuration(duration*time.Second)) } return builder.BuildState.ExitCode, nil }
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() // 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 // 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) http.Handle("/static/", http.StripPrefix("/static", assetserve)) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { r.URL.Path = "/" assetserve.ServeHTTP(w, r) }) // 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)) } }