Пример #1
0
// 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
}
Пример #2
0
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))
	}
}