mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-04-26 13:34:45 +00:00
Merge pull request #1628 from bradrydzewski/master
added query, endpoint, cmd to list builds in queue
This commit is contained in:
commit
540f95630e
12 changed files with 172 additions and 61 deletions
|
@ -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)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,5 +11,6 @@ var buildCmd = cli.Command{
|
||||||
buildInfoCmd,
|
buildInfoCmd,
|
||||||
buildStopCmd,
|
buildStopCmd,
|
||||||
buildStartCmd,
|
buildStartCmd,
|
||||||
|
buildQueueCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
60
drone/build_queue.go
Normal file
60
drone/build_queue.go
Normal 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 }}
|
||||||
|
`
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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')
|
||||||
|
`
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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...)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue