refactored how remotes work and how (some) config is loaded

This commit is contained in:
Brad Rydzewski 2014-09-03 00:23:36 -07:00
parent 38379992bf
commit ca3d15bca2
8 changed files with 173 additions and 118 deletions

View file

@ -18,40 +18,70 @@ We have optimized the installation process for Ubuntu since that is what we test
wget downloads.drone.io/exp/drone.deb
sudo dpkg -i drone.deb
```
https://github.com/drone/drone/milestones/v0.3
## What Changed
## Setup
This branch introduces major changes, including:
We are in the process of moving configuration out of the UI and into configuration
files and/or environment variables (your choice which). If you prefer configuration files
you can provide Drone with the path to your configuration file:
1. modification to project structure
2. api-driven design
3. interface to abstract github, bitbucket, gitlab code (see /shared/remote)
4. handlers are structures with service providers "injected"
5. github, bitbucket, etc native permissions are used. No more teams or permissions in Drone
6. github, bitbucket, etc authentication is used. No more drone password
7. github, bitbucket, etc repository data is cached upon login (and subsequent logins)
8. angularjs user interface with modified responsive design
```sh
./drone --config=/path/to/drone.conf
## Database Compatibility Issues
```
The configuration file is in TOML format:
```toml
[github]
client=""
secret=""
[github_enterprise]
client=""
secret=""
api=""
url=""
[bitbucket]
client=""
secret=""
[smtp]
host=""
port=""
from=""
user=""
pass=""
```
Or you can use environment variables
```sh
# github configuration
export DRONE_GITHUB_CLIENT=""
export DRONE_GITHUB_secret=""
# github enterprise configuration
export DRONE_GITHUB_ENTERPRISE_CLIENT=""
export DRONE_GITHUB_ENTERPRISE_SECRET=""
export DRONE_GITHUB_ENTERPRISE_API=""
export DRONE_GITHUB_ENTERPRISE_URL=""
# bitbucket configuration
export DRONE_BITBUCKET_CLIENT=""
export DRONE_BITBUCKET_SECRET=""
# email configuration
export DRONE_SMTP_HOST=""
export DRONE_SMTP_PORT=""
export DRONE_SMTP_FROM=""
export DRONE_SMTP_USER=""
export DRONE_SMTP_PASS=""
```
## Compatibility Issues
**WARNING**
There were some fundamental changes to the application and we decided to introduce breaking changes to the dataabase. Migration would have been difficult and time consuming. Drone is an alpha product and therefore backward compatibility is not a primary goal until we hit a stable release. Apologizes for any inconvenience.
## Filing Bugs
This is an experimental branch with known bugs and issues, namely:
* notifications
* github status api updates
* gitlab integration
* smtp settings screen
* github / bitbucket / gitlab settings screen
* mysql support
Please do not log issues for the above items. We are aware and will fix as soon as possible, as they are holding up the 0.3 release. Pull requests, however, are very welcome :)
You can track progress of this release here:
https://github.com/drone/drone/milestones/v0.3

View file

@ -5,9 +5,9 @@ import (
"fmt"
"net"
"net/smtp"
"os"
"strings"
"github.com/drone/config"
"github.com/drone/drone/shared/model"
)
@ -28,11 +28,11 @@ const (
)
var (
DefaultHost = os.Getenv("SMTP_HOST")
DefaultPort = os.Getenv("SMTP_PORT")
DefaultFrom = os.Getenv("SMTP_FROM")
DefaultUser = os.Getenv("SMTP_USER")
DefaultPass = os.Getenv("SMTP_PASS")
DefaultHost = config.String("smtp-host", "")
DefaultPort = config.String("smtp-port", "")
DefaultFrom = config.String("smtp-from", "")
DefaultUser = config.String("smtp-user", "")
DefaultPass = config.String("smtp-pass", "")
)
type Email struct {
@ -139,12 +139,12 @@ func (e *Email) send(subject, body string, recipients []string) error {
// configuration. If None provided, attempt to
// use the global configuration set in the environet
// variables.
if len(DefaultHost) != 0 {
e.Host = DefaultHost
e.Port = DefaultPort
e.From = DefaultFrom
e.Username = DefaultUser
e.Password = DefaultPass
if len(*DefaultHost) != 0 {
e.Host = *DefaultHost
e.Port = *DefaultPort
e.From = *DefaultFrom
e.Username = *DefaultUser
e.Password = *DefaultPass
}
var auth smtp.Auth

View file

@ -3,21 +3,12 @@ package github
import (
"fmt"
"net/url"
"os"
"strings"
"code.google.com/p/goauth2/oauth"
"github.com/drone/drone/shared/model"
"github.com/google/go-github/github"
)
// TODO (bradrydzewski) explore using the Repo.URL to parse the GitHub
// Entperprise Scheme+Hostname, instead of the environment variable. Is
// there any reason not to use the environment variable?
// GitHub enterprise URL
var URL = os.Getenv("GITHUB_ENTERPRISE_API")
const (
NotifyDisabled = "disabled"
NotifyFalse = "false"
@ -38,6 +29,10 @@ const (
DescError = "oops, something went wrong"
)
const (
BaseURL = "https://api.github.com/"
)
type GitHub string
// Send uses the github status API to update the build
@ -70,6 +65,7 @@ func (g GitHub) Send(context *model.Request) error {
)
return send(
context.Repo.URL,
context.Repo.Host,
context.Repo.Owner,
context.Repo.Name,
@ -81,7 +77,7 @@ func (g GitHub) Send(context *model.Request) error {
)
}
func send(host, owner, repo, status, desc, target, ref, token string) error {
func send(rawurl, host, owner, repo, status, desc, target, ref, token string) error {
transport := &oauth.Transport{
Token: &oauth.Token{AccessToken: token},
}
@ -99,10 +95,7 @@ func send(host, owner, repo, status, desc, target, ref, token string) error {
// the base url. Per the documentation, we need to
// ensure there is a trailing slash.
if host != model.RemoteGithub {
client.BaseURL, _ = url.Parse(URL)
if !strings.HasSuffix(client.BaseURL.Path, "/") {
client.BaseURL.Path = client.BaseURL.Path + "/"
}
client.BaseURL, _ = getEndpoint(rawurl)
}
_, _, err := client.Repositories.CreateStatus(owner, repo, ref, &data)
@ -151,3 +144,15 @@ func getDesc(status string) string {
func getTarget(url, host, owner, repo, branch, commit string) string {
return fmt.Sprintf("%s/%s/%s/%s/%s/%s", url, host, owner, repo, branch, commit)
}
// getEndpoint is a helper funcation that parsed the
// repository HTML URL to determine the API URL. It is
// intended for use with GitHub enterprise.
func getEndpoint(rawurl string) (*url.URL, error) {
uri, err := url.Parse(rawurl)
if err != nil {
return nil, err
}
uri.Path = "/api/v3"
return uri, nil
}

View file

@ -1,16 +1,24 @@
package bitbucket
import (
"os"
"github.com/drone/config"
"github.com/drone/drone/plugin/remote"
)
func init() {
var cli = os.Getenv("BITBUCKET_CLIENT")
var sec = os.Getenv("BITBUCKET_SECRET")
if len(cli) == 0 || len(sec) == 0 {
var (
// Bitbucket cloud configuration details
bitbucketClient = config.String("bitbucket-client", "")
bitbucketSecret = config.String("bitbucket-secret", "")
)
// Registers the Bitbucket plugin using the default
// settings from the config file or environment
// variables.
func Register() {
if len(*bitbucketClient) == 0 || len(*bitbucketSecret) == 0 {
return
}
remote.Register(NewDefault(cli, sec))
remote.Register(
NewDefault(*bitbucketClient, *bitbucketSecret),
)
}

View file

@ -140,7 +140,7 @@ func (r *GitHub) GetRepos(user *model.User) ([]*model.Repo, error) {
Owner: *item.Owner.Login,
Name: *item.Name,
Private: *item.Private,
URL: *item.URL,
URL: *item.HTMLURL,
CloneURL: *item.GitURL,
GitURL: *item.GitURL,
SSHURL: *item.SSHURL,

View file

@ -1,41 +1,54 @@
package github
import (
"os"
"github.com/drone/config"
"github.com/drone/drone/plugin/remote"
)
func init() {
init_github()
init_github_enterprise()
var (
// GitHub cloud configuration details
githubClient = config.String("github-client", "")
githubSecret = config.String("github-secret", "")
// GitHub Enterprise configuration details
githubEnterpriseURL = config.String("github-enterprise-url", "")
githubEnterpriseAPI = config.String("github-enterprise-api", "")
githubEnterpriseClient = config.String("github-enterprise-client", "")
githubEnterpriseSecret = config.String("github-enterprise-secret", "")
)
// Registers the GitHub plugins using the default
// settings from the config file or environment
// variables.
func Register() {
registerGitHub()
registerGitHubEnterprise()
}
// registers the GitHub (github.com) plugin
func init_github() {
var cli = os.Getenv("GITHUB_CLIENT")
var sec = os.Getenv("GITHUB_SECRET")
if len(cli) == 0 ||
len(sec) == 0 {
func registerGitHub() {
if len(*githubClient) == 0 || len(*githubSecret) == 0 {
return
}
var github = NewDefault(cli, sec)
remote.Register(github)
remote.Register(
NewDefault(*githubClient, *githubSecret),
)
}
// registers the GitHub Enterprise plugin
func init_github_enterprise() {
var url = os.Getenv("GITHUB_ENTERPRISE_URL")
var api = os.Getenv("GITHUB_ENTERPRISE_API")
var cli = os.Getenv("GITHUB_ENTERPRISE_CLIENT")
var sec = os.Getenv("GITHUB_ENTERPRISE_SECRET")
if len(url) == 0 ||
len(api) == 0 ||
len(cli) == 0 ||
len(sec) == 0 {
func registerGitHubEnterprise() {
if len(*githubEnterpriseURL) == 0 ||
len(*githubEnterpriseAPI) == 0 ||
len(*githubEnterpriseClient) == 0 ||
len(*githubEnterpriseSecret) == 0 {
return
}
var github = New(url, api, cli, sec)
remote.Register(github)
remote.Register(
New(
*githubEnterpriseURL,
*githubEnterpriseAPI,
*githubEnterpriseClient,
*githubEnterpriseSecret,
),
)
}

View file

@ -1,16 +1,22 @@
package gitlab
import (
"os"
"github.com/drone/config"
"github.com/drone/drone/plugin/remote"
)
// registers the Gitlab plugin
func init() {
var url = os.Getenv("GITLAB_URL")
if len(url) == 0 {
var (
gitlabURL = config.String("gitlab-url", "")
)
// Registers the Gitlab plugin using the default
// settings from the config file or environment
// variables.
func Register() {
if len(*gitlabURL) == 0 {
return
}
remote.Register(New(url))
remote.Register(
New(*gitlabURL),
)
}

View file

@ -7,6 +7,7 @@ import (
"runtime"
"strings"
"github.com/drone/config"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/database/schema"
"github.com/drone/drone/server/handler"
@ -22,9 +23,9 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/russross/meddler"
_ "github.com/drone/drone/plugin/remote/bitbucket"
_ "github.com/drone/drone/plugin/remote/github"
_ "github.com/drone/drone/plugin/remote/gitlab"
"github.com/drone/drone/plugin/remote/bitbucket"
"github.com/drone/drone/plugin/remote/github"
"github.com/drone/drone/plugin/remote/gitlab"
)
var (
@ -49,12 +50,16 @@ var (
// Number of concurrent build workers to run
// default to number of CPUs on machine
workers int
conf string
prefix string
)
func main() {
log.SetPriority(log.LOG_NOTICE)
flag.StringVar(&conf, "config", "", "")
flag.StringVar(&prefix, "prefix", "DRONE_", "")
flag.StringVar(&port, "port", ":8080", "")
flag.StringVar(&driver, "driver", "sqlite3", "")
flag.StringVar(&datasource, "datasource", "drone.sqlite", "")
@ -63,6 +68,14 @@ func main() {
flag.IntVar(&workers, "workers", runtime.NumCPU(), "")
flag.Parse()
config.SetPrefix(prefix)
config.Parse(conf)
// setup the remote services
bitbucket.Register()
github.Register()
gitlab.Register()
// setup the database
meddler.Default = meddler.SQLite
db, _ := sql.Open(driver, datasource)
@ -147,23 +160,3 @@ func main() {
panic(http.ListenAndServe(port, nil))
}
}
func init() {
}
func init_flags() {
}
func init_database() {
}
func init_workers() {
}
func init_handlers() {
}