mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-27 04:11:03 +00:00
Merge pull request #2114 from bradrydzewski/rfc/sync
implement fast repository sync
This commit is contained in:
commit
0f693cb66d
149 changed files with 3092 additions and 22517 deletions
40
cache/cache.go
vendored
40
cache/cache.go
vendored
|
@ -1,40 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
//go:generate mockery -name Cache -output mock -case=underscore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/koding/cache"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Cache interface {
|
|
||||||
Get(string) (interface{}, error)
|
|
||||||
Set(string, interface{}) error
|
|
||||||
Delete(string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func Get(c context.Context, key string) (interface{}, error) {
|
|
||||||
return FromContext(c).Get(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Set(c context.Context, key string, value interface{}) error {
|
|
||||||
return FromContext(c).Set(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Delete(c context.Context, key string) error {
|
|
||||||
return FromContext(c).Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default creates an in-memory cache with the default
|
|
||||||
// 30 minute expiration period.
|
|
||||||
func Default() Cache {
|
|
||||||
return NewTTL(time.Minute * 30)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTTL returns an in-memory cache with the specified
|
|
||||||
// ttl expiration period.
|
|
||||||
func NewTTL(t time.Duration) Cache {
|
|
||||||
return cache.NewMemoryWithTTL(t)
|
|
||||||
}
|
|
34
cache/cache_test.go
vendored
34
cache/cache_test.go
vendored
|
@ -1,34 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCache(t *testing.T) {
|
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
g.Describe("Cache", func() {
|
|
||||||
|
|
||||||
var c *gin.Context
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
c = new(gin.Context)
|
|
||||||
ToContext(c, Default())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should set and get an item", func() {
|
|
||||||
Set(c, "foo", "bar")
|
|
||||||
v, e := Get(c, "foo")
|
|
||||||
g.Assert(v).Equal("bar")
|
|
||||||
g.Assert(e == nil).IsTrue()
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should return nil when item not found", func() {
|
|
||||||
v, e := Get(c, "foo")
|
|
||||||
g.Assert(v == nil).IsTrue()
|
|
||||||
g.Assert(e == nil).IsFalse()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
23
cache/context.go
vendored
23
cache/context.go
vendored
|
@ -1,23 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
const key = "cache"
|
|
||||||
|
|
||||||
// Setter defines a context that enables setting values.
|
|
||||||
type Setter interface {
|
|
||||||
Set(string, interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromContext returns the Cache associated with this context.
|
|
||||||
func FromContext(c context.Context) Cache {
|
|
||||||
return c.Value(key).(Cache)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToContext adds the Cache to this context if it supports
|
|
||||||
// the Setter interface.
|
|
||||||
func ToContext(c Setter, cache Cache) {
|
|
||||||
c.Set(key, cache)
|
|
||||||
}
|
|
99
cache/helper.go
vendored
99
cache/helper.go
vendored
|
@ -1,99 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/drone/drone/remote"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetPerms returns the user permissions repositories from the cache
|
|
||||||
// associated with the current repository.
|
|
||||||
func GetPerms(c context.Context, user *model.User, owner, name string) (*model.Perm, error) {
|
|
||||||
key := fmt.Sprintf("perms:%s:%s/%s",
|
|
||||||
user.Login,
|
|
||||||
owner,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
// if we fetch from the cache we can return immediately
|
|
||||||
val, err := Get(c, key)
|
|
||||||
if err == nil {
|
|
||||||
return val.(*model.Perm), nil
|
|
||||||
}
|
|
||||||
// else we try to grab from the remote system and
|
|
||||||
// populate our cache.
|
|
||||||
perm, err := remote.Perm(c, user, owner, name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
Set(c, key, perm)
|
|
||||||
return perm, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTeamPerms returns the user permissions from the cache
|
|
||||||
// associated with the current organization.
|
|
||||||
func GetTeamPerms(c context.Context, user *model.User, org string) (*model.Perm, error) {
|
|
||||||
key := fmt.Sprintf("perms:%s:%s",
|
|
||||||
user.Login,
|
|
||||||
org,
|
|
||||||
)
|
|
||||||
// if we fetch from the cache we can return immediately
|
|
||||||
val, err := Get(c, key)
|
|
||||||
if err == nil {
|
|
||||||
return val.(*model.Perm), nil
|
|
||||||
}
|
|
||||||
// else we try to grab from the remote system and
|
|
||||||
// populate our cache.
|
|
||||||
perm, err := remote.TeamPerm(c, user, org)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
Set(c, key, perm)
|
|
||||||
return perm, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRepos returns the list of user repositories from the cache
|
|
||||||
// associated with the current context.
|
|
||||||
func GetRepos(c context.Context, user *model.User) ([]*model.RepoLite, error) {
|
|
||||||
key := fmt.Sprintf("repos:%s",
|
|
||||||
user.Login,
|
|
||||||
)
|
|
||||||
// if we fetch from the cache we can return immediately
|
|
||||||
val, err := Get(c, key)
|
|
||||||
if err == nil {
|
|
||||||
return val.([]*model.RepoLite), nil
|
|
||||||
}
|
|
||||||
// else we try to grab from the remote system and
|
|
||||||
// populate our cache.
|
|
||||||
repos, err := remote.Repos(c, user)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
Set(c, key, repos)
|
|
||||||
return repos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRepoMap returns the list of user repositories from the cache
|
|
||||||
// associated with the current context in a map structure.
|
|
||||||
func GetRepoMap(c context.Context, user *model.User) (map[string]bool, error) {
|
|
||||||
repos, err := GetRepos(c, user)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
repom := map[string]bool{}
|
|
||||||
for _, repo := range repos {
|
|
||||||
repom[repo.FullName] = true
|
|
||||||
}
|
|
||||||
return repom, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteRepos evicts the cached user repositories from the cache associated
|
|
||||||
// with the current context.
|
|
||||||
func DeleteRepos(c context.Context, user *model.User) error {
|
|
||||||
key := fmt.Sprintf("repos:%s",
|
|
||||||
user.Login,
|
|
||||||
)
|
|
||||||
return Delete(c, key)
|
|
||||||
}
|
|
115
cache/helper_test.go
vendored
115
cache/helper_test.go
vendored
|
@ -1,115 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/drone/drone/remote"
|
|
||||||
"github.com/drone/drone/remote/mock"
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHelper(t *testing.T) {
|
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
|
|
||||||
g.Describe("Cache helpers", func() {
|
|
||||||
|
|
||||||
var c *gin.Context
|
|
||||||
var r *mock.Remote
|
|
||||||
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
c = new(gin.Context)
|
|
||||||
ToContext(c, Default())
|
|
||||||
|
|
||||||
r = new(mock.Remote)
|
|
||||||
remote.ToContext(c, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should get permissions from remote", func() {
|
|
||||||
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(fakePerm, nil).Once()
|
|
||||||
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
|
||||||
g.Assert(p).Equal(fakePerm)
|
|
||||||
g.Assert(err).Equal(nil)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should get permissions from cache", func() {
|
|
||||||
key := fmt.Sprintf("perms:%s:%s/%s",
|
|
||||||
fakeUser.Login,
|
|
||||||
fakeRepo.Owner,
|
|
||||||
fakeRepo.Name,
|
|
||||||
)
|
|
||||||
|
|
||||||
Set(c, key, fakePerm)
|
|
||||||
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(nil, fakeErr).Once()
|
|
||||||
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
|
||||||
g.Assert(p).Equal(fakePerm)
|
|
||||||
g.Assert(err).Equal(nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should get permissions error", func() {
|
|
||||||
r.On("Perm", fakeUser, fakeRepo.Owner, fakeRepo.Name).Return(nil, fakeErr).Once()
|
|
||||||
p, err := GetPerms(c, fakeUser, fakeRepo.Owner, fakeRepo.Name)
|
|
||||||
g.Assert(p == nil).IsTrue()
|
|
||||||
g.Assert(err).Equal(fakeErr)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should set and get repos", func() {
|
|
||||||
|
|
||||||
r.On("Repos", fakeUser).Return(fakeRepos, nil).Once()
|
|
||||||
p, err := GetRepos(c, fakeUser)
|
|
||||||
g.Assert(p).Equal(fakeRepos)
|
|
||||||
g.Assert(err).Equal(nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should get repos", func() {
|
|
||||||
key := fmt.Sprintf("repos:%s",
|
|
||||||
fakeUser.Login,
|
|
||||||
)
|
|
||||||
|
|
||||||
Set(c, key, fakeRepos)
|
|
||||||
r.On("Repos", fakeUser).Return(nil, fakeErr).Once()
|
|
||||||
p, err := GetRepos(c, fakeUser)
|
|
||||||
g.Assert(p).Equal(fakeRepos)
|
|
||||||
g.Assert(err).Equal(nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should get repos error", func() {
|
|
||||||
r.On("Repos", fakeUser).Return(nil, fakeErr).Once()
|
|
||||||
p, err := GetRepos(c, fakeUser)
|
|
||||||
g.Assert(p == nil).IsTrue()
|
|
||||||
g.Assert(err).Equal(fakeErr)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should evict repos", func() {
|
|
||||||
key := fmt.Sprintf("repos:%s",
|
|
||||||
fakeUser.Login,
|
|
||||||
)
|
|
||||||
|
|
||||||
Set(c, key, fakeRepos)
|
|
||||||
repos, err := Get(c, key)
|
|
||||||
g.Assert(repos != nil).IsTrue()
|
|
||||||
g.Assert(err == nil).IsTrue()
|
|
||||||
|
|
||||||
DeleteRepos(c, fakeUser)
|
|
||||||
repos, err = Get(c, key)
|
|
||||||
g.Assert(repos == nil).IsTrue()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
fakeErr = errors.New("Not Found")
|
|
||||||
fakeUser = &model.User{Login: "octocat"}
|
|
||||||
fakePerm = &model.Perm{true, true, true}
|
|
||||||
fakeRepo = &model.RepoLite{Owner: "octocat", Name: "Hello-World"}
|
|
||||||
fakeRepos = []*model.RepoLite{
|
|
||||||
{Owner: "octocat", Name: "Hello-World"},
|
|
||||||
{Owner: "octocat", Name: "hello-world"},
|
|
||||||
{Owner: "octocat", Name: "Spoon-Knife"},
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -80,12 +80,6 @@ var flags = []cli.Flag{
|
||||||
Name: "open",
|
Name: "open",
|
||||||
Usage: "open user registration",
|
Usage: "open user registration",
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
|
||||||
EnvVar: "DRONE_CACHE_TTL",
|
|
||||||
Name: "cache-ttl",
|
|
||||||
Usage: "cache duration",
|
|
||||||
Value: time.Minute * 15,
|
|
||||||
},
|
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
EnvVar: "DRONE_ESCALATE",
|
EnvVar: "DRONE_ESCALATE",
|
||||||
Name: "escalate",
|
Name: "escalate",
|
||||||
|
@ -415,7 +409,6 @@ func server(c *cli.Context) error {
|
||||||
ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
|
ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
|
||||||
middleware.Version,
|
middleware.Version,
|
||||||
middleware.Config(c),
|
middleware.Config(c),
|
||||||
middleware.Cache(c),
|
|
||||||
middleware.Store(c, store_),
|
middleware.Store(c, store_),
|
||||||
middleware.Remote(remote_),
|
middleware.Remote(remote_),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
type Perm struct {
|
// PermStore persists repository permissions information to storage.
|
||||||
Pull bool `json:"pull"`
|
type PermStore interface {
|
||||||
Push bool `json:"push"`
|
PermFind(user *User, repo *Repo) (*Perm, error)
|
||||||
Admin bool `json:"admin"`
|
PermUpsert(perm *Perm) error
|
||||||
|
PermBatch(perms []*Perm) error
|
||||||
|
PermDelete(perm *Perm) error
|
||||||
|
PermFlush(user *User, before int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perm defines a repository permission for an individual user.
|
||||||
|
type Perm struct {
|
||||||
|
UserID int64 `json:"-" meddler:"perm_user_id"`
|
||||||
|
RepoID int64 `json:"-" meddler:"perm_repo_id"`
|
||||||
|
Repo string `json:"-" meddler:"-"`
|
||||||
|
Pull bool `json:"pull" meddler:"perm_pull"`
|
||||||
|
Push bool `json:"push" meddler:"perm_push"`
|
||||||
|
Admin bool `json:"admin" meddler:"perm_admin"`
|
||||||
|
Synced int64 `json:"synced" meddler:"perm_synced"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ type Repo struct {
|
||||||
IsTrusted bool `json:"trusted" meddler:"repo_trusted"`
|
IsTrusted bool `json:"trusted" meddler:"repo_trusted"`
|
||||||
IsStarred bool `json:"starred,omitempty" meddler:"-"`
|
IsStarred bool `json:"starred,omitempty" meddler:"-"`
|
||||||
IsGated bool `json:"gated" meddler:"repo_gated"`
|
IsGated bool `json:"gated" meddler:"repo_gated"`
|
||||||
|
IsActive bool `json:"active,omitempty" meddler:"repo_active"`
|
||||||
AllowPull bool `json:"allow_pr" meddler:"repo_allow_pr"`
|
AllowPull bool `json:"allow_pr" meddler:"repo_allow_pr"`
|
||||||
AllowPush bool `json:"allow_push" meddler:"repo_allow_push"`
|
AllowPush bool `json:"allow_push" meddler:"repo_allow_push"`
|
||||||
AllowDeploy bool `json:"allow_deploys" meddler:"repo_allow_deploys"`
|
AllowDeploy bool `json:"allow_deploys" meddler:"repo_allow_deploys"`
|
||||||
|
@ -34,6 +35,7 @@ type Repo struct {
|
||||||
Counter int `json:"last_build" meddler:"repo_counter"`
|
Counter int `json:"last_build" meddler:"repo_counter"`
|
||||||
Config string `json:"config_file" meddler:"repo_config_path"`
|
Config string `json:"config_file" meddler:"repo_config_path"`
|
||||||
Hash string `json:"-" meddler:"repo_hash"`
|
Hash string `json:"-" meddler:"repo_hash"`
|
||||||
|
Perm *Perm `json:"-" meddler:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RepoPatch represents a repository patch object.
|
// RepoPatch represents a repository patch object.
|
||||||
|
|
|
@ -34,6 +34,9 @@ type User struct {
|
||||||
// Activate indicates the user is active in the system.
|
// Activate indicates the user is active in the system.
|
||||||
Active bool `json:"active" meddler:"user_active"`
|
Active bool `json:"active" meddler:"user_active"`
|
||||||
|
|
||||||
|
// Synced is the timestamp when the user was synced with the remote system.
|
||||||
|
Synced int64 `json:"synced" meddler:"user_synced"`
|
||||||
|
|
||||||
// Admin indicates the user is a system administrator.
|
// Admin indicates the user is a system administrator.
|
||||||
//
|
//
|
||||||
// NOTE: This is sourced from the DRONE_ADMINS environment variable and is no
|
// NOTE: This is sourced from the DRONE_ADMINS environment variable and is no
|
||||||
|
|
|
@ -114,11 +114,6 @@ func (c *config) Teams(u *model.User) ([]*model.Team, error) {
|
||||||
return convertTeamList(resp.Values), nil
|
return convertTeamList(resp.Values), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm is not supported by the Bitbucket driver.
|
|
||||||
func (c *config) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo returns the named Bitbucket repository.
|
// Repo returns the named Bitbucket repository.
|
||||||
func (c *config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (c *config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
repo, err := c.newClient(u).FindRepo(owner, name)
|
repo, err := c.newClient(u).FindRepo(owner, name)
|
||||||
|
@ -130,10 +125,10 @@ func (c *config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
|
|
||||||
// Repos returns a list of all repositories for Bitbucket account, including
|
// Repos returns a list of all repositories for Bitbucket account, including
|
||||||
// organization repositories.
|
// organization repositories.
|
||||||
func (c *config) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
client := c.newClient(u)
|
client := c.newClient(u)
|
||||||
|
|
||||||
var all []*model.RepoLite
|
var all []*model.Repo
|
||||||
|
|
||||||
accounts := []string{u.Login}
|
accounts := []string{u.Login}
|
||||||
resp, err := client.ListTeams(&internal.ListTeamOpts{
|
resp, err := client.ListTeams(&internal.ListTeamOpts{
|
||||||
|
@ -153,7 +148,7 @@ func (c *config) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
return all, err
|
return all, err
|
||||||
}
|
}
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
all = append(all, convertRepoLite(repo))
|
all = append(all, convertRepo(repo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return all, nil
|
return all, nil
|
||||||
|
|
|
@ -110,17 +110,6 @@ func cloneLink(repo *internal.Repo) string {
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertRepoLite is a helper function used to convert a Bitbucket repository
|
|
||||||
// structure to the simplified Drone repository structure.
|
|
||||||
func convertRepoLite(from *internal.Repo) *model.RepoLite {
|
|
||||||
return &model.RepoLite{
|
|
||||||
Owner: strings.Split(from.FullName, "/")[0],
|
|
||||||
Name: strings.Split(from.FullName, "/")[1],
|
|
||||||
FullName: from.FullName,
|
|
||||||
Avatar: from.Owner.Links.Avatar.Href,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertUser is a helper function used to convert a Bitbucket user account
|
// convertUser is a helper function used to convert a Bitbucket user account
|
||||||
// structure to the Drone User structure.
|
// structure to the Drone User structure.
|
||||||
func convertUser(from *internal.Account, token *oauth2.Token) *model.User {
|
func convertUser(from *internal.Account, token *oauth2.Token) *model.User {
|
||||||
|
|
|
@ -49,18 +49,6 @@ func Test_helper(t *testing.T) {
|
||||||
g.Assert(convertDesc(model.StatusError)).Equal(descError)
|
g.Assert(convertDesc(model.StatusError)).Equal(descError)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("should convert repository lite", func() {
|
|
||||||
from := &internal.Repo{}
|
|
||||||
from.FullName = "octocat/hello-world"
|
|
||||||
from.Owner.Links.Avatar.Href = "http://..."
|
|
||||||
|
|
||||||
to := convertRepoLite(from)
|
|
||||||
g.Assert(to.Avatar).Equal(from.Owner.Links.Avatar.Href)
|
|
||||||
g.Assert(to.FullName).Equal(from.FullName)
|
|
||||||
g.Assert(to.Owner).Equal("octocat")
|
|
||||||
g.Assert(to.Name).Equal("hello-world")
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should convert repository", func() {
|
g.It("should convert repository", func() {
|
||||||
from := &internal.Repo{
|
from := &internal.Repo{
|
||||||
FullName: "octocat/hello-world",
|
FullName: "octocat/hello-world",
|
||||||
|
|
|
@ -140,14 +140,14 @@ func (c *Config) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
return convertRepo(repo), nil
|
return convertRepo(repo), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *Config) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
repos, err := internal.NewClientWithToken(c.URL, c.Consumer, u.Token).FindRepos()
|
repos, err := internal.NewClientWithToken(c.URL, c.Consumer, u.Token).FindRepos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var all []*model.RepoLite
|
var all []*model.Repo
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
all = append(all, convertRepoLite(repo))
|
all = append(all, convertRepo(repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
return all, nil
|
return all, nil
|
||||||
|
@ -233,7 +233,7 @@ func CreateConsumer(URL string, ConsumerKey string, PrivateKey *rsa.PrivateKey)
|
||||||
consumer.HttpClient = &http.Client{
|
consumer.HttpClient = &http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return consumer
|
return consumer
|
||||||
|
|
|
@ -86,19 +86,6 @@ func convertRepo(from *internal.Repo) *model.Repo {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertRepoLite is a helper function used to convert a Bitbucket repository
|
|
||||||
// structure to the simplified Drone repository structure.
|
|
||||||
func convertRepoLite(from *internal.Repo) *model.RepoLite {
|
|
||||||
return &model.RepoLite{
|
|
||||||
Owner: from.Project.Key,
|
|
||||||
Name: from.Slug,
|
|
||||||
FullName: from.Project.Key + "/" + from.Slug,
|
|
||||||
//TODO: find the avatar for the repo
|
|
||||||
//Avatar: might need another ws call?
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertPushHook is a helper function used to convert a Bitbucket push
|
// convertPushHook is a helper function used to convert a Bitbucket push
|
||||||
// hook to the Drone build struct holding commit information.
|
// hook to the Drone build struct holding commit information.
|
||||||
func convertPushHook(hook *internal.PostHook, baseURL string) *model.Build {
|
func convertPushHook(hook *internal.PostHook, baseURL string) *model.Build {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package bitbucketserver
|
package bitbucketserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote/bitbucketserver/internal"
|
"github.com/drone/drone/remote/bitbucketserver/internal"
|
||||||
"github.com/franela/goblin"
|
"github.com/franela/goblin"
|
||||||
"github.com/mrjones/oauth"
|
"github.com/mrjones/oauth"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_helper(t *testing.T) {
|
func Test_helper(t *testing.T) {
|
||||||
|
@ -13,17 +14,6 @@ func Test_helper(t *testing.T) {
|
||||||
g := goblin.Goblin(t)
|
g := goblin.Goblin(t)
|
||||||
g.Describe("Bitbucket Server converter", func() {
|
g.Describe("Bitbucket Server converter", func() {
|
||||||
|
|
||||||
g.It("should convert repository lite", func() {
|
|
||||||
from := &internal.Repo{}
|
|
||||||
from.Project.Key = "octocat"
|
|
||||||
from.Slug = "hello-world"
|
|
||||||
|
|
||||||
to := convertRepoLite(from)
|
|
||||||
g.Assert(to.FullName).Equal("octocat/hello-world")
|
|
||||||
g.Assert(to.Owner).Equal("octocat")
|
|
||||||
g.Assert(to.Name).Equal("hello-world")
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should convert repository", func() {
|
g.It("should convert repository", func() {
|
||||||
from := &internal.Repo{
|
from := &internal.Repo{
|
||||||
Slug: "hello-world",
|
Slug: "hello-world",
|
||||||
|
|
|
@ -69,18 +69,13 @@ func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||||
return empty, nil
|
return empty, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm is not supported by the Gerrit driver.
|
|
||||||
func (c *client) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo is not supported by the Gerrit driver.
|
// Repo is not supported by the Gerrit driver.
|
||||||
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repos is not supported by the Gerrit driver.
|
// Repos is not supported by the Gerrit driver.
|
||||||
func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,8 +200,8 @@ func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
|
|
||||||
// Repos returns a list of all repositories for the Gitea account, including
|
// Repos returns a list of all repositories for the Gitea account, including
|
||||||
// organization repositories.
|
// organization repositories.
|
||||||
func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
repos := []*model.RepoLite{}
|
repos := []*model.Repo{}
|
||||||
|
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
all, err := client.ListMyRepos()
|
all, err := client.ListMyRepos()
|
||||||
|
@ -210,7 +210,7 @@ func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repo := range all {
|
for _, repo := range all {
|
||||||
repos = append(repos, toRepoLite(repo))
|
repos = append(repos, toRepo(repo))
|
||||||
}
|
}
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,21 +12,6 @@ import (
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// helper function that converts a Gitea repository to a Drone repository.
|
|
||||||
func toRepoLite(from *gitea.Repository) *model.RepoLite {
|
|
||||||
name := strings.Split(from.FullName, "/")[1]
|
|
||||||
avatar := expandAvatar(
|
|
||||||
from.HTMLURL,
|
|
||||||
from.Owner.AvatarURL,
|
|
||||||
)
|
|
||||||
return &model.RepoLite{
|
|
||||||
Name: name,
|
|
||||||
Owner: from.Owner.UserName,
|
|
||||||
FullName: from.FullName,
|
|
||||||
Avatar: avatar,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function that converts a Gitea repository to a Drone repository.
|
// helper function that converts a Gitea repository to a Drone repository.
|
||||||
func toRepo(from *gitea.Repository) *model.Repo {
|
func toRepo(from *gitea.Repository) *model.Repo {
|
||||||
name := strings.Split(from.FullName, "/")[1]
|
name := strings.Split(from.FullName, "/")[1]
|
||||||
|
|
|
@ -177,21 +177,6 @@ func Test_parse(t *testing.T) {
|
||||||
g.Assert(repo.IsPrivate).Equal(from.Private)
|
g.Assert(repo.IsPrivate).Equal(from.Private)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should return a RepoLite struct from a Gitea Repo", func() {
|
|
||||||
from := gitea.Repository{
|
|
||||||
FullName: "gophers/hello-world",
|
|
||||||
Owner: &gitea.User{
|
|
||||||
UserName: "gordon",
|
|
||||||
AvatarURL: "http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
repo := toRepoLite(&from)
|
|
||||||
g.Assert(repo.FullName).Equal(from.FullName)
|
|
||||||
g.Assert(repo.Owner).Equal(from.Owner.UserName)
|
|
||||||
g.Assert(repo.Name).Equal("hello-world")
|
|
||||||
g.Assert(repo.Avatar).Equal(from.Owner.AvatarURL)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should correct a malformed avatar url", func() {
|
g.It("Should correct a malformed avatar url", func() {
|
||||||
|
|
||||||
var urls = []struct {
|
var urls = []struct {
|
||||||
|
|
|
@ -80,6 +80,7 @@ func convertRepo(from *github.Repository, private bool) *model.Repo {
|
||||||
Avatar: *from.Owner.AvatarURL,
|
Avatar: *from.Owner.AvatarURL,
|
||||||
Kind: model.RepoGit,
|
Kind: model.RepoGit,
|
||||||
Branch: defaultBranch,
|
Branch: defaultBranch,
|
||||||
|
Perm: convertPerm(from),
|
||||||
}
|
}
|
||||||
if from.DefaultBranch != nil {
|
if from.DefaultBranch != nil {
|
||||||
repo.Branch = *from.DefaultBranch
|
repo.Branch = *from.DefaultBranch
|
||||||
|
@ -114,24 +115,24 @@ func convertTeamPerm(from *github.Membership) *model.Perm {
|
||||||
|
|
||||||
// convertRepoList is a helper function used to convert a GitHub repository
|
// convertRepoList is a helper function used to convert a GitHub repository
|
||||||
// list to the common Drone repository structure.
|
// list to the common Drone repository structure.
|
||||||
func convertRepoList(from []github.Repository) []*model.RepoLite {
|
func convertRepoList(from []github.Repository, private bool) []*model.Repo {
|
||||||
var repos []*model.RepoLite
|
var repos []*model.Repo
|
||||||
for _, repo := range from {
|
for _, repo := range from {
|
||||||
repos = append(repos, convertRepoLite(repo))
|
repos = append(repos, convertRepo(&repo, private))
|
||||||
}
|
}
|
||||||
return repos
|
return repos
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertRepoLite is a helper function used to convert a GitHub repository
|
// // convertRepoLite is a helper function used to convert a GitHub repository
|
||||||
// structure to the common Drone repository structure.
|
// // structure to the common Drone repository structure.
|
||||||
func convertRepoLite(from github.Repository) *model.RepoLite {
|
// func convertRepoLite(from github.Repository) *model.RepoLite {
|
||||||
return &model.RepoLite{
|
// return &model.RepoLite{
|
||||||
Owner: *from.Owner.Login,
|
// Owner: *from.Owner.Login,
|
||||||
Name: *from.Name,
|
// Name: *from.Name,
|
||||||
FullName: *from.FullName,
|
// FullName: *from.FullName,
|
||||||
Avatar: *from.Owner.AvatarURL,
|
// Avatar: *from.Owner.AvatarURL,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// convertTeamList is a helper function used to convert a GitHub team list to
|
// convertTeamList is a helper function used to convert a GitHub team list to
|
||||||
// the common Drone repository structure.
|
// the common Drone repository structure.
|
||||||
|
|
|
@ -50,36 +50,27 @@ func Test_helper(t *testing.T) {
|
||||||
g.Assert(convertDesc(model.StatusError)).Equal(descError)
|
g.Assert(convertDesc(model.StatusError)).Equal(descError)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("should convert repository lite", func() {
|
|
||||||
from := github.Repository{
|
|
||||||
FullName: github.String("octocat/hello-world"),
|
|
||||||
Name: github.String("hello-world"),
|
|
||||||
Owner: &github.User{
|
|
||||||
AvatarURL: github.String("http://..."),
|
|
||||||
Login: github.String("octocat"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
to := convertRepoLite(from)
|
|
||||||
g.Assert(to.Avatar).Equal("http://...")
|
|
||||||
g.Assert(to.FullName).Equal("octocat/hello-world")
|
|
||||||
g.Assert(to.Owner).Equal("octocat")
|
|
||||||
g.Assert(to.Name).Equal("hello-world")
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("should convert repository list", func() {
|
g.It("should convert repository list", func() {
|
||||||
from := []github.Repository{
|
from := []github.Repository{
|
||||||
{
|
{
|
||||||
|
Private: github.Bool(false),
|
||||||
FullName: github.String("octocat/hello-world"),
|
FullName: github.String("octocat/hello-world"),
|
||||||
Name: github.String("hello-world"),
|
Name: github.String("hello-world"),
|
||||||
Owner: &github.User{
|
Owner: &github.User{
|
||||||
AvatarURL: github.String("http://..."),
|
AvatarURL: github.String("http://..."),
|
||||||
Login: github.String("octocat"),
|
Login: github.String("octocat"),
|
||||||
},
|
},
|
||||||
|
HTMLURL: github.String("https://github.com/octocat/hello-world"),
|
||||||
|
CloneURL: github.String("https://github.com/octocat/hello-world.git"),
|
||||||
|
Permissions: &map[string]bool{
|
||||||
|
"push": true,
|
||||||
|
"pull": true,
|
||||||
|
"admin": true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
to := convertRepoList(from)
|
to := convertRepoList(from, false)
|
||||||
g.Assert(to[0].Avatar).Equal("http://...")
|
g.Assert(to[0].Avatar).Equal("http://...")
|
||||||
g.Assert(to[0].FullName).Equal("octocat/hello-world")
|
g.Assert(to[0].FullName).Equal("octocat/hello-world")
|
||||||
g.Assert(to[0].Owner).Equal("octocat")
|
g.Assert(to[0].Owner).Equal("octocat")
|
||||||
|
@ -98,6 +89,11 @@ func Test_helper(t *testing.T) {
|
||||||
AvatarURL: github.String("http://..."),
|
AvatarURL: github.String("http://..."),
|
||||||
Login: github.String("octocat"),
|
Login: github.String("octocat"),
|
||||||
},
|
},
|
||||||
|
Permissions: &map[string]bool{
|
||||||
|
"push": true,
|
||||||
|
"pull": true,
|
||||||
|
"admin": true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
to := convertRepo(&from, false)
|
to := convertRepo(&from, false)
|
||||||
|
|
|
@ -168,16 +168,6 @@ func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||||
return teams, nil
|
return teams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm returns the user permissions for the named GitHub organization.
|
|
||||||
func (c *client) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
|
||||||
client := c.newClientToken(u.Token)
|
|
||||||
membership, _, err := client.Organizations.GetOrgMembership(u.Login, org)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertTeamPerm(membership), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo returns the named GitHub repository.
|
// Repo returns the named GitHub repository.
|
||||||
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
|
@ -190,20 +180,20 @@ func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
|
|
||||||
// Repos returns a list of all repositories for GitHub account, including
|
// Repos returns a list of all repositories for GitHub account, including
|
||||||
// organization repositories.
|
// organization repositories.
|
||||||
func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
|
|
||||||
opts := new(github.RepositoryListOptions)
|
opts := new(github.RepositoryListOptions)
|
||||||
opts.PerPage = 100
|
opts.PerPage = 100
|
||||||
opts.Page = 1
|
opts.Page = 1
|
||||||
|
|
||||||
var repos []*model.RepoLite
|
var repos []*model.Repo
|
||||||
for opts.Page > 0 {
|
for opts.Page > 0 {
|
||||||
list, resp, err := client.Repositories.List("", opts)
|
list, resp, err := client.Repositories.List("", opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
repos = append(repos, convertRepoList(list)...)
|
repos = append(repos, convertRepoList(list, c.PrivateMode)...)
|
||||||
opts.Page = resp.NextPage
|
opts.Page = resp.NextPage
|
||||||
}
|
}
|
||||||
return repos, nil
|
return repos, nil
|
||||||
|
|
|
@ -110,23 +110,6 @@ func Test_github(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
g.Describe("Requesting organization permissions", func() {
|
|
||||||
g.It("Should return the permission details of an admin", func() {
|
|
||||||
perm, err := c.TeamPerm(fakeUser, "octocat")
|
|
||||||
g.Assert(err == nil).IsTrue()
|
|
||||||
g.Assert(perm.Admin).IsTrue()
|
|
||||||
})
|
|
||||||
g.It("Should return the permission details of a member", func() {
|
|
||||||
perm, err := c.TeamPerm(fakeUser, "github")
|
|
||||||
g.Assert(err == nil).IsTrue()
|
|
||||||
g.Assert(perm.Admin).IsFalse()
|
|
||||||
})
|
|
||||||
g.It("Should handle a not found error", func() {
|
|
||||||
_, err := c.TeamPerm(fakeUser, "org_not_found")
|
|
||||||
g.Assert(err != nil).IsTrue()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should return a user repository list")
|
g.It("Should return a user repository list")
|
||||||
|
|
||||||
g.It("Should return a user team list")
|
g.It("Should return a user team list")
|
||||||
|
|
|
@ -203,11 +203,6 @@ func (g *Gitlab) Teams(u *model.User) ([]*model.Team, error) {
|
||||||
return teams, nil
|
return teams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm is not supported by the Gitlab driver.
|
|
||||||
func (g *Gitlab) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo fetches the named repository from the remote system.
|
// Repo fetches the named repository from the remote system.
|
||||||
func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
|
@ -248,32 +243,40 @@ func (g *Gitlab) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repos fetches a list of repos from the remote system.
|
// Repos fetches a list of repos from the remote system.
|
||||||
func (g *Gitlab) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (g *Gitlab) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
|
|
||||||
var repos = []*model.RepoLite{}
|
var repos = []*model.Repo{}
|
||||||
|
|
||||||
all, err := client.AllProjects(g.HideArchives)
|
all, err := client.AllProjects(g.HideArchives)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repo := range all {
|
for _, repo_ := range all {
|
||||||
var parts = strings.Split(repo.PathWithNamespace, "/")
|
var parts = strings.Split(repo_.PathWithNamespace, "/")
|
||||||
var owner = parts[0]
|
var owner = parts[0]
|
||||||
var name = parts[1]
|
var name = parts[1]
|
||||||
var avatar = repo.AvatarUrl
|
|
||||||
|
|
||||||
if len(avatar) != 0 && !strings.HasPrefix(avatar, "http") {
|
repo := &model.Repo{}
|
||||||
avatar = fmt.Sprintf("%s/%s", g.URL, avatar)
|
repo.Owner = owner
|
||||||
|
repo.Name = name
|
||||||
|
repo.FullName = repo_.PathWithNamespace
|
||||||
|
repo.Link = repo_.Url
|
||||||
|
repo.Clone = repo_.HttpRepoUrl
|
||||||
|
repo.Branch = "master"
|
||||||
|
|
||||||
|
if repo_.DefaultBranch != "" {
|
||||||
|
repo.Branch = repo_.DefaultBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
repos = append(repos, &model.RepoLite{
|
if g.PrivateMode {
|
||||||
Owner: owner,
|
repo.IsPrivate = true
|
||||||
Name: name,
|
} else {
|
||||||
FullName: repo.PathWithNamespace,
|
repo.IsPrivate = !repo_.Public
|
||||||
Avatar: avatar,
|
}
|
||||||
})
|
|
||||||
|
repos = append(repos, repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return repos, err
|
return repos, err
|
||||||
|
@ -295,7 +298,7 @@ func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||||
|
|
||||||
// repo owner is granted full access
|
// repo owner is granted full access
|
||||||
if repo.Owner != nil && repo.Owner.Username == u.Login {
|
if repo.Owner != nil && repo.Owner.Username == u.Login {
|
||||||
return &model.Perm{true, true, true}, nil
|
return &model.Perm{Push: true, Pull: true, Admin: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// check permission for current user
|
// check permission for current user
|
||||||
|
|
|
@ -127,11 +127,6 @@ func (c *client) Teams(u *model.User) ([]*model.Team, error) {
|
||||||
return teams, nil
|
return teams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm is not supported by the Gogs driver.
|
|
||||||
func (c *client) TeamPerm(u *model.User, org string) (*model.Perm, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo returns the named Gogs repository.
|
// Repo returns the named Gogs repository.
|
||||||
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
|
@ -147,8 +142,8 @@ func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
|
|
||||||
// Repos returns a list of all repositories for the Gogs account, including
|
// Repos returns a list of all repositories for the Gogs account, including
|
||||||
// organization repositories.
|
// organization repositories.
|
||||||
func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (c *client) Repos(u *model.User) ([]*model.Repo, error) {
|
||||||
repos := []*model.RepoLite{}
|
repos := []*model.Repo{}
|
||||||
|
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
all, err := client.ListMyRepos()
|
all, err := client.ListMyRepos()
|
||||||
|
@ -157,7 +152,7 @@ func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repo := range all {
|
for _, repo := range all {
|
||||||
repos = append(repos, toRepoLite(repo))
|
repos = append(repos, toRepo(repo))
|
||||||
}
|
}
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,21 +12,6 @@ import (
|
||||||
"github.com/gogits/go-gogs-client"
|
"github.com/gogits/go-gogs-client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// helper function that converts a Gogs repository to a Drone repository.
|
|
||||||
func toRepoLite(from *gogs.Repository) *model.RepoLite {
|
|
||||||
name := strings.Split(from.FullName, "/")[1]
|
|
||||||
avatar := expandAvatar(
|
|
||||||
from.HtmlUrl,
|
|
||||||
from.Owner.AvatarUrl,
|
|
||||||
)
|
|
||||||
return &model.RepoLite{
|
|
||||||
Name: name,
|
|
||||||
Owner: from.Owner.UserName,
|
|
||||||
FullName: from.FullName,
|
|
||||||
Avatar: avatar,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function that converts a Gogs repository to a Drone repository.
|
// helper function that converts a Gogs repository to a Drone repository.
|
||||||
func toRepo(from *gogs.Repository) *model.Repo {
|
func toRepo(from *gogs.Repository) *model.Repo {
|
||||||
name := strings.Split(from.FullName, "/")[1]
|
name := strings.Split(from.FullName, "/")[1]
|
||||||
|
|
|
@ -176,21 +176,6 @@ func Test_parse(t *testing.T) {
|
||||||
g.Assert(repo.IsPrivate).Equal(from.Private)
|
g.Assert(repo.IsPrivate).Equal(from.Private)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should return a RepoLite struct from a Gogs Repo", func() {
|
|
||||||
from := gogs.Repository{
|
|
||||||
FullName: "gophers/hello-world",
|
|
||||||
Owner: gogs.User{
|
|
||||||
UserName: "gordon",
|
|
||||||
AvatarUrl: "http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
repo := toRepoLite(&from)
|
|
||||||
g.Assert(repo.FullName).Equal(from.FullName)
|
|
||||||
g.Assert(repo.Owner).Equal(from.Owner.UserName)
|
|
||||||
g.Assert(repo.Name).Equal("hello-world")
|
|
||||||
g.Assert(repo.Avatar).Equal(from.Owner.AvatarUrl)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should correct a malformed avatar url", func() {
|
g.It("Should correct a malformed avatar url", func() {
|
||||||
|
|
||||||
var urls = []struct {
|
var urls = []struct {
|
||||||
|
|
|
@ -23,15 +23,11 @@ type Remote interface {
|
||||||
// Teams fetches a list of team memberships from the remote system.
|
// Teams fetches a list of team memberships from the remote system.
|
||||||
Teams(u *model.User) ([]*model.Team, error)
|
Teams(u *model.User) ([]*model.Team, error)
|
||||||
|
|
||||||
// TeamPerm fetches the named organization permissions from
|
|
||||||
// the remote system for the specified user.
|
|
||||||
TeamPerm(u *model.User, org string) (*model.Perm, error)
|
|
||||||
|
|
||||||
// Repo fetches the named repository from the remote system.
|
// Repo fetches the named repository from the remote system.
|
||||||
Repo(u *model.User, owner, repo string) (*model.Repo, error)
|
Repo(u *model.User, owner, repo string) (*model.Repo, error)
|
||||||
|
|
||||||
// Repos fetches a list of repos from the remote system.
|
// Repos fetches a list of repos from the remote system.
|
||||||
Repos(u *model.User) ([]*model.RepoLite, error)
|
Repos(u *model.User) ([]*model.Repo, error)
|
||||||
|
|
||||||
// Perm fetches the named repository permissions from
|
// Perm fetches the named repository permissions from
|
||||||
// the remote system for the specified user.
|
// the remote system for the specified user.
|
||||||
|
@ -89,19 +85,13 @@ func Teams(c context.Context, u *model.User) ([]*model.Team, error) {
|
||||||
return FromContext(c).Teams(u)
|
return FromContext(c).Teams(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeamPerm fetches the named organization permissions from
|
|
||||||
// the remote system for the specified user.
|
|
||||||
func TeamPerm(c context.Context, u *model.User, org string) (*model.Perm, error) {
|
|
||||||
return FromContext(c).TeamPerm(u, org)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repo fetches the named repository from the remote system.
|
// Repo fetches the named repository from the remote system.
|
||||||
func Repo(c context.Context, u *model.User, owner, repo string) (*model.Repo, error) {
|
func Repo(c context.Context, u *model.User, owner, repo string) (*model.Repo, error) {
|
||||||
return FromContext(c).Repo(u, owner, repo)
|
return FromContext(c).Repo(u, owner, repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repos fetches a list of repos from the remote system.
|
// Repos fetches a list of repos from the remote system.
|
||||||
func Repos(c context.Context, u *model.User) ([]*model.RepoLite, error) {
|
func Repos(c context.Context, u *model.User) ([]*model.Repo, error) {
|
||||||
return FromContext(c).Repos(u)
|
return FromContext(c).Repos(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cache is a middleware function that initializes the Cache and attaches to
|
|
||||||
// the context of every http.Request.
|
|
||||||
func Cache(cli *cli.Context) gin.HandlerFunc {
|
|
||||||
v := setupCache(cli)
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
cache.ToContext(c, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to create the cache from the CLI context.
|
|
||||||
func setupCache(c *cli.Context) cache.Cache {
|
|
||||||
return cache.NewTTL(
|
|
||||||
c.Duration("cache-ttl"),
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -2,9 +2,10 @@ package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/remote"
|
||||||
"github.com/drone/drone/store"
|
"github.com/drone/drone/store"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
@ -92,10 +93,20 @@ func SetPerm() gin.HandlerFunc {
|
||||||
|
|
||||||
case user != nil:
|
case user != nil:
|
||||||
var err error
|
var err error
|
||||||
perm, err = cache.GetPerms(c, user, repo.Owner, repo.Name)
|
perm, err = store.FromContext(c).PermFind(user, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error fetching permission for %s %s",
|
log.Errorf("Error fetching permission for %s %s. %s",
|
||||||
user.Login, repo.FullName)
|
user.Login, repo.FullName, err)
|
||||||
|
}
|
||||||
|
if time.Unix(perm.Synced, 0).Add(time.Hour).Before(time.Now()) {
|
||||||
|
perm, err = remote.FromContext(c).Perm(user, repo.Owner, repo.Name)
|
||||||
|
if err == nil {
|
||||||
|
log.Debugf("Synced user permission for %s %s", user.Login, repo.FullName)
|
||||||
|
perm.Repo = repo.FullName
|
||||||
|
perm.UserID = user.ID
|
||||||
|
perm.Synced = time.Now().Unix()
|
||||||
|
store.FromContext(c).PermUpsert(perm)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
package session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TeamPerm(c *gin.Context) *model.Perm {
|
|
||||||
user := User(c)
|
|
||||||
team := c.Param("team")
|
|
||||||
perm := &model.Perm{}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
// if the user is not authenticated
|
|
||||||
case user == nil:
|
|
||||||
perm.Admin = false
|
|
||||||
perm.Pull = false
|
|
||||||
perm.Push = false
|
|
||||||
|
|
||||||
// if the user is a DRONE_ADMIN
|
|
||||||
case user.Admin:
|
|
||||||
perm.Admin = true
|
|
||||||
perm.Pull = true
|
|
||||||
perm.Push = true
|
|
||||||
|
|
||||||
// otherwise if the user is authenticated we should
|
|
||||||
// check the remote system to get the users permissiosn.
|
|
||||||
default:
|
|
||||||
log.Debugf("Fetching team permission for %s %s",
|
|
||||||
user.Login, team)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
perm, err = cache.GetTeamPerms(c, user, team)
|
|
||||||
if err != nil {
|
|
||||||
// debug
|
|
||||||
log.Errorf("Error fetching team permission for %s %s",
|
|
||||||
user.Login, team)
|
|
||||||
|
|
||||||
perm.Admin = false
|
|
||||||
perm.Pull = false
|
|
||||||
perm.Push = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if user != nil {
|
|
||||||
log.Debugf("%s granted %+v team permission to %s",
|
|
||||||
user.Login, perm, team)
|
|
||||||
} else {
|
|
||||||
log.Debugf("Guest granted %+v to %s", perm, team)
|
|
||||||
|
|
||||||
perm.Admin = false
|
|
||||||
perm.Pull = false
|
|
||||||
perm.Push = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return perm
|
|
||||||
}
|
|
||||||
|
|
||||||
func MustTeamAdmin() gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
perm := TeamPerm(c)
|
|
||||||
|
|
||||||
if perm.Admin {
|
|
||||||
c.Next()
|
|
||||||
} else {
|
|
||||||
c.String(401, "User not authorized")
|
|
||||||
c.Abort()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTeamPerm(t *testing.T) {
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
|
|
||||||
g.Describe("TeamPerm", func() {
|
|
||||||
|
|
||||||
var c *gin.Context
|
|
||||||
g.BeforeEach(func() {
|
|
||||||
c = new(gin.Context)
|
|
||||||
cache.ToContext(c, cache.Default())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should set admin to false (user not logged in)", func() {
|
|
||||||
p := TeamPerm(c)
|
|
||||||
g.Assert(p.Admin).IsFalse("admin should be false")
|
|
||||||
})
|
|
||||||
g.It("Should set admin to true (user is DRONE_ADMIN)", func() {
|
|
||||||
// Set DRONE_ADMIN user
|
|
||||||
c.Set("user", fakeUserAdmin)
|
|
||||||
|
|
||||||
p := TeamPerm(c)
|
|
||||||
g.Assert(p.Admin).IsTrue("admin should be false")
|
|
||||||
})
|
|
||||||
g.It("Should set admin to false (user logged in, not owner of org)", func() {
|
|
||||||
// Set fake org
|
|
||||||
params := gin.Params{
|
|
||||||
gin.Param{
|
|
||||||
Key: "team",
|
|
||||||
Value: "test_org",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.Params = params
|
|
||||||
|
|
||||||
// Set cache to show user does not Owner/Admin
|
|
||||||
cache.Set(c, "perms:octocat:test_org", fakeTeamPerm)
|
|
||||||
|
|
||||||
// Set User
|
|
||||||
c.Set("user", fakeUser)
|
|
||||||
|
|
||||||
p := TeamPerm(c)
|
|
||||||
g.Assert(p.Admin).IsFalse("admin should be false")
|
|
||||||
})
|
|
||||||
g.It("Should set admin to true (user logged in, owner of org)", func() {
|
|
||||||
// Set fake org
|
|
||||||
params := gin.Params{
|
|
||||||
gin.Param{
|
|
||||||
Key: "team",
|
|
||||||
Value: "test_org",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.Params = params
|
|
||||||
|
|
||||||
// Set cache to show user is Owner/Admin
|
|
||||||
cache.Set(c, "perms:octocat:test_org", fakeTeamPermAdmin)
|
|
||||||
|
|
||||||
// Set User
|
|
||||||
c.Set("user", fakeUser)
|
|
||||||
|
|
||||||
p := TeamPerm(c)
|
|
||||||
g.Assert(p.Admin).IsTrue("admin should be true")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
fakeUserAdmin = &model.User{
|
|
||||||
Login: "octocatAdmin",
|
|
||||||
Token: "cfcd2084",
|
|
||||||
Admin: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeUser = &model.User{
|
|
||||||
Login: "octocat",
|
|
||||||
Token: "cfcd2084",
|
|
||||||
Admin: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeTeamPermAdmin = &model.Perm{
|
|
||||||
Admin: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeTeamPerm = &model.Perm{
|
|
||||||
Admin: false,
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -47,7 +47,6 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
||||||
user.GET("", server.GetSelf)
|
user.GET("", server.GetSelf)
|
||||||
user.GET("/feed", server.GetFeed)
|
user.GET("/feed", server.GetFeed)
|
||||||
user.GET("/repos", server.GetRepos)
|
user.GET("/repos", server.GetRepos)
|
||||||
user.GET("/repos/remote", server.GetRemoteRepos)
|
|
||||||
user.POST("/token", server.PostToken)
|
user.POST("/token", server.PostToken)
|
||||||
user.DELETE("/token", server.DeleteToken)
|
user.DELETE("/token", server.DeleteToken)
|
||||||
}
|
}
|
||||||
|
@ -62,46 +61,42 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
||||||
users.DELETE("/:login", server.DeleteUser)
|
users.DELETE("/:login", server.DeleteUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
repos := e.Group("/api/repos/:owner/:name")
|
repo := e.Group("/api/repos/:owner/:name")
|
||||||
{
|
{
|
||||||
repos.POST("", server.PostRepo)
|
repo.Use(session.SetRepo())
|
||||||
|
repo.Use(session.SetPerm())
|
||||||
|
repo.Use(session.MustPull)
|
||||||
|
|
||||||
repo := repos.Group("")
|
repo.POST("", session.MustRepoAdmin(), server.PostRepo)
|
||||||
{
|
repo.GET("", server.GetRepo)
|
||||||
repo.Use(session.SetRepo())
|
repo.GET("/builds", server.GetBuilds)
|
||||||
repo.Use(session.SetPerm())
|
repo.GET("/builds/:number", server.GetBuild)
|
||||||
repo.Use(session.MustPull)
|
repo.GET("/logs/:number/:ppid/:proc", server.GetBuildLogs)
|
||||||
|
|
||||||
repo.GET("", server.GetRepo)
|
// requires push permissions
|
||||||
repo.GET("/builds", server.GetBuilds)
|
repo.GET("/secrets", session.MustPush, server.GetSecretList)
|
||||||
repo.GET("/builds/:number", server.GetBuild)
|
repo.POST("/secrets", session.MustPush, server.PostSecret)
|
||||||
repo.GET("/logs/:number/:ppid/:proc", server.GetBuildLogs)
|
repo.GET("/secrets/:secret", session.MustPush, server.GetSecret)
|
||||||
|
repo.PATCH("/secrets/:secret", session.MustPush, server.PatchSecret)
|
||||||
|
repo.DELETE("/secrets/:secret", session.MustPush, server.DeleteSecret)
|
||||||
|
|
||||||
// requires push permissions
|
// requires push permissions
|
||||||
repo.GET("/secrets", session.MustPush, server.GetSecretList)
|
repo.GET("/registry", session.MustPush, server.GetRegistryList)
|
||||||
repo.POST("/secrets", session.MustPush, server.PostSecret)
|
repo.POST("/registry", session.MustPush, server.PostRegistry)
|
||||||
repo.GET("/secrets/:secret", session.MustPush, server.GetSecret)
|
repo.GET("/registry/:registry", session.MustPush, server.GetRegistry)
|
||||||
repo.PATCH("/secrets/:secret", session.MustPush, server.PatchSecret)
|
repo.PATCH("/registry/:registry", session.MustPush, server.PatchRegistry)
|
||||||
repo.DELETE("/secrets/:secret", session.MustPush, server.DeleteSecret)
|
repo.DELETE("/registry/:registry", session.MustPush, server.DeleteRegistry)
|
||||||
|
|
||||||
// requires push permissions
|
// requires admin permissions
|
||||||
repo.GET("/registry", session.MustPush, server.GetRegistryList)
|
repo.PATCH("", session.MustRepoAdmin(), server.PatchRepo)
|
||||||
repo.POST("/registry", session.MustPush, server.PostRegistry)
|
repo.DELETE("", session.MustRepoAdmin(), server.DeleteRepo)
|
||||||
repo.GET("/registry/:registry", session.MustPush, server.GetRegistry)
|
repo.POST("/chown", session.MustRepoAdmin(), server.ChownRepo)
|
||||||
repo.PATCH("/registry/:registry", session.MustPush, server.PatchRegistry)
|
repo.POST("/repair", session.MustRepoAdmin(), server.RepairRepo)
|
||||||
repo.DELETE("/registry/:registry", session.MustPush, server.DeleteRegistry)
|
|
||||||
|
|
||||||
// requires push permissions
|
repo.POST("/builds/:number", session.MustPush, server.PostBuild)
|
||||||
repo.PATCH("", session.MustPush, server.PatchRepo)
|
repo.POST("/builds/:number/approve", session.MustPush, server.PostApproval)
|
||||||
repo.DELETE("", session.MustRepoAdmin(), server.DeleteRepo)
|
repo.POST("/builds/:number/decline", session.MustPush, server.PostDecline)
|
||||||
repo.POST("/chown", session.MustRepoAdmin(), server.ChownRepo)
|
repo.DELETE("/builds/:number/:job", session.MustPush, server.DeleteBuild)
|
||||||
repo.POST("/repair", session.MustRepoAdmin(), server.RepairRepo)
|
|
||||||
|
|
||||||
repo.POST("/builds/:number", session.MustPush, server.PostBuild)
|
|
||||||
repo.POST("/builds/:number/approve", session.MustPush, server.PostApproval)
|
|
||||||
repo.POST("/builds/:number/decline", session.MustPush, server.PostDecline)
|
|
||||||
repo.DELETE("/builds/:number/:job", session.MustPush, server.DeleteBuild)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
badges := e.Group("/api/badges/:owner/:name")
|
badges := e.Group("/api/badges/:owner/:name")
|
||||||
|
|
|
@ -84,6 +84,11 @@ func PostHook(c *gin.Context) {
|
||||||
c.AbortWithError(404, err)
|
c.AbortWithError(404, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !repo.IsActive {
|
||||||
|
logrus.Errorf("ignoring hook. %s/%s is inactive.", tmprepo.Owner, tmprepo.Name)
|
||||||
|
c.AbortWithError(204, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// get the token and verify the hook is authorized
|
// get the token and verify the hook is authorized
|
||||||
parsed, err := token.ParseRequest(c.Request, func(t *token.Token) (string, error) {
|
parsed, err := token.ParseRequest(c.Request, func(t *token.Token) (string, error) {
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/securecookie"
|
"github.com/gorilla/securecookie"
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote"
|
"github.com/drone/drone/remote"
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
|
@ -20,54 +20,40 @@ import (
|
||||||
func PostRepo(c *gin.Context) {
|
func PostRepo(c *gin.Context) {
|
||||||
remote := remote.FromContext(c)
|
remote := remote.FromContext(c)
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
owner := c.Param("owner")
|
repo := session.Repo(c)
|
||||||
name := c.Param("name")
|
|
||||||
|
|
||||||
if user == nil {
|
if repo.IsActive {
|
||||||
c.AbortWithStatus(403)
|
c.String(409, "Repository is already active.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := remote.Repo(user, owner, name)
|
repo.IsActive = true
|
||||||
if err != nil {
|
repo.UserID = user.ID
|
||||||
c.String(404, err.Error())
|
if !repo.AllowPush && !repo.AllowPull && !repo.AllowDeploy && !repo.AllowTag {
|
||||||
return
|
repo.AllowPush = true
|
||||||
|
repo.AllowPull = true
|
||||||
}
|
}
|
||||||
m, err := cache.GetPerms(c, user, owner, name)
|
if repo.Visibility == "" {
|
||||||
if err != nil {
|
repo.Visibility = model.VisibilityPublic
|
||||||
c.String(404, err.Error())
|
if repo.IsPrivate {
|
||||||
return
|
repo.Visibility = model.VisibilityPrivate
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !m.Admin {
|
if repo.Config == "" {
|
||||||
c.String(403, "Administrative access is required.")
|
repo.Config = ".drone.yml"
|
||||||
return
|
}
|
||||||
|
if repo.Timeout == 0 {
|
||||||
|
repo.Timeout = 60 // 1 hour default build time
|
||||||
|
}
|
||||||
|
if repo.Hash == "" {
|
||||||
|
repo.Hash = base32.StdEncoding.EncodeToString(
|
||||||
|
securecookie.GenerateRandomKey(32),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// error if the repository already exists
|
// creates the jwt token used to verify the repository
|
||||||
_, err = store.GetRepoOwnerName(c, owner, name)
|
t := token.New(token.HookToken, repo.FullName)
|
||||||
if err == nil {
|
sig, err := t.Sign(repo.Hash)
|
||||||
c.String(409, "Repository already exists.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the repository owner to the
|
|
||||||
// currently authenticated user.
|
|
||||||
r.UserID = user.ID
|
|
||||||
r.AllowPush = true
|
|
||||||
r.AllowPull = true
|
|
||||||
r.Visibility = model.VisibilityPublic
|
|
||||||
r.Config = ".drone.yml"
|
|
||||||
r.Timeout = 60 // 1 hour default build time
|
|
||||||
r.Hash = base32.StdEncoding.EncodeToString(
|
|
||||||
securecookie.GenerateRandomKey(32),
|
|
||||||
)
|
|
||||||
if r.IsPrivate {
|
|
||||||
r.Visibility = model.VisibilityPrivate
|
|
||||||
}
|
|
||||||
|
|
||||||
// crates the jwt token used to verify the repository
|
|
||||||
t := token.New(token.HookToken, r.FullName)
|
|
||||||
sig, err := t.Sign(r.Hash)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, err.Error())
|
c.String(500, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -79,22 +65,19 @@ func PostRepo(c *gin.Context) {
|
||||||
sig,
|
sig,
|
||||||
)
|
)
|
||||||
|
|
||||||
// activate the repository before we make any
|
err = remote.Activate(user, repo, link)
|
||||||
// local changes to the database.
|
|
||||||
err = remote.Activate(user, r, link)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, err.Error())
|
c.String(500, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// persist the repository
|
err = store.UpdateRepo(c, repo)
|
||||||
err = store.CreateRepo(c, r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, err.Error())
|
c.String(500, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, r)
|
c.JSON(200, repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PatchRepo(c *gin.Context) {
|
func PatchRepo(c *gin.Context) {
|
||||||
|
@ -173,16 +156,28 @@ func GetRepo(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteRepo(c *gin.Context) {
|
func DeleteRepo(c *gin.Context) {
|
||||||
|
remove, _ := strconv.ParseBool(c.Query("remove"))
|
||||||
remote := remote.FromContext(c)
|
remote := remote.FromContext(c)
|
||||||
repo := session.Repo(c)
|
repo := session.Repo(c)
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
|
|
||||||
err := store.DeleteRepo(c, repo)
|
repo.IsActive = false
|
||||||
|
repo.UserID = 0
|
||||||
|
|
||||||
|
err := store.UpdateRepo(c, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithError(http.StatusInternalServerError, err)
|
c.AbortWithError(http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if remove {
|
||||||
|
err := store.DeleteRepo(c, repo)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
remote.Deactivate(user, repo, httputil.GetURL(c.Request))
|
remote.Deactivate(user, repo, httputil.GetURL(c.Request))
|
||||||
c.Writer.WriteHeader(http.StatusOK)
|
c.Writer.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
|
|
||||||
"github.com/cncd/logging"
|
"github.com/cncd/logging"
|
||||||
"github.com/cncd/pubsub"
|
"github.com/cncd/pubsub"
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
"github.com/drone/drone/store"
|
"github.com/drone/drone/store"
|
||||||
|
@ -149,7 +148,10 @@ func EventStream(c *gin.Context) {
|
||||||
user := session.User(c)
|
user := session.User(c)
|
||||||
repo := map[string]bool{}
|
repo := map[string]bool{}
|
||||||
if user != nil {
|
if user != nil {
|
||||||
repo, _ = cache.GetRepoMap(c, user)
|
repos, _ := store.FromContext(c).RepoList(user)
|
||||||
|
for _, r := range repos {
|
||||||
|
repo[r.FullName] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(pingPeriod)
|
ticker := time.NewTicker(pingPeriod)
|
||||||
|
|
66
server/sync.go
Normal file
66
server/sync.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/remote"
|
||||||
|
"github.com/drone/drone/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Syncer synces the user repository and permissions.
|
||||||
|
type Syncer interface {
|
||||||
|
Sync(user *model.User) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type syncer struct {
|
||||||
|
remote remote.Remote
|
||||||
|
store store.Store
|
||||||
|
perms model.PermStore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncer) Sync(user *model.User) error {
|
||||||
|
unix := time.Now().Unix() - 1 // force immediate expiration
|
||||||
|
repos, err := s.remote.Repos(user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var perms []*model.Perm
|
||||||
|
for _, repo := range repos {
|
||||||
|
perm := model.Perm{
|
||||||
|
UserID: user.ID,
|
||||||
|
Repo: repo.FullName,
|
||||||
|
Pull: true,
|
||||||
|
Synced: unix,
|
||||||
|
}
|
||||||
|
if repo.Perm != nil {
|
||||||
|
perm.Push = repo.Perm.Push
|
||||||
|
perm.Admin = repo.Perm.Admin
|
||||||
|
}
|
||||||
|
perms = append(perms, &perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.store.RepoBatch(repos)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.store.PermBatch(perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is here as a precaution. I want to make sure that if an api
|
||||||
|
// call to the version control system fails and (for some reason) returns
|
||||||
|
// an empty list, we don't wipe out the user repository permissions.
|
||||||
|
//
|
||||||
|
// the side-effect of this code is that a user with 1 repository whose
|
||||||
|
// access is removed will still display in the feed, but they will not
|
||||||
|
// be able to access the actual repository data.
|
||||||
|
if len(repos) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.perms.PermFlush(user, unix)
|
||||||
|
}
|
|
@ -5,6 +5,9 @@
|
||||||
<meta name="author" content="bradrydzewski">
|
<meta name="author" content="bradrydzewski">
|
||||||
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="shortcut icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
|
||||||
<title></title>
|
<title></title>
|
||||||
<script>
|
<script>
|
||||||
window.ENV = {};
|
window.ENV = {};
|
||||||
|
|
|
@ -94,6 +94,9 @@ var indexpolymer = `<!DOCTYPE html>
|
||||||
<meta name="author" content="bradrydzewski">
|
<meta name="author" content="bradrydzewski">
|
||||||
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="shortcut icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
|
||||||
<title></title>
|
<title></title>
|
||||||
<script>
|
<script>
|
||||||
window.ENV = {};
|
window.ENV = {};
|
||||||
|
|
18
server/ui.go
18
server/ui.go
|
@ -23,12 +23,13 @@ type website struct {
|
||||||
|
|
||||||
// NewWebsite returns a new website loader.
|
// NewWebsite returns a new website loader.
|
||||||
func NewWebsite() Website {
|
func NewWebsite() Website {
|
||||||
|
// TODO change to DRONE_WEB_PATH and add DRONE_WEB_PROXY
|
||||||
path := os.Getenv("DRONE_WWW")
|
path := os.Getenv("DRONE_WWW")
|
||||||
if path != "" {
|
if path != "" {
|
||||||
return NewLocalWebsite(path)
|
return NewLocalWebsite(path)
|
||||||
}
|
}
|
||||||
return &website{
|
return &website{
|
||||||
fs: http.FileServer(dist.AssetFS()),
|
fs: http.FileServer(dist.New()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,14 +39,9 @@ func (w *website) Page(rw http.ResponseWriter, r *http.Request, u *model.User) {
|
||||||
|
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
switch path {
|
switch path {
|
||||||
case "/login/form":
|
|
||||||
params := map[string]interface{}{}
|
|
||||||
template.T.ExecuteTemplate(rw, "login.html", params)
|
|
||||||
|
|
||||||
case "/login":
|
case "/login":
|
||||||
if err := r.FormValue("error"); err != "" {
|
if err := r.FormValue("error"); err != "" {
|
||||||
params := map[string]interface{}{"error": err}
|
// TODO login error
|
||||||
template.T.ExecuteTemplate(rw, "error.html", params)
|
|
||||||
} else {
|
} else {
|
||||||
http.Redirect(rw, r, "/authorize", 303)
|
http.Redirect(rw, r, "/authorize", 303)
|
||||||
}
|
}
|
||||||
|
@ -62,7 +58,8 @@ func (w *website) Page(rw http.ResponseWriter, r *http.Request, u *model.User) {
|
||||||
"user": u,
|
"user": u,
|
||||||
"csrf": csrf,
|
"csrf": csrf,
|
||||||
}
|
}
|
||||||
template.T.ExecuteTemplate(rw, "index.html", params)
|
|
||||||
|
template.T.ExecuteTemplate(rw, "index_polymer.html", params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +70,9 @@ func (w *website) File(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func (w *website) Routes() []string {
|
func (w *website) Routes() []string {
|
||||||
return []string{
|
return []string{
|
||||||
"/static/*filepath",
|
"/favicon-32x32.png",
|
||||||
|
"/favicon-16x16.png",
|
||||||
|
"/src/*filepath",
|
||||||
|
"/bower_components/*filepath",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,14 @@ import (
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/securecookie"
|
"github.com/gorilla/securecookie"
|
||||||
|
|
||||||
"github.com/drone/drone/cache"
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/remote"
|
||||||
"github.com/drone/drone/router/middleware/session"
|
"github.com/drone/drone/router/middleware/session"
|
||||||
"github.com/drone/drone/shared/token"
|
"github.com/drone/drone/shared/token"
|
||||||
"github.com/drone/drone/store"
|
"github.com/drone/drone/store"
|
||||||
|
@ -21,17 +22,38 @@ func GetSelf(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFeed(c *gin.Context) {
|
func GetFeed(c *gin.Context) {
|
||||||
|
user := session.User(c)
|
||||||
latest, _ := strconv.ParseBool(c.Query("latest"))
|
latest, _ := strconv.ParseBool(c.Query("latest"))
|
||||||
|
|
||||||
repos, err := cache.GetRepos(c, session.User(c))
|
if time.Unix(user.Synced, 0).Add(time.Hour * 72).Before(time.Now()) {
|
||||||
if err != nil {
|
logrus.Debugf("sync begin: %s", user.Login)
|
||||||
c.String(500, "Error fetching repository list. %s", err)
|
sync := syncer{
|
||||||
|
remote: remote.FromContext(c),
|
||||||
|
store: store.FromContext(c),
|
||||||
|
perms: store.FromContext(c),
|
||||||
|
}
|
||||||
|
if err := sync.Sync(user); err != nil {
|
||||||
|
logrus.Debugf("sync error: %s: %s", user.Login, err)
|
||||||
|
} else {
|
||||||
|
logrus.Debugf("sync complete: %s", user.Login)
|
||||||
|
user.Synced = time.Now().Unix()
|
||||||
|
store.FromContext(c).UpdateUser(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if latest {
|
||||||
|
feed, err := store.FromContext(c).RepoListLatest(user)
|
||||||
|
if err != nil {
|
||||||
|
c.String(500, "Error fetching feed. %s", err)
|
||||||
|
} else {
|
||||||
|
c.JSON(200, feed)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
feed, err := store.GetUserFeed(c, repos, latest)
|
feed, err := store.FromContext(c).UserFeed(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, "Error fetching feed. %s", err)
|
c.String(500, "Error fetching user feed. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(200, feed)
|
c.JSON(200, feed)
|
||||||
|
@ -44,58 +66,40 @@ func GetRepos(c *gin.Context) {
|
||||||
flush, _ = strconv.ParseBool(c.Query("flush"))
|
flush, _ = strconv.ParseBool(c.Query("flush"))
|
||||||
)
|
)
|
||||||
|
|
||||||
if flush {
|
if flush || time.Unix(user.Synced, 0).Add(time.Hour*72).Before(time.Now()) {
|
||||||
log.Debugf("Evicting repository cache for user %s.", user.Login)
|
logrus.Debugf("sync begin: %s", user.Login)
|
||||||
cache.DeleteRepos(c, user)
|
sync := syncer{
|
||||||
|
remote: remote.FromContext(c),
|
||||||
|
store: store.FromContext(c),
|
||||||
|
perms: store.FromContext(c),
|
||||||
|
}
|
||||||
|
if err := sync.Sync(user); err != nil {
|
||||||
|
logrus.Debugf("sync error: %s: %s", user.Login, err)
|
||||||
|
} else {
|
||||||
|
logrus.Debugf("sync complete: %s", user.Login)
|
||||||
|
user.Synced = time.Now().Unix()
|
||||||
|
store.FromContext(c).UpdateUser(user)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := cache.GetRepos(c, user)
|
repos, err := store.FromContext(c).RepoList(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, "Error fetching repository list. %s", err)
|
c.String(500, "Error fetching repository list. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repos, err := store.GetRepoListOf(c, remote)
|
if all {
|
||||||
if err != nil {
|
|
||||||
c.String(500, "Error fetching repository list. %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !all {
|
|
||||||
c.JSON(http.StatusOK, repos)
|
c.JSON(http.StatusOK, repos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// below we combine the two lists to include both active and inactive
|
active := []*model.Repo{}
|
||||||
// repositories. This is displayed on the settings screen to enable
|
|
||||||
// toggling on / off repository settings.
|
|
||||||
|
|
||||||
repom := map[string]bool{}
|
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
repom[repo.FullName] = true
|
if repo.IsActive {
|
||||||
}
|
active = append(active, repo)
|
||||||
|
|
||||||
for _, repo := range remote {
|
|
||||||
if repom[repo.FullName] {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
repos = append(repos, &model.Repo{
|
|
||||||
Avatar: repo.Avatar,
|
|
||||||
FullName: repo.FullName,
|
|
||||||
Owner: repo.Owner,
|
|
||||||
Name: repo.Name,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, repos)
|
c.JSON(http.StatusOK, active)
|
||||||
}
|
|
||||||
|
|
||||||
func GetRemoteRepos(c *gin.Context) {
|
|
||||||
repos, err := cache.GetRepos(c, session.User(c))
|
|
||||||
if err != nil {
|
|
||||||
c.String(500, "Error fetching repository list. %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, repos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostToken(c *gin.Context) {
|
func PostToken(c *gin.Context) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ func TestBuilds(t *testing.T) {
|
||||||
// table data from the database.
|
// table data from the database.
|
||||||
g.BeforeEach(func() {
|
g.BeforeEach(func() {
|
||||||
s.Exec("DELETE FROM builds")
|
s.Exec("DELETE FROM builds")
|
||||||
s.Exec("DELETE FROM jobs")
|
s.Exec("DELETE FROM procs")
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should Post a Build", func() {
|
g.It("Should Post a Build", func() {
|
||||||
|
|
|
@ -108,6 +108,34 @@ var migrations = []struct {
|
||||||
name: "update-table-set-repo-seq-default",
|
name: "update-table-set-repo-seq-default",
|
||||||
stmt: updateTableSetRepoSeqDefault,
|
stmt: updateTableSetRepoSeqDefault,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-repo-active",
|
||||||
|
stmt: alterTableAddRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-repo-active",
|
||||||
|
stmt: updateTableSetRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-user-synced",
|
||||||
|
stmt: alterTableAddUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-user-synced",
|
||||||
|
stmt: updateTableSetUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-table-perms",
|
||||||
|
stmt: createTablePerms,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-repo",
|
||||||
|
stmt: createIndexPermsRepo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-user",
|
||||||
|
stmt: createIndexPermsUser,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate performs the database migration. If the migration fails
|
// Migrate performs the database migration. If the migration fails
|
||||||
|
@ -499,3 +527,51 @@ var updateTableSetRepoSeqDefault = `
|
||||||
UPDATE repos SET repo_counter = 0
|
UPDATE repos SET repo_counter = 0
|
||||||
WHERE repo_counter IS NULL
|
WHERE repo_counter IS NULL
|
||||||
`
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 015_add_column_repo_active.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddRepoActive = `
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetRepoActive = `
|
||||||
|
UPDATE repos SET repo_active = true
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 016_add_column_user_synced.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddUserSynced = `
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetUserSynced = `
|
||||||
|
UPDATE users SET user_synced = 0
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 017_create_table_perms.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var createTablePerms = `
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsRepo = `
|
||||||
|
CREATE INDEX ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsUser = `
|
||||||
|
CREATE INDEX ix_perms_user ON perms (perm_user_id);
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-repo-active
|
||||||
|
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
|
||||||
|
-- name: update-table-set-repo-active
|
||||||
|
|
||||||
|
UPDATE repos SET repo_active = true
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-user-synced
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
|
||||||
|
-- name: update-table-set-user-synced
|
||||||
|
|
||||||
|
UPDATE users SET user_synced = 0
|
19
store/datastore/ddl/mysql/files/017_create_table_perms.sql
Normal file
19
store/datastore/ddl/mysql/files/017_create_table_perms.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-- name: create-table-perms
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- name: create-index-perms-repo
|
||||||
|
|
||||||
|
CREATE INDEX ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
|
||||||
|
-- name: create-index-perms-user
|
||||||
|
|
||||||
|
CREATE INDEX ix_perms_user ON perms (perm_user_id);
|
|
@ -108,6 +108,34 @@ var migrations = []struct {
|
||||||
name: "update-table-set-repo-seq-default",
|
name: "update-table-set-repo-seq-default",
|
||||||
stmt: updateTableSetRepoSeqDefault,
|
stmt: updateTableSetRepoSeqDefault,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-repo-active",
|
||||||
|
stmt: alterTableAddRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-repo-active",
|
||||||
|
stmt: updateTableSetRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-user-synced",
|
||||||
|
stmt: alterTableAddUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-user-synced",
|
||||||
|
stmt: updateTableSetUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-table-perms",
|
||||||
|
stmt: createTablePerms,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-repo",
|
||||||
|
stmt: createIndexPermsRepo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-user",
|
||||||
|
stmt: createIndexPermsUser,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate performs the database migration. If the migration fails
|
// Migrate performs the database migration. If the migration fails
|
||||||
|
@ -499,3 +527,51 @@ var updateTableSetRepoSeqDefault = `
|
||||||
UPDATE repos SET repo_counter = 0
|
UPDATE repos SET repo_counter = 0
|
||||||
WHERE repo_counter IS NULL
|
WHERE repo_counter IS NULL
|
||||||
`
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 015_add_column_repo_active.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddRepoActive = `
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetRepoActive = `
|
||||||
|
UPDATE repos SET repo_active = true
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 016_add_column_user_synced.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddUserSynced = `
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetUserSynced = `
|
||||||
|
UPDATE users SET user_synced = 0
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 017_create_table_perms.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var createTablePerms = `
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsRepo = `
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsUser = `
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id);
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-repo-active
|
||||||
|
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
|
||||||
|
-- name: update-table-set-repo-active
|
||||||
|
|
||||||
|
UPDATE repos SET repo_active = true
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-user-synced
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
|
||||||
|
-- name: update-table-set-user-synced
|
||||||
|
|
||||||
|
UPDATE users SET user_synced = 0
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- name: create-table-perms
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- name: create-index-perms-repo
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
|
||||||
|
-- name: create-index-perms-user
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id);
|
|
@ -112,6 +112,34 @@ var migrations = []struct {
|
||||||
name: "update-table-set-repo-seq-default",
|
name: "update-table-set-repo-seq-default",
|
||||||
stmt: updateTableSetRepoSeqDefault,
|
stmt: updateTableSetRepoSeqDefault,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-repo-active",
|
||||||
|
stmt: alterTableAddRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-repo-active",
|
||||||
|
stmt: updateTableSetRepoActive,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-user-synced",
|
||||||
|
stmt: alterTableAddUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-user-synced",
|
||||||
|
stmt: updateTableSetUserSynced,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-table-perms",
|
||||||
|
stmt: createTablePerms,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-repo",
|
||||||
|
stmt: createIndexPermsRepo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create-index-perms-user",
|
||||||
|
stmt: createIndexPermsUser,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate performs the database migration. If the migration fails
|
// Migrate performs the database migration. If the migration fails
|
||||||
|
@ -500,3 +528,51 @@ var updateTableSetRepoSeqDefault = `
|
||||||
UPDATE repos SET repo_counter = 0
|
UPDATE repos SET repo_counter = 0
|
||||||
WHERE repo_counter IS NULL
|
WHERE repo_counter IS NULL
|
||||||
`
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 015_add_column_repo_active.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddRepoActive = `
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetRepoActive = `
|
||||||
|
UPDATE repos SET repo_active = 1
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 016_add_column_user_synced.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddUserSynced = `
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetUserSynced = `
|
||||||
|
UPDATE users SET user_synced = 0
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 017_create_table_perms.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var createTablePerms = `
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsRepo = `
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
`
|
||||||
|
|
||||||
|
var createIndexPermsUser = `
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id);
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-repo-active
|
||||||
|
|
||||||
|
ALTER TABLE repos ADD COLUMN repo_active BOOLEAN
|
||||||
|
|
||||||
|
-- name: update-table-set-repo-active
|
||||||
|
|
||||||
|
UPDATE repos SET repo_active = 1
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-user-synced
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN user_synced INTEGER;
|
||||||
|
|
||||||
|
-- name: update-table-set-user-synced
|
||||||
|
|
||||||
|
UPDATE users SET user_synced = 0
|
19
store/datastore/ddl/sqlite/files/017_create_table_perms.sql
Normal file
19
store/datastore/ddl/sqlite/files/017_create_table_perms.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-- name: create-table-perms
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS perms (
|
||||||
|
perm_user_id INTEGER NOT NULL
|
||||||
|
,perm_repo_id INTEGER NOT NULL
|
||||||
|
,perm_pull BOOLEAN
|
||||||
|
,perm_push BOOLEAN
|
||||||
|
,perm_admin BOOLEAN
|
||||||
|
,perm_synced INTEGER
|
||||||
|
,UNIQUE(perm_user_id, perm_repo_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- name: create-index-perms-repo
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id);
|
||||||
|
|
||||||
|
-- name: create-index-perms-user
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id);
|
|
@ -1,242 +0,0 @@
|
||||||
-- name: create-table-users
|
|
||||||
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,user_login TEXT
|
|
||||||
,user_token TEXT
|
|
||||||
,user_secret TEXT
|
|
||||||
,user_expiry INTEGER
|
|
||||||
,user_email TEXT
|
|
||||||
,user_avatar TEXT
|
|
||||||
,user_active BOOLEAN
|
|
||||||
,user_admin BOOLEAN
|
|
||||||
,user_hash TEXT
|
|
||||||
|
|
||||||
,UNIQUE(user_login)
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-repos
|
|
||||||
|
|
||||||
CREATE TABLE repos (
|
|
||||||
repo_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,repo_user_id INTEGER
|
|
||||||
,repo_owner TEXT
|
|
||||||
,repo_name TEXT
|
|
||||||
,repo_full_name TEXT
|
|
||||||
,repo_avatar TEXT
|
|
||||||
,repo_link TEXT
|
|
||||||
,repo_clone TEXT
|
|
||||||
,repo_branch TEXT
|
|
||||||
,repo_timeout INTEGER
|
|
||||||
,repo_private BOOLEAN
|
|
||||||
,repo_trusted BOOLEAN
|
|
||||||
,repo_allow_pr BOOLEAN
|
|
||||||
,repo_allow_push BOOLEAN
|
|
||||||
,repo_allow_deploys BOOLEAN
|
|
||||||
,repo_allow_tags BOOLEAN
|
|
||||||
,repo_hash TEXT
|
|
||||||
,repo_scm TEXT
|
|
||||||
,repo_config_path TEXT
|
|
||||||
,repo_gated BOOLEAN
|
|
||||||
,UNIQUE(repo_full_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-secrets
|
|
||||||
|
|
||||||
CREATE TABLE secrets (
|
|
||||||
secret_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,secret_repo_id INTEGER
|
|
||||||
,secret_name TEXT
|
|
||||||
,secret_value TEXT
|
|
||||||
,secret_images TEXT
|
|
||||||
,secret_events TEXT
|
|
||||||
,secret_skip_verify BOOLEAN
|
|
||||||
,secret_conceal BOOLEAN
|
|
||||||
,UNIQUE(secret_name, secret_repo_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-secrets-repo
|
|
||||||
|
|
||||||
CREATE INDEX ix_secrets_repo ON secrets (secret_repo_id);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-registry
|
|
||||||
|
|
||||||
CREATE TABLE registry (
|
|
||||||
registry_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,registry_repo_id INTEGER
|
|
||||||
,registry_addr TEXT
|
|
||||||
,registry_username TEXT
|
|
||||||
,registry_password TEXT
|
|
||||||
,registry_email TEXT
|
|
||||||
,registry_token TEXT
|
|
||||||
|
|
||||||
,UNIQUE(registry_addr, registry_repo_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-registry-repo
|
|
||||||
|
|
||||||
CREATE INDEX ix_registry_repo ON registry (registry_repo_id);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-builds
|
|
||||||
|
|
||||||
CREATE TABLE builds (
|
|
||||||
build_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,build_repo_id INTEGER
|
|
||||||
,build_number INTEGER
|
|
||||||
,build_event TEXT
|
|
||||||
,build_status TEXT
|
|
||||||
,build_enqueued INTEGER
|
|
||||||
,build_created INTEGER
|
|
||||||
,build_started INTEGER
|
|
||||||
,build_finished INTEGER
|
|
||||||
,build_commit TEXT
|
|
||||||
,build_branch TEXT
|
|
||||||
,build_ref TEXT
|
|
||||||
,build_refspec TEXT
|
|
||||||
,build_remote TEXT
|
|
||||||
,build_title TEXT
|
|
||||||
,build_message TEXT
|
|
||||||
,build_timestamp INTEGER
|
|
||||||
,build_author TEXT
|
|
||||||
,build_avatar TEXT
|
|
||||||
,build_email TEXT
|
|
||||||
,build_link TEXT
|
|
||||||
,build_deploy TEXT
|
|
||||||
,build_signed BOOLEAN
|
|
||||||
,build_verified BOOLEAN
|
|
||||||
,build_parent INTEGER
|
|
||||||
,build_error TEXT
|
|
||||||
,build_reviewer TEXT
|
|
||||||
,build_reviewed INTEGER
|
|
||||||
,build_sender TEXT
|
|
||||||
,build_config_id INTEGER
|
|
||||||
,UNIQUE(build_number, build_repo_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-builds-repo
|
|
||||||
|
|
||||||
CREATE INDEX ix_build_repo ON builds (build_repo_id);
|
|
||||||
|
|
||||||
-- name: create-index-builds-author
|
|
||||||
|
|
||||||
CREATE INDEX ix_build_author ON builds (build_author);
|
|
||||||
|
|
||||||
-- name: create-index-builds-status
|
|
||||||
|
|
||||||
CREATE INDEX ix_build_status_running ON builds (build_status)
|
|
||||||
WHERE build_status IN ('pending', 'running');
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-procs
|
|
||||||
|
|
||||||
CREATE TABLE procs (
|
|
||||||
proc_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,proc_build_id INTEGER
|
|
||||||
,proc_pid INTEGER
|
|
||||||
,proc_ppid INTEGER
|
|
||||||
,proc_pgid INTEGER
|
|
||||||
,proc_name TEXT
|
|
||||||
,proc_state TEXT
|
|
||||||
,proc_error TEXT
|
|
||||||
,proc_exit_code INTEGER
|
|
||||||
,proc_started INTEGER
|
|
||||||
,proc_stopped INTEGER
|
|
||||||
,proc_machine TEXT
|
|
||||||
,proc_platform TEXT
|
|
||||||
,proc_environ TEXT
|
|
||||||
,UNIQUE(proc_build_id, proc_pid)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-procs-build
|
|
||||||
|
|
||||||
CREATE INDEX proc_build_ix ON procs (proc_build_id);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-logs
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS logs (
|
|
||||||
log_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,log_job_id INTEGER
|
|
||||||
,log_data BLOB
|
|
||||||
,UNIQUE(log_job_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-files
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS files (
|
|
||||||
file_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,file_build_id INTEGER
|
|
||||||
,file_proc_id INTEGER
|
|
||||||
,file_name TEXT
|
|
||||||
,file_mime TEXT
|
|
||||||
,file_size INTEGER
|
|
||||||
,file_time INTEGER
|
|
||||||
,file_data BLOB
|
|
||||||
,UNIQUE(file_proc_id,file_name)
|
|
||||||
,FOREIGN KEY(file_proc_id) REFERENCES procs (proc_id) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-files-builds
|
|
||||||
|
|
||||||
CREATE INDEX file_build_ix ON files (file_build_id);
|
|
||||||
|
|
||||||
-- name: create-index-files-procs
|
|
||||||
|
|
||||||
CREATE INDEX file_proc_ix ON files (file_proc_id);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-senders
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS senders (
|
|
||||||
sender_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,sender_repo_id INTEGER
|
|
||||||
,sender_login BOOLEAN
|
|
||||||
,sender_allow BOOLEAN
|
|
||||||
,sender_block BOOLEAN
|
|
||||||
|
|
||||||
,UNIQUE(sender_repo_id,sender_login)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- name: create-index-sender-repos
|
|
||||||
|
|
||||||
CREATE INDEX sender_repo_ix ON senders (sender_repo_id);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-config
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS config (
|
|
||||||
config_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,config_repo_id INTEGER
|
|
||||||
,config_hash TEXT
|
|
||||||
,config_data BLOB
|
|
||||||
|
|
||||||
,UNIQUE(config_hash, config_repo_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-tasks
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
task_id TEXT PRIMARY KEY
|
|
||||||
,task_data BLOB
|
|
||||||
,task_labels BLOB
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- name: create-table-agents
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
agent_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
||||||
,agent_addr TEXT
|
|
||||||
,agent_platform TEXT
|
|
||||||
,agent_capacity INTEGER
|
|
||||||
,agent_created INTEGER
|
|
||||||
,agent_updated INTEGER
|
|
||||||
|
|
||||||
,UNIQUE(agent_addr)
|
|
||||||
);
|
|
50
store/datastore/perms.go
Normal file
50
store/datastore/perms.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/store/datastore/sql"
|
||||||
|
|
||||||
|
"github.com/russross/meddler"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (db *datastore) PermFind(user *model.User, repo *model.Repo) (*model.Perm, error) {
|
||||||
|
stmt := sql.Lookup(db.driver, "perms-find-user-repo")
|
||||||
|
data := new(model.Perm)
|
||||||
|
err := meddler.QueryRow(db, data, stmt, user.ID, repo.ID)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) PermUpsert(perm *model.Perm) error {
|
||||||
|
stmt := sql.Lookup(db.driver, "perms-insert-replace-lookup")
|
||||||
|
_, err := db.Exec(stmt,
|
||||||
|
perm.UserID,
|
||||||
|
perm.Repo,
|
||||||
|
perm.Pull,
|
||||||
|
perm.Push,
|
||||||
|
perm.Admin,
|
||||||
|
perm.Synced,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) PermBatch(perms []*model.Perm) (err error) {
|
||||||
|
for _, perm := range perms {
|
||||||
|
err = db.PermUpsert(perm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) PermDelete(perm *model.Perm) error {
|
||||||
|
stmt := sql.Lookup(db.driver, "perms-delete-user-repo")
|
||||||
|
_, err := db.Exec(stmt, perm.UserID, perm.RepoID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) PermFlush(user *model.User, before int64) error {
|
||||||
|
stmt := sql.Lookup(db.driver, "perms-delete-user-date")
|
||||||
|
_, err := db.Exec(stmt, user.ID, before)
|
||||||
|
return err
|
||||||
|
}
|
187
store/datastore/perms_test.go
Normal file
187
store/datastore/perms_test.go
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPermFind(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
user := &model.User{ID: 1}
|
||||||
|
repo := &model.Repo{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo)
|
||||||
|
|
||||||
|
err := s.PermUpsert(
|
||||||
|
&model.Perm{
|
||||||
|
UserID: user.ID,
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo.FullName,
|
||||||
|
Pull: true,
|
||||||
|
Push: false,
|
||||||
|
Admin: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
perm, err := s.PermFind(user, repo)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got, want := perm.Pull, true; got != want {
|
||||||
|
t.Errorf("Wanted pull %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Push, false; got != want {
|
||||||
|
t.Errorf("Wanted push %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Admin, false; got != want {
|
||||||
|
t.Errorf("Wanted admin %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPermUpsert(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
user := &model.User{ID: 1}
|
||||||
|
repo := &model.Repo{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo)
|
||||||
|
|
||||||
|
err := s.PermUpsert(
|
||||||
|
&model.Perm{
|
||||||
|
UserID: user.ID,
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo.FullName,
|
||||||
|
Pull: true,
|
||||||
|
Push: false,
|
||||||
|
Admin: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
perm, err := s.PermFind(user, repo)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got, want := perm.Pull, true; got != want {
|
||||||
|
t.Errorf("Wanted pull %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Push, false; got != want {
|
||||||
|
t.Errorf("Wanted push %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Admin, false; got != want {
|
||||||
|
t.Errorf("Wanted admin %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// this will attempt to replace the existing permissions
|
||||||
|
// using the insert or replace logic.
|
||||||
|
//
|
||||||
|
|
||||||
|
err = s.PermUpsert(
|
||||||
|
&model.Perm{
|
||||||
|
UserID: user.ID,
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo.FullName,
|
||||||
|
Pull: true,
|
||||||
|
Push: true,
|
||||||
|
Admin: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
perm, err = s.PermFind(user, repo)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got, want := perm.Pull, true; got != want {
|
||||||
|
t.Errorf("Wanted pull %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Push, true; got != want {
|
||||||
|
t.Errorf("Wanted push %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
if got, want := perm.Admin, true; got != want {
|
||||||
|
t.Errorf("Wanted admin %v, got %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPermDelete(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
user := &model.User{ID: 1}
|
||||||
|
repo := &model.Repo{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo)
|
||||||
|
|
||||||
|
err := s.PermUpsert(
|
||||||
|
&model.Perm{
|
||||||
|
UserID: user.ID,
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo.FullName,
|
||||||
|
Pull: true,
|
||||||
|
Push: false,
|
||||||
|
Admin: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: insert perm: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
perm, err := s.PermFind(user, repo)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: select perm: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = s.PermDelete(perm)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: delete perm: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = s.PermFind(user, repo)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expect error: sql.ErrNoRows")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/store/datastore/sql"
|
"github.com/drone/drone/store/datastore/sql"
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
|
@ -20,25 +18,6 @@ func (db *datastore) GetRepoName(name string) (*model.Repo, error) {
|
||||||
return repo, err
|
return repo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *datastore) GetRepoListOf(listof []*model.RepoLite) ([]*model.Repo, error) {
|
|
||||||
var (
|
|
||||||
repos []*model.Repo
|
|
||||||
args []interface{}
|
|
||||||
stmt string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
switch meddler.Default {
|
|
||||||
case meddler.PostgreSQL:
|
|
||||||
stmt, args = toListPostgres(listof)
|
|
||||||
default:
|
|
||||||
stmt, args = toList(listof)
|
|
||||||
}
|
|
||||||
if len(args) > 0 {
|
|
||||||
err = meddler.QueryAll(db, &repos, fmt.Sprintf(repoListOfQuery, stmt), args...)
|
|
||||||
}
|
|
||||||
return repos, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *datastore) GetRepoCount() (count int, err error) {
|
func (db *datastore) GetRepoCount() (count int, err error) {
|
||||||
err = db.QueryRow(
|
err = db.QueryRow(
|
||||||
sql.Lookup(db.driver, "count-repos"),
|
sql.Lookup(db.driver, "count-repos"),
|
||||||
|
@ -55,10 +34,59 @@ func (db *datastore) UpdateRepo(repo *model.Repo) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *datastore) DeleteRepo(repo *model.Repo) error {
|
func (db *datastore) DeleteRepo(repo *model.Repo) error {
|
||||||
var _, err = db.Exec(rebind(repoDeleteStmt), repo.ID)
|
stmt := sql.Lookup(db.driver, "repo-delete")
|
||||||
|
_, err := db.Exec(stmt, repo.ID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *datastore) RepoList(user *model.User) ([]*model.Repo, error) {
|
||||||
|
stmt := sql.Lookup(db.driver, "repo-find-user")
|
||||||
|
data := []*model.Repo{}
|
||||||
|
err := meddler.QueryAll(db, &data, stmt, user.ID)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) RepoListLatest(user *model.User) ([]*model.Feed, error) {
|
||||||
|
stmt := sql.Lookup(db.driver, "feed-latest-build")
|
||||||
|
data := []*model.Feed{}
|
||||||
|
err := meddler.QueryAll(db, &data, stmt, user.ID)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *datastore) RepoBatch(repos []*model.Repo) error {
|
||||||
|
stmt := sql.Lookup(db.driver, "repo-insert-ignore")
|
||||||
|
for _, repo := range repos {
|
||||||
|
_, err := db.Exec(stmt,
|
||||||
|
repo.UserID,
|
||||||
|
repo.Owner,
|
||||||
|
repo.Name,
|
||||||
|
repo.FullName,
|
||||||
|
repo.Avatar,
|
||||||
|
repo.Link,
|
||||||
|
repo.Clone,
|
||||||
|
repo.Branch,
|
||||||
|
repo.Timeout,
|
||||||
|
repo.IsPrivate,
|
||||||
|
repo.IsTrusted,
|
||||||
|
repo.IsActive,
|
||||||
|
repo.AllowPull,
|
||||||
|
repo.AllowPush,
|
||||||
|
repo.AllowDeploy,
|
||||||
|
repo.AllowTag,
|
||||||
|
repo.Hash,
|
||||||
|
repo.Kind,
|
||||||
|
repo.Config,
|
||||||
|
repo.IsGated,
|
||||||
|
repo.Visibility,
|
||||||
|
repo.Counter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
const repoTable = "repos"
|
const repoTable = "repos"
|
||||||
|
|
||||||
const repoNameQuery = `
|
const repoNameQuery = `
|
||||||
|
@ -68,17 +96,6 @@ WHERE repo_full_name = ?
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
`
|
`
|
||||||
|
|
||||||
const repoListOfQuery = `
|
|
||||||
SELECT *
|
|
||||||
FROM repos
|
|
||||||
WHERE repo_full_name IN (%s)
|
|
||||||
ORDER BY repo_name
|
|
||||||
`
|
|
||||||
|
|
||||||
const repoCountQuery = `
|
|
||||||
SELECT COUNT(*) FROM repos
|
|
||||||
`
|
|
||||||
|
|
||||||
const repoDeleteStmt = `
|
const repoDeleteStmt = `
|
||||||
DELETE FROM repos
|
DELETE FROM repos
|
||||||
WHERE repo_id = ?
|
WHERE repo_id = ?
|
||||||
|
|
|
@ -84,76 +84,6 @@ func TestRepos(t *testing.T) {
|
||||||
g.Assert(repo.Name).Equal(getrepo.Name)
|
g.Assert(repo.Name).Equal(getrepo.Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should Get a Repo List", func() {
|
|
||||||
repo1 := &model.Repo{
|
|
||||||
UserID: 1,
|
|
||||||
Owner: "bradrydzewski",
|
|
||||||
Name: "drone",
|
|
||||||
FullName: "bradrydzewski/drone",
|
|
||||||
}
|
|
||||||
repo2 := &model.Repo{
|
|
||||||
UserID: 2,
|
|
||||||
Owner: "drone",
|
|
||||||
Name: "drone",
|
|
||||||
FullName: "drone/drone",
|
|
||||||
}
|
|
||||||
repo3 := &model.Repo{
|
|
||||||
UserID: 2,
|
|
||||||
Owner: "octocat",
|
|
||||||
Name: "hello-world",
|
|
||||||
FullName: "octocat/hello-world",
|
|
||||||
}
|
|
||||||
s.CreateRepo(repo1)
|
|
||||||
s.CreateRepo(repo2)
|
|
||||||
s.CreateRepo(repo3)
|
|
||||||
|
|
||||||
repos, err := s.GetRepoListOf([]*model.RepoLite{
|
|
||||||
{FullName: "bradrydzewski/drone"},
|
|
||||||
{FullName: "drone/drone"},
|
|
||||||
})
|
|
||||||
g.Assert(err == nil).IsTrue()
|
|
||||||
g.Assert(len(repos)).Equal(2)
|
|
||||||
g.Assert(repos[0].ID).Equal(repo1.ID)
|
|
||||||
g.Assert(repos[1].ID).Equal(repo2.ID)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should Get a Repo List", func() {
|
|
||||||
repo1 := &model.Repo{
|
|
||||||
UserID: 1,
|
|
||||||
Owner: "bradrydzewski",
|
|
||||||
Name: "drone",
|
|
||||||
FullName: "bradrydzewski/drone",
|
|
||||||
}
|
|
||||||
repo2 := &model.Repo{
|
|
||||||
UserID: 2,
|
|
||||||
Owner: "drone",
|
|
||||||
Name: "drone",
|
|
||||||
FullName: "drone/drone",
|
|
||||||
}
|
|
||||||
s.CreateRepo(repo1)
|
|
||||||
s.CreateRepo(repo2)
|
|
||||||
|
|
||||||
count, err := s.GetRepoCount()
|
|
||||||
g.Assert(err == nil).IsTrue()
|
|
||||||
g.Assert(count).Equal(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should Delete a Repo", func() {
|
|
||||||
repo := model.Repo{
|
|
||||||
UserID: 1,
|
|
||||||
FullName: "bradrydzewski/drone",
|
|
||||||
Owner: "bradrydzewski",
|
|
||||||
Name: "drone",
|
|
||||||
}
|
|
||||||
s.CreateRepo(&repo)
|
|
||||||
_, err1 := s.GetRepo(repo.ID)
|
|
||||||
err2 := s.DeleteRepo(&repo)
|
|
||||||
_, err3 := s.GetRepo(repo.ID)
|
|
||||||
g.Assert(err1 == nil).IsTrue()
|
|
||||||
g.Assert(err2 == nil).IsTrue()
|
|
||||||
g.Assert(err3 == nil).IsFalse()
|
|
||||||
})
|
|
||||||
|
|
||||||
g.It("Should Enforce Unique Repo Name", func() {
|
g.It("Should Enforce Unique Repo Name", func() {
|
||||||
repo1 := model.Repo{
|
repo1 := model.Repo{
|
||||||
UserID: 1,
|
UserID: 1,
|
||||||
|
@ -174,3 +104,263 @@ func TestRepos(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepoList(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
user := &model.User{
|
||||||
|
Login: "joe",
|
||||||
|
Email: "foo@bar.com",
|
||||||
|
Token: "e42080dddf012c718e476da161d21ad5",
|
||||||
|
}
|
||||||
|
s.CreateUser(user)
|
||||||
|
|
||||||
|
repo1 := &model.Repo{
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
}
|
||||||
|
repo2 := &model.Repo{
|
||||||
|
Owner: "drone",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "drone/drone",
|
||||||
|
}
|
||||||
|
repo3 := &model.Repo{
|
||||||
|
Owner: "octocat",
|
||||||
|
Name: "hello-world",
|
||||||
|
FullName: "octocat/hello-world",
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo1)
|
||||||
|
s.CreateRepo(repo2)
|
||||||
|
s.CreateRepo(repo3)
|
||||||
|
|
||||||
|
s.PermBatch([]*model.Perm{
|
||||||
|
{UserID: user.ID, Repo: repo1.FullName},
|
||||||
|
{UserID: user.ID, Repo: repo2.FullName},
|
||||||
|
})
|
||||||
|
|
||||||
|
repos, err := s.RepoList(user)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got, want := len(repos), 2; got != want {
|
||||||
|
t.Errorf("Want %d repositories, got %d", want, got)
|
||||||
|
}
|
||||||
|
if got, want := repos[0].ID, repo1.ID; got != want {
|
||||||
|
t.Errorf("Want repository id %d, got %d", want, got)
|
||||||
|
}
|
||||||
|
if got, want := repos[1].ID, repo2.ID; got != want {
|
||||||
|
t.Errorf("Want repository id %d, got %d", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepoListLatest(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
user := &model.User{
|
||||||
|
Login: "joe",
|
||||||
|
Email: "foo@bar.com",
|
||||||
|
Token: "e42080dddf012c718e476da161d21ad5",
|
||||||
|
}
|
||||||
|
s.CreateUser(user)
|
||||||
|
|
||||||
|
repo1 := &model.Repo{
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
repo2 := &model.Repo{
|
||||||
|
Owner: "drone",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "drone/drone",
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
repo3 := &model.Repo{
|
||||||
|
Owner: "octocat",
|
||||||
|
Name: "hello-world",
|
||||||
|
FullName: "octocat/hello-world",
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo1)
|
||||||
|
s.CreateRepo(repo2)
|
||||||
|
s.CreateRepo(repo3)
|
||||||
|
|
||||||
|
s.PermBatch([]*model.Perm{
|
||||||
|
{UserID: user.ID, Repo: repo1.FullName},
|
||||||
|
{UserID: user.ID, Repo: repo2.FullName},
|
||||||
|
})
|
||||||
|
|
||||||
|
build1 := &model.Build{
|
||||||
|
RepoID: repo1.ID,
|
||||||
|
Status: model.StatusFailure,
|
||||||
|
}
|
||||||
|
build2 := &model.Build{
|
||||||
|
RepoID: repo1.ID,
|
||||||
|
Status: model.StatusRunning,
|
||||||
|
}
|
||||||
|
build3 := &model.Build{
|
||||||
|
RepoID: repo2.ID,
|
||||||
|
Status: model.StatusKilled,
|
||||||
|
}
|
||||||
|
build4 := &model.Build{
|
||||||
|
RepoID: repo3.ID,
|
||||||
|
Status: model.StatusError,
|
||||||
|
}
|
||||||
|
s.CreateBuild(build1)
|
||||||
|
s.CreateBuild(build2)
|
||||||
|
s.CreateBuild(build3)
|
||||||
|
s.CreateBuild(build4)
|
||||||
|
|
||||||
|
builds, err := s.RepoListLatest(user)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: repository list with latest build: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got, want := len(builds), 2; got != want {
|
||||||
|
t.Errorf("Want %d repositories, got %d", want, got)
|
||||||
|
}
|
||||||
|
if got, want := builds[0].Status, model.StatusRunning; want != got {
|
||||||
|
t.Errorf("Want repository status %s, got %s", want, got)
|
||||||
|
}
|
||||||
|
if got, want := builds[0].FullName, repo1.FullName; want != got {
|
||||||
|
t.Errorf("Want repository name %s, got %s", want, got)
|
||||||
|
}
|
||||||
|
if got, want := builds[1].Status, model.StatusKilled; want != got {
|
||||||
|
t.Errorf("Want repository status %s, got %s", want, got)
|
||||||
|
}
|
||||||
|
if got, want := builds[1].FullName, repo2.FullName; want != got {
|
||||||
|
t.Errorf("Want repository name %s, got %s", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepoCount(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
repo1 := &model.Repo{
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
}
|
||||||
|
repo2 := &model.Repo{
|
||||||
|
Owner: "drone",
|
||||||
|
Name: "drone",
|
||||||
|
FullName: "drone/drone",
|
||||||
|
}
|
||||||
|
s.CreateRepo(repo1)
|
||||||
|
s.CreateRepo(repo2)
|
||||||
|
|
||||||
|
s.Exec("ANALYZE")
|
||||||
|
count, _ := s.GetRepoCount()
|
||||||
|
if got, want := count, 2; got != want {
|
||||||
|
t.Errorf("Want %d repositories, got %d", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepoBatch(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
repo := &model.Repo{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "foo/bar",
|
||||||
|
Owner: "foo",
|
||||||
|
Name: "bar",
|
||||||
|
}
|
||||||
|
err := s.CreateRepo(repo)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.RepoBatch(
|
||||||
|
[]*model.Repo{
|
||||||
|
{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "foo/bar",
|
||||||
|
Owner: "foo",
|
||||||
|
Name: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "bar/baz",
|
||||||
|
Owner: "bar",
|
||||||
|
Name: "baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "baz/qux",
|
||||||
|
Owner: "baz",
|
||||||
|
Name: "qux",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Exec("ANALYZE")
|
||||||
|
count, _ := s.GetRepoCount()
|
||||||
|
if got, want := count, 3; got != want {
|
||||||
|
t.Errorf("Want %d repositories, got %d", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepoCrud(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from repos")
|
||||||
|
s.Exec("delete from users")
|
||||||
|
s.Exec("delete from perms")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
repo := model.Repo{
|
||||||
|
UserID: 1,
|
||||||
|
FullName: "bradrydzewski/drone",
|
||||||
|
Owner: "bradrydzewski",
|
||||||
|
Name: "drone",
|
||||||
|
}
|
||||||
|
s.CreateRepo(&repo)
|
||||||
|
_, err1 := s.GetRepo(repo.ID)
|
||||||
|
err2 := s.DeleteRepo(&repo)
|
||||||
|
_, err3 := s.GetRepo(repo.ID)
|
||||||
|
if err1 != nil {
|
||||||
|
t.Errorf("Unexpected error: select repository: %s", err1)
|
||||||
|
}
|
||||||
|
if err2 != nil {
|
||||||
|
t.Errorf("Unexpected error: delete repository: %s", err2)
|
||||||
|
}
|
||||||
|
if err3 == nil {
|
||||||
|
t.Errorf("Expected error: sql.ErrNoRows")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ func TestSecretList(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if got, want := len(list), 2; got != want {
|
if got, want := len(list), 2; got != want {
|
||||||
t.Errorf("Want %d registries, got %d", want, got)
|
t.Errorf("Want %d secrets, got %d", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,34 @@ func TestSecretUpdate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSecretDelete(t *testing.T) {
|
||||||
|
s := newTest()
|
||||||
|
defer func() {
|
||||||
|
s.Exec("delete from secrets")
|
||||||
|
s.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
secret := &model.Secret{
|
||||||
|
RepoID: 1,
|
||||||
|
Name: "foo",
|
||||||
|
Value: "baz",
|
||||||
|
}
|
||||||
|
if err := s.SecretCreate(secret); err != nil {
|
||||||
|
t.Errorf("Unexpected error: insert secret: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.SecretDelete(secret); err != nil {
|
||||||
|
t.Errorf("Unexpected error: delete secret: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err := s.SecretFind(&model.Repo{ID: 1}, "foo")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expect error: sql.ErrNoRows")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSecretIndexes(t *testing.T) {
|
func TestSecretIndexes(t *testing.T) {
|
||||||
s := newTest()
|
s := newTest()
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/drone/drone/store/datastore/sql/mysql"
|
||||||
"github.com/drone/drone/store/datastore/sql/postgres"
|
"github.com/drone/drone/store/datastore/sql/postgres"
|
||||||
"github.com/drone/drone/store/datastore/sql/sqlite"
|
"github.com/drone/drone/store/datastore/sql/sqlite"
|
||||||
)
|
)
|
||||||
|
@ -18,6 +19,8 @@ func Lookup(driver string, name string) string {
|
||||||
switch driver {
|
switch driver {
|
||||||
case DriverPostgres:
|
case DriverPostgres:
|
||||||
return postgres.Lookup(name)
|
return postgres.Lookup(name)
|
||||||
|
case DriverMysql:
|
||||||
|
return mysql.Lookup(name)
|
||||||
default:
|
default:
|
||||||
return sqlite.Lookup(name)
|
return sqlite.Lookup(name)
|
||||||
}
|
}
|
||||||
|
|
28
store/datastore/sql/mysql/files/config.sql
Normal file
28
store/datastore/sql/mysql/files/config.sql
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-- name: config-find-id
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
config_id
|
||||||
|
,config_repo_id
|
||||||
|
,config_hash
|
||||||
|
,config_data
|
||||||
|
FROM config
|
||||||
|
WHERE config_id = ?
|
||||||
|
|
||||||
|
-- name: config-find-repo-hash
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
config_id
|
||||||
|
,config_repo_id
|
||||||
|
,config_hash
|
||||||
|
,config_data
|
||||||
|
FROM config
|
||||||
|
WHERE config_repo_id = ?
|
||||||
|
AND config_hash = ?
|
||||||
|
|
||||||
|
-- name: config-find-approved
|
||||||
|
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE build_repo_id = ?
|
||||||
|
AND build_config_id = ?
|
||||||
|
AND build_status NOT IN ('blocked', 'pending')
|
||||||
|
LIMIT 1
|
14
store/datastore/sql/mysql/files/counts.sql
Normal file
14
store/datastore/sql/mysql/files/counts.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
-- name: count-users
|
||||||
|
|
||||||
|
SELECT count(1)
|
||||||
|
FROM users
|
||||||
|
|
||||||
|
-- name: count-repos
|
||||||
|
|
||||||
|
SELECT count(1)
|
||||||
|
FROM repos
|
||||||
|
|
||||||
|
-- name: count-builds
|
||||||
|
|
||||||
|
SELECT count(1)
|
||||||
|
FROM builds
|
61
store/datastore/sql/mysql/files/feed.sql
Normal file
61
store/datastore/sql/mysql/files/feed.sql
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
-- name: feed-latest-build
|
||||||
|
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
AND repos.repo_active = true
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
|
||||||
|
-- name: feed
|
||||||
|
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
45
store/datastore/sql/mysql/files/files.sql
Normal file
45
store/datastore/sql/mysql/files/files.sql
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
-- name: files-find-build
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
FROM files
|
||||||
|
WHERE file_build_id = ?
|
||||||
|
|
||||||
|
-- name: files-find-proc-name
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
FROM files
|
||||||
|
WHERE file_proc_id = ?
|
||||||
|
AND file_name = ?
|
||||||
|
|
||||||
|
-- name: files-find-proc-name-data
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
,file_data
|
||||||
|
FROM files
|
||||||
|
WHERE file_proc_id = ?
|
||||||
|
AND file_name = ?
|
||||||
|
|
||||||
|
-- name: files-delete-build
|
||||||
|
|
||||||
|
DELETE FROM files WHERE file_build_id = ?
|
58
store/datastore/sql/mysql/files/perms.sql
Normal file
58
store/datastore/sql/mysql/files/perms.sql
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
-- name: perms-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
|
||||||
|
-- name: perms-find-user-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
|
||||||
|
-- name: perms-insert-replace
|
||||||
|
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,?,?,?,?,?)
|
||||||
|
|
||||||
|
-- name: perms-insert-replace-lookup
|
||||||
|
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?)
|
||||||
|
|
||||||
|
-- name: perms-delete-user-repo
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
|
||||||
|
-- name: perms-delete-user-date
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_synced < ?
|
87
store/datastore/sql/mysql/files/procs.sql
Normal file
87
store/datastore/sql/mysql/files/procs.sql
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
-- name: procs-find-id
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_id = ?
|
||||||
|
|
||||||
|
-- name: procs-find-build
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
ORDER BY proc_id ASC
|
||||||
|
|
||||||
|
-- name: procs-find-build-pid
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
AND proc_pid = ?
|
||||||
|
|
||||||
|
-- name: procs-find-build-ppid
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
AND proc_ppid = ?
|
||||||
|
AND proc_name = ?
|
||||||
|
|
||||||
|
-- name: procs-delete-build
|
||||||
|
|
||||||
|
DELETE FROM procs WHERE proc_build_id = ?
|
34
store/datastore/sql/mysql/files/registry.sql
Normal file
34
store/datastore/sql/mysql/files/registry.sql
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
-- name: registry-find-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
registry_id
|
||||||
|
,registry_repo_id
|
||||||
|
,registry_addr
|
||||||
|
,registry_username
|
||||||
|
,registry_password
|
||||||
|
,registry_email
|
||||||
|
,registry_token
|
||||||
|
FROM registry
|
||||||
|
WHERE registry_repo_id = ?
|
||||||
|
|
||||||
|
-- name: registry-find-repo-addr
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
registry_id
|
||||||
|
,registry_repo_id
|
||||||
|
,registry_addr
|
||||||
|
,registry_username
|
||||||
|
,registry_password
|
||||||
|
,registry_email
|
||||||
|
,registry_token
|
||||||
|
FROM registry
|
||||||
|
WHERE registry_repo_id = ?
|
||||||
|
AND registry_addr = ?
|
||||||
|
|
||||||
|
-- name: registry-delete-repo
|
||||||
|
|
||||||
|
DELETE FROM registry WHERE registry_repo_id = ?
|
||||||
|
|
||||||
|
-- name: registry-delete
|
||||||
|
|
||||||
|
DELETE FROM registry WHERE registry_id = ?
|
67
store/datastore/sql/mysql/files/repos.sql
Normal file
67
store/datastore/sql/mysql/files/repos.sql
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
-- name: repo-update-counter
|
||||||
|
|
||||||
|
UPDATE repos SET repo_counter = ?
|
||||||
|
WHERE repo_counter = ?
|
||||||
|
AND repo_id = ?
|
||||||
|
|
||||||
|
-- name: repo-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
|
||||||
|
-- name: repo-insert-ignore
|
||||||
|
|
||||||
|
INSERT IGNORE INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||||
|
|
||||||
|
-- name: repo-delete
|
||||||
|
|
||||||
|
DELETE FROM repos WHERE repo_id = ?
|
32
store/datastore/sql/mysql/files/secret.sql
Normal file
32
store/datastore/sql/mysql/files/secret.sql
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
-- name: secret-find-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
secret_id
|
||||||
|
,secret_repo_id
|
||||||
|
,secret_name
|
||||||
|
,secret_value
|
||||||
|
,secret_images
|
||||||
|
,secret_events
|
||||||
|
,secret_conceal
|
||||||
|
,secret_skip_verify
|
||||||
|
FROM secrets
|
||||||
|
WHERE secret_repo_id = ?
|
||||||
|
|
||||||
|
-- name: secret-find-repo-name
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
secret_id
|
||||||
|
,secret_repo_id
|
||||||
|
,secret_name
|
||||||
|
,secret_value
|
||||||
|
,secret_images
|
||||||
|
,secret_events
|
||||||
|
,secret_conceal
|
||||||
|
,secret_skip_verify
|
||||||
|
FROM secrets
|
||||||
|
WHERE secret_repo_id = ?
|
||||||
|
AND secret_name = ?
|
||||||
|
|
||||||
|
-- name: secret-delete
|
||||||
|
|
||||||
|
DELETE FROM secrets WHERE secret_id = ?
|
30
store/datastore/sql/mysql/files/sender.sql
Normal file
30
store/datastore/sql/mysql/files/sender.sql
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
-- name: sender-find-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
sender_id
|
||||||
|
,sender_repo_id
|
||||||
|
,sender_login
|
||||||
|
,sender_allow
|
||||||
|
,sender_block
|
||||||
|
FROM senders
|
||||||
|
WHERE sender_repo_id = ?
|
||||||
|
|
||||||
|
-- name: sender-find-repo-login
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
sender_id
|
||||||
|
,sender_repo_id
|
||||||
|
,sender_login
|
||||||
|
,sender_allow
|
||||||
|
,sender_block
|
||||||
|
FROM senders
|
||||||
|
WHERE sender_repo_id = ?
|
||||||
|
AND sender_login = ?
|
||||||
|
|
||||||
|
-- name: sender-delete-repo
|
||||||
|
|
||||||
|
DELETE FROM senders WHERE sender_repo_id = ?
|
||||||
|
|
||||||
|
-- name: sender-delete
|
||||||
|
|
||||||
|
DELETE FROM senders WHERE sender_id = ?
|
11
store/datastore/sql/mysql/files/task.sql
Normal file
11
store/datastore/sql/mysql/files/task.sql
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
-- name: task-list
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
task_id
|
||||||
|
,task_data
|
||||||
|
,task_labels
|
||||||
|
FROM tasks
|
||||||
|
|
||||||
|
-- name: task-delete
|
||||||
|
|
||||||
|
DELETE FROM tasks WHERE task_id = ?
|
3
store/datastore/sql/mysql/sql.go
Normal file
3
store/datastore/sql/mysql/sql.go
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
//go:generate togo sql --package=mysql
|
527
store/datastore/sql/mysql/sql_gen.go
Normal file
527
store/datastore/sql/mysql/sql_gen.go
Normal file
|
@ -0,0 +1,527 @@
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
// Lookup returns the named statement.
|
||||||
|
func Lookup(name string) string {
|
||||||
|
return index[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = map[string]string{
|
||||||
|
"config-find-id": configFindId,
|
||||||
|
"config-find-repo-hash": configFindRepoHash,
|
||||||
|
"config-find-approved": configFindApproved,
|
||||||
|
"count-users": countUsers,
|
||||||
|
"count-repos": countRepos,
|
||||||
|
"count-builds": countBuilds,
|
||||||
|
"feed-latest-build": feedLatestBuild,
|
||||||
|
"feed": feed,
|
||||||
|
"files-find-build": filesFindBuild,
|
||||||
|
"files-find-proc-name": filesFindProcName,
|
||||||
|
"files-find-proc-name-data": filesFindProcNameData,
|
||||||
|
"files-delete-build": filesDeleteBuild,
|
||||||
|
"perms-find-user": permsFindUser,
|
||||||
|
"perms-find-user-repo": permsFindUserRepo,
|
||||||
|
"perms-insert-replace": permsInsertReplace,
|
||||||
|
"perms-insert-replace-lookup": permsInsertReplaceLookup,
|
||||||
|
"perms-delete-user-repo": permsDeleteUserRepo,
|
||||||
|
"perms-delete-user-date": permsDeleteUserDate,
|
||||||
|
"procs-find-id": procsFindId,
|
||||||
|
"procs-find-build": procsFindBuild,
|
||||||
|
"procs-find-build-pid": procsFindBuildPid,
|
||||||
|
"procs-find-build-ppid": procsFindBuildPpid,
|
||||||
|
"procs-delete-build": procsDeleteBuild,
|
||||||
|
"registry-find-repo": registryFindRepo,
|
||||||
|
"registry-find-repo-addr": registryFindRepoAddr,
|
||||||
|
"registry-delete-repo": registryDeleteRepo,
|
||||||
|
"registry-delete": registryDelete,
|
||||||
|
"repo-update-counter": repoUpdateCounter,
|
||||||
|
"repo-find-user": repoFindUser,
|
||||||
|
"repo-insert-ignore": repoInsertIgnore,
|
||||||
|
"repo-delete": repoDelete,
|
||||||
|
"secret-find-repo": secretFindRepo,
|
||||||
|
"secret-find-repo-name": secretFindRepoName,
|
||||||
|
"secret-delete": secretDelete,
|
||||||
|
"sender-find-repo": senderFindRepo,
|
||||||
|
"sender-find-repo-login": senderFindRepoLogin,
|
||||||
|
"sender-delete-repo": senderDeleteRepo,
|
||||||
|
"sender-delete": senderDelete,
|
||||||
|
"task-list": taskList,
|
||||||
|
"task-delete": taskDelete,
|
||||||
|
}
|
||||||
|
|
||||||
|
var configFindId = `
|
||||||
|
SELECT
|
||||||
|
config_id
|
||||||
|
,config_repo_id
|
||||||
|
,config_hash
|
||||||
|
,config_data
|
||||||
|
FROM config
|
||||||
|
WHERE config_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var configFindRepoHash = `
|
||||||
|
SELECT
|
||||||
|
config_id
|
||||||
|
,config_repo_id
|
||||||
|
,config_hash
|
||||||
|
,config_data
|
||||||
|
FROM config
|
||||||
|
WHERE config_repo_id = ?
|
||||||
|
AND config_hash = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var configFindApproved = `
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE build_repo_id = ?
|
||||||
|
AND build_config_id = ?
|
||||||
|
AND build_status NOT IN ('blocked', 'pending')
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
var countUsers = `
|
||||||
|
SELECT count(1)
|
||||||
|
FROM users
|
||||||
|
`
|
||||||
|
|
||||||
|
var countRepos = `
|
||||||
|
SELECT count(1)
|
||||||
|
FROM repos
|
||||||
|
`
|
||||||
|
|
||||||
|
var countBuilds = `
|
||||||
|
SELECT count(1)
|
||||||
|
FROM builds
|
||||||
|
`
|
||||||
|
|
||||||
|
var feedLatestBuild = `
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
AND repos.repo_active = true
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
`
|
||||||
|
|
||||||
|
var feed = `
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
||||||
|
`
|
||||||
|
|
||||||
|
var filesFindBuild = `
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
FROM files
|
||||||
|
WHERE file_build_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var filesFindProcName = `
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
FROM files
|
||||||
|
WHERE file_proc_id = ?
|
||||||
|
AND file_name = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var filesFindProcNameData = `
|
||||||
|
SELECT
|
||||||
|
file_id
|
||||||
|
,file_build_id
|
||||||
|
,file_proc_id
|
||||||
|
,file_name
|
||||||
|
,file_mime
|
||||||
|
,file_size
|
||||||
|
,file_time
|
||||||
|
,file_data
|
||||||
|
FROM files
|
||||||
|
WHERE file_proc_id = ?
|
||||||
|
AND file_name = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var filesDeleteBuild = `
|
||||||
|
DELETE FROM files WHERE file_build_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsFindUser = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsFindUserRepo = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplace = `
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,?,?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplaceLookup = `
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserRepo = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserDate = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_synced < ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var procsFindId = `
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var procsFindBuild = `
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
ORDER BY proc_id ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
var procsFindBuildPid = `
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
AND proc_pid = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var procsFindBuildPpid = `
|
||||||
|
SELECT
|
||||||
|
proc_id
|
||||||
|
,proc_build_id
|
||||||
|
,proc_pid
|
||||||
|
,proc_ppid
|
||||||
|
,proc_pgid
|
||||||
|
,proc_name
|
||||||
|
,proc_state
|
||||||
|
,proc_error
|
||||||
|
,proc_exit_code
|
||||||
|
,proc_started
|
||||||
|
,proc_stopped
|
||||||
|
,proc_machine
|
||||||
|
,proc_platform
|
||||||
|
,proc_environ
|
||||||
|
FROM procs
|
||||||
|
WHERE proc_build_id = ?
|
||||||
|
AND proc_ppid = ?
|
||||||
|
AND proc_name = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var procsDeleteBuild = `
|
||||||
|
DELETE FROM procs WHERE proc_build_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var registryFindRepo = `
|
||||||
|
SELECT
|
||||||
|
registry_id
|
||||||
|
,registry_repo_id
|
||||||
|
,registry_addr
|
||||||
|
,registry_username
|
||||||
|
,registry_password
|
||||||
|
,registry_email
|
||||||
|
,registry_token
|
||||||
|
FROM registry
|
||||||
|
WHERE registry_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var registryFindRepoAddr = `
|
||||||
|
SELECT
|
||||||
|
registry_id
|
||||||
|
,registry_repo_id
|
||||||
|
,registry_addr
|
||||||
|
,registry_username
|
||||||
|
,registry_password
|
||||||
|
,registry_email
|
||||||
|
,registry_token
|
||||||
|
FROM registry
|
||||||
|
WHERE registry_repo_id = ?
|
||||||
|
AND registry_addr = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var registryDeleteRepo = `
|
||||||
|
DELETE FROM registry WHERE registry_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var registryDelete = `
|
||||||
|
DELETE FROM registry WHERE registry_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoUpdateCounter = `
|
||||||
|
UPDATE repos SET repo_counter = ?
|
||||||
|
WHERE repo_counter = ?
|
||||||
|
AND repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoFindUser = `
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoInsertIgnore = `
|
||||||
|
INSERT IGNORE INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoDelete = `
|
||||||
|
DELETE FROM repos WHERE repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var secretFindRepo = `
|
||||||
|
SELECT
|
||||||
|
secret_id
|
||||||
|
,secret_repo_id
|
||||||
|
,secret_name
|
||||||
|
,secret_value
|
||||||
|
,secret_images
|
||||||
|
,secret_events
|
||||||
|
,secret_conceal
|
||||||
|
,secret_skip_verify
|
||||||
|
FROM secrets
|
||||||
|
WHERE secret_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var secretFindRepoName = `
|
||||||
|
SELECT
|
||||||
|
secret_id
|
||||||
|
,secret_repo_id
|
||||||
|
,secret_name
|
||||||
|
,secret_value
|
||||||
|
,secret_images
|
||||||
|
,secret_events
|
||||||
|
,secret_conceal
|
||||||
|
,secret_skip_verify
|
||||||
|
FROM secrets
|
||||||
|
WHERE secret_repo_id = ?
|
||||||
|
AND secret_name = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var secretDelete = `
|
||||||
|
DELETE FROM secrets WHERE secret_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var senderFindRepo = `
|
||||||
|
SELECT
|
||||||
|
sender_id
|
||||||
|
,sender_repo_id
|
||||||
|
,sender_login
|
||||||
|
,sender_allow
|
||||||
|
,sender_block
|
||||||
|
FROM senders
|
||||||
|
WHERE sender_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var senderFindRepoLogin = `
|
||||||
|
SELECT
|
||||||
|
sender_id
|
||||||
|
,sender_repo_id
|
||||||
|
,sender_login
|
||||||
|
,sender_allow
|
||||||
|
,sender_block
|
||||||
|
FROM senders
|
||||||
|
WHERE sender_repo_id = ?
|
||||||
|
AND sender_login = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var senderDeleteRepo = `
|
||||||
|
DELETE FROM senders WHERE sender_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var senderDelete = `
|
||||||
|
DELETE FROM senders WHERE sender_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var taskList = `
|
||||||
|
SELECT
|
||||||
|
task_id
|
||||||
|
,task_data
|
||||||
|
,task_labels
|
||||||
|
FROM tasks
|
||||||
|
`
|
||||||
|
|
||||||
|
var taskDelete = `
|
||||||
|
DELETE FROM tasks WHERE task_id = ?
|
||||||
|
`
|
61
store/datastore/sql/postgres/files/feed.sql
Normal file
61
store/datastore/sql/postgres/files/feed.sql
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
-- name: feed-latest-build
|
||||||
|
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
AND repos.repo_active = true
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
|
||||||
|
-- name: feed
|
||||||
|
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
63
store/datastore/sql/postgres/files/perms.sql
Normal file
63
store/datastore/sql/postgres/files/perms.sql
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
-- name: perms-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
|
||||||
|
-- name: perms-find-user-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_repo_id = $2
|
||||||
|
|
||||||
|
-- name: perms-insert-replace
|
||||||
|
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES ($1,$2,$3,$4,$5,$6)
|
||||||
|
|
||||||
|
-- name: perms-insert-replace-lookup
|
||||||
|
|
||||||
|
INSERT INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6)
|
||||||
|
ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET
|
||||||
|
perm_pull = EXCLUDED.perm_pull
|
||||||
|
,perm_push = EXCLUDED.perm_push
|
||||||
|
,perm_admin = EXCLUDED.perm_admin
|
||||||
|
,perm_synced = EXCLUDED.perm_synced
|
||||||
|
|
||||||
|
-- name: perms-delete-user-repo
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_repo_id = $2
|
||||||
|
|
||||||
|
-- name: perms-delete-user-date
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_synced < $2
|
|
@ -3,3 +3,67 @@
|
||||||
UPDATE repos SET repo_counter = $1
|
UPDATE repos SET repo_counter = $1
|
||||||
WHERE repo_counter = $2
|
WHERE repo_counter = $2
|
||||||
AND repo_id = $3
|
AND repo_id = $3
|
||||||
|
|
||||||
|
-- name: repo-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
|
||||||
|
-- name: repo-insert-ignore
|
||||||
|
|
||||||
|
INSERT INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22)
|
||||||
|
ON CONFLICT (repo_full_name) DO NOTHING
|
||||||
|
|
||||||
|
-- name: repo-delete
|
||||||
|
|
||||||
|
DELETE FROM repos
|
||||||
|
WHERE repo_id = $1
|
||||||
|
|
|
@ -6,35 +6,46 @@ func Lookup(name string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var index = map[string]string{
|
var index = map[string]string{
|
||||||
"config-find-id": configFindId,
|
"config-find-id": configFindId,
|
||||||
"config-find-repo-hash": configFindRepoHash,
|
"config-find-repo-hash": configFindRepoHash,
|
||||||
"config-find-approved": configFindApproved,
|
"config-find-approved": configFindApproved,
|
||||||
"count-users": countUsers,
|
"count-users": countUsers,
|
||||||
"count-repos": countRepos,
|
"count-repos": countRepos,
|
||||||
"count-builds": countBuilds,
|
"count-builds": countBuilds,
|
||||||
"files-find-build": filesFindBuild,
|
"feed-latest-build": feedLatestBuild,
|
||||||
"files-find-proc-name": filesFindProcName,
|
"feed": feed,
|
||||||
"files-find-proc-name-data": filesFindProcNameData,
|
"files-find-build": filesFindBuild,
|
||||||
"files-delete-build": filesDeleteBuild,
|
"files-find-proc-name": filesFindProcName,
|
||||||
"procs-find-id": procsFindId,
|
"files-find-proc-name-data": filesFindProcNameData,
|
||||||
"procs-find-build": procsFindBuild,
|
"files-delete-build": filesDeleteBuild,
|
||||||
"procs-find-build-pid": procsFindBuildPid,
|
"perms-find-user": permsFindUser,
|
||||||
"procs-find-build-ppid": procsFindBuildPpid,
|
"perms-find-user-repo": permsFindUserRepo,
|
||||||
"procs-delete-build": procsDeleteBuild,
|
"perms-insert-replace": permsInsertReplace,
|
||||||
"registry-find-repo": registryFindRepo,
|
"perms-insert-replace-lookup": permsInsertReplaceLookup,
|
||||||
"registry-find-repo-addr": registryFindRepoAddr,
|
"perms-delete-user-repo": permsDeleteUserRepo,
|
||||||
"registry-delete-repo": registryDeleteRepo,
|
"perms-delete-user-date": permsDeleteUserDate,
|
||||||
"registry-delete": registryDelete,
|
"procs-find-id": procsFindId,
|
||||||
"repo-update-counter": repoUpdateCounter,
|
"procs-find-build": procsFindBuild,
|
||||||
"secret-find-repo": secretFindRepo,
|
"procs-find-build-pid": procsFindBuildPid,
|
||||||
"secret-find-repo-name": secretFindRepoName,
|
"procs-find-build-ppid": procsFindBuildPpid,
|
||||||
"secret-delete": secretDelete,
|
"procs-delete-build": procsDeleteBuild,
|
||||||
"sender-find-repo": senderFindRepo,
|
"registry-find-repo": registryFindRepo,
|
||||||
"sender-find-repo-login": senderFindRepoLogin,
|
"registry-find-repo-addr": registryFindRepoAddr,
|
||||||
"sender-delete-repo": senderDeleteRepo,
|
"registry-delete-repo": registryDeleteRepo,
|
||||||
"sender-delete": senderDelete,
|
"registry-delete": registryDelete,
|
||||||
"task-list": taskList,
|
"repo-update-counter": repoUpdateCounter,
|
||||||
"task-delete": taskDelete,
|
"repo-find-user": repoFindUser,
|
||||||
|
"repo-insert-ignore": repoInsertIgnore,
|
||||||
|
"repo-delete": repoDelete,
|
||||||
|
"secret-find-repo": secretFindRepo,
|
||||||
|
"secret-find-repo-name": secretFindRepoName,
|
||||||
|
"secret-delete": secretDelete,
|
||||||
|
"sender-find-repo": senderFindRepo,
|
||||||
|
"sender-find-repo-login": senderFindRepoLogin,
|
||||||
|
"sender-delete-repo": senderDeleteRepo,
|
||||||
|
"sender-delete": senderDelete,
|
||||||
|
"task-list": taskList,
|
||||||
|
"task-delete": taskDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
var configFindId = `
|
var configFindId = `
|
||||||
|
@ -81,6 +92,68 @@ SELECT reltuples
|
||||||
FROM pg_class WHERE relname = 'builds';
|
FROM pg_class WHERE relname = 'builds';
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var feedLatestBuild = `
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
AND repos.repo_active = true
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
`
|
||||||
|
|
||||||
|
var feed = `
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
||||||
|
`
|
||||||
|
|
||||||
var filesFindBuild = `
|
var filesFindBuild = `
|
||||||
SELECT
|
SELECT
|
||||||
file_id
|
file_id
|
||||||
|
@ -127,6 +200,70 @@ var filesDeleteBuild = `
|
||||||
DELETE FROM files WHERE file_build_id = $1
|
DELETE FROM files WHERE file_build_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var permsFindUser = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsFindUserRepo = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_repo_id = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplace = `
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES ($1,$2,$3,$4,$5,$6)
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplaceLookup = `
|
||||||
|
INSERT INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6)
|
||||||
|
ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET
|
||||||
|
perm_pull = EXCLUDED.perm_pull
|
||||||
|
,perm_push = EXCLUDED.perm_push
|
||||||
|
,perm_admin = EXCLUDED.perm_admin
|
||||||
|
,perm_synced = EXCLUDED.perm_synced
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserRepo = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_repo_id = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserDate = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = $1
|
||||||
|
AND perm_synced < $2
|
||||||
|
`
|
||||||
|
|
||||||
var procsFindId = `
|
var procsFindId = `
|
||||||
SELECT
|
SELECT
|
||||||
proc_id
|
proc_id
|
||||||
|
@ -256,6 +393,70 @@ WHERE repo_counter = $2
|
||||||
AND repo_id = $3
|
AND repo_id = $3
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var repoFindUser = `
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = $1
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoInsertIgnore = `
|
||||||
|
INSERT INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22)
|
||||||
|
ON CONFLICT (repo_full_name) DO NOTHING
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoDelete = `
|
||||||
|
DELETE FROM repos
|
||||||
|
WHERE repo_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
var secretFindRepo = `
|
var secretFindRepo = `
|
||||||
SELECT
|
SELECT
|
||||||
secret_id
|
secret_id
|
||||||
|
|
61
store/datastore/sql/sqlite/files/feed.sql
Normal file
61
store/datastore/sql/sqlite/files/feed.sql
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
-- name: feed-latest-build
|
||||||
|
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
AND repos.repo_active = 1
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
|
||||||
|
-- name: feed
|
||||||
|
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
58
store/datastore/sql/sqlite/files/perms.sql
Normal file
58
store/datastore/sql/sqlite/files/perms.sql
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
-- name: perms-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
|
||||||
|
-- name: perms-find-user-repo
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
|
||||||
|
-- name: perms-insert-replace
|
||||||
|
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,?,?,?,?,?)
|
||||||
|
|
||||||
|
-- name: perms-insert-replace-lookup
|
||||||
|
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?)
|
||||||
|
|
||||||
|
-- name: perms-delete-user-repo
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
|
||||||
|
-- name: perms-delete-user-date
|
||||||
|
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_synced < ?
|
|
@ -3,3 +3,65 @@
|
||||||
UPDATE repos SET repo_counter = ?
|
UPDATE repos SET repo_counter = ?
|
||||||
WHERE repo_counter = ?
|
WHERE repo_counter = ?
|
||||||
AND repo_id = ?
|
AND repo_id = ?
|
||||||
|
|
||||||
|
-- name: repo-find-user
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
|
||||||
|
-- name: repo-insert-ignore
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||||
|
|
||||||
|
-- name: repo-delete
|
||||||
|
|
||||||
|
DELETE FROM repos WHERE repo_id = ?
|
||||||
|
|
|
@ -6,35 +6,46 @@ func Lookup(name string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var index = map[string]string{
|
var index = map[string]string{
|
||||||
"config-find-id": configFindId,
|
"config-find-id": configFindId,
|
||||||
"config-find-repo-hash": configFindRepoHash,
|
"config-find-repo-hash": configFindRepoHash,
|
||||||
"config-find-approved": configFindApproved,
|
"config-find-approved": configFindApproved,
|
||||||
"count-users": countUsers,
|
"count-users": countUsers,
|
||||||
"count-repos": countRepos,
|
"count-repos": countRepos,
|
||||||
"count-builds": countBuilds,
|
"count-builds": countBuilds,
|
||||||
"files-find-build": filesFindBuild,
|
"feed-latest-build": feedLatestBuild,
|
||||||
"files-find-proc-name": filesFindProcName,
|
"feed": feed,
|
||||||
"files-find-proc-name-data": filesFindProcNameData,
|
"files-find-build": filesFindBuild,
|
||||||
"files-delete-build": filesDeleteBuild,
|
"files-find-proc-name": filesFindProcName,
|
||||||
"procs-find-id": procsFindId,
|
"files-find-proc-name-data": filesFindProcNameData,
|
||||||
"procs-find-build": procsFindBuild,
|
"files-delete-build": filesDeleteBuild,
|
||||||
"procs-find-build-pid": procsFindBuildPid,
|
"perms-find-user": permsFindUser,
|
||||||
"procs-find-build-ppid": procsFindBuildPpid,
|
"perms-find-user-repo": permsFindUserRepo,
|
||||||
"procs-delete-build": procsDeleteBuild,
|
"perms-insert-replace": permsInsertReplace,
|
||||||
"registry-find-repo": registryFindRepo,
|
"perms-insert-replace-lookup": permsInsertReplaceLookup,
|
||||||
"registry-find-repo-addr": registryFindRepoAddr,
|
"perms-delete-user-repo": permsDeleteUserRepo,
|
||||||
"registry-delete-repo": registryDeleteRepo,
|
"perms-delete-user-date": permsDeleteUserDate,
|
||||||
"registry-delete": registryDelete,
|
"procs-find-id": procsFindId,
|
||||||
"repo-update-counter": repoUpdateCounter,
|
"procs-find-build": procsFindBuild,
|
||||||
"secret-find-repo": secretFindRepo,
|
"procs-find-build-pid": procsFindBuildPid,
|
||||||
"secret-find-repo-name": secretFindRepoName,
|
"procs-find-build-ppid": procsFindBuildPpid,
|
||||||
"secret-delete": secretDelete,
|
"procs-delete-build": procsDeleteBuild,
|
||||||
"sender-find-repo": senderFindRepo,
|
"registry-find-repo": registryFindRepo,
|
||||||
"sender-find-repo-login": senderFindRepoLogin,
|
"registry-find-repo-addr": registryFindRepoAddr,
|
||||||
"sender-delete-repo": senderDeleteRepo,
|
"registry-delete-repo": registryDeleteRepo,
|
||||||
"sender-delete": senderDelete,
|
"registry-delete": registryDelete,
|
||||||
"task-list": taskList,
|
"repo-update-counter": repoUpdateCounter,
|
||||||
"task-delete": taskDelete,
|
"repo-find-user": repoFindUser,
|
||||||
|
"repo-insert-ignore": repoInsertIgnore,
|
||||||
|
"repo-delete": repoDelete,
|
||||||
|
"secret-find-repo": secretFindRepo,
|
||||||
|
"secret-find-repo-name": secretFindRepoName,
|
||||||
|
"secret-delete": secretDelete,
|
||||||
|
"sender-find-repo": senderFindRepo,
|
||||||
|
"sender-find-repo-login": senderFindRepoLogin,
|
||||||
|
"sender-delete-repo": senderDeleteRepo,
|
||||||
|
"sender-delete": senderDelete,
|
||||||
|
"task-list": taskList,
|
||||||
|
"task-delete": taskDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
var configFindId = `
|
var configFindId = `
|
||||||
|
@ -81,6 +92,68 @@ SELECT count(1)
|
||||||
FROM builds
|
FROM builds
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var feedLatestBuild = `
|
||||||
|
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 repos LEFT OUTER JOIN builds ON build_id = (
|
||||||
|
SELECT build_id FROM builds
|
||||||
|
WHERE builds.build_repo_id = repos.repo_id
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
AND repos.repo_active = 1
|
||||||
|
ORDER BY repo_full_name ASC;
|
||||||
|
`
|
||||||
|
|
||||||
|
var feed = `
|
||||||
|
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 repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
INNER JOIN builds ON builds.build_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY build_id DESC
|
||||||
|
LIMIT 50
|
||||||
|
`
|
||||||
|
|
||||||
var filesFindBuild = `
|
var filesFindBuild = `
|
||||||
SELECT
|
SELECT
|
||||||
file_id
|
file_id
|
||||||
|
@ -127,6 +200,65 @@ var filesDeleteBuild = `
|
||||||
DELETE FROM files WHERE file_build_id = ?
|
DELETE FROM files WHERE file_build_id = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var permsFindUser = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_date
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsFindUserRepo = `
|
||||||
|
SELECT
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplace = `
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,?,?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsInsertReplaceLookup = `
|
||||||
|
REPLACE INTO perms (
|
||||||
|
perm_user_id
|
||||||
|
,perm_repo_id
|
||||||
|
,perm_pull
|
||||||
|
,perm_push
|
||||||
|
,perm_admin
|
||||||
|
,perm_synced
|
||||||
|
) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserRepo = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
var permsDeleteUserDate = `
|
||||||
|
DELETE FROM perms
|
||||||
|
WHERE perm_user_id = ?
|
||||||
|
AND perm_synced < ?
|
||||||
|
`
|
||||||
|
|
||||||
var procsFindId = `
|
var procsFindId = `
|
||||||
SELECT
|
SELECT
|
||||||
proc_id
|
proc_id
|
||||||
|
@ -256,6 +388,68 @@ WHERE repo_counter = ?
|
||||||
AND repo_id = ?
|
AND repo_id = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var repoFindUser = `
|
||||||
|
SELECT
|
||||||
|
repo_id
|
||||||
|
,repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
FROM repos
|
||||||
|
INNER JOIN perms ON perms.perm_repo_id = repos.repo_id
|
||||||
|
WHERE perms.perm_user_id = ?
|
||||||
|
ORDER BY repo_full_name ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoInsertIgnore = `
|
||||||
|
INSERT OR IGNORE INTO repos (
|
||||||
|
repo_user_id
|
||||||
|
,repo_owner
|
||||||
|
,repo_name
|
||||||
|
,repo_full_name
|
||||||
|
,repo_avatar
|
||||||
|
,repo_link
|
||||||
|
,repo_clone
|
||||||
|
,repo_branch
|
||||||
|
,repo_timeout
|
||||||
|
,repo_private
|
||||||
|
,repo_trusted
|
||||||
|
,repo_active
|
||||||
|
,repo_allow_pr
|
||||||
|
,repo_allow_push
|
||||||
|
,repo_allow_deploys
|
||||||
|
,repo_allow_tags
|
||||||
|
,repo_hash
|
||||||
|
,repo_scm
|
||||||
|
,repo_config_path
|
||||||
|
,repo_gated
|
||||||
|
,repo_visibility
|
||||||
|
,repo_counter
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||||
|
`
|
||||||
|
|
||||||
|
var repoDelete = `
|
||||||
|
DELETE FROM repos WHERE repo_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
var secretFindRepo = `
|
var secretFindRepo = `
|
||||||
SELECT
|
SELECT
|
||||||
secret_id
|
secret_id
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/store/datastore/sql"
|
"github.com/drone/drone/store/datastore/sql"
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
|
@ -26,46 +24,6 @@ func (db *datastore) GetUserList() ([]*model.User, error) {
|
||||||
return users, err
|
return users, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *datastore) GetUserFeed(listof []*model.RepoLite) ([]*model.Feed, error) {
|
|
||||||
var (
|
|
||||||
args []interface{}
|
|
||||||
stmt string
|
|
||||||
err error
|
|
||||||
|
|
||||||
feed = []*model.Feed{}
|
|
||||||
)
|
|
||||||
switch meddler.Default {
|
|
||||||
case meddler.PostgreSQL:
|
|
||||||
stmt, args = toListPostgres(listof)
|
|
||||||
default:
|
|
||||||
stmt, args = toList(listof)
|
|
||||||
}
|
|
||||||
if len(args) > 0 {
|
|
||||||
err = meddler.QueryAll(db, &feed, fmt.Sprintf(userFeedQuery, stmt), args...)
|
|
||||||
}
|
|
||||||
return feed, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *datastore) GetUserFeedLatest(listof []*model.RepoLite) ([]*model.Feed, error) {
|
|
||||||
var (
|
|
||||||
args []interface{}
|
|
||||||
stmt string
|
|
||||||
err error
|
|
||||||
|
|
||||||
feed = []*model.Feed{}
|
|
||||||
)
|
|
||||||
switch meddler.Default {
|
|
||||||
case meddler.PostgreSQL:
|
|
||||||
stmt, args = toListPostgres(listof)
|
|
||||||
default:
|
|
||||||
stmt, args = toList(listof)
|
|
||||||
}
|
|
||||||
if len(args) > 0 {
|
|
||||||
err = meddler.QueryAll(db, &feed, fmt.Sprintf(userFeedLatest, stmt), args...)
|
|
||||||
}
|
|
||||||
return feed, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *datastore) GetUserCount() (count int, err error) {
|
func (db *datastore) GetUserCount() (count int, err error) {
|
||||||
err = db.QueryRow(
|
err = db.QueryRow(
|
||||||
sql.Lookup(db.driver, "count-users"),
|
sql.Lookup(db.driver, "count-users"),
|
||||||
|
@ -86,6 +44,13 @@ func (db *datastore) DeleteUser(user *model.User) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *datastore) UserFeed(user *model.User) ([]*model.Feed, error) {
|
||||||
|
stmt := sql.Lookup(db.driver, "feed")
|
||||||
|
data := []*model.Feed{}
|
||||||
|
err := meddler.QueryAll(db, &data, stmt, user.ID)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
const userTable = "users"
|
const userTable = "users"
|
||||||
|
|
||||||
const userLoginQuery = `
|
const userLoginQuery = `
|
||||||
|
@ -101,75 +66,7 @@ FROM users
|
||||||
ORDER BY user_login ASC
|
ORDER BY user_login ASC
|
||||||
`
|
`
|
||||||
|
|
||||||
const userCountQuery = `
|
|
||||||
SELECT count(1)
|
|
||||||
FROM users
|
|
||||||
`
|
|
||||||
|
|
||||||
const userDeleteStmt = `
|
const userDeleteStmt = `
|
||||||
DELETE FROM users
|
DELETE FROM users
|
||||||
WHERE user_id=?
|
WHERE user_id=?
|
||||||
`
|
`
|
||||||
|
|
||||||
const userFeedQuery = `
|
|
||||||
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 r.repo_full_name IN (%s)
|
|
||||||
ORDER BY b.build_id DESC
|
|
||||||
LIMIT 50
|
|
||||||
`
|
|
||||||
|
|
||||||
// thanks to this article for helping me find a sane sql query
|
|
||||||
// https://www.periscopedata.com/blog/4-ways-to-join-only-the-first-row-in-sql.html
|
|
||||||
|
|
||||||
const userFeedLatest = `
|
|
||||||
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 repos LEFT OUTER JOIN builds ON build_id = (
|
|
||||||
SELECT build_id FROM builds
|
|
||||||
WHERE builds.build_repo_id = repos.repo_id
|
|
||||||
ORDER BY build_id DESC
|
|
||||||
LIMIT 1
|
|
||||||
)
|
|
||||||
WHERE repo_full_name IN (%s)
|
|
||||||
`
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func TestUsers(t *testing.T) {
|
||||||
s.Exec("DELETE FROM users")
|
s.Exec("DELETE FROM users")
|
||||||
s.Exec("DELETE FROM repos")
|
s.Exec("DELETE FROM repos")
|
||||||
s.Exec("DELETE FROM builds")
|
s.Exec("DELETE FROM builds")
|
||||||
s.Exec("DELETE FROM jobs")
|
s.Exec("DELETE FROM procs")
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should Update a User", func() {
|
g.It("Should Update a User", func() {
|
||||||
|
@ -166,28 +166,40 @@ func TestUsers(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should get the Build feed for a User", func() {
|
g.It("Should get the Build feed for a User", func() {
|
||||||
|
user := &model.User{
|
||||||
|
Login: "joe",
|
||||||
|
Email: "foo@bar.com",
|
||||||
|
Token: "e42080dddf012c718e476da161d21ad5",
|
||||||
|
}
|
||||||
|
s.CreateUser(user)
|
||||||
|
|
||||||
repo1 := &model.Repo{
|
repo1 := &model.Repo{
|
||||||
UserID: 1,
|
|
||||||
Owner: "bradrydzewski",
|
Owner: "bradrydzewski",
|
||||||
Name: "drone",
|
Name: "drone",
|
||||||
FullName: "bradrydzewski/drone",
|
FullName: "bradrydzewski/drone",
|
||||||
|
IsActive: true,
|
||||||
}
|
}
|
||||||
repo2 := &model.Repo{
|
repo2 := &model.Repo{
|
||||||
UserID: 2,
|
|
||||||
Owner: "drone",
|
Owner: "drone",
|
||||||
Name: "drone",
|
Name: "drone",
|
||||||
FullName: "drone/drone",
|
FullName: "drone/drone",
|
||||||
|
IsActive: true,
|
||||||
}
|
}
|
||||||
repo3 := &model.Repo{
|
repo3 := &model.Repo{
|
||||||
UserID: 2,
|
|
||||||
Owner: "octocat",
|
Owner: "octocat",
|
||||||
Name: "hello-world",
|
Name: "hello-world",
|
||||||
FullName: "octocat/hello-world",
|
FullName: "octocat/hello-world",
|
||||||
|
IsActive: true,
|
||||||
}
|
}
|
||||||
s.CreateRepo(repo1)
|
s.CreateRepo(repo1)
|
||||||
s.CreateRepo(repo2)
|
s.CreateRepo(repo2)
|
||||||
s.CreateRepo(repo3)
|
s.CreateRepo(repo3)
|
||||||
|
|
||||||
|
s.PermBatch([]*model.Perm{
|
||||||
|
{UserID: user.ID, Repo: repo1.FullName},
|
||||||
|
{UserID: user.ID, Repo: repo2.FullName},
|
||||||
|
})
|
||||||
|
|
||||||
build1 := &model.Build{
|
build1 := &model.Build{
|
||||||
RepoID: repo1.ID,
|
RepoID: repo1.ID,
|
||||||
Status: model.StatusFailure,
|
Status: model.StatusFailure,
|
||||||
|
@ -209,10 +221,7 @@ func TestUsers(t *testing.T) {
|
||||||
s.CreateBuild(build3)
|
s.CreateBuild(build3)
|
||||||
s.CreateBuild(build4)
|
s.CreateBuild(build4)
|
||||||
|
|
||||||
builds, err := s.GetUserFeed([]*model.RepoLite{
|
builds, err := s.UserFeed(user)
|
||||||
{FullName: "bradrydzewski/drone"},
|
|
||||||
{FullName: "drone/drone"},
|
|
||||||
})
|
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
g.Assert(len(builds)).Equal(3)
|
g.Assert(len(builds)).Equal(3)
|
||||||
g.Assert(builds[0].FullName).Equal(repo2.FullName)
|
g.Assert(builds[0].FullName).Equal(repo2.FullName)
|
||||||
|
|
|
@ -2,9 +2,7 @@ package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,41 +33,3 @@ func rebind(query string) string {
|
||||||
}
|
}
|
||||||
return string(rqb)
|
return string(rqb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function that converts a simple repsitory list
|
|
||||||
// to a sql IN statment.
|
|
||||||
func toList(listof []*model.RepoLite) (string, []interface{}) {
|
|
||||||
var size = len(listof)
|
|
||||||
switch {
|
|
||||||
case meddler.Default == meddler.SQLite && size > 999:
|
|
||||||
size = 999
|
|
||||||
listof = listof[:999]
|
|
||||||
case size > 15000:
|
|
||||||
size = 15000
|
|
||||||
listof = listof[:15000]
|
|
||||||
}
|
|
||||||
var qs = make([]string, size, size)
|
|
||||||
var in = make([]interface{}, size, size)
|
|
||||||
for i, repo := range listof {
|
|
||||||
qs[i] = "?"
|
|
||||||
in[i] = repo.FullName
|
|
||||||
}
|
|
||||||
return strings.Join(qs, ","), in
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function that converts a simple repository list
|
|
||||||
// to a sql IN statement compatible with postgres.
|
|
||||||
func toListPostgres(listof []*model.RepoLite) (string, []interface{}) {
|
|
||||||
var size = len(listof)
|
|
||||||
if size > 15000 {
|
|
||||||
size = 15000
|
|
||||||
listof = listof[:15000]
|
|
||||||
}
|
|
||||||
var qs = make([]string, size, size)
|
|
||||||
var in = make([]interface{}, size, size)
|
|
||||||
for i, repo := range listof {
|
|
||||||
qs[i] = "$" + strconv.Itoa(i+1)
|
|
||||||
in[i] = repo.FullName
|
|
||||||
}
|
|
||||||
return strings.Join(qs, ","), in
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,13 +18,6 @@ type Store interface {
|
||||||
// GetUserList gets a list of all users in the system.
|
// GetUserList gets a list of all users in the system.
|
||||||
GetUserList() ([]*model.User, error)
|
GetUserList() ([]*model.User, error)
|
||||||
|
|
||||||
// GetUserFeed gets a user activity feed.
|
|
||||||
GetUserFeed([]*model.RepoLite) ([]*model.Feed, error)
|
|
||||||
|
|
||||||
// GetUserFeedLatest gets a user activity feed for all repositories including
|
|
||||||
// only the latest build for each repository.
|
|
||||||
GetUserFeedLatest(listof []*model.RepoLite) ([]*model.Feed, error)
|
|
||||||
|
|
||||||
// GetUserCount gets a count of all users in the system.
|
// GetUserCount gets a count of all users in the system.
|
||||||
GetUserCount() (int, error)
|
GetUserCount() (int, error)
|
||||||
|
|
||||||
|
@ -43,9 +36,6 @@ type Store interface {
|
||||||
// GetRepoName gets a repo by its full name.
|
// GetRepoName gets a repo by its full name.
|
||||||
GetRepoName(string) (*model.Repo, error)
|
GetRepoName(string) (*model.Repo, error)
|
||||||
|
|
||||||
// GetRepoListOf gets the list of enumerated repos in the system.
|
|
||||||
GetRepoListOf([]*model.RepoLite) ([]*model.Repo, error)
|
|
||||||
|
|
||||||
// GetRepoCount gets a count of all repositories in the system.
|
// GetRepoCount gets a count of all repositories in the system.
|
||||||
GetRepoCount() (int, error)
|
GetRepoCount() (int, error)
|
||||||
|
|
||||||
|
@ -92,6 +82,18 @@ type Store interface {
|
||||||
// new functions
|
// new functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
UserFeed(*model.User) ([]*model.Feed, error)
|
||||||
|
|
||||||
|
RepoList(*model.User) ([]*model.Repo, error)
|
||||||
|
RepoListLatest(*model.User) ([]*model.Feed, error)
|
||||||
|
RepoBatch([]*model.Repo) error
|
||||||
|
|
||||||
|
PermFind(user *model.User, repo *model.Repo) (*model.Perm, error)
|
||||||
|
PermUpsert(perm *model.Perm) error
|
||||||
|
PermBatch(perms []*model.Perm) error
|
||||||
|
PermDelete(perm *model.Perm) error
|
||||||
|
PermFlush(user *model.User, before int64) error
|
||||||
|
|
||||||
ConfigLoad(int64) (*model.Config, error)
|
ConfigLoad(int64) (*model.Config, error)
|
||||||
ConfigFind(*model.Repo, string) (*model.Config, error)
|
ConfigFind(*model.Repo, string) (*model.Config, error)
|
||||||
ConfigFindApproved(*model.Config) (bool, error)
|
ConfigFindApproved(*model.Config) (bool, error)
|
||||||
|
@ -151,14 +153,6 @@ func GetUserList(c context.Context) ([]*model.User, error) {
|
||||||
return FromContext(c).GetUserList()
|
return FromContext(c).GetUserList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserFeed gets a user activity feed.
|
|
||||||
func GetUserFeed(c context.Context, listof []*model.RepoLite, latest bool) ([]*model.Feed, error) {
|
|
||||||
if latest {
|
|
||||||
return FromContext(c).GetUserFeedLatest(listof)
|
|
||||||
}
|
|
||||||
return FromContext(c).GetUserFeed(listof)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserCount gets a count of all users in the system.
|
// GetUserCount gets a count of all users in the system.
|
||||||
func GetUserCount(c context.Context) (int, error) {
|
func GetUserCount(c context.Context) (int, error) {
|
||||||
return FromContext(c).GetUserCount()
|
return FromContext(c).GetUserCount()
|
||||||
|
@ -188,10 +182,6 @@ func GetRepoOwnerName(c context.Context, owner, name string) (*model.Repo, error
|
||||||
return FromContext(c).GetRepoName(owner + "/" + name)
|
return FromContext(c).GetRepoName(owner + "/" + name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoListOf(c context.Context, listof []*model.RepoLite) ([]*model.Repo, error) {
|
|
||||||
return FromContext(c).GetRepoListOf(listof)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateRepo(c context.Context, repo *model.Repo) error {
|
func CreateRepo(c context.Context, repo *model.Repo) error {
|
||||||
return FromContext(c).CreateRepo(repo)
|
return FromContext(c).CreateRepo(repo)
|
||||||
}
|
}
|
||||||
|
|
27
vendor/github.com/ianschenck/envflag/LICENSE
generated
vendored
27
vendor/github.com/ianschenck/envflag/LICENSE
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
Copyright (c) 2013, Ian Schenck
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
Neither the name of Ian Schenck nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
37
vendor/github.com/ianschenck/envflag/README.md
generated
vendored
37
vendor/github.com/ianschenck/envflag/README.md
generated
vendored
|
@ -1,37 +0,0 @@
|
||||||
envflag
|
|
||||||
=======
|
|
||||||
|
|
||||||
Golang flags, but bolted onto the environment rather than the command-line.
|
|
||||||
|
|
||||||
Read the [godocs](http://godoc.org/github.com/ianschenck/envflag).
|
|
||||||
|
|
||||||
Motivation
|
|
||||||
==========
|
|
||||||
|
|
||||||
Some like the distinction that command-line flags control behavior
|
|
||||||
while environment variables configure. Also
|
|
||||||
[12-factor](http://12factor.net/) recommends the use of environment
|
|
||||||
variables for configuration. The interface of the golang flag package
|
|
||||||
is well designed and easy to use, and allows for other lists
|
|
||||||
(os.Environ() vs os.Args) to be parsed as flags. It makes sense then
|
|
||||||
to use the same interface, the same types, and the same parsing
|
|
||||||
(caveat: there is some ugly string hacking to make environment
|
|
||||||
variables look like flags) to the same ends.
|
|
||||||
|
|
||||||
Differences
|
|
||||||
===========
|
|
||||||
|
|
||||||
Calling `flag.Parse()` will not parse environment flags. Calling
|
|
||||||
`envflag.Parse()` will not parse command-line flags. There is no good
|
|
||||||
reason to combine these two when the net savings is a single line in a
|
|
||||||
`func main()`. Furthermore, doing so would require users to accept a
|
|
||||||
precedence order of my choosing.
|
|
||||||
|
|
||||||
The presence of an environment variable named `h` or `help` will
|
|
||||||
probably cause problems (print Usage and os.Exit(0)). Work around this
|
|
||||||
by defining those flags somewhere (and ignoring them).
|
|
||||||
|
|
||||||
Before calling `Flagset.Parse` on `EnvironmentFlags`, the environment
|
|
||||||
variables being passed to `Parse` are trimmed down using
|
|
||||||
`Lookup`. This behavior is different from `flag.Parse` in that extra
|
|
||||||
environment variables are ignored (and won't crash `envflag.Parse`).
|
|
192
vendor/github.com/ianschenck/envflag/envflag.go
generated
vendored
192
vendor/github.com/ianschenck/envflag/envflag.go
generated
vendored
|
@ -1,192 +0,0 @@
|
||||||
// Copyright 2013 Ian Schenck. Use of this source code is governed by
|
|
||||||
// a license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package envflag adds environment variable flags to the flag package.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
Define flags using envflag.String(), Bool(), Int(), etc. This package
|
|
||||||
works nearly the same as the stdlib flag package. Parsing the
|
|
||||||
Environment flags is done by calling envflag.Parse()
|
|
||||||
|
|
||||||
It will *not* attempt to parse any normally-defined command-line
|
|
||||||
flags. Command-line flags are explicitly left alone and separate.
|
|
||||||
*/
|
|
||||||
package envflag
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// VisitAll visits the environment flags in lexicographical order,
|
|
||||||
// calling fn for each. It visits all flags, even those not set.
|
|
||||||
func VisitAll(fn func(*flag.Flag)) {
|
|
||||||
EnvironmentFlags.VisitAll(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit visits the environment flags in lexicographical order,
|
|
||||||
// calling fn for each. It visits only those flags that have been
|
|
||||||
// set.
|
|
||||||
func Visit(fn func(*flag.Flag)) {
|
|
||||||
EnvironmentFlags.Visit(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup returns the Flag structure of the named environment flag,
|
|
||||||
// returning nil if none exists.
|
|
||||||
func Lookup(name string) *flag.Flag {
|
|
||||||
return EnvironmentFlags.Lookup(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the value of the named environment flag.
|
|
||||||
func Set(name, value string) error {
|
|
||||||
return EnvironmentFlags.Set(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolVar defines a bool flag with specified name, default value, and
|
|
||||||
// usage string. The argument p points to a bool variable in which to
|
|
||||||
// store the value of the flag.
|
|
||||||
func BoolVar(p *bool, name string, value bool, usage string) {
|
|
||||||
EnvironmentFlags.BoolVar(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool defines a bool flag with specified name, default value, and
|
|
||||||
// usage string. The return value is the address of a bool variable
|
|
||||||
// that stores the value of the flag.
|
|
||||||
func Bool(name string, value bool, usage string) *bool {
|
|
||||||
return EnvironmentFlags.Bool(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntVar defines an int flag with specified name, default value, and
|
|
||||||
// usage string. The argument p points to an int variable in which to
|
|
||||||
// store the value of the flag.
|
|
||||||
func IntVar(p *int, name string, value int, usage string) {
|
|
||||||
EnvironmentFlags.IntVar(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int defines an int flag with specified name, default value, and
|
|
||||||
// usage string. The return value is the address of an int variable
|
|
||||||
// that stores the value of the flag.
|
|
||||||
func Int(name string, value int, usage string) *int {
|
|
||||||
return EnvironmentFlags.Int(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Var defines an int64 flag with specified name, default value,
|
|
||||||
// and usage string. The argument p points to an int64 variable in
|
|
||||||
// which to store the value of the flag.
|
|
||||||
func Int64Var(p *int64, name string, value int64, usage string) {
|
|
||||||
EnvironmentFlags.Int64Var(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 defines an int64 flag with specified name, default value, and
|
|
||||||
// usage string. The return value is the address of an int64 variable
|
|
||||||
// that stores the value of the flag.
|
|
||||||
func Int64(name string, value int64, usage string) *int64 {
|
|
||||||
return EnvironmentFlags.Int64(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintVar defines a uint flag with specified name, default value, and
|
|
||||||
// usage string. The argument p points to a uint variable in which to
|
|
||||||
// store the value of the flag.
|
|
||||||
func UintVar(p *uint, name string, value uint, usage string) {
|
|
||||||
EnvironmentFlags.UintVar(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint defines a uint flag with specified name, default value, and
|
|
||||||
// usage string. The return value is the address of a uint variable
|
|
||||||
// that stores the value of the flag.
|
|
||||||
func Uint(name string, value uint, usage string) *uint {
|
|
||||||
return EnvironmentFlags.Uint(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64Var defines a uint64 flag with specified name, default value,
|
|
||||||
// and usage string. The argument p points to a uint64 variable in
|
|
||||||
// which to store the value of the flag.
|
|
||||||
func Uint64Var(p *uint64, name string, value uint64, usage string) {
|
|
||||||
EnvironmentFlags.Uint64Var(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64 defines a uint64 flag with specified name, default value,
|
|
||||||
// and usage string. The return value is the address of a uint64
|
|
||||||
// variable that stores the value of the flag.
|
|
||||||
func Uint64(name string, value uint64, usage string) *uint64 {
|
|
||||||
return EnvironmentFlags.Uint64(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringVar defines a string flag with specified name, default value,
|
|
||||||
// and usage string. The argument p points to a string variable in
|
|
||||||
// which to store the value of the flag.
|
|
||||||
func StringVar(p *string, name string, value string, usage string) {
|
|
||||||
EnvironmentFlags.StringVar(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String defines a string flag with specified name, default value,
|
|
||||||
// and usage string. The return value is the address of a string
|
|
||||||
// variable that stores the value of the flag.
|
|
||||||
func String(name string, value string, usage string) *string {
|
|
||||||
return EnvironmentFlags.String(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Var defines a float64 flag with specified name, default
|
|
||||||
// value, and usage string. The argument p points to a float64
|
|
||||||
// variable in which to store the value of the flag.
|
|
||||||
func Float64Var(p *float64, name string, value float64, usage string) {
|
|
||||||
EnvironmentFlags.Float64Var(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 defines a float64 flag with specified name, default value,
|
|
||||||
// and usage string. The return value is the address of a float64
|
|
||||||
// variable that stores the value of the flag.
|
|
||||||
func Float64(name string, value float64, usage string) *float64 {
|
|
||||||
return EnvironmentFlags.Float64(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DurationVar defines a time.Duration flag with specified name,
|
|
||||||
// default value, and usage string. The argument p points to a
|
|
||||||
// time.Duration variable in which to store the value of the flag.
|
|
||||||
func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
|
|
||||||
EnvironmentFlags.DurationVar(p, name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Duration defines a time.Duration flag with specified name, default
|
|
||||||
// value, and usage string. The return value is the address of a
|
|
||||||
// time.Duration variable that stores the value of the flag.
|
|
||||||
func Duration(name string, value time.Duration, usage string) *time.Duration {
|
|
||||||
return EnvironmentFlags.Duration(name, value, usage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintDefaults prints to standard error the default values of all
|
|
||||||
// defined environment flags.
|
|
||||||
func PrintDefaults() {
|
|
||||||
EnvironmentFlags.PrintDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses the environment flags from os.Environ. Must be called
|
|
||||||
// after all flags are defined and before flags are accessed by the
|
|
||||||
// program.
|
|
||||||
func Parse() {
|
|
||||||
env := os.Environ()
|
|
||||||
// Clean up and "fake" some flag k/v pairs.
|
|
||||||
args := make([]string, 0, len(env))
|
|
||||||
for _, value := range env {
|
|
||||||
if Lookup(value[:strings.Index(value, "=")]) == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args = append(args, fmt.Sprintf("-%s", value))
|
|
||||||
}
|
|
||||||
EnvironmentFlags.Parse(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parsed returns true if the environment flags have been parsed.
|
|
||||||
func Parsed() bool {
|
|
||||||
return EnvironmentFlags.Parsed()
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvironmentFlags is the default set of environment flags, parsed
|
|
||||||
// from os.Environ(). The top-level functions such as BoolVar, Arg,
|
|
||||||
// and on are wrappers for the methods of EnvironmentFlags.
|
|
||||||
var EnvironmentFlags = flag.NewFlagSet("environment", flag.ExitOnError)
|
|
201
vendor/github.com/jackspirou/syscerts/LICENSE
generated
vendored
201
vendor/github.com/jackspirou/syscerts/LICENSE
generated
vendored
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright {yyyy} {name of copyright owner}
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
42
vendor/github.com/jackspirou/syscerts/README.md
generated
vendored
42
vendor/github.com/jackspirou/syscerts/README.md
generated
vendored
|
@ -1,42 +0,0 @@
|
||||||
# syscerts
|
|
||||||
Gather local system certificates in Go via a public `SystemRootsPool` method.
|
|
||||||
|
|
||||||
#### What does this do?
|
|
||||||
Provide a way to gather local system certificates
|
|
||||||
on different OS platforms.
|
|
||||||
|
|
||||||
#### How does it do it?
|
|
||||||
It uses the `crypto/x509` package and provides a single public method called
|
|
||||||
`SystemRootsPool()` to return a `*x509.CertPool` object.
|
|
||||||
|
|
||||||
#### How do you use it?
|
|
||||||
```Go
|
|
||||||
// gather CA certs
|
|
||||||
certpool := syscerts.SystemRootsPool()
|
|
||||||
|
|
||||||
// place them in an HTTP client for trusted SSL/TLS connections
|
|
||||||
tlsConfig := &tls.Config{RootCAs: certpool}
|
|
||||||
transport := &http.Transport{TLSClientConfig: tlsConfig}
|
|
||||||
client := &http.Client{Transport: transport}
|
|
||||||
|
|
||||||
// make a request
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Why even do it?
|
|
||||||
The `crypto/x509` package already has a `systemRootsPool` method.
|
|
||||||
The `crypto/x509.systemRootsPool` method is almost the same as
|
|
||||||
`github.com/jackspirou/syscerts.SystemRootsPool`.
|
|
||||||
The difference? The `crypto/x509.systemRootsPool` method is private so you
|
|
||||||
cannot access it. :(
|
|
||||||
|
|
||||||
There are plans for the `crypto/x509.systemRootsPool` method to become public
|
|
||||||
in Go 1.7. When this happens you might no longer need `github.com/jackspirou/syscerts.SystemRootsPool`.
|
|
||||||
|
|
||||||
The only reason you may still use this package after the Go 1.7 release might
|
|
||||||
be for the Mac OSX System Keychain certs which are not included in the
|
|
||||||
`crypto/x509` package. Relevant lines below:
|
|
||||||
|
|
||||||
* https://github.com/jackspirou/syscerts/blob/master/root_darwin.go#L24-L32
|
|
||||||
|
|
||||||
Find more about this Go issue here: https://github.com/golang/go/issues/13335
|
|
22
vendor/github.com/jackspirou/syscerts/root.go
generated
vendored
22
vendor/github.com/jackspirou/syscerts/root.go
generated
vendored
|
@ -1,22 +0,0 @@
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
once sync.Once
|
|
||||||
systemRoots *x509.CertPool
|
|
||||||
)
|
|
||||||
|
|
||||||
// SystemRootsPool attempts to find and return a pool of all all installed
|
|
||||||
// system certificates.
|
|
||||||
func SystemRootsPool() *x509.CertPool {
|
|
||||||
once.Do(initSystemRoots)
|
|
||||||
return systemRoots
|
|
||||||
}
|
|
14
vendor/github.com/jackspirou/syscerts/root_bsd.go
generated
vendored
14
vendor/github.com/jackspirou/syscerts/root_bsd.go
generated
vendored
|
@ -1,14 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
// Possible certificate files; stop after finding one.
|
|
||||||
var certFiles = []string{
|
|
||||||
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
|
|
||||||
"/etc/ssl/cert.pem", // OpenBSD
|
|
||||||
"/etc/openssl/certs/ca-certificates.crt", // NetBSD
|
|
||||||
}
|
|
85
vendor/github.com/jackspirou/syscerts/root_cgo_darwin.go
generated
vendored
85
vendor/github.com/jackspirou/syscerts/root_cgo_darwin.go
generated
vendored
|
@ -1,85 +0,0 @@
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build cgo,darwin,!arm,!arm64,!ios
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
|
|
||||||
#cgo LDFLAGS: -framework CoreFoundation -framework Security
|
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#include <Security/Security.h>
|
|
||||||
|
|
||||||
// FetchPEMRootsC fetches the system's list of trusted X.509 root certificates.
|
|
||||||
//
|
|
||||||
// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
|
|
||||||
// certificates of the system. On failure, the function returns -1.
|
|
||||||
//
|
|
||||||
// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
|
|
||||||
// we've consumed its content.
|
|
||||||
int FetchPEMRootsC(CFDataRef *pemRoots) {
|
|
||||||
if (pemRoots == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFArrayRef certs = NULL;
|
|
||||||
OSStatus err = SecTrustCopyAnchorCertificates(&certs);
|
|
||||||
if (err != noErr) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
|
|
||||||
int i, ncerts = CFArrayGetCount(certs);
|
|
||||||
for (i = 0; i < ncerts; i++) {
|
|
||||||
CFDataRef data = NULL;
|
|
||||||
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
|
|
||||||
if (cert == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
|
|
||||||
// Once we support weak imports via cgo we should prefer that, and fall back to this
|
|
||||||
// for older systems.
|
|
||||||
err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
|
|
||||||
if (err != noErr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data != NULL) {
|
|
||||||
CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
|
|
||||||
CFRelease(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CFRelease(certs);
|
|
||||||
|
|
||||||
*pemRoots = combinedData;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initSystemRoots() {
|
|
||||||
roots := x509.NewCertPool()
|
|
||||||
|
|
||||||
var data C.CFDataRef = nil
|
|
||||||
err := C.FetchPEMRootsC(&data)
|
|
||||||
if err == -1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer C.CFRelease(C.CFTypeRef(data))
|
|
||||||
buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
|
|
||||||
roots.AppendCertsFromPEM(buf)
|
|
||||||
systemRoots = roots
|
|
||||||
}
|
|
||||||
*/
|
|
39
vendor/github.com/jackspirou/syscerts/root_darwin.go
generated
vendored
39
vendor/github.com/jackspirou/syscerts/root_darwin.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:generate go run root_darwin_arm_gen.go -output root_darwin_armx.go
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func execSecurityRoots() (*x509.CertPool, error) {
|
|
||||||
roots := x509.NewCertPool()
|
|
||||||
cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
|
|
||||||
data, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
roots.AppendCertsFromPEM(data)
|
|
||||||
|
|
||||||
// if available add the Mac OSX System Keychain
|
|
||||||
if _, err := os.Stat("/Library/Keychains/System.keychain"); err == nil {
|
|
||||||
cmd = exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/Library/Keychains/System.keychain")
|
|
||||||
data, err = cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
roots.AppendCertsFromPEM(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
return roots, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initSystemRoots() {
|
|
||||||
systemRoots, _ = execSecurityRoots()
|
|
||||||
}
|
|
4909
vendor/github.com/jackspirou/syscerts/root_darwin_armx.go
generated
vendored
4909
vendor/github.com/jackspirou/syscerts/root_darwin_armx.go
generated
vendored
File diff suppressed because it is too large
Load diff
13
vendor/github.com/jackspirou/syscerts/root_linux.go
generated
vendored
13
vendor/github.com/jackspirou/syscerts/root_linux.go
generated
vendored
|
@ -1,13 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
// Possible certificate files; stop after finding one.
|
|
||||||
var certFiles = []string{
|
|
||||||
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
|
|
||||||
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
|
|
||||||
"/etc/ssl/ca-bundle.pem", // OpenSUSE
|
|
||||||
"/etc/pki/tls/cacert.pem", // OpenELEC
|
|
||||||
}
|
|
8
vendor/github.com/jackspirou/syscerts/root_nacl.go
generated
vendored
8
vendor/github.com/jackspirou/syscerts/root_nacl.go
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
// Possible certificate files; stop after finding one.
|
|
||||||
var certFiles = []string{}
|
|
32
vendor/github.com/jackspirou/syscerts/root_plan9.go
generated
vendored
32
vendor/github.com/jackspirou/syscerts/root_plan9.go
generated
vendored
|
@ -1,32 +0,0 @@
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build plan9
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/x509"
|
|
||||||
"io/ioutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Possible certificate files; stop after finding one.
|
|
||||||
var certFiles = []string{
|
|
||||||
"/sys/lib/tls/ca.pem",
|
|
||||||
}
|
|
||||||
|
|
||||||
func initSystemRoots() {
|
|
||||||
roots := x509.NewCertPool()
|
|
||||||
for _, file := range certFiles {
|
|
||||||
data, err := ioutil.ReadFile(file)
|
|
||||||
if err == nil {
|
|
||||||
roots.AppendCertsFromPEM(data)
|
|
||||||
systemRoots = roots
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// All of the files failed to load. systemRoots will be nil which will
|
|
||||||
// trigger a specific error at verification time.
|
|
||||||
}
|
|
12
vendor/github.com/jackspirou/syscerts/root_solaris.go
generated
vendored
12
vendor/github.com/jackspirou/syscerts/root_solaris.go
generated
vendored
|
@ -1,12 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package syscerts
|
|
||||||
|
|
||||||
// Possible certificate files; stop after finding one.
|
|
||||||
var certFiles = []string{
|
|
||||||
"/etc/certs/ca-certificates.crt", // Solaris 11.2+
|
|
||||||
"/etc/ssl/certs/ca-certificates.crt", // Joyent SmartOS
|
|
||||||
"/etc/ssl/cacert.pem", // OmniOS
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue