mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-23 00:46:30 +00:00
code to stream stdout to the browser
This commit is contained in:
parent
6375eaa552
commit
d000ca2918
9 changed files with 37 additions and 52 deletions
|
@ -31,6 +31,8 @@
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>
|
||||||
|
|
||||||
<!-- main javascript application -->
|
<!-- main javascript application -->
|
||||||
|
<script src="/scripts/line_formatter.js"></script>
|
||||||
|
<script src="/scripts/commit_updates.js"></script>
|
||||||
<script src="/scripts/app.js"></script>
|
<script src="/scripts/app.js"></script>
|
||||||
<script src="/scripts/controllers/conf.js"></script>
|
<script src="/scripts/controllers/conf.js"></script>
|
||||||
<script src="/scripts/controllers/home.js"></script>
|
<script src="/scripts/controllers/home.js"></script>
|
||||||
|
|
|
@ -213,11 +213,11 @@ app.controller("CommitController", function($scope, $http, $routeParams, stdout,
|
||||||
var name = $routeParams.name;
|
var name = $routeParams.name;
|
||||||
var branch = $routeParams.branch;
|
var branch = $routeParams.branch;
|
||||||
var commit = $routeParams.commit;
|
var commit = $routeParams.commit;
|
||||||
|
$scope.console='';
|
||||||
|
|
||||||
feed.subscribe(function(item) {
|
feed.subscribe(function(item) {
|
||||||
// if the
|
if (item.commit.sha == commit &&
|
||||||
if (item.commit.sha == commit
|
item.commit.branch == branch) {
|
||||||
&& item.commit.branch == branch) {
|
|
||||||
$scope.commit = item.commit;
|
$scope.commit = item.commit;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,15 +247,20 @@ app.controller("CommitController", function($scope, $http, $routeParams, stdout,
|
||||||
if (data.status!='Started' && data.status!='Pending') {
|
if (data.status!='Started' && data.status!='Pending') {
|
||||||
$http({method: 'GET', url: '/v1/repos/'+remote+'/'+owner+"/"+name+"/branches/"+branch+"/commits/"+commit+"/console"}).
|
$http({method: 'GET', url: '/v1/repos/'+remote+'/'+owner+"/"+name+"/branches/"+branch+"/commits/"+commit+"/console"}).
|
||||||
success(function(data, status, headers, config) {
|
success(function(data, status, headers, config) {
|
||||||
$scope.console = data;
|
var lineFormatter = new Drone.LineFormatter();
|
||||||
|
var el = document.querySelector('#output');
|
||||||
|
angular.element(el).append(lineFormatter.format(data));
|
||||||
}).
|
}).
|
||||||
error(function(data, status, headers, config) {
|
error(function(data, status, headers, config) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lineFormatter = new Drone.LineFormatter();
|
||||||
|
var el = document.querySelector('#output');
|
||||||
stdout.subscribe(data.id, function(out){
|
stdout.subscribe(data.id, function(out){
|
||||||
console.log(out);
|
angular.element(el).append(lineFormatter.format(out));
|
||||||
});
|
});
|
||||||
}).
|
}).
|
||||||
error(function(data, status, headers, config) {
|
error(function(data, status, headers, config) {
|
||||||
|
|
|
@ -3,49 +3,29 @@
|
||||||
if(typeof(Drone) === 'undefined') { Drone = {}; }
|
if(typeof(Drone) === 'undefined') { Drone = {}; }
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
Drone.CommitUpdates = function(socket) {
|
Drone.Console = function() {
|
||||||
if(typeof(socket) === "string") {
|
|
||||||
var url = [(window.location.protocol == 'https:' ? 'wss' : 'ws'),
|
|
||||||
'://',
|
|
||||||
window.location.host,
|
|
||||||
socket].join('')
|
|
||||||
this.socket = new WebSocket(url);
|
|
||||||
} else {
|
|
||||||
this.socket = socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lineFormatter = new Drone.LineFormatter();
|
this.lineFormatter = new Drone.LineFormatter();
|
||||||
this.attach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Drone.CommitUpdates.prototype = {
|
Drone.Console.prototype = {
|
||||||
lineBuffer: "",
|
lineBuffer: "",
|
||||||
autoFollow: false,
|
autoFollow: false,
|
||||||
|
|
||||||
startOutput: function(el) {
|
start: function(el) {
|
||||||
if(typeof(el) === 'string') {
|
if(typeof(el) === 'string') {
|
||||||
this.el = document.getElementById(el);
|
this.el = document.getElementById(el);
|
||||||
} else {
|
} else {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.reqId) {
|
this.update();
|
||||||
this.updateScreen();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
stopOutput: function() {
|
stop: function() {
|
||||||
this.stoppingRefresh = true;
|
this.stoppingRefresh = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
attach: function() {
|
update: function() {
|
||||||
this.socket.onopen = this.onOpen;
|
|
||||||
this.socket.onerror = this.onError;
|
|
||||||
this.socket.onmessage = this.onMessage.bind(this);
|
|
||||||
this.socket.onclose = this.onClose;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateScreen: function() {
|
|
||||||
if(this.lineBuffer.length > 0) {
|
if(this.lineBuffer.length > 0) {
|
||||||
this.el.innerHTML += this.lineBuffer;
|
this.el.innerHTML += this.lineBuffer;
|
||||||
this.lineBuffer = '';
|
this.lineBuffer = '';
|
||||||
|
@ -62,21 +42,8 @@ if(typeof(Drone) === 'undefined') { Drone = {}; }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpen: function() {
|
write: function(e) {
|
||||||
console.log('output websocket open');
|
|
||||||
},
|
|
||||||
|
|
||||||
onError: function(e) {
|
|
||||||
console.log('websocket error: ' + e);
|
|
||||||
},
|
|
||||||
|
|
||||||
onMessage: function(e) {
|
|
||||||
this.lineBuffer += this.lineFormatter.format(e.data);
|
this.lineBuffer += this.lineFormatter.format(e.data);
|
||||||
},
|
|
||||||
|
|
||||||
onClose: function(e) {
|
|
||||||
console.log('output websocket closed: ' + JSON.stringify(e));
|
|
||||||
window.location.reload();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ angular.module('app').service('stdout', ['$window', function($window) {
|
||||||
this.unsubscribe = function() {
|
this.unsubscribe = function() {
|
||||||
callback = undefined;
|
callback = undefined;
|
||||||
if (websocket != undefined) {
|
if (websocket != undefined) {
|
||||||
|
console.log('unsubscribing websocket at '+websocket.url);
|
||||||
websocket.close();
|
websocket.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,6 @@
|
||||||
<a href="#">{{ commit.sha | shortHash}}</a>
|
<a href="#">{{ commit.sha | shortHash}}</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<pre>{{ console }}</pre>
|
<pre id="output"></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -46,8 +46,6 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Printf("%#v", hook)
|
|
||||||
|
|
||||||
// fetch the repository from the database
|
// fetch the repository from the database
|
||||||
repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo)
|
repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -157,16 +158,19 @@ func (h *WsHandler) WsConsole(w http.ResponseWriter, r *http.Request) error {
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
err := ws.WriteMessage(websocket.TextMessage, data)
|
err := ws.WriteMessage(websocket.TextMessage, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println("websocket for commit %d closed. Err: %s", commitID, err)
|
||||||
ws.Close()
|
ws.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case <-sub.CloseNotify():
|
case <-sub.CloseNotify():
|
||||||
|
log.Println("websocket for commit %d closed by client", commitID)
|
||||||
ws.Close()
|
ws.Close()
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
err := ws.WriteMessage(websocket.PingMessage, []byte{})
|
err := ws.WriteMessage(websocket.PingMessage, []byte{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println("websocket for commit %d closed. Err: %s", commitID, err)
|
||||||
ws.Close()
|
ws.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pubsub
|
package pubsub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +48,9 @@ func (c *Channel) start() {
|
||||||
// if somehow we encounter a nil pointer or some
|
// if somehow we encounter a nil pointer or some
|
||||||
// other unexpected behavior.
|
// other unexpected behavior.
|
||||||
defer func() {
|
defer func() {
|
||||||
recover()
|
if r := recover(); r != nil {
|
||||||
|
log.Println("recoved from panic", r)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// timeout the channel after N duration
|
// timeout the channel after N duration
|
||||||
|
@ -63,6 +66,7 @@ func (c *Channel) start() {
|
||||||
case sub := <-c.unsubscribe:
|
case sub := <-c.unsubscribe:
|
||||||
delete(c.subscriptions, sub)
|
delete(c.subscriptions, sub)
|
||||||
close(sub.send)
|
close(sub.send)
|
||||||
|
log.Println("usubscribed to subscription")
|
||||||
|
|
||||||
case sub := <-c.subscribe:
|
case sub := <-c.subscribe:
|
||||||
c.subscriptions[sub] = true
|
c.subscriptions[sub] = true
|
||||||
|
@ -89,15 +93,18 @@ func (c *Channel) start() {
|
||||||
select {
|
select {
|
||||||
case sub.send <- msg:
|
case sub.send <- msg:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
//default:
|
||||||
sub.Close()
|
// log.Println("subscription closed in inner select")
|
||||||
|
// sub.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
|
log.Println("subscription's timedout channel received message")
|
||||||
c.Close()
|
c.Close()
|
||||||
|
|
||||||
case <-c.closed:
|
case <-c.closed:
|
||||||
|
log.Println("subscription's close channel received message")
|
||||||
c.stop()
|
c.stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -111,6 +118,7 @@ func replay(s *Subscription, history []interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Channel) stop() {
|
func (c *Channel) stop() {
|
||||||
|
log.Println("subscription stopped")
|
||||||
for sub := range c.subscriptions {
|
for sub := range c.subscriptions {
|
||||||
sub.Close()
|
sub.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,6 @@ var DefaultOpts = &Opts{
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConsoleOpts = &Opts{
|
var ConsoleOpts = &Opts{
|
||||||
Timeout: time.Minute * 60,
|
Timeout: time.Minute * 120,
|
||||||
Record: true,
|
Record: true,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue