2015-04-07 08:20:55 +00:00
|
|
|
package bolt
|
|
|
|
|
|
|
|
import (
|
2015-04-14 04:39:05 +00:00
|
|
|
"bytes"
|
2015-04-07 08:20:55 +00:00
|
|
|
"time"
|
|
|
|
|
2015-04-10 19:52:33 +00:00
|
|
|
"github.com/boltdb/bolt"
|
2015-04-14 04:39:05 +00:00
|
|
|
"github.com/drone/drone/common"
|
2015-04-07 08:20:55 +00:00
|
|
|
)
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// Repo returns the repository with the given name.
|
|
|
|
func (db *DB) Repo(repo string) (*common.Repo, error) {
|
2015-04-07 08:20:55 +00:00
|
|
|
repo_ := &common.Repo{}
|
|
|
|
key := []byte(repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
err := db.View(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return get(t, bucketRepo, key, repo_)
|
|
|
|
})
|
|
|
|
|
2015-04-07 08:20:55 +00:00
|
|
|
return repo_, err
|
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// RepoList returns a list of repositories for the
|
|
|
|
// given user account.
|
|
|
|
func (db *DB) RepoList(login string) ([]*common.Repo, error) {
|
|
|
|
repos := []*common.Repo{}
|
|
|
|
err := db.View(func(t *bolt.Tx) error {
|
|
|
|
// get the index of user tokens and unmarshal
|
|
|
|
// to a string array.
|
|
|
|
var keys [][]byte
|
|
|
|
err := get(t, bucketUserRepos, []byte(login), &keys)
|
|
|
|
if err != nil && err != ErrKeyNotFound {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// for each item in the index, get the repository
|
|
|
|
// and append to the array
|
|
|
|
for _, key := range keys {
|
|
|
|
repo := &common.Repo{}
|
|
|
|
err := get(t, bucketRepo, key, repo)
|
|
|
|
if err == ErrKeyNotFound {
|
|
|
|
// TODO if we come across ErrKeyNotFound it means
|
|
|
|
// we need to re-build the index
|
|
|
|
continue
|
|
|
|
} else if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
repos = append(repos, repo)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return repos, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// RepoParams returns the private environment parameters
|
2015-04-07 08:20:55 +00:00
|
|
|
// for the given repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) RepoParams(repo string) (map[string]string, error) {
|
2015-04-07 08:20:55 +00:00
|
|
|
params := map[string]string{}
|
|
|
|
key := []byte(repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
err := db.View(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return get(t, bucketRepoParams, key, ¶ms)
|
|
|
|
})
|
|
|
|
|
2015-04-07 08:20:55 +00:00
|
|
|
return params, err
|
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// RepoKeypair returns the private and public rsa keys
|
2015-04-07 08:20:55 +00:00
|
|
|
// for the given repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) RepoKeypair(repo string) (*common.Keypair, error) {
|
2015-04-07 08:20:55 +00:00
|
|
|
keypair := &common.Keypair{}
|
|
|
|
key := []byte(repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
err := db.View(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return get(t, bucketRepoKeys, key, keypair)
|
|
|
|
})
|
|
|
|
|
2015-04-07 08:20:55 +00:00
|
|
|
return keypair, err
|
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// SetRepo inserts or updates a repository.
|
|
|
|
func (db *DB) SetRepo(repo *common.Repo) error {
|
2015-04-07 08:20:55 +00:00
|
|
|
key := []byte(repo.FullName)
|
|
|
|
repo.Updated = time.Now().UTC().Unix()
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return update(t, bucketRepo, key, repo)
|
|
|
|
})
|
2015-04-07 08:20:55 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// SetRepoNotExists updates a repository. If the repository
|
|
|
|
// already exists ErrConflict is returned.
|
|
|
|
func (db *DB) SetRepoNotExists(user *common.User, repo *common.Repo) error {
|
2015-04-14 04:39:05 +00:00
|
|
|
repokey := []byte(repo.FullName)
|
2015-04-07 08:20:55 +00:00
|
|
|
repo.Created = time.Now().UTC().Unix()
|
|
|
|
repo.Updated = time.Now().UTC().Unix()
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
|
|
|
userkey := []byte(user.Login)
|
|
|
|
err := push(t, bucketUserRepos, userkey, repokey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// err = push(t, bucketRepoUsers, repokey, userkey)
|
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
|
|
|
return insert(t, bucketRepo, repokey, repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
})
|
2015-04-07 08:20:55 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// SetRepoParams inserts or updates the private
|
2015-04-07 08:20:55 +00:00
|
|
|
// environment parameters for the named repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) SetRepoParams(repo string, params map[string]string) error {
|
2015-04-07 08:20:55 +00:00
|
|
|
key := []byte(repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return update(t, bucketRepoParams, key, params)
|
|
|
|
})
|
2015-04-07 08:20:55 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// SetRepoKeypair inserts or updates the private and
|
2015-04-07 08:20:55 +00:00
|
|
|
// public keypair for the named repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) SetRepoKeypair(repo string, keypair *common.Keypair) error {
|
2015-04-07 08:20:55 +00:00
|
|
|
key := []byte(repo)
|
2015-04-10 19:52:33 +00:00
|
|
|
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
2015-04-10 19:52:33 +00:00
|
|
|
return update(t, bucketRepoKeys, key, keypair)
|
|
|
|
})
|
2015-04-07 08:20:55 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// DelRepo deletes the repository.
|
|
|
|
func (db *DB) DelRepo(repo *common.Repo) error {
|
2015-04-07 08:20:55 +00:00
|
|
|
key := []byte(repo.FullName)
|
2015-04-20 22:48:44 +00:00
|
|
|
|
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
|
|
|
err := t.Bucket(bucketRepo).Delete(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.Bucket(bucketRepoKeys).Delete(key)
|
|
|
|
t.Bucket(bucketRepoParams).Delete(key)
|
|
|
|
|
|
|
|
// should we just ignore these error conditions? or should
|
|
|
|
// we go ahead with the transaction and assume we can
|
|
|
|
// cleanup the leftovers through some other maintenance process?
|
|
|
|
err = db.deleteTracesOfRepo(t, key)
|
|
|
|
|
2015-04-07 08:20:55 +00:00
|
|
|
return err
|
2015-04-20 22:48:44 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// deleteTracesOfRepo cleans up build leftovers when a repo is removed
|
|
|
|
func (db *DB) deleteTracesOfRepo(t *bolt.Tx, repoKey []byte) error {
|
|
|
|
// bucketBuildSeq uses the repoKey directly
|
2015-04-22 16:50:45 +00:00
|
|
|
err := t.Bucket(bucketBuildSeq).Delete(repoKey)
|
|
|
|
if err != nil {
|
|
|
|
// only error here is if our Tx is read-only
|
|
|
|
return err
|
|
|
|
}
|
2015-04-20 22:48:44 +00:00
|
|
|
|
|
|
|
// the other buckets use repoKey with '/buildNumber', at least.
|
|
|
|
// validating that an additiona '/' is there ensures that we don't
|
|
|
|
// match 'github.com/drone/droney' when we're cleaning up after
|
|
|
|
// 'github.com/drone/drone'.
|
|
|
|
prefix := append(repoKey, '/')
|
2015-04-22 16:50:45 +00:00
|
|
|
buckets := [][]byte{bucketBuildStatus, bucketBuildLogs, bucketBuild}
|
|
|
|
for _, b := range buckets {
|
|
|
|
err = deleteWithPrefix(t, b, prefix)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2015-04-20 22:48:44 +00:00
|
|
|
|
|
|
|
return err
|
2015-04-07 08:20:55 +00:00
|
|
|
}
|
2015-04-08 22:43:59 +00:00
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// Subscribed returns true if the user is subscribed
|
|
|
|
// to the named repository.
|
|
|
|
//
|
|
|
|
// TODO (bradrydzewski) we are currently storing the subscription
|
|
|
|
// data in a wrapper element called common.Subscriber. This is
|
|
|
|
// no longer necessary.
|
|
|
|
func (db *DB) Subscribed(login, repo string) (bool, error) {
|
2015-04-14 04:39:05 +00:00
|
|
|
sub := &common.Subscriber{}
|
|
|
|
err := db.View(func(t *bolt.Tx) error {
|
|
|
|
repokey := []byte(repo)
|
|
|
|
|
|
|
|
// get the index of user tokens and unmarshal
|
|
|
|
// to a string array.
|
|
|
|
var keys [][]byte
|
|
|
|
err := get(t, bucketUserRepos, []byte(login), &keys)
|
|
|
|
if err != nil && err != ErrKeyNotFound {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, key := range keys {
|
|
|
|
if bytes.Equal(repokey, key) {
|
|
|
|
sub.Subscribed = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2015-04-15 05:04:38 +00:00
|
|
|
return sub.Subscribed, err
|
2015-04-14 04:39:05 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// SetSubscriber inserts a subscriber for the named
|
2015-04-14 04:39:05 +00:00
|
|
|
// repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) SetSubscriber(login, repo string) error {
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
|
|
|
userkey := []byte(login)
|
|
|
|
repokey := []byte(repo)
|
|
|
|
return push(t, bucketUserRepos, userkey, repokey)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-04-15 05:04:38 +00:00
|
|
|
// DelSubscriber removes the subscriber by login for the
|
2015-04-14 04:39:05 +00:00
|
|
|
// named repository.
|
2015-04-15 05:04:38 +00:00
|
|
|
func (db *DB) DelSubscriber(login, repo string) error {
|
2015-04-14 04:39:05 +00:00
|
|
|
return db.Update(func(t *bolt.Tx) error {
|
|
|
|
userkey := []byte(login)
|
|
|
|
repokey := []byte(repo)
|
|
|
|
return splice(t, bucketUserRepos, userkey, repokey)
|
|
|
|
})
|
|
|
|
}
|