mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-02-03 05:02:23 +00:00
integrated plugin model for remotes
This commit is contained in:
parent
91f7a63d21
commit
aa9a8f4878
30 changed files with 552 additions and 297 deletions
20
plugin/remote/bitbucket/init.go
Normal file
20
plugin/remote/bitbucket/init.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package bitbucket
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
func init() {
|
||||
remote.Register(model.RemoteBitbucket, plugin)
|
||||
}
|
||||
|
||||
func plugin(remote *model.Remote) remote.Remote {
|
||||
return &Bitbucket{
|
||||
URL: remote.URL,
|
||||
API: remote.API,
|
||||
Client: remote.Client,
|
||||
Secret: remote.Secret,
|
||||
Enabled: remote.Open,
|
||||
}
|
||||
}
|
21
plugin/remote/github/init.go
Normal file
21
plugin/remote/github/init.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
func init() {
|
||||
remote.Register(model.RemoteGithub, plugin)
|
||||
remote.Register(model.RemoteGithubEnterprise, plugin)
|
||||
}
|
||||
|
||||
func plugin(remote *model.Remote) remote.Remote {
|
||||
return &Github{
|
||||
URL: remote.URL,
|
||||
API: remote.API,
|
||||
Client: remote.Client,
|
||||
Secret: remote.Secret,
|
||||
Enabled: remote.Open,
|
||||
}
|
||||
}
|
17
plugin/remote/gitlab/init.go
Normal file
17
plugin/remote/gitlab/init.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
func init() {
|
||||
remote.Register(model.RemoteGitlab, plugin)
|
||||
}
|
||||
|
||||
func plugin(remote *model.Remote) remote.Remote {
|
||||
return &Gitlab{
|
||||
URL: remote.URL,
|
||||
Enabled: remote.Open,
|
||||
}
|
||||
}
|
|
@ -2,8 +2,27 @@ package remote
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
// Defines a model for integrating (or pluggin in) remote version
|
||||
// control systems, such as GitHub and Bitbucket.
|
||||
type Plugin func(*model.Remote) Remote
|
||||
|
||||
var plugins = map[string]Plugin{}
|
||||
|
||||
// Register registers a new plugin.
|
||||
func Register(name string, plugin Plugin) {
|
||||
plugins[name] = plugin
|
||||
}
|
||||
|
||||
// Lookup retrieves the plugin for the remote.
|
||||
func Lookup(name string) (Plugin, bool) {
|
||||
plugin, ok := plugins[name]
|
||||
return plugin, ok
|
||||
}
|
||||
|
||||
type Remote interface {
|
||||
// GetName returns the name of this remote system.
|
||||
GetName() string
|
||||
|
|
|
@ -42,11 +42,13 @@
|
|||
<script src="/scripts/controllers/setup.js"></script>
|
||||
<script src="/scripts/controllers/sync.js"></script>
|
||||
<script src="/scripts/controllers/main.js"></script>
|
||||
<script src="/scripts/controllers/login.js"></script>
|
||||
<script src="/scripts/services/auth.js"></script>
|
||||
<script src="/scripts/services/conf.js"></script>
|
||||
<script src="/scripts/services/repo.js"></script>
|
||||
<script src="/scripts/services/user.js"></script>
|
||||
<script src="/scripts/services/feed.js"></script>
|
||||
<script src="/scripts/services/remote.js"></script>
|
||||
<script src="/scripts/services/notify.js"></script>
|
||||
<script src="/scripts/services/stdout.js"></script>
|
||||
<script src="/scripts/filters/filters.js"></script>
|
||||
|
|
|
@ -23,6 +23,7 @@ app.config(['$routeProvider', '$locationProvider', function($routeProvider, $loc
|
|||
})
|
||||
.when('/login', {
|
||||
templateUrl: '/views/login.html',
|
||||
controller: 'LoginController',
|
||||
title: 'Login',
|
||||
})
|
||||
.when('/setup', {
|
||||
|
|
13
server/app/scripts/controllers/login.js
Normal file
13
server/app/scripts/controllers/login.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('app').controller("LoginController", function($scope, $http, remotes) {
|
||||
$scope.state=0
|
||||
$scope.user = remotes.getLogins().success(function (data) {
|
||||
$scope.remotes = (typeof data==="string")?[]:data;
|
||||
$scope.state = 1;
|
||||
})
|
||||
.error(function (error) {
|
||||
$scope.remotes = [];
|
||||
$scope.state = 1;
|
||||
});
|
||||
});
|
|
@ -1,14 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('app').controller("SetupController", function($scope, $http, $routeParams) {
|
||||
angular.module('app').controller("SetupController", function($scope, $http, $routeParams, $window) {
|
||||
|
||||
// create a remote that will be populated
|
||||
// and persisted to the database.
|
||||
$scope.remote = {};
|
||||
$scope.remote.type = $routeParams.remote;
|
||||
$scope.remote.register = true;
|
||||
$scope.remote.register = false;
|
||||
$scope.window = $window
|
||||
|
||||
// pre-populate the form if the remote
|
||||
// type is selected and is a cloud service
|
||||
// with a known URL and standard configuration.
|
||||
switch($scope.remote.type) {
|
||||
case undefined:
|
||||
case 'github.com':
|
||||
$scope.remote.type = "github.com"
|
||||
$scope.remote.url = "https://github.com";
|
||||
|
@ -26,7 +30,7 @@ angular.module('app').controller("SetupController", function($scope, $http, $rou
|
|||
success(function(data, status, headers, config) {
|
||||
delete $scope.failure;
|
||||
$scope.remote = data;
|
||||
console.log('success', $scope.remote);
|
||||
$window.location.href="/login/"+data.type;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
$scope.failure = data;
|
||||
|
|
|
@ -64,6 +64,31 @@ angular.module('app').filter('badgeMarkup', function() {
|
|||
}
|
||||
});
|
||||
|
||||
angular.module('app').filter('remoteName', function() {
|
||||
return function(name) {
|
||||
switch (name) {
|
||||
case 'gitlab.com' : return 'GitLab';
|
||||
case 'github.com' : return 'GitHub';
|
||||
case 'enterprise.github.com' : return 'GitHub Enterprise';
|
||||
case 'bitbucket.org' : return 'Bitbucket';
|
||||
case 'stash.atlassian.com' : return 'Atlassian Stash';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
angular.module('app').filter('remoteIcon', function() {
|
||||
return function(name) {
|
||||
switch (name) {
|
||||
case 'gitlab.com' : return 'fa-git-square';
|
||||
case 'github.com' : return 'fa-github-square';
|
||||
case 'enterprise.github.com' : return 'fa-github-square';
|
||||
case 'bitbucket.org' : return 'fa-bitbucket-square';
|
||||
case 'stash.atlassian.com' : return 'fa-bitbucket-square';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
angular.module('app').filter('unique', function() {
|
||||
return function(input, key) {
|
||||
var unique = {};
|
||||
|
|
13
server/app/scripts/services/remote.js
Normal file
13
server/app/scripts/services/remote.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
// Service facilitates interaction with the remote API.
|
||||
angular.module('app').service('remotes', ['$http', function($http) {
|
||||
|
||||
this.get = function() {
|
||||
return $http.get('/v1/remotes');
|
||||
};
|
||||
|
||||
this.getLogins = function() {
|
||||
return $http.get('/v1/logins');
|
||||
};
|
||||
}]);
|
|
@ -650,6 +650,7 @@ nav div.options .pure-button i {
|
|||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#setuppage .pure-g,
|
||||
#loginpage .pure-g {
|
||||
padding: 30px;
|
||||
border: 1px solid #DDD;
|
||||
|
@ -662,6 +663,7 @@ nav div.options .pure-button i {
|
|||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#setuppage .pure-g a,
|
||||
#loginpage .pure-g a {
|
||||
display: block;
|
||||
background: #45494b;
|
||||
|
@ -671,9 +673,11 @@ nav div.options .pure-button i {
|
|||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
}
|
||||
#setuppage .pure-g a:hover,
|
||||
#loginpage .pure-g a:hover {
|
||||
background: #262626;
|
||||
}
|
||||
#setuppage .pure-g [class*="fa-"],
|
||||
#loginpage .pure-g [class*="fa-"] {
|
||||
float: left;
|
||||
font-size: 20px;
|
||||
|
@ -684,12 +688,74 @@ nav div.options .pure-button i {
|
|||
min-width: 27px;
|
||||
min-height: 20px;
|
||||
}
|
||||
#setuppage .pure-g .pure-u-1 a,
|
||||
#loginpage .pure-g .pure-u-1 a {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#setuppage .pure-g .pure-u-1:last-child a,
|
||||
#loginpage .pure-g .pure-u-1:last-child a {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
#setuppage2 {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
#setuppage2 section {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#setuppage2 section .pure-g {
|
||||
padding: 30px;
|
||||
border: 1px solid #DDD;
|
||||
max-width: 400px;
|
||||
margin: 0px auto;
|
||||
margin-top: 50px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#setuppage2 section label {
|
||||
display: inline-block;
|
||||
}
|
||||
#setuppage2 section input[type='text'] {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
}
|
||||
#setuppage2 section .pure-button-primary {
|
||||
color: #FFF;
|
||||
background: #4ab1ce;
|
||||
padding: 10px 20px;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
#setuppage2 section .tip h2 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
#setuppage2 section .tip dd {
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
#setuppage2 section .tip dt {
|
||||
padding: .5em .6em;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
#syncpage {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -579,6 +579,7 @@ nav {
|
|||
}
|
||||
}
|
||||
|
||||
#setuppage,
|
||||
#loginpage {
|
||||
.pure-g {
|
||||
padding: 30px;
|
||||
|
@ -622,6 +623,57 @@ nav {
|
|||
}
|
||||
}
|
||||
|
||||
#setuppage2 {
|
||||
margin-bottom:50px;
|
||||
section {
|
||||
.border_box;
|
||||
.pure-g {
|
||||
padding: 30px;
|
||||
border: 1px solid #DDD;
|
||||
max-width:400px;
|
||||
margin:0px auto;
|
||||
margin-top:50px;
|
||||
.border_box;
|
||||
}
|
||||
label {
|
||||
display:inline-block;
|
||||
}
|
||||
input[type='text'] {
|
||||
margin-top:5px;
|
||||
margin-bottom:10px;
|
||||
box-shadow:none;
|
||||
width:100%;
|
||||
}
|
||||
.pure-button-primary {
|
||||
color:#FFF;
|
||||
background: @link2;
|
||||
padding:10px 20px;
|
||||
margin-top:20px;
|
||||
width:100%;
|
||||
}
|
||||
.tip {
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
dd {
|
||||
font-weight:bold;
|
||||
color:#666;
|
||||
margin-top:15px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
dt {
|
||||
padding: .5em .6em;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
.border_box;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#syncpage {
|
||||
width:100%;
|
||||
section {
|
||||
|
|
2
server/app/styles/drone.min.css
vendored
2
server/app/styles/drone.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -1,28 +1,14 @@
|
|||
<article id="loginpage">
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1">
|
||||
<a href="/login/github.com" target="_self">
|
||||
<i class="fa fa fa-github-square"></i> GitHub
|
||||
<div class="pure-u-1" ng-if="state == 1 && remotes.length != 0" ng-repeat="remote in remotes">
|
||||
<a href="/login/{{ remote.type }}" target="_self">
|
||||
<i class="fa {{ remote.type | remoteIcon }}"></i> {{ remote.type | remoteName }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/login/enterprise.github.com" target="_self">
|
||||
<i class="fa fa fa-github-square"></i> GitHub Enterprise
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/login/bitbucket.org" target="_self">
|
||||
<i class="fa fa fa-bitbucket-square"></i> Bitbucket
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/login/stash.atlassian.com" target="_self">
|
||||
<i class="fa fa fa-bitbucket-square"></i> Stash
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/login/gitlab.com" target="_self">
|
||||
<i class="fa fa fa-sign-in"></i> Gitlab
|
||||
|
||||
<div class="pure-u-1" ng-if="state == 1 && remotes.length == 0">
|
||||
<a href="/setup">
|
||||
<i class="fa fa-rocket"></i> Launch Setup Wizard
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,57 +1,105 @@
|
|||
<h1>First Time Setup</h1>
|
||||
<article id="setuppage" ng-if="remote.type == undefined">
|
||||
<nav>
|
||||
<a href="#"><span class="fa fa-th"></span></a>
|
||||
<a href="#">Choose a Remote System</a>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-3">
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td><a href="/setup/github.com">GitHub</a></td>
|
||||
<td><a href="/setup/enterprise.github.com">GitHub Enterprise</a></td>
|
||||
<td><a href="/setup/gitlab.com">Gitlab</a></td>
|
||||
<td><a href="/setup/bitbucket.org">Bitbucket</a></td>
|
||||
<td><a href="/setup/stash.atlassian.com">Stash</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- primary column -->
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
|
||||
<div>
|
||||
<label>Registration</label>
|
||||
<input type="radio" ng-model="remote.register" ng-value="true" />
|
||||
<input type="radio" ng-model="remote.register" ng-value="false" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>URL</label>
|
||||
<div ng-switch="remote.type">
|
||||
<input ng-switch-when="github.com" ng-model="remote.url" type="text" readonly />
|
||||
<input ng-switch-when="bitbucket.org" ng-model="remote.url" type="text" readonly />
|
||||
<input ng-switch-default ng-model="remote.url" type="text" />
|
||||
<section>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1">
|
||||
<a href="/setup/github.com">
|
||||
<i class="fa fa-github-square"></i> GitHub
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/setup/enterprise.github.com">
|
||||
<i class="fa fa-github-square"></i> GitHub Enterprise
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/setup/bitbucket.org">
|
||||
<i class="fa fa-bitbucket-square"></i> Bitbucket
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/setup/stash.atlassian.com">
|
||||
<i class="fa fa-bitbucket-square"></i> Atlassian Stash
|
||||
</a>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<a href="/setup/gitlab.com">
|
||||
<i class="fa fa-git-square"></i> GitLab
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<div ng-if="remote.type != 'gitlab.com'">
|
||||
<label>API</label>
|
||||
<div ng-switch="remote.type">
|
||||
<input ng-switch-when="github.com" ng-model="remote.api" type="text" readonly />
|
||||
<input ng-switch-when="bitbucket.org" ng-model="remote.api" type="text" readonly />
|
||||
<input ng-switch-default ng-model="remote.api" type="text" />
|
||||
<article ng-if="remote.type != undefined" id="setuppage2">
|
||||
<nav>
|
||||
<a href="/setup">
|
||||
<span class="fa fa-arrow-left"></span>
|
||||
</a>
|
||||
<a href="/setup">Configure {{ remote.type | remoteName }}</a>
|
||||
</nav>
|
||||
|
||||
<section ng-if-"remote.type == 'github.com' || remote.type == 'enterprise.github.com' ">
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 tip">
|
||||
<h2>Register with {{ remote.type | remoteName }}</h2>
|
||||
<dl>
|
||||
<dd>Homepage URL</dd>
|
||||
<dt>{{ window.location.protocol }}//{{ window.location.host }}</dt>
|
||||
</dl>
|
||||
<dl>
|
||||
<dd>Authorization callback URL</dd>
|
||||
<dt>{{ window.location.protocol }}//{{ window.location.host }}/login/{{ remote.type }}</dt>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div ng-if="remote.type != 'gitlab.com'">
|
||||
<label>Client</label>
|
||||
<input type="text" ng-model="remote.client" />
|
||||
</div>
|
||||
<section>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1">
|
||||
<div class="pure-form">
|
||||
<div ng-if="remote.type != 'github.com' && remote.type != 'bitbucket.org' ">
|
||||
<label>URL</label>
|
||||
<div ng-switch="remote.type">
|
||||
<input ng-switch-default ng-model="remote.url" type="text" placeholder="https://www.foo.com" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="remote.type != 'gitlab.com'">
|
||||
<label>Secret</label>
|
||||
<input type="text" ng-model="remote.secret" />
|
||||
</div>
|
||||
<div ng-if="remote.type != 'github.com' && remote.type != 'bitbucket.org' ">
|
||||
<label>API URL</label>
|
||||
<div ng-switch="remote.type">
|
||||
<input ng-switch-default ng-model="remote.api" type="text" placeholder="https://www.foo.com/api" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ng-click="save()">Save</button>
|
||||
<div ng-if="remote.type != 'gitlab.com'">
|
||||
<label>OAuth Client</label>
|
||||
<div>
|
||||
<input type="text" ng-model="remote.client" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="remote.type != 'gitlab.com'">
|
||||
<label>OAuth Secret</label>
|
||||
<div>
|
||||
<input type="text" ng-model="remote.secret" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toggle">
|
||||
<input type="checkbox" ng-model="remote.register" id="register" />
|
||||
<label for="register"></label>
|
||||
<span>Enable Self-Registration</span>
|
||||
</div>
|
||||
|
||||
<button ng-click="save()" class="pure-button pure-button-primary">Save and Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package database
|
||||
|
||||
/*
|
||||
import (
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/drone/drone/shared/model"
|
||||
|
@ -33,3 +34,4 @@ func NewConfigManager(filename string) ConfigManager {
|
|||
func (c *configManager) Find() *model.Config {
|
||||
return c.conf
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -14,6 +14,9 @@ type RemoteManager interface {
|
|||
// FindHost finds the Remote by hostname.
|
||||
FindHost(name string) (*model.Remote, error)
|
||||
|
||||
// FindHost finds the Remote by type.
|
||||
FindType(t string) (*model.Remote, error)
|
||||
|
||||
// List finds all registered Remotes of the system.
|
||||
List() ([]*model.Remote, error)
|
||||
|
||||
|
@ -40,10 +43,19 @@ WHERE remote_host=?
|
|||
LIMIT 1
|
||||
`
|
||||
|
||||
// SQL query to retrieve a Remote by remote login.
|
||||
const findRemoteTypeQuery = `
|
||||
SELECT *
|
||||
FROM remotes
|
||||
WHERE remote_type=?
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
// SQL query to retrieve a list of all Remotes.
|
||||
const listRemoteQuery = `
|
||||
SELECT *
|
||||
FROM remotes
|
||||
ORDER BY remote_type
|
||||
`
|
||||
|
||||
// SQL statement to delete a Remote by ID.
|
||||
|
@ -69,6 +81,12 @@ func (db *remoteManager) FindHost(host string) (*model.Remote, error) {
|
|||
return &dst, err
|
||||
}
|
||||
|
||||
func (db *remoteManager) FindType(t string) (*model.Remote, error) {
|
||||
dst := model.Remote{}
|
||||
err := meddler.QueryRow(db, &dst, findRemoteTypeQuery, t)
|
||||
return &dst, err
|
||||
}
|
||||
|
||||
func (db *remoteManager) List() ([]*model.Remote, error) {
|
||||
var dst []*model.Remote
|
||||
err := meddler.QueryAll(db, &dst, listRemoteQuery)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/session"
|
||||
"github.com/drone/drone/server/worker"
|
||||
"github.com/drone/drone/shared/httputil"
|
||||
"github.com/drone/drone/shared/model"
|
||||
"github.com/gorilla/pat"
|
||||
)
|
||||
|
@ -16,10 +16,10 @@ type CommitHandler struct {
|
|||
repos database.RepoManager
|
||||
commits database.CommitManager
|
||||
sess session.Session
|
||||
queue chan *worker.Request
|
||||
queue chan *model.Request
|
||||
}
|
||||
|
||||
func NewCommitHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue chan *worker.Request) *CommitHandler {
|
||||
func NewCommitHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue chan *model.Request) *CommitHandler {
|
||||
return &CommitHandler{perms, repos, commits, sess, queue}
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,8 @@ func (h *CommitHandler) PostCommit(w http.ResponseWriter, r *http.Request) error
|
|||
// drop the items on the queue
|
||||
// drop the items on the queue
|
||||
go func() {
|
||||
h.queue <- &worker.Request{
|
||||
h.queue <- &model.Request{
|
||||
Host: httputil.GetURL(r),
|
||||
Repo: repo,
|
||||
Commit: c,
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/session"
|
||||
"github.com/gorilla/pat"
|
||||
)
|
||||
|
||||
type ConfigHandler struct {
|
||||
conf database.ConfigManager
|
||||
sess session.Session
|
||||
}
|
||||
|
||||
func NewConfigHandler(conf database.ConfigManager, sess session.Session) *ConfigHandler {
|
||||
return &ConfigHandler{conf, sess}
|
||||
}
|
||||
|
||||
// GetConfig gets the system configuration details.
|
||||
// GET /api/config
|
||||
func (h *ConfigHandler) GetConfig(w http.ResponseWriter, r *http.Request) error {
|
||||
// get the user form the session
|
||||
user := h.sess.User(r)
|
||||
if user == nil || !user.Admin {
|
||||
return notAuthorized{}
|
||||
}
|
||||
|
||||
return json.NewEncoder(w).Encode(h.conf.Find())
|
||||
}
|
||||
|
||||
func (h *ConfigHandler) Register(r *pat.Router) {
|
||||
r.Get("/v1/config", errorHandler(h.GetConfig))
|
||||
}
|
|
@ -3,8 +3,9 @@ package handler
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/worker"
|
||||
"github.com/drone/drone/shared/httputil"
|
||||
"github.com/drone/drone/shared/model"
|
||||
"github.com/gorilla/pat"
|
||||
)
|
||||
|
@ -13,12 +14,12 @@ type HookHandler struct {
|
|||
users database.UserManager
|
||||
repos database.RepoManager
|
||||
commits database.CommitManager
|
||||
conf database.ConfigManager
|
||||
queue chan *worker.Request
|
||||
remotes database.RemoteManager
|
||||
queue chan *model.Request
|
||||
}
|
||||
|
||||
func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf database.ConfigManager, queue chan *worker.Request) *HookHandler {
|
||||
return &HookHandler{users, repos, commits, conf, queue}
|
||||
func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, remotes database.RemoteManager, queue chan *model.Request) *HookHandler {
|
||||
return &HookHandler{users, repos, commits, remotes, queue}
|
||||
}
|
||||
|
||||
// PostHook receives a post-commit hook from GitHub, Bitbucket, etc
|
||||
|
@ -26,14 +27,21 @@ func NewHookHandler(users database.UserManager, repos database.RepoManager, comm
|
|||
func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
|
||||
host := r.FormValue(":host")
|
||||
|
||||
// get the remote system's client.
|
||||
remote := h.conf.Find().GetRemote(host)
|
||||
if remote == nil {
|
||||
remoteServer, err := h.remotes.FindType(host)
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
|
||||
remotePlugin, ok := remote.Lookup(remoteServer.Type)
|
||||
if !ok {
|
||||
return notFound{}
|
||||
}
|
||||
|
||||
// get the remote system's client.
|
||||
plugin := remotePlugin(remoteServer)
|
||||
|
||||
// parse the hook payload
|
||||
hook, err := remote.GetHook(r)
|
||||
hook, err := plugin.GetHook(r)
|
||||
if err != nil {
|
||||
return badRequest{err}
|
||||
}
|
||||
|
@ -47,7 +55,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// fetch the repository from the database
|
||||
repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo)
|
||||
repo, err := h.repos.FindName(plugin.GetHost(), hook.Owner, hook.Repo)
|
||||
if err != nil {
|
||||
return notFound{}
|
||||
}
|
||||
|
@ -66,7 +74,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// featch the .drone.yml file from the database
|
||||
client := remote.GetClient(user.Access, user.Secret)
|
||||
client := plugin.GetClient(user.Access, user.Secret)
|
||||
yml, err := client.GetScript(hook)
|
||||
if err != nil {
|
||||
return badRequest{err}
|
||||
|
@ -91,7 +99,8 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
|
|||
|
||||
// drop the items on the queue
|
||||
go func() {
|
||||
h.queue <- &worker.Request{
|
||||
h.queue <- &model.Request{
|
||||
Host: httputil.GetURL(r),
|
||||
Repo: repo,
|
||||
Commit: &c,
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/session"
|
||||
"github.com/drone/drone/shared/model"
|
||||
|
@ -15,12 +16,13 @@ type LoginHandler struct {
|
|||
users database.UserManager
|
||||
repos database.RepoManager
|
||||
perms database.PermManager
|
||||
conf database.ConfigManager
|
||||
sess session.Session
|
||||
//conf database.ConfigManager
|
||||
sess session.Session
|
||||
remotes database.RemoteManager
|
||||
}
|
||||
|
||||
func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session, conf database.ConfigManager) *LoginHandler {
|
||||
return &LoginHandler{users, repos, perms, conf, sess}
|
||||
func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session /*conf database.ConfigManager,*/, remotes database.RemoteManager) *LoginHandler {
|
||||
return &LoginHandler{users, repos, perms /*conf,*/, sess, remotes}
|
||||
}
|
||||
|
||||
// GetLogin gets the login to the 3rd party remote system.
|
||||
|
@ -29,14 +31,21 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
|
|||
host := r.FormValue(":host")
|
||||
redirect := "/"
|
||||
|
||||
// get the remote system's client.
|
||||
remote := h.conf.Find().GetRemote(host)
|
||||
if remote == nil {
|
||||
remoteServer, err := h.remotes.FindType(host)
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
|
||||
remotePlugin, ok := remote.Lookup(remoteServer.Type)
|
||||
if !ok {
|
||||
return notFound{}
|
||||
}
|
||||
|
||||
// get the remote system's client.
|
||||
plugin := remotePlugin(remoteServer)
|
||||
|
||||
// authenticate the user
|
||||
login, err := remote.GetLogin(w, r)
|
||||
login, err := plugin.GetLogin(w, r)
|
||||
if err != nil {
|
||||
return badRequest{err}
|
||||
} else if login == nil {
|
||||
|
@ -51,12 +60,12 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
|
|||
// if self-registration is disabled we should
|
||||
// return a notAuthorized error. the only exception
|
||||
// is if no users exist yet in the system we'll proceed.
|
||||
if h.conf.Find().Registration == false && h.users.Exist() {
|
||||
if remoteServer.Open == false && h.users.Exist() {
|
||||
return notAuthorized{}
|
||||
}
|
||||
|
||||
// create the user account
|
||||
u = model.NewUser(remote.GetName(), login.Login, login.Email)
|
||||
u = model.NewUser(plugin.GetName(), login.Login, login.Email)
|
||||
u.Name = login.Name
|
||||
u.SetEmail(login.Email)
|
||||
|
||||
|
@ -102,7 +111,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
|
|||
// its own package / sync utility.
|
||||
go func() {
|
||||
// list all repositories
|
||||
client := remote.GetClient(u.Access, u.Secret)
|
||||
client := plugin.GetClient(u.Access, u.Secret)
|
||||
repos, err := client.GetRepos("")
|
||||
if err != nil {
|
||||
log.Println("Error syncing user account, listing repositories", u.Login, err)
|
||||
|
@ -111,7 +120,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
|
|||
|
||||
// insert all repositories
|
||||
for _, remoteRepo := range repos {
|
||||
repo, _ := model.NewRepo(remote.GetName(), remoteRepo.Owner, remoteRepo.Name)
|
||||
repo, _ := model.NewRepo(plugin.GetName(), remoteRepo.Owner, remoteRepo.Name)
|
||||
repo.Private = remoteRepo.Private
|
||||
repo.Host = remoteRepo.Host
|
||||
repo.CloneURL = remoteRepo.Clone
|
||||
|
@ -131,13 +140,13 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
log.Println("Successfully syced repo.", u.Login+"/"+remoteRepo.Name)
|
||||
}
|
||||
|
||||
u.Synced = time.Now().Unix()
|
||||
u.Syncing = false
|
||||
if err := h.users.Update(u); err != nil {
|
||||
log.Println("Error syncing user account, updating sync date", u.Login, err)
|
||||
return
|
||||
}
|
||||
u.Synced = time.Now().UTC().Unix()
|
||||
u.Syncing = false
|
||||
if err := h.users.Update(u); err != nil {
|
||||
log.Println("Error syncing user account, updating sync date", u.Login, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -38,6 +38,23 @@ func (h *RemoteHandler) GetRemotes(w http.ResponseWriter, r *http.Request) error
|
|||
return json.NewEncoder(w).Encode(remotes)
|
||||
}
|
||||
|
||||
// GetRemoteLogins gets all remote logins.
|
||||
// GET /api/remotes/logins
|
||||
func (h *RemoteHandler) GetRemoteLogins(w http.ResponseWriter, r *http.Request) error {
|
||||
remotes, err := h.remotes.List()
|
||||
if err != nil {
|
||||
return internalServerError{err}
|
||||
}
|
||||
var logins []interface{}
|
||||
for _, remote := range remotes {
|
||||
logins = append(logins, struct {
|
||||
Type string `json:"type"`
|
||||
Host string `json:"host"`
|
||||
}{remote.Type, remote.Host})
|
||||
}
|
||||
return json.NewEncoder(w).Encode(&logins)
|
||||
}
|
||||
|
||||
// PostRemote creates a new remote.
|
||||
// POST /api/remotes
|
||||
func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error {
|
||||
|
@ -57,7 +74,6 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error
|
|||
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
|
||||
return badRequest{err}
|
||||
}
|
||||
|
||||
uri, err := url.Parse(in.URL)
|
||||
if err != nil {
|
||||
return badRequest{err}
|
||||
|
@ -65,7 +81,8 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error
|
|||
in.Host = uri.Host
|
||||
|
||||
// there is an edge case where, during installation, a user could attempt
|
||||
// to add the same result multiple times.
|
||||
// to add the same result multiple times. In this case we will delete
|
||||
// the old remote prior to adding the new one.
|
||||
if remote, err := h.remotes.FindHost(in.Host); err == nil && h.users.Exist() {
|
||||
h.remotes.Delete(remote)
|
||||
}
|
||||
|
@ -78,31 +95,50 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error
|
|||
return json.NewEncoder(w).Encode(&in)
|
||||
}
|
||||
|
||||
// DeleteRemote delete the remote.
|
||||
// GET /api/remotes/:name
|
||||
func (h *RemoteHandler) DeleteRemote(w http.ResponseWriter, r *http.Request) error {
|
||||
host := r.FormValue(":host")
|
||||
|
||||
// PutRemote updates an existing remote.
|
||||
// PUT /api/remotes
|
||||
func (h *RemoteHandler) PutRemote(w http.ResponseWriter, r *http.Request) error {
|
||||
// get the user form the session
|
||||
user := h.sess.User(r)
|
||||
if user == nil || !user.Admin {
|
||||
return notAuthorized{}
|
||||
}
|
||||
// get the remote
|
||||
remote, err := h.remotes.FindHost(host)
|
||||
// unmarshal the remote from the payload
|
||||
defer r.Body.Close()
|
||||
in := model.Remote{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
|
||||
return badRequest{err}
|
||||
}
|
||||
uri, err := url.Parse(in.URL)
|
||||
if err != nil {
|
||||
return badRequest{err}
|
||||
}
|
||||
in.Host = uri.Host
|
||||
|
||||
// retrieve the remote and return an error if not exists
|
||||
remote, err := h.remotes.FindHost(in.Host)
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
if err := h.remotes.Delete(remote); err != nil {
|
||||
|
||||
// update the remote details
|
||||
remote.API = in.API
|
||||
remote.URL = in.URL
|
||||
remote.Host = in.Host
|
||||
remote.Client = in.Client
|
||||
remote.Secret = in.Secret
|
||||
|
||||
// insert the remote in the database
|
||||
if err := h.remotes.Update(remote); err != nil {
|
||||
return internalServerError{err}
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return nil
|
||||
return json.NewEncoder(w).Encode(remote)
|
||||
}
|
||||
|
||||
func (h *RemoteHandler) Register(r *pat.Router) {
|
||||
r.Delete("/v1/remotes/:name", errorHandler(h.DeleteRemote))
|
||||
r.Post("/v1/remotes", errorHandler(h.PostRemote))
|
||||
r.Get("/v1/logins", errorHandler(h.GetRemoteLogins))
|
||||
r.Get("/v1/remotes", errorHandler(h.GetRemotes))
|
||||
r.Post("/v1/remotes", errorHandler(h.PostRemote))
|
||||
r.Put("/v1/remotes", errorHandler(h.PutRemote))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/session"
|
||||
"github.com/drone/drone/shared/httputil"
|
||||
|
@ -14,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
type RepoHandler struct {
|
||||
conf database.ConfigManager
|
||||
remotes database.RemoteManager
|
||||
commits database.CommitManager
|
||||
perms database.PermManager
|
||||
repos database.RepoManager
|
||||
|
@ -22,8 +23,8 @@ type RepoHandler struct {
|
|||
}
|
||||
|
||||
func NewRepoHandler(repos database.RepoManager, commits database.CommitManager,
|
||||
perms database.PermManager, sess session.Session, conf database.ConfigManager) *RepoHandler {
|
||||
return &RepoHandler{conf, commits, perms, repos, sess}
|
||||
perms database.PermManager, sess session.Session, remotes database.RemoteManager) *RepoHandler {
|
||||
return &RepoHandler{remotes, commits, perms, repos, sess}
|
||||
}
|
||||
|
||||
// GetRepo gets the named repository.
|
||||
|
@ -105,16 +106,24 @@ func (h *RepoHandler) PostRepo(w http.ResponseWriter, r *http.Request) error {
|
|||
repo.PrivateKey = sshutil.MarshalPrivateKey(key)
|
||||
|
||||
// get the remote and client
|
||||
remote := h.conf.Find().GetRemote(host)
|
||||
if remote == nil {
|
||||
remoteServer, err := h.remotes.FindType(repo.Remote)
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
|
||||
remotePlugin, ok := remote.Lookup(remoteServer.Type)
|
||||
if !ok {
|
||||
return notFound{}
|
||||
}
|
||||
|
||||
// get the remote system's client.
|
||||
plugin := remotePlugin(remoteServer)
|
||||
|
||||
// post commit hook url
|
||||
hook := fmt.Sprintf("%s://%s/v1/hook/%s", httputil.GetScheme(r), httputil.GetHost(r), remote.GetName())
|
||||
hook := fmt.Sprintf("%s://%s/v1/hook/%s", httputil.GetScheme(r), httputil.GetHost(r), plugin.GetName())
|
||||
|
||||
// activate the repository in the remote system
|
||||
client := remote.GetClient(user.Access, user.Secret)
|
||||
client := plugin.GetClient(user.Access, user.Secret)
|
||||
if err := client.SetActive(owner, name, hook, repo.PublicKey); err != nil {
|
||||
return badRequest{err}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/drone/drone/server/database"
|
||||
"github.com/drone/drone/server/pubsub"
|
||||
"github.com/drone/drone/server/session"
|
||||
"github.com/drone/drone/server/worker"
|
||||
"github.com/drone/drone/shared/model"
|
||||
"github.com/gorilla/pat"
|
||||
|
||||
|
@ -72,7 +71,7 @@ func (h *WsHandler) WsUser(w http.ResponseWriter, r *http.Request) error {
|
|||
for {
|
||||
select {
|
||||
case msg := <-sub.Read():
|
||||
work, ok := msg.(*worker.Request)
|
||||
work, ok := msg.(*model.Request)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
@ -203,7 +202,7 @@ func readWebsocket(ws *websocket.Conn) {
|
|||
// will be removed prior to release
|
||||
func (h *WsHandler) Ping(w http.ResponseWriter, r *http.Request) error {
|
||||
channel := h.pubsub.Register("_global")
|
||||
msg := worker.Request{
|
||||
msg := model.Request{
|
||||
Repo: &model.Repo{ID: 1, Private: false, Host: "github.com", Owner: "drone", Name: "drone"},
|
||||
Commit: &model.Commit{ID: 1, Status: "Started", Branch: "master", Sha: "113f4917ff9174945388d86395f902cd154074cb", Message: "Remove branches by SCM hook", Author: "bradrydzewski", Gravatar: "8c58a0be77ee441bb8f8595b7f1b4e87"},
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ import (
|
|||
"github.com/GeertJohan/go.rice"
|
||||
_ "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"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -79,7 +83,7 @@ func main() {
|
|||
commits := database.NewCommitManager(db)
|
||||
servers := database.NewServerManager(db)
|
||||
remotes := database.NewRemoteManager(db)
|
||||
configs := database.NewConfigManager(filepath.Join(home, "config.toml"))
|
||||
//configs := database.NewConfigManager(filepath.Join(home, "config.toml"))
|
||||
|
||||
// message broker
|
||||
pubsub := pubsub.NewPubSub()
|
||||
|
@ -87,10 +91,10 @@ func main() {
|
|||
// cancel all previously running builds
|
||||
go commits.CancelAll()
|
||||
|
||||
queue := make(chan *worker.Request)
|
||||
workers := make(chan chan *worker.Request)
|
||||
queue := make(chan *model.Request)
|
||||
workers := make(chan chan *model.Request)
|
||||
worker.NewDispatch(queue, workers).Start()
|
||||
worker.NewWorker(workers, users, repos, commits, configs, pubsub, &model.Server{}).Start()
|
||||
worker.NewWorker(workers, users, repos, commits, pubsub, &model.Server{}).Start()
|
||||
|
||||
// setup the session managers
|
||||
sess := session.NewSession(users)
|
||||
|
@ -99,13 +103,13 @@ func main() {
|
|||
router := pat.New()
|
||||
handler.NewUsersHandler(users, sess).Register(router)
|
||||
handler.NewUserHandler(users, repos, commits, sess).Register(router)
|
||||
handler.NewHookHandler(users, repos, commits, configs, queue).Register(router)
|
||||
handler.NewLoginHandler(users, repos, perms, sess, configs).Register(router)
|
||||
handler.NewHookHandler(users, repos, commits, remotes, queue).Register(router)
|
||||
handler.NewLoginHandler(users, repos, perms, sess, remotes).Register(router)
|
||||
handler.NewCommitHandler(repos, commits, perms, sess, queue).Register(router)
|
||||
handler.NewBranchHandler(repos, commits, perms, sess).Register(router)
|
||||
handler.NewRepoHandler(repos, commits, perms, sess, configs).Register(router)
|
||||
handler.NewRepoHandler(repos, commits, perms, sess, remotes).Register(router)
|
||||
handler.NewBadgeHandler(repos, commits).Register(router)
|
||||
handler.NewConfigHandler(configs, sess).Register(router)
|
||||
//handler.NewConfigHandler(configs, sess).Register(router)
|
||||
handler.NewServerHandler(servers, sess).Register(router)
|
||||
handler.NewRemoteHandler(users, remotes, sess).Register(router)
|
||||
handler.NewWsHandler(repos, commits, perms, sess, pubsub).Register(router)
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
// http://nesv.github.io/golang/2014/02/25/worker-queues-in-go.html
|
||||
|
||||
type Dispatch struct {
|
||||
requests chan *Request
|
||||
workers chan chan *Request
|
||||
requests chan *model.Request
|
||||
workers chan chan *model.Request
|
||||
quit chan bool
|
||||
}
|
||||
|
||||
func NewDispatch(requests chan *Request, workers chan chan *Request) *Dispatch {
|
||||
func NewDispatch(requests chan *model.Request, workers chan chan *model.Request) *Dispatch {
|
||||
return &Dispatch{
|
||||
requests: requests,
|
||||
workers: workers,
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
User *model.User `json:"-"`
|
||||
Repo *model.Repo `json:"repo"`
|
||||
Commit *model.Commit `json:"commit"`
|
||||
server *model.Server
|
||||
}
|
|
@ -24,25 +24,25 @@ type worker struct {
|
|||
users database.UserManager
|
||||
repos database.RepoManager
|
||||
commits database.CommitManager
|
||||
config database.ConfigManager
|
||||
pubsub *pubsub.PubSub
|
||||
server *model.Server
|
||||
//config database.ConfigManager
|
||||
pubsub *pubsub.PubSub
|
||||
server *model.Server
|
||||
|
||||
request chan *Request
|
||||
dispatch chan chan *Request
|
||||
request chan *model.Request
|
||||
dispatch chan chan *model.Request
|
||||
quit chan bool
|
||||
}
|
||||
|
||||
func NewWorker(dispatch chan chan *Request, users database.UserManager, repos database.RepoManager, commits database.CommitManager, config database.ConfigManager, pubsub *pubsub.PubSub, server *model.Server) Worker {
|
||||
func NewWorker(dispatch chan chan *model.Request, users database.UserManager, repos database.RepoManager, commits database.CommitManager /*config database.ConfigManager,*/, pubsub *pubsub.PubSub, server *model.Server) Worker {
|
||||
return &worker{
|
||||
users: users,
|
||||
repos: repos,
|
||||
commits: commits,
|
||||
config: config,
|
||||
users: users,
|
||||
repos: repos,
|
||||
commits: commits,
|
||||
//config: config,
|
||||
pubsub: pubsub,
|
||||
server: server,
|
||||
dispatch: dispatch,
|
||||
request: make(chan *Request),
|
||||
request: make(chan *model.Request),
|
||||
quit: make(chan bool),
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ func (w *worker) Start() {
|
|||
select {
|
||||
case r := <-w.request:
|
||||
// handle the request
|
||||
r.server = w.server
|
||||
r.Server = w.server
|
||||
w.Execute(r)
|
||||
|
||||
case <-w.quit:
|
||||
|
@ -78,7 +78,7 @@ func (w *worker) Stop() {
|
|||
// Execute executes the work Request, persists the
|
||||
// results to the database, and sends event messages
|
||||
// to the pubsub (for websocket updates on the website).
|
||||
func (w *worker) Execute(r *Request) {
|
||||
func (w *worker) Execute(r *model.Request) {
|
||||
// mark the build as Started and update the database
|
||||
r.Commit.Status = model.StatusStarted
|
||||
r.Commit.Started = time.Now().UTC().Unix()
|
||||
|
@ -123,6 +123,11 @@ func (w *worker) Execute(r *Request) {
|
|||
dockerClient = docker.NewHost(w.server.Host)
|
||||
}
|
||||
|
||||
// send all "started" notifications
|
||||
if script.Notifications != nil {
|
||||
script.Notifications.Send(r)
|
||||
}
|
||||
|
||||
// create an instance of the Docker builder
|
||||
builder := build.New(dockerClient)
|
||||
builder.Build = script
|
||||
|
@ -162,5 +167,9 @@ func (w *worker) Execute(r *Request) {
|
|||
|
||||
// todo(bradrydzewski) update github status API
|
||||
// todo(bradrydzewski) send email notifications
|
||||
// todo(bradrydzewski) send other notifications
|
||||
|
||||
// send all "finished" notifications
|
||||
if script.Notifications != nil {
|
||||
script.Notifications.Send(r)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/plugin/remote"
|
||||
"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/stash"
|
||||
"github.com/drone/drone/plugin/smtp"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// Hostname of the server, eg drone.io
|
||||
//Host string `json:"host"`
|
||||
|
||||
// Scheme of the server, eg https
|
||||
//Scheme string `json:"scheme"`
|
||||
|
||||
// Registration with a value of True allows developers
|
||||
// to register themselves. If false, must be approved
|
||||
// or invited by the system administrator.
|
||||
Registration bool `json:"registration"`
|
||||
|
||||
// SMTP stores configuration details for connecting with
|
||||
// and smtp server to send email notifications.
|
||||
SMTP *smtp.SMTP `json:"smtp"`
|
||||
|
||||
// Bitbucket stores configuration details for communicating
|
||||
// with the bitbucket.org public cloud service.
|
||||
Bitbucket *bitbucket.Bitbucket `json:"bitbucket"`
|
||||
|
||||
// Github stores configuration details for communicating
|
||||
// with the github.com public cloud service.
|
||||
Github *github.Github `json:"github"`
|
||||
|
||||
// GithubEnterprise stores configuration details for
|
||||
// communicating with a private Github installation.
|
||||
GithubEnterprise *github.Github `json:"githubEnterprise"`
|
||||
|
||||
// Gitlab stores configuration details for communicating
|
||||
// with a private gitlab installation.
|
||||
Gitlab *gitlab.Gitlab `json:"gitlab"`
|
||||
|
||||
// Stash stores configuration details for communicating
|
||||
// with a private Atlassian Stash installation.
|
||||
Stash *stash.Stash `json:"stash"`
|
||||
}
|
||||
|
||||
// GetRemote is a helper function that will return the
|
||||
// remote plugin name based on the specified hostname.
|
||||
func (c *Config) GetRemote(name string) remote.Remote {
|
||||
// first attempt to get the remote instance
|
||||
// by the unique plugin name (ie enterprise.github.com)
|
||||
switch name {
|
||||
case c.Github.GetName():
|
||||
return c.Github
|
||||
case c.Bitbucket.GetName():
|
||||
return c.Bitbucket
|
||||
case c.GithubEnterprise.GetName():
|
||||
return c.GithubEnterprise
|
||||
case c.Gitlab.GetName():
|
||||
return c.Gitlab
|
||||
case c.Stash.GetName():
|
||||
return c.Stash
|
||||
}
|
||||
|
||||
// else attempt to get the remote instance
|
||||
// by the hostname (ie github.drone.io)
|
||||
switch {
|
||||
case c.Github.IsMatch(name):
|
||||
return c.Github
|
||||
case c.Bitbucket.IsMatch(name):
|
||||
return c.Bitbucket
|
||||
case c.GithubEnterprise.IsMatch(name):
|
||||
return c.GithubEnterprise
|
||||
case c.Gitlab.IsMatch(name):
|
||||
return c.Gitlab
|
||||
case c.Stash.IsMatch(name):
|
||||
return c.Stash
|
||||
}
|
||||
|
||||
// else none found
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetClient is a helper function taht will return the named
|
||||
// remote plugin client, used to interact with the remote system.
|
||||
func (c *Config) GetClient(name, access, secret string) remote.Client {
|
||||
remote := c.GetRemote(name)
|
||||
if remote == nil {
|
||||
return nil
|
||||
}
|
||||
return remote.GetClient(access, secret)
|
||||
}
|
9
shared/model/request.go
Normal file
9
shared/model/request.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package model
|
||||
|
||||
type Request struct {
|
||||
Host string `json:"-"`
|
||||
User *User `json:"-"`
|
||||
Repo *Repo `json:"repo"`
|
||||
Commit *Commit `json:"commit"`
|
||||
Server *Server `json:"-"`
|
||||
}
|
Loading…
Reference in a new issue