Merge pull request #1628 from bradrydzewski/master

added query, endpoint, cmd to list builds in queue
This commit is contained in:
Brad Rydzewski 2016-05-10 22:26:49 -07:00
commit 540f95630e
12 changed files with 172 additions and 61 deletions

View file

@ -33,8 +33,8 @@ type Client interface {
// Repo returns a repository by name. // Repo returns a repository by name.
Repo(string, string) (*model.Repo, error) Repo(string, string) (*model.Repo, error)
// RepoList returns a list of all repositories to which // RepoList returns a list of all repositories to which the user has explicit
// the user has explicit access in the host system. // access in the host system.
RepoList() ([]*model.Repo, error) RepoList() ([]*model.Repo, error)
// RepoPost activates a repository. // RepoPost activates a repository.
@ -58,29 +58,32 @@ type Client interface {
// Build returns a repository build by number. // Build returns a repository build by number.
Build(string, string, int) (*model.Build, error) Build(string, string, int) (*model.Build, error)
// BuildLast returns the latest repository build by branch. // BuildLast returns the latest repository build by branch. An empty branch
// An empty branch will result in the default branch. // will result in the default branch.
BuildLast(string, string, string) (*model.Build, error) BuildLast(string, string, string) (*model.Build, error)
// BuildList returns a list of recent builds for the // BuildList returns a list of recent builds for the
// the specified repository. // the specified repository.
BuildList(string, string) ([]*model.Build, error) BuildList(string, string) ([]*model.Build, error)
// BuildQueue returns a list of enqueued builds.
BuildQueue() ([]*model.Feed, error)
// BuildStart re-starts a stopped build. // BuildStart re-starts a stopped build.
BuildStart(string, string, int) (*model.Build, error) BuildStart(string, string, int) (*model.Build, error)
// BuildStop stops the specified running job for given build. // BuildStop stops the specified running job for given build.
BuildStop(string, string, int, int) error BuildStop(string, string, int, int) error
// BuildFork re-starts a stopped build with a new build number, // BuildFork re-starts a stopped build with a new build number, preserving
// preserving the prior history. // the prior history.
BuildFork(string, string, int) (*model.Build, error) BuildFork(string, string, int) (*model.Build, error)
// BuildLogs returns the build logs for the specified job. // BuildLogs returns the build logs for the specified job.
BuildLogs(string, string, int, int) (io.ReadCloser, error) BuildLogs(string, string, int, int) (io.ReadCloser, error)
// Deploy triggers a deployment for an existing build using the // Deploy triggers a deployment for an existing build using the specified
// specified target environment. // target environment.
Deploy(string, string, int, string) (*model.Build, error) Deploy(string, string, int, string) (*model.Build, error)
// //

View file

@ -24,23 +24,24 @@ const (
pathStream = "%s/api/queue/stream/%d" pathStream = "%s/api/queue/stream/%d"
pathPush = "%s/api/queue/status/%d" pathPush = "%s/api/queue/status/%d"
pathSelf = "%s/api/user" pathSelf = "%s/api/user"
pathFeed = "%s/api/user/feed" pathFeed = "%s/api/user/feed"
pathRepos = "%s/api/user/repos" pathRepos = "%s/api/user/repos"
pathRepo = "%s/api/repos/%s/%s" pathRepo = "%s/api/repos/%s/%s"
pathEncrypt = "%s/api/repos/%s/%s/encrypt" pathEncrypt = "%s/api/repos/%s/%s/encrypt"
pathBuilds = "%s/api/repos/%s/%s/builds" pathBuilds = "%s/api/repos/%s/%s/builds"
pathBuild = "%s/api/repos/%s/%s/builds/%v" pathBuild = "%s/api/repos/%s/%s/builds/%v"
pathJob = "%s/api/repos/%s/%s/builds/%d/%d" pathJob = "%s/api/repos/%s/%s/builds/%d/%d"
pathLog = "%s/api/repos/%s/%s/logs/%d/%d" pathLog = "%s/api/repos/%s/%s/logs/%d/%d"
pathKey = "%s/api/repos/%s/%s/key" pathKey = "%s/api/repos/%s/%s/key"
pathSign = "%s/api/repos/%s/%s/sign" pathSign = "%s/api/repos/%s/%s/sign"
pathSecrets = "%s/api/repos/%s/%s/secrets" pathSecrets = "%s/api/repos/%s/%s/secrets"
pathSecret = "%s/api/repos/%s/%s/secrets/%s" pathSecret = "%s/api/repos/%s/%s/secrets/%s"
pathNodes = "%s/api/nodes" pathNodes = "%s/api/nodes"
pathNode = "%s/api/nodes/%d" pathNode = "%s/api/nodes/%d"
pathUsers = "%s/api/users" pathUsers = "%s/api/users"
pathUser = "%s/api/users/%s" pathUser = "%s/api/users/%s"
pathBuildQueue = "%s/api/builds"
) )
type client struct { type client struct {
@ -189,6 +190,14 @@ func (c *client) BuildList(owner, name string) ([]*model.Build, error) {
return out, err return out, err
} }
// BuildQueue returns a list of enqueued builds.
func (c *client) BuildQueue() ([]*model.Feed, error) {
var out []*model.Feed
uri := fmt.Sprintf(pathBuildQueue, c.base)
err := c.get(uri, &out)
return out, err
}
// BuildStart re-starts a stopped build. // BuildStart re-starts a stopped build.
func (c *client) BuildStart(owner, name string, num int) (*model.Build, error) { func (c *client) BuildStart(owner, name string, num int) (*model.Build, error) {
out := new(model.Build) out := new(model.Build)

View file

@ -53,8 +53,8 @@ var AgentCmd = cli.Command{
Value: "amd64", Value: "amd64",
}, },
cli.StringFlag{ cli.StringFlag{
EnvVar: "DOCKER_STORAGE_DRIVER", EnvVar: "DRONE_STORAGE_DRIVER",
Name: "docker-storage-driver", Name: "drone-storage-driver",
Usage: "docker storage driver", Usage: "docker storage driver",
Value: "overlay", Value: "overlay",
}, },
@ -80,26 +80,6 @@ var AgentCmd = cli.Command{
Name: "debug", Name: "debug",
Usage: "start the agent in debug mode", Usage: "start the agent in debug mode",
}, },
cli.BoolFlag{
EnvVar: "DRONE_EXPERIMENTAL",
Name: "experimental",
Usage: "start the agent with experimental features",
},
cli.StringSliceFlag{
EnvVar: "DRONE_PLUGIN_NETRC",
Name: "netrc-plugin",
Usage: "plugins that receive the netrc file",
Value: &cli.StringSlice{
"git",
"git:*",
"hg",
"hg:*",
"plugins/hg",
"plugins/hg:*",
"plugins/git",
"plugins/git:*",
},
},
cli.StringSliceFlag{ cli.StringSliceFlag{
EnvVar: "DRONE_PLUGIN_PRIVILEGED", EnvVar: "DRONE_PLUGIN_PRIVILEGED",
Name: "privileged", Name: "privileged",
@ -113,22 +93,16 @@ var AgentCmd = cli.Command{
"plugins/ecr:*", "plugins/ecr:*",
}, },
}, },
cli.BoolFlag{
EnvVar: "DRONE_PLUGIN_PULL",
Name: "pull",
Usage: "always pull latest plugin images",
},
cli.StringFlag{ cli.StringFlag{
EnvVar: "DRONE_PLUGIN_NAMESPACE", EnvVar: "DRONE_PLUGIN_NAMESPACE",
Name: "namespace", Name: "namespace",
Value: "plugins", Value: "plugins",
Usage: "default plugin image namespace", Usage: "default plugin image namespace",
}, },
cli.StringSliceFlag{ cli.BoolFlag{
EnvVar: "DRONE_PLUGIN_WHITELIST", EnvVar: "DRONE_PLUGIN_PULL",
Name: "whitelist", Name: "pull",
Usage: "plugins that are permitted to run on the host", Usage: "always pull latest plugin images",
Value: &cli.StringSlice{"plugins/*"},
}, },
}, },
} }
@ -168,10 +142,8 @@ func start(c *cli.Context) {
drone: client, drone: client,
docker: docker, docker: docker,
config: config{ config: config{
whitelist: c.StringSlice("whitelist"),
namespace: c.String("namespace"), namespace: c.String("namespace"),
privileged: c.StringSlice("privileged"), privileged: c.StringSlice("privileged"),
netrc: c.StringSlice("netrc-plugin"),
pull: c.Bool("pull"), pull: c.Bool("pull"),
}, },
} }

View file

@ -15,9 +15,7 @@ import (
type config struct { type config struct {
platform string platform string
namespace string namespace string
whitelist []string
privileged []string privileged []string
netrc []string
pull bool pull bool
} }

View file

@ -11,5 +11,6 @@ var buildCmd = cli.Command{
buildInfoCmd, buildInfoCmd,
buildStopCmd, buildStopCmd,
buildStartCmd, buildStartCmd,
buildQueueCmd,
}, },
} }

60
drone/build_queue.go Normal file
View file

@ -0,0 +1,60 @@
package main
import (
"log"
"os"
"text/template"
"github.com/codegangsta/cli"
)
var buildQueueCmd = cli.Command{
Name: "queue",
Usage: "show build queue",
Action: func(c *cli.Context) {
if err := buildQueue(c); err != nil {
log.Fatalln(err)
}
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "format",
Usage: "format output",
Value: tmplBuildQueue,
},
},
}
func buildQueue(c *cli.Context) error {
client, err := newClient(c)
if err != nil {
return err
}
builds, err := client.BuildQueue()
if err != nil {
return err
}
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
if err != nil {
return err
}
for _, build := range builds {
tmpl.Execute(os.Stdout, build)
}
return nil
}
// template for build list information
var tmplBuildQueue = "\x1b[33m{{ .FullName }} #{{ .Number }} \x1b[0m" + `
Status: {{ .Status }}
Event: {{ .Event }}
Commit: {{ .Commit }}
Branch: {{ .Branch }}
Ref: {{ .Ref }}
Author: {{ .Author }} {{ if .Email }}<{{.Email}}>{{ end }}
Message: {{ .Message }}
`

