Exemple #1
0
// setup a mock docker client for testing purposes. This will use
// a test http server that can return mock responses to the docker client.
func setup() {
	mux = http.NewServeMux()
	server = httptest.NewServer(mux)

	url, _ := url.Parse(server.URL)
	url.Scheme = "tcp"
	os.Setenv("DOCKER_HOST", url.String())
	client = docker.New()
}
Exemple #2
0
// setup routes for serving dynamic content.
func setupHandlers() {
	queueRunner := queue.NewBuildRunner(docker.New(), timeout)
	queue := queue.Start(runtime.NumCPU(), queueRunner)

	hookHandler := handler.NewHookHandler(queue)

	m := pat.New()
	m.Get("/login", handler.ErrorHandler(handler.Login))
	m.Post("/login", handler.ErrorHandler(handler.Authorize))
	m.Get("/logout", handler.ErrorHandler(handler.Logout))
	m.Get("/forgot", handler.ErrorHandler(handler.Forgot))
	m.Post("/forgot", handler.ErrorHandler(handler.ForgotPost))
	m.Get("/reset", handler.ErrorHandler(handler.Reset))
	m.Post("/reset", handler.ErrorHandler(handler.ResetPost))
	m.Get("/signup", handler.ErrorHandler(handler.SignUp))
	m.Post("/signup", handler.ErrorHandler(handler.SignUpPost))
	m.Get("/register", handler.ErrorHandler(handler.Register))
	m.Post("/register", handler.ErrorHandler(handler.RegisterPost))
	m.Get("/accept", handler.UserHandler(handler.TeamMemberAccept))

	// handlers for setting up your GitHub repository
	m.Post("/new/github.com", handler.UserHandler(handler.RepoCreateGithub))
	m.Get("/new/github.com", handler.UserHandler(handler.RepoAdd))

	// handlers for linking your GitHub account
	m.Get("/auth/login/github", handler.UserHandler(handler.LinkGithub))

	// handlers for dashboard pages
	m.Get("/dashboard/team/:team", handler.UserHandler(handler.TeamShow))
	m.Get("/dashboard", handler.UserHandler(handler.UserShow))

	// handlers for user account management
	m.Get("/account/user/profile", handler.UserHandler(handler.UserEdit))
	m.Post("/account/user/profile", handler.UserHandler(handler.UserUpdate))
	m.Get("/account/user/delete", handler.UserHandler(handler.UserDeleteConfirm))
	m.Post("/account/user/delete", handler.UserHandler(handler.UserDelete))
	m.Get("/account/user/password", handler.UserHandler(handler.UserPass))
	m.Post("/account/user/password", handler.UserHandler(handler.UserPassUpdate))
	m.Get("/account/user/teams/add", handler.UserHandler(handler.TeamAdd))
	m.Post("/account/user/teams/add", handler.UserHandler(handler.TeamCreate))
	m.Get("/account/user/teams", handler.UserHandler(handler.UserTeams))

	// handlers for team managements
	m.Get("/account/team/:team/profile", handler.UserHandler(handler.TeamEdit))
	m.Post("/account/team/:team/profile", handler.UserHandler(handler.TeamUpdate))
	m.Get("/account/team/:team/delete", handler.UserHandler(handler.TeamDeleteConfirm))
	m.Post("/account/team/:team/delete", handler.UserHandler(handler.TeamDelete))
	m.Get("/account/team/:team/members/add", handler.UserHandler(handler.TeamMemberAdd))
	m.Post("/account/team/:team/members/add", handler.UserHandler(handler.TeamMemberInvite))
	m.Get("/account/team/:team/members/edit", handler.UserHandler(handler.TeamMemberEdit))
	m.Post("/account/team/:team/members/edit", handler.UserHandler(handler.TeamMemberUpdate))
	m.Post("/account/team/:team/members/delete", handler.UserHandler(handler.TeamMemberDelete))
	m.Get("/account/team/:team/members", handler.UserHandler(handler.TeamMembers))

	// handlers for system administration
	m.Get("/account/admin/settings", handler.AdminHandler(handler.AdminSettings))
	m.Post("/account/admin/settings", handler.AdminHandler(handler.AdminSettingsUpdate))
	m.Get("/account/admin/users/edit", handler.AdminHandler(handler.AdminUserEdit))
	m.Post("/account/admin/users/edit", handler.AdminHandler(handler.AdminUserUpdate))
	m.Post("/account/admin/users/delete", handler.AdminHandler(handler.AdminUserDelete))
	m.Get("/account/admin/users/add", handler.AdminHandler(handler.AdminUserAdd))
	m.Post("/account/admin/users", handler.AdminHandler(handler.AdminUserInvite))
	m.Get("/account/admin/users", handler.AdminHandler(handler.AdminUserList))

	// handlers for GitHub post-commit hooks
	m.Post("/hook/github.com", handler.ErrorHandler(hookHandler.Hook))

	// handlers for first-time installation
	m.Get("/install", handler.ErrorHandler(handler.Install))
	m.Post("/install", handler.ErrorHandler(handler.InstallPost))

	// handlers for repository, commits and build details
	m.Get("/:host/:owner/:name/commit/:commit/build/:label/out.txt", handler.RepoHandler(handler.BuildOut))
	m.Get("/:host/:owner/:name/commit/:commit/build/:label", handler.RepoHandler(handler.CommitShow))
	m.Get("/:host/:owner/:name/commit/:commit", handler.RepoHandler(handler.CommitShow))
	m.Get("/:host/:owner/:name/tree", handler.RepoHandler(handler.RepoDashboard))
	m.Get("/:host/:owner/:name/status.png", handler.ErrorHandler(handler.Badge))
	m.Get("/:host/:owner/:name/settings", handler.RepoAdminHandler(handler.RepoSettingsForm))
	m.Get("/:host/:owner/:name/params", handler.RepoAdminHandler(handler.RepoParamsForm))
	m.Get("/:host/:owner/:name/badges", handler.RepoAdminHandler(handler.RepoBadges))
	m.Get("/:host/:owner/:name/keys", handler.RepoAdminHandler(handler.RepoKeys))
	m.Get("/:host/:owner/:name/delete", handler.RepoAdminHandler(handler.RepoDeleteForm))
	m.Post("/:host/:owner/:name/delete", handler.RepoAdminHandler(handler.RepoDelete))
	m.Get("/:host/:owner/:name", handler.RepoHandler(handler.RepoDashboard))
	m.Post("/:host/:owner/:name", handler.RepoHandler(handler.RepoUpdate))
	http.Handle("/feed", websocket.Handler(channel.Read))

	// no routes are served at the root URL. Instead we will
	// redirect the user to his/her dashboard page.
	m.Get("/", http.RedirectHandler("/dashboard", http.StatusSeeOther))

	// the first time a page is requested we should record
	// the scheme and hostname.
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// our multiplexer is a bit finnicky and therefore requires
		// us to strip any trailing slashes in order to correctly
		// find and match a route.
		if r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/") {
			http.Redirect(w, r, r.URL.Path[:len(r.URL.Path)-1], http.StatusSeeOther)
			return
		}

		// standard header variables that should be set, for good measure.
		w.Header().Add("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
		w.Header().Add("X-Frame-Options", "DENY")
		w.Header().Add("X-Content-Type-Options", "nosniff")
		w.Header().Add("X-XSS-Protection", "1; mode=block")

		// ok, now we're ready to serve the request.
		m.ServeHTTP(w, r)
	})
}
Exemple #3
0
func run(path string) {
	dockerClient := docker.New()

	// parse the Drone yml file
	s, err := script.ParseBuildFile(path)
	if err != nil {
		log.Err(err.Error())
		os.Exit(1)
		return
	}

	// get the repository root directory
	dir := filepath.Dir(path)
	code := repo.Repo{
		Name:   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))

	// track all build results
	var builders []*build.Builder

	// 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)
			os.Exit(1)
			return
		}
	}

	builds := []*script.Build{s}

	// loop through and create builders
	for _, b := range builds { //script.Builds {
		builder := build.New(dockerClient)
		builder.Build = b
		builder.Repo = &code
		builder.Key = key
		builder.Stdout = os.Stdout
		builder.Timeout = *timeout

		if *parallel == true {
			var buf bytes.Buffer
			builder.Stdout = &buf
		}

		builders = append(builders, builder)
	}

	switch *parallel {
	case false:
		runSequential(builders)
	case true:
		runParallel(builders)
	}

	// if in parallel mode, print out the buffer
	// if we had a failure
	for _, builder := range builders {
		if builder.BuildState.ExitCode == 0 {
			continue
		}

		if buf, ok := builder.Stdout.(*bytes.Buffer); ok {
			log.Noticef("printing stdout for failed build %s", builder.Build.Name)
			println(buf.String())
		}
	}

	// this exit code is initially 0 and will
	// be set to an error code if any of the
	// builds fail.
	var exit int

	fmt.Printf("\nDrone Build Results \033[90m(%v)\033[0m\n", len(builders))

	// loop through and print results
	for _, builder := range builders {
		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))
			exit = builder.BuildState.ExitCode
		}
	}

	os.Exit(exit)
}
Exemple #4
0
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/drone/drone/pkg/build/buildfile"
	"github.com/drone/drone/pkg/build/docker"
	"github.com/drone/drone/pkg/build/dockerfile"
	"github.com/drone/drone/pkg/build/log"
	"github.com/drone/drone/pkg/build/proxy"
	"github.com/drone/drone/pkg/build/repo"
	"github.com/drone/drone/pkg/build/script"
)

// instance of the Docker client
var client = docker.New()

// BuildState stores information about a build
// process including the Exit status and various
// Runtime statistics (coming soon).
type BuildState struct {
	Started  int64
	Finished int64
	ExitCode int

	// we may eventually include detailed resource
	// usage statistics, including including CPU time,
	// Max RAM, Max Swap, Disk space, and more.
}

// Builder represents a build process being prepared