Merge branch 'master' of github.com:drone/drone into mesos-marathon

This commit is contained in:
Dwayne Jones 2015-07-31 13:02:27 -04:00
commit 55b9c34708
8 changed files with 100 additions and 48 deletions

View file

@ -35,6 +35,7 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
// parse the hook payload // parse the hook payload
hook, err := remote.ParseHook(r) hook, err := remote.ParseHook(r)
if err != nil { if err != nil {
log.Printf("Unable to parse hook. %s\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -84,6 +85,7 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
user.TokenExpiry = user_token.Expiry user.TokenExpiry = user_token.Expiry
datastore.PutUser(ctx, user) datastore.PutUser(ctx, user)
} else if err != nil { } else if err != nil {
log.Printf("Unable to refresh token. %s\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -91,6 +93,7 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
// featch the .drone.yml file from the database // featch the .drone.yml file from the database
yml, err := remote.GetScript(user, repo, hook) yml, err := remote.GetScript(user, repo, hook)
if err != nil { if err != nil {
log.Printf("Unable to fetch .drone.yml file. %s\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -118,12 +121,14 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
// inserts the commit into the database // inserts the commit into the database
if err := datastore.PostCommit(ctx, &commit); err != nil { if err := datastore.PostCommit(ctx, &commit); err != nil {
log.Printf("Unable to persist commit %s@%s. %s\n", commit.Sha, commit.Branch, err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
owner, err := datastore.GetUser(ctx, repo.UserID) owner, err := datastore.GetUser(ctx, repo.UserID)
if err != nil { if err != nil {
log.Printf("Unable to retrieve repository owner. %s.\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }

View file

@ -102,15 +102,6 @@ func (d *Docker) Do(c context.Context, r *worker.Work) {
log.Printf("Error parsing YAML for %s/%s, Err: %s", r.Repo.Owner, r.Repo.Name, err.Error()) log.Printf("Error parsing YAML for %s/%s, Err: %s", r.Repo.Owner, r.Repo.Name, err.Error())
} }
// append private parameters to the environment
// variable section of the .drone.yml file, iff
// this is not a pull request (for security purposes)
if params != nil && (r.Repo.Private || len(r.Commit.PullRequest) == 0) {
for k, v := range params {
script.Env = append(script.Env, k+"="+v)
}
}
// TODO: handle error better? // TODO: handle error better?
buildNumber, err := datastore.GetBuildNumber(c, r.Commit) buildNumber, err := datastore.GetBuildNumber(c, r.Commit)
if err != nil { if err != nil {
@ -126,10 +117,20 @@ func (d *Docker) Do(c context.Context, r *worker.Work) {
Branch: r.Commit.Branch, Branch: r.Commit.Branch,
Commit: r.Commit.Sha, Commit: r.Commit.Sha,
PR: r.Commit.PullRequest, PR: r.Commit.PullRequest,
Private: r.Repo.Private,
Dir: filepath.Join("/var/cache/drone/src", git.GitPath(script.Git, path)), Dir: filepath.Join("/var/cache/drone/src", git.GitPath(script.Git, path)),
Depth: git.GitDepth(script.Git), Depth: git.GitDepth(script.Git),
} }
// append private parameters to the environment
// variable section of the .drone.yml file, if
// this is trusted
if params != nil && repo.IsTrusted() {
for k, v := range params {
script.Env = append(script.Env, k+"="+v)
}
}
priorCommit, _ := datastore.GetCommitPrior(c, r.Commit) priorCommit, _ := datastore.GetCommitPrior(c, r.Commit)
// send all "started" notifications // send all "started" notifications
@ -152,7 +153,7 @@ func (d *Docker) Do(c context.Context, r *worker.Work) {
builder.Timeout = time.Duration(r.Repo.Timeout) * time.Second builder.Timeout = time.Duration(r.Repo.Timeout) * time.Second
builder.Privileged = r.Repo.Privileged builder.Privileged = r.Repo.Privileged
if r.Repo.Private || len(r.Commit.PullRequest) == 0 { if repo.IsTrusted() {
builder.Key = []byte(r.Repo.PrivateKey) builder.Key = []byte(r.Repo.PrivateKey)
} }

View file

@ -327,7 +327,7 @@ func (b *Builder) run() error {
// configure if Docker should run in privileged mode // configure if Docker should run in privileged mode
host := docker.HostConfig{ host := docker.HostConfig{
Privileged: (b.Privileged && len(b.Repo.PR) == 0), Privileged: (b.Privileged && b.Repo.IsTrusted()),
} }
if host.Privileged { if host.Privileged {

View file

@ -55,14 +55,14 @@ func TestSetup(t *testing.T) {
// Handles a request to inspect the Go 1.2 image // Handles a request to inspect the Go 1.2 image
// This will return a dummy image ID, so that the system knows // This will return a dummy image ID, so that the system knows
// the build image exists, and doens't need to be downloaded. // the build image exists, and doens't need to be downloaded.
mux.HandleFunc("/v1.9/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) {
body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]` body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
// Handles a request to create the build image, with the build // Handles a request to create the build image, with the build
// script injected. This will return a dummy stream. // script injected. This will return a dummy stream.
mux.HandleFunc("/v1.9/build", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/build", func(w http.ResponseWriter, r *http.Request) {
body := `{"stream":"Step 1..."}` body := `{"stream":"Step 1..."}`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
@ -71,7 +71,7 @@ func TestSetup(t *testing.T) {
// that we are doing a "wildcard" url match here, since the name of // that we are doing a "wildcard" url match here, since the name of
// the image will be random. This will return a dummy image ID // the image will be random. This will return a dummy image ID
// to confirm the build image was created successfully. // to confirm the build image was created successfully.
mux.HandleFunc("/v1.9/images/", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/", func(w http.ResponseWriter, r *http.Request) {
body := `{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }` body := `{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
@ -122,7 +122,7 @@ func TestSetupErrorPullImage(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
}) })
@ -134,12 +134,12 @@ func TestSetupErrorRunDaemonPorts(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) {
data := []byte(`{"config": { "ExposedPorts": { "6379/tcp": {}}}}`) data := []byte(`{"config": { "ExposedPorts": { "6379/tcp": {}}}}`)
w.Write(data) w.Write(data)
}) })
mux.HandleFunc("/v1.9/containers/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/create", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -164,21 +164,21 @@ func TestSetupErrorServiceInspect(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) {
data := []byte(`{"config": { "ExposedPorts": { "6379/tcp": {}}}}`) data := []byte(`{"config": { "ExposedPorts": { "6379/tcp": {}}}}`)
w.Write(data) w.Write(data)
}) })
mux.HandleFunc("/v1.9/containers/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/create", func(w http.ResponseWriter, r *http.Request) {
body := `{ "Id":"e90e34656806", "Warnings":[] }` body := `{ "Id":"e90e34656806", "Warnings":[] }`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
}) })
mux.HandleFunc("/v1.9/containers/e90e34656806/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/e90e34656806/json", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -202,11 +202,11 @@ func TestSetupErrorImagePull(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/mysql:5.5/json", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
}) })
mux.HandleFunc("/v1.9/images/create?fromImage=bradrydzewski/mysql&tag=5.5", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/create?fromImage=bradrydzewski/mysql&tag=5.5", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -230,7 +230,7 @@ func TestSetupErrorUpdate(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/create", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -254,12 +254,12 @@ func TestSetupErrorBuild(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) {
body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]` body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/build", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/build", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -284,17 +284,17 @@ func TestSetupErrorBuildInspect(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/bradrydzewski/go:1.2/json", func(w http.ResponseWriter, r *http.Request) {
body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]` body := `[{ "id": "7bf9ce0ffb7236ca68da0f9fed0e1682053b393db3c724ff3c5a4e8c0793b34c" }]`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/build", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/build", func(w http.ResponseWriter, r *http.Request) {
body := `{"stream":"Step 1..."}` body := `{"stream":"Step 1..."}`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/images/", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -325,27 +325,27 @@ func TestTeardown(t *testing.T) {
imageRemoved = false imageRemoved = false
) )
mux.HandleFunc("/v1.9/containers/7bf9ce0ffb/stop", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/7bf9ce0ffb/stop", func(w http.ResponseWriter, r *http.Request) {
containerStopped = true containerStopped = true
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}) })
mux.HandleFunc("/v1.9/containers/7bf9ce0ffb", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/7bf9ce0ffb", func(w http.ResponseWriter, r *http.Request) {
containerRemoved = true containerRemoved = true
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}) })
mux.HandleFunc("/v1.9/containers/ec62dcc736/stop", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/ec62dcc736/stop", func(w http.ResponseWriter, r *http.Request) {
serviceStopped = true serviceStopped = true
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}) })
mux.HandleFunc("/v1.9/containers/ec62dcc736", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/ec62dcc736", func(w http.ResponseWriter, r *http.Request) {
serviceRemoved = true serviceRemoved = true
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}) })
mux.HandleFunc("/v1.9/images/c3ab8ff137", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/images/c3ab8ff137", func(w http.ResponseWriter, r *http.Request) {
imageRemoved = true imageRemoved = true
w.Write([]byte(`[{"Untagged":"c3ab8ff137"},{"Deleted":"c3ab8ff137"}]`)) w.Write([]byte(`[{"Untagged":"c3ab8ff137"},{"Deleted":"c3ab8ff137"}]`))
}) })
@ -389,12 +389,12 @@ func TestRunPrivileged(t *testing.T) {
var conf = docker.HostConfig{} var conf = docker.HostConfig{}
mux.HandleFunc("/v1.9/containers/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/create", func(w http.ResponseWriter, r *http.Request) {
body := `{ "Id":"e90e34656806", "Warnings":[] }` body := `{ "Id":"e90e34656806", "Warnings":[] }`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) {
json.NewDecoder(r.Body).Decode(&conf) json.NewDecoder(r.Body).Decode(&conf)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -428,13 +428,31 @@ func TestRunPrivileged(t *testing.T) {
if conf.Privileged != false { if conf.Privileged != false {
t.Errorf("Expected container NOT started in Privileged mode when PR") t.Errorf("Expected container NOT started in Privileged mode when PR")
} }
// now lets set priviliged mode for a pull request from public repo
b.Privileged = true
b.Repo.Private = false
b.run()
if conf.Privileged != false {
t.Errorf("Expected container NOT started in Privileged mode when PR from public repo")
}
// now lets set priviliged mode for a pull request from private repo
b.Privileged = true
b.Repo.Private = true
b.run()
if conf.Privileged != true {
t.Errorf("Expected container started in Privileged mode when PR from private repo")
}
} }
func TestRunErrorCreate(t *testing.T) { func TestRunErrorCreate(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
mux.HandleFunc("/v1.9/containers/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/create", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })
@ -459,13 +477,13 @@ func TestRunErrorStart(t *testing.T) {
containerStarted = false containerStarted = false
) )
mux.HandleFunc("/v1.9/containers/create", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/create", func(w http.ResponseWriter, r *http.Request) {
containerCreated = true containerCreated = true
body := `{ "Id":"e90e34656806", "Warnings":[] }` body := `{ "Id":"e90e34656806", "Warnings":[] }`
w.Write([]byte(body)) w.Write([]byte(body))
}) })
mux.HandleFunc("/v1.9/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1.12/containers/e90e34656806/start", func(w http.ResponseWriter, r *http.Request) {
containerStarted = true containerStarted = true
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
}) })

View file

@ -21,7 +21,7 @@ import (
) )
const ( const (
APIVERSION = 1.9 APIVERSION = 1.12
DEFAULTHTTPPORT = 2375 DEFAULTHTTPPORT = 2375
DEFAULTUNIXSOCKET = "/var/run/docker.sock" DEFAULTUNIXSOCKET = "/var/run/docker.sock"
DEFAULTPROTOCOL = "unix" DEFAULTPROTOCOL = "unix"

View file

@ -33,6 +33,9 @@ type Repo struct {
// checkout when the Repository is cloned. // checkout when the Repository is cloned.
PR string PR string
// Private specifies if a git repo is private or not
Private bool
// (optional) The filesystem path that the repository // (optional) The filesystem path that the repository
// will be cloned into (or copied to) inside the // will be cloned into (or copied to) inside the
// host system (Docker Container). // host system (Docker Container).
@ -125,3 +128,8 @@ func (r *Repo) Commands() []string {
return cmds return cmds
} }
// IsTrusted returns if a repo is trusted to run under privileged mode
func (r *Repo) IsTrusted() bool {
return r.Private || len(r.PR) == 0
}

View file

@ -52,3 +52,23 @@ func TestIsGit(t *testing.T) {
} }
} }
} }
func TestIsTrusted(t *testing.T) {
repos := []struct {
private bool
PR string
trusted bool
}{
{true, "1", true},
{false, "1", false},
{true, "", true},
{false, "", true},
}
for _, r := range repos {
repo := Repo{Private: r.private, PR: r.PR}
if trusted := repo.IsTrusted(); trusted != r.trusted {
t.Errorf("IsTrusted was %v, expected %v", trusted, r.trusted)
}
}
}

View file

@ -30,7 +30,7 @@ func DockerNetworkMode(d *Docker) string {
return *d.NetworkMode return *d.NetworkMode
} }
// DockerNetworkMode returns empty string // DockerHostname returns empty string
// when Docker.NetworkMode is empty. // when Docker.NetworkMode is empty.
// DockerNetworkMode returns Docker.NetworkMode // DockerNetworkMode returns Docker.NetworkMode
// when it is not empty. // when it is not empty.