View file

@ -135,6 +135,16 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
auth.POST("/token", server.GetLoginToken) auth.POST("/token", server.GetLoginToken)
} }
builds := e.Group("/api/builds")
{
builds.Use(session.MustAdmin())
builds.GET("", server.GetBuildQueue)
}
// agents := e.Group("/api/agents") {
// builds.Use(session.MustAdmin, server.GetAgents)
// }
queue := e.Group("/api/queue") queue := e.Group("/api/queue")
{ {
queue.Use(session.AuthorizeAgent) queue.Use(session.AuthorizeAgent)

View file

@ -305,3 +305,12 @@ func PostBuild(c *gin.Context) {
}) })
} }
} }
func GetBuildQueue(c *gin.Context) {
out, err := store.GetBuildQueue(c)
if err != nil {
c.String(500, "Error getting build queue. %s", err)
return
}
c.JSON(200, out)
}

View file

@ -49,6 +49,12 @@ func (db *datastore) GetBuildList(repo *model.Repo) ([]*model.Build, error) {
return builds, err return builds, err
} }
func (db *datastore) GetBuildQueue() ([]*model.Feed, error) {
feed := []*model.Feed{}
err := meddler.QueryAll(db, &feed, buildQueueList)
return feed, err
}
func (db *datastore) CreateBuild(build *model.Build, jobs ...*model.Job) error { func (db *datastore) CreateBuild(build *model.Build, jobs ...*model.Job) error {
var number int var number int
db.QueryRow(rebind(buildNumberLast), build.RepoID).Scan(&number) db.QueryRow(rebind(buildNumberLast), build.RepoID).Scan(&number)
@ -135,3 +141,31 @@ SELECT MAX(build_number)
FROM builds FROM builds
WHERE build_repo_id = ? WHERE build_repo_id = ?
` `
const buildQueueList = `
SELECT
repo_owner
,repo_name
,repo_full_name
,build_number
,build_event
,build_status
,build_created
,build_started
,build_finished
,build_commit
,build_branch
,build_ref
,build_refspec
,build_remote
,build_title
,build_message
,build_author
,build_email
,build_avatar
FROM
builds b
,repos r
WHERE b.build_repo_id = r.repo_id
AND b.build_status IN ('pending','running')
`

View file

@ -6,7 +6,11 @@ ALTER TABLE builds ADD COLUMN build_verified BOOLEAN;
UPDATE builds SET build_signed = false; UPDATE builds SET build_signed = false;
UPDATE builds SET build_verified = false; UPDATE builds SET build_verified = false;
CREATE INDEX ix_build_status_running ON builds (build_status)
WHERE build_status IN ('pending', 'running');
-- +migrate Down -- +migrate Down
ALTER TABLE builds DROP COLUMN build_signed; ALTER TABLE builds DROP COLUMN build_signed;
ALTER TABLE builds DROP COLUMN build_verified; ALTER TABLE builds DROP COLUMN build_verified;
DROP INDEX ix_build_status_running;

View file

@ -6,7 +6,11 @@ ALTER TABLE builds ADD COLUMN build_verified BOOLEAN;
UPDATE builds SET build_signed = 0; UPDATE builds SET build_signed = 0;
UPDATE builds SET build_verified = 0; UPDATE builds SET build_verified = 0;
CREATE INDEX ix_build_status_running ON builds (build_status)
WHERE build_status IN ('pending', 'running');
-- +migrate Down -- +migrate Down
ALTER TABLE builds DROP COLUMN build_signed; ALTER TABLE builds DROP COLUMN build_signed;
ALTER TABLE builds DROP COLUMN build_verified; ALTER TABLE builds DROP COLUMN build_verified;
DROP INDEX ix_build_status_running;

View file

@ -87,6 +87,9 @@ type Store interface {
// GetBuildList gets a list of builds for the repository // GetBuildList gets a list of builds for the repository
GetBuildList(*model.Repo) ([]*model.Build, error) GetBuildList(*model.Repo) ([]*model.Build, error)
// GetBuildQueue gets a list of build in queue.
GetBuildQueue() ([]*model.Feed, error)
// CreateBuild creates a new build and jobs. // CreateBuild creates a new build and jobs.
CreateBuild(*model.Build, ...*model.Job) error CreateBuild(*model.Build, ...*model.Job) error
@ -224,6 +227,10 @@ func GetBuildList(c context.Context, repo *model.Repo) ([]*model.Build, error) {
return FromContext(c).GetBuildList(repo) return FromContext(c).GetBuildList(repo)
} }
func GetBuildQueue(c context.Context) ([]*model.Feed, error) {
return FromContext(c).GetBuildQueue()
}
func CreateBuild(c context.Context, build *model.Build, jobs ...*model.Job) error { func CreateBuild(c context.Context, build *model.Build, jobs ...*model.Job) error {
return FromContext(c).CreateBuild(build, jobs...) return FromContext(c).CreateBuild(build, jobs...)
} }