diff --git a/cmd/droned/drone.go b/cmd/droned/drone.go index 607716fe2..616d87cea 100644 --- a/cmd/droned/drone.go +++ b/cmd/droned/drone.go @@ -64,6 +64,7 @@ func main() { if err := database.Init(driver, datasource); err != nil { log.Fatal("Can't initialize database: ", err) } + discardOldBuilds() setupStatic() setupHandlers() @@ -89,6 +90,22 @@ func checkTLSFlags() { } +// discardOldBuilds sets builds that are in the 'Started' +// state to 'Failure' on startup. The assumption is that +// the drone process was shut down mid-build and thus the +// builds will never complete. +func discardOldBuilds() { + err := database.FailUnfinishedBuilds() + if err != nil { + log.Fatal(err) + } + + err = database.FailUnfinishedCommits() + if err != nil { + log.Fatal(err) + } +} + // setup routes for static assets. These assets may // be directly embedded inside the application using // the `rice embed` command, else they are served from disk. diff --git a/pkg/database/builds.go b/pkg/database/builds.go index 8aacf32dd..fefe1e7bb 100644 --- a/pkg/database/builds.go +++ b/pkg/database/builds.go @@ -32,6 +32,13 @@ WHERE slug = ? AND commit_id = ? LIMIT 1 ` +// SQL Queries to fail all builds that are running or pending +const buildFailUnfinishedStmt = ` +UPDATE builds +SET status = 'Failure' +WHERE status IN ('Started', 'Pending') +` + // SQL Queries to delete a Commit. const buildDeleteStmt = ` DELETE FROM builds WHERE id = ? @@ -69,3 +76,10 @@ func ListBuilds(id int64) ([]*Build, error) { err := meddler.QueryAll(db, &builds, buildStmt, id) return builds, err } + +// FailUnfinishedBuilds sets status=Failure to all builds +// in the Pending and Started states +func FailUnfinishedBuilds() error { + _, err := db.Exec(buildFailUnfinishedStmt) + return err +} diff --git a/pkg/database/commits.go b/pkg/database/commits.go index 883d3d065..743f32d14 100644 --- a/pkg/database/commits.go +++ b/pkg/database/commits.go @@ -101,11 +101,18 @@ WHERE id IN ( SELECT MAX(id) FROM commits WHERE repo_id = ? - AND branch = ? + AND branch = ? GROUP BY branch) LIMIT 1 ` +// SQL Queries to fail all commits that are currently building +const commitFailUnfinishedStmt = ` +UPDATE commits +SET status = 'Failure' +WHERE status IN ('Started', 'Pending') +` + // Returns the Commit with the given ID. func GetCommit(id int64) (*Commit, error) { commit := Commit{} @@ -172,3 +179,8 @@ func ListBranches(repo int64) ([]*Commit, error) { err := meddler.QueryAll(db, &commits, commitBranchesStmt, repo) return commits, err } + +func FailUnfinishedCommits() error { + _, err := db.Exec(commitFailUnfinishedStmt) + return err +}