From 5acc8bcbe0637790cbb90a73c97813ad08ada85b Mon Sep 17 00:00:00 2001 From: Philip Thomas Date: Fri, 22 May 2015 18:10:10 +0200 Subject: [PATCH 1/2] Refactored scaffolding. Add checkbox to disable ansii converting. --- client/.gitignore | 1 + client/gulpfile.js | 99 +++++++++ client/js/app.js | 22 ++ client/js/config.js | 27 +++ client/js/controller/ContainersCtrl.js | 11 + client/js/controller/DeployTabCtrl.js | 20 ++ client/js/controller/HeaderCtrl.js | 14 ++ client/js/controller/LogTabCtrl.js | 50 +++++ client/js/controller/ProjectsCtrl.js | 110 ++++++++++ client/js/factory/Socket.js | 45 ++++ client/js/filter/Unsafe.js | 8 + client/package.json | 20 ++ http/static/app.css | 9 + http/static/app.js | 283 +------------------------ http/static/app.js.map | 1 + http/static/index.html | 16 +- 16 files changed, 450 insertions(+), 286 deletions(-) create mode 100644 client/.gitignore create mode 100644 client/gulpfile.js create mode 100644 client/js/app.js create mode 100644 client/js/config.js create mode 100644 client/js/controller/ContainersCtrl.js create mode 100644 client/js/controller/DeployTabCtrl.js create mode 100644 client/js/controller/HeaderCtrl.js create mode 100644 client/js/controller/LogTabCtrl.js create mode 100644 client/js/controller/ProjectsCtrl.js create mode 100644 client/js/factory/Socket.js create mode 100644 client/js/filter/Unsafe.js create mode 100644 client/package.json create mode 100644 http/static/app.js.map diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/client/gulpfile.js b/client/gulpfile.js new file mode 100644 index 0000000..1e12806 --- /dev/null +++ b/client/gulpfile.js @@ -0,0 +1,99 @@ +var gulp = require('gulp'); +var gutil = require('gulp-util'); +var browserify = require('browserify'); +var watchify = require('watchify'); +var source = require('vinyl-source-stream'); +var buffer = require('vinyl-buffer'); +var uglify = require('gulp-uglify'); +var sourcemaps = require('gulp-sourcemaps'); +var clean = require('gulp-clean'); +var debug = require('gulp-debug'); +var compass = require('gulp-compass'); +var minifyCSS = require('gulp-minify-css'); +var plumber = require('gulp-plumber'); +var filter = require('gulp-filter'); + +var SASS_CACHE = './.sass-cache'; +var SCSS_ENTRY = './src/assets/scss/style.scss'; +var BUILD_DIR = './../http/static'; +var SRC_DIR = './js'; +var JS_APP_FILE = 'app.js'; + +var executeJsPipeline = function (stream) { + return stream + .bundle() + .pipe(source(JS_APP_FILE)) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true})) + .pipe(uglify()) + .on('error', gutil.log) + .pipe(sourcemaps.write('./', { + sourceRoot: '../src/js' + })) + .pipe(gulp.dest(BUILD_DIR)); +}; + +gulp.task('javascript', function () { + var bundler = browserify({ + entries: SRC_DIR + '/' + JS_APP_FILE, + debug: true + }); + + return executeJsPipeline(bundler); +}); + +gulp.task('watch-js', function() { + var bundler = browserify({ + entries: SRC_DIR + '/' + JS_APP_FILE, + debug: true + }); + var watcher = watchify(bundler); + + watcher + .on('update', function () { + var updateStart = Date.now(); + console.log('Updating...'); + executeJsPipeline(watcher).on('end', function () { + console.log((new Date()).toTimeString().split(' ')[0] + ' Updated!', (Date.now() - updateStart) + 'ms'); + }); + }); + + console.log('Building and generating cache for watcher!'); + executeJsPipeline(watcher).on('end', function () { + console.log((new Date()).toTimeString().split(' ')[0] + ' Finished cache generation!'); + }); + console.log('Watcher running...'); + + return watcher; +}); + +// Compile .scss files to plain .js in tmp/. +gulp.task('css', function () { + gutil.log(gutil.colors.yellow('Building CSS from SCSS')); + return gulp.src(SCSS_ENTRY) + .pipe(sourcemaps.init()) + .pipe(plumber({ + errorHandler: function (error) { + console.log(error.message); + this.emit('end'); + }})) + .pipe(compass({ + config_file: './config.rb', + css: BUILD_DIR, + sass: 'src/assets/scss' + })) + .on('error', function(err) { + console.log(err); + }) + .pipe(minifyCSS()) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest(BUILD_DIR)); +}); + +gulp.task('build', ['javascript', 'css'], function () { + gutil.log(gutil.colors.yellow('Removing temporary files & folders.')); + return gulp.src(SASS_CACHE) + .pipe(clean()); +}); + +gulp.task('default', ['build']); \ No newline at end of file diff --git a/client/js/app.js b/client/js/app.js new file mode 100644 index 0000000..98945c0 --- /dev/null +++ b/client/js/app.js @@ -0,0 +1,22 @@ +angular.module('dockership', [ + 'ui.bootstrap', + 'angular-loading-bar', + 'ansiToHtml', + 'ngAnimate', + 'bd.sockjs', + 'headroom', + 'dialogs.main', + 'notification' +]).run(['$templateCache', function ($templateCache) { + $templateCache.put('template/popover/popover.html', + '
' + + '
' + + '
' + + '

' + + '
' + + '
' + + '
' + ); +}]); + +require('./config'); diff --git a/client/js/config.js b/client/js/config.js new file mode 100644 index 0000000..de6ea74 --- /dev/null +++ b/client/js/config.js @@ -0,0 +1,27 @@ +var components = { + controller: { + ContainersCtrl: require('./controller/ContainersCtrl'), + DeployTabCtrl: require('./controller/DeployTabCtrl'), + HeaderCtrl: require('./controller/HeaderCtrl'), + LogTabCtrl: require('./controller/LogTabCtrl'), + ProjectsCtrl: require('./controller/ProjectsCtrl') + }, + filter: { + unsafe: require('./filter/Unsafe') + }, + factory: { + socket: require('./factory/Socket') + } +}; + +// bootstrap components +var componentType; +var component; +for (componentType in components) { + for (component in components[componentType]) { + angular.module('dockership')[componentType]( + component, + components[componentType][component] + ); + } +} \ No newline at end of file diff --git a/client/js/controller/ContainersCtrl.js b/client/js/controller/ContainersCtrl.js new file mode 100644 index 0000000..fe61d80 --- /dev/null +++ b/client/js/controller/ContainersCtrl.js @@ -0,0 +1,11 @@ +module.exports = [ + '$scope', '$modalInstance', '$http', 'project', 'containers', + function ($scope, $modalInstance, $http, project, containers) { + $scope.project = project; + $scope.containers = containers; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + } +]; \ No newline at end of file diff --git a/client/js/controller/DeployTabCtrl.js b/client/js/controller/DeployTabCtrl.js new file mode 100644 index 0000000..8f68d8d --- /dev/null +++ b/client/js/controller/DeployTabCtrl.js @@ -0,0 +1,20 @@ +module.exports = [ + '$scope', '$http', '$rootScope', 'socket', 'ansi2html', + function ($scope, $http, $rootScope, socket, ansi2html) { + $scope.log = {}; + $scope.current = 'latest'; + $rootScope.pendingDeployments = 0; + + socket.addHandler('deploy', function (result) { + var key = result.project + ' ' + result.environment + ' ' + + result.date.slice(0, 16); + $scope.current = key; + + if ($scope.log[key] == undefined) { + $rootScope.pendingDeployments++; + $scope.log[key] = '' + } + $scope.log[key] += $scope.ansii ? ansi2html.toHtml(result.log) : result.log; + }); + } +]; \ No newline at end of file diff --git a/client/js/controller/HeaderCtrl.js b/client/js/controller/HeaderCtrl.js new file mode 100644 index 0000000..1ce2db9 --- /dev/null +++ b/client/js/controller/HeaderCtrl.js @@ -0,0 +1,14 @@ +module.exports = [ + '$scope', '$http', + function ($scope, $http) { + $scope.loadUser = function () { + $http.get('/rest/user').then(function (res) { + $scope.user = res.data; + }, function (msg) { + $scope.log(msg.data); + }); + }; + + $scope.loadUser() + } +]; \ No newline at end of file diff --git a/client/js/controller/LogTabCtrl.js b/client/js/controller/LogTabCtrl.js new file mode 100644 index 0000000..2d5a39e --- /dev/null +++ b/client/js/controller/LogTabCtrl.js @@ -0,0 +1,50 @@ +module.exports = [ + '$scope', '$rootScope', 'socket', 'Notification', + function ($scope, $rootScope, socket, Notification) { + $scope.level = 3; + $rootScope.pendingLogs = 0; + + $scope.chageLevel = function (level) { + $scope.level = level; + }; + + $scope.filter = function (line) { + return line.lvl <= $scope.level; + }; + + $scope.log = []; + socket.addHandler('log', function (log) { + $scope.log.unshift(log); + if (log.lvl < 4) { + $rootScope.pendingLogs++; + } + + if (log.lvl < 1) { + var notification = new Notification('[Critical Error]', { + body: log.msg, + icon: '/logo.png', + delay: 4000 + }); + } + }); + + $scope.params = function (params, first) { + var strings = []; + angular.forEach(params, function (value, key) { + if (key != 't' && key != 'msg' && key != 'lvl' && key != 'revision') { + this.push('' + key + ': ' + value); + } + + if (key == 'revision') { + this.push('' + key + ': ' + value.slice(0,12)); + } + }, strings); + + if (first) { + return strings[0].replace(/<[^>]+>/gm, ''); + } + + return strings.join('
'); + }; + } +]; \ No newline at end of file diff --git a/client/js/controller/ProjectsCtrl.js b/client/js/controller/ProjectsCtrl.js new file mode 100644 index 0000000..61378fe --- /dev/null +++ b/client/js/controller/ProjectsCtrl.js @@ -0,0 +1,110 @@ +module.exports = [ + '$scope', '$http', 'socket', 'dialogs', '$modal', + function ($scope, $http, socket, dialogs, $modal) { + 'use strict'; + $scope.processing = false; + + socket.addHandler('containers', function (result) { + $scope.processing = false; + var modalInstance = $modal.open({ + templateUrl: 'ContainersContent.html', + controller: 'ContainersCtrl', + size: 'lg', + resolve: { + project: function () { + return ''; + }, + containers: function () { + return result; + } + } + }); + }); + + var envStatus = function (status) { + if (status == undefined) { + return ['loading']; + } + + var total = status.Environment.DockerEndPoints.length; + var running = status.RunningContainers; + var revision = status.LastRevisionLabel; + var outdated = 0; + + if (running.length == 0) { + return ['down'] + } + + if (running.length != total) { + return ['down', 'partial'] + } + + for (var i = running.length - 1; i >= 0; i--) { + var tmp = running[i].Image.split(':'); + if (revision.slice(0, tmp[1].length) != tmp[1]) { + outdated++; + } + }; + + if (outdated == total) { + return ['outdated'] + } + + if (outdated != 0) { + return ['outdated', 'partial'] + } + + return ['ok']; + }; + + socket.addHandler('status', function (result) { + $scope.processing = false; + $scope.loaded = true; + + angular.forEach(result, function (project, key) { + angular.forEach(project.Status, function (status, key) { + status.Status = envStatus(status); + }); + }); + + $scope.status = result; + + }); + + socket.addHandler('projects', function (result) { + $scope.projects = result; + + angular.forEach(result, function (project, key) { + $scope.taskStatus[project.Name] = project.TaskStatus; + }); + + $scope.loadStatus(); + }); + + $scope.openContainers = function (project) { + $scope.processing = true; + socket.getContainers(project); + }; + + $scope.taskStatus = []; + $scope.openDeploy = function (project, environment) { + var msg = 'Are you sure want to deploy ' + project.Name + ' at ' + + environment.Name + '?' ; + var dlg = dialogs.confirm('Confirm', msg, {size: 'md'}); + dlg.result.then(function (btn){ + if ($scope.taskStatus[project.Name][environment.Name] == undefined) { + $scope.taskStatus[project.Name][environment.Name] = {}; + } + + $scope.taskStatus[project.Name][environment.Name]['deploy'] = true; + socket.doDeploy(project, environment); + }); + }; + + + $scope.loaded = false; + $scope.loadStatus = function () { + socket.getStatus(); + }; + } +]; \ No newline at end of file diff --git a/client/js/factory/Socket.js b/client/js/factory/Socket.js new file mode 100644 index 0000000..b013b60 --- /dev/null +++ b/client/js/factory/Socket.js @@ -0,0 +1,45 @@ +module.exports = [ + 'socketFactory', + function (socketFactory) { + var socket = socketFactory({ + url: '/socket' + }); + + socket._handlers = {}; + socket.addHandler = function (name, handler) { + socket._handlers[name] = handler; + }; + + socket.doDeploy = function (project, environment) { + socket.send(angular.toJson({ + event: 'deploy', + request: { + project: project.Name, + environment: environment.Name + } + })) + }; + + socket.getContainers = function (project) { + socket.send(angular.toJson({ + event: 'containers', + request: {project: project.Name} + })) + }; + + socket.getStatus = function (project) { + socket.send(angular.toJson({ + event: 'status', + request: {} + })) + }; + + socket.setHandler('message', function (e) { + data = angular.fromJson(e.data); + socket._handlers[data.event](data.result); + }); + + + return socket; + } +]; \ No newline at end of file diff --git a/client/js/filter/Unsafe.js b/client/js/filter/Unsafe.js new file mode 100644 index 0000000..ac29304 --- /dev/null +++ b/client/js/filter/Unsafe.js @@ -0,0 +1,8 @@ +module.exports = [ + '$sce', + function ($sce) { + return function (val) { + return $sce.trustAsHtml(val); + }; + } +]; \ No newline at end of file diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..ca85eae --- /dev/null +++ b/client/package.json @@ -0,0 +1,20 @@ +{ + "name": "dockership", + "version": "0.0.1", + "devDependencies": { + "browserify": "^9.0.8", + "gulp": "^3.8.11", + "gulp-clean": "^0.3.1", + "gulp-compass": "^2.0.4", + "gulp-debug": "^2.0.1", + "gulp-filter": "^2.0.2", + "gulp-minify-css": "^1.0.0", + "gulp-plumber": "^1.0.0", + "gulp-sourcemaps": "^1.5.1", + "gulp-uglify": "^1.2.0", + "gulp-util": "^3.0.4", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0", + "watchify": "^3.1.0" + } +} \ No newline at end of file diff --git a/http/static/app.css b/http/static/app.css index d56e32d..dbee66a 100644 --- a/http/static/app.css +++ b/http/static/app.css @@ -176,3 +176,12 @@ li.active > a { .log { font-family: } +.log-controls { + display: flex; +} +.log-controls>.ansii-checkbox { + white-space: nowrap; + margin: 0; + margin-left: 20px; + line-height: 38px; +} \ No newline at end of file diff --git a/http/static/app.js b/http/static/app.js index b1ec9b1..59299cd 100644 --- a/http/static/app.js +++ b/http/static/app.js @@ -1,281 +1,2 @@ -angular.module('dockership', [ - 'ui.bootstrap', 'angular-loading-bar', 'ansiToHtml', 'ngAnimate', - 'bd.sockjs', 'headroom', 'dialogs.main', 'notification', -]); - -angular.module('dockership').controller( - 'LogTabCtrl', - function ($scope, $rootScope, socket, ansi2html, Notification) { - $scope.level = 3 - $rootScope.pendingLogs = 0; - - $scope.chageLevel = function(level) { - $scope.level = level; - }; - - $scope.filter = function(line) { - if (line.lvl <= $scope.level) { - return true; - } - - return false; - }; - - $scope.log = []; - socket.addHandler('log', function (log) { - $scope.log.unshift(log); - if (log.lvl < 4) { - $rootScope.pendingLogs++; - } - - if (log.lvl < 1) { - var notification = new Notification('[Critical Error]', { - body: log.msg, - icon: '/logo.png', - delay: 4000 - }); - } - }); - - $scope.params = function (params, first) { - var strings = []; - angular.forEach(params, function(value, key) { - if (key != 't' && key != 'msg' && key != 'lvl' && key != 'revision') { - this.push('' + key + ': ' + value); - } - - if (key == 'revision') { - this.push('' + key + ': ' + value.slice(0,12)); - } - }, strings); - - if (first) { - return strings[0].replace(/<[^>]+>/gm, ''); - } - - return strings.join('
'); - }; - } -); - -angular.module('dockership').controller( - 'DeployTabCtrl', - function ($scope, $http, $rootScope, socket, ansi2html) { - $scope.log = {} - $scope.current = 'latest' - $rootScope.pendingDeployments = 0; - - socket.addHandler('deploy', function (result) { - var key = result.project + ' ' + result.environment + ' ' + result.date.slice(0, 16) - $scope.current = key; - - if ($scope.log[key] == undefined) { - $rootScope.pendingDeployments++; - $scope.log[key] = '' - } - - $scope.log[key] += ansi2html.toHtml(result.log); - }); - } -); - -angular.module('dockership').controller( - 'ProjectsCtrl', - function ($scope, $http, socket, dialogs, $modal, $log) { - 'use strict'; - $scope.processing = false; - - socket.addHandler('containers', function (result) { - $scope.processing = false; - var modalInstance = $modal.open({ - templateUrl: 'ContainersContent.html', - controller: 'ContainersCtrl', - size: 'lg', - resolve: { - project: function () { - return ''; - }, - containers: function () { - return result; - } - } - }); - }); - - var envStatus = function(status) { - if (status == undefined) { - return ['loading']; - } - - var total = status.Environment.DockerEndPoints.length; - var running = status.RunningContainers; - var revision = status.LastRevisionLabel; - var outdated = 0; - - if (running.length == 0) { - return ['down'] - } - - if (running.length != total) { - return ['down', 'partial'] - } - - for (var i = running.length - 1; i >= 0; i--) { - var tmp = running[i].Image.split(':'); - if (revision.slice(0, tmp[1].length) != tmp[1]) { - outdated++; - } - }; - - if (outdated == total) { - return ['outdated'] - } - - if (outdated != 0) { - return ['outdated', 'partial'] - } - - return ['ok']; - }; - - socket.addHandler('status', function (result) { - $scope.processing = false; - $scope.loaded = true; - - angular.forEach(result, function(project, key) { - angular.forEach(project.Status, function(status, key) { - status.Status = envStatus(status); - }); - }); - - $scope.status = result; - - }); - - socket.addHandler('projects', function (result) { - $scope.projects = result; - - angular.forEach(result, function(project, key) { - $scope.taskStatus[project.Name] = project.TaskStatus; - }); - - $scope.loadStatus(); - }); - - $scope.openContainers = function (project) { - $scope.processing = true; - socket.getContainers(project); - }; - - $scope.taskStatus = []; - $scope.openDeploy = function (project, environment) { - var msg = 'Are you sure want to deploy ' + project.Name + ' at ' + environment.Name + '?' ; - var dlg = dialogs.confirm('Confirm', msg, {size: 'md'}); - dlg.result.then(function(btn){ - if ($scope.taskStatus[project.Name][environment.Name] == undefined) { - $scope.taskStatus[project.Name][environment.Name] = {}; - } - - $scope.taskStatus[project.Name][environment.Name]['deploy'] = true; - socket.doDeploy(project, environment); - }); - }; - - - $scope.loaded = false; - $scope.loadStatus = function() { - socket.getStatus(); - }; - } -); - -angular.module('dockership').controller( - 'HeaderCtrl', - function ($scope, $http, $log) { - $scope.loadUser = function() { - $http.get('/rest/user').then(function(res) { - $scope.user = res.data; - }, function(msg) { - $scope.log(msg.data); - }); - } - - $scope.loadUser() - } -); - -angular.module('dockership').controller( - 'ContainersCtrl', - function ($scope, $modalInstance, $http, project, containers) { - $scope.project = project; - $scope.containers = containers; - - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; - } -); - -angular.module('dockership').factory('socket', function (socketFactory) { - var socket = socketFactory({ - url: '/socket' - }); - - socket._handlers = {}; - socket.addHandler = function(name, handler) { - socket._handlers[name] = handler; - }; - - socket.doDeploy = function(project, environment) { - socket.send(angular.toJson({ - event: 'deploy', - request: { - project: project.Name, - environment: environment.Name - } - })) - }; - - socket.getContainers = function(project) { - socket.send(angular.toJson({ - event: 'containers', - request: {project: project.Name} - })) - }; - - socket.getStatus = function(project) { - socket.send(angular.toJson({ - event: 'status', - request: {} - })) - }; - - socket.setHandler('message', function (e) { - data = angular.fromJson(e.data); - socket._handlers[data.event](data.result); - }); - - - return socket; -}); - -angular.module('dockership').filter('unsafe', ['$sce', function ($sce) { - return function (val) { - return $sce.trustAsHtml(val); - }; -}]); - - -// update popover template for binding unsafe html -angular.module('template/popover/popover.html', []).run(['$templateCache', function ($templateCache) { - $templateCache.put("template/popover/popover.html", - "
\n" + - "
\n" + - "\n" + - "
\n" + - "

\n" + - "
\n" + - "
\n" + - "
\n" + - ""); -}]); +!function t(n,e,o){function r(l,i){if(!e[l]){if(!n[l]){var s="function"==typeof require&&require;if(!i&&s)return s(l,!0);if(a)return a(l,!0);var c=new Error("Cannot find module '"+l+"'");throw c.code="MODULE_NOT_FOUND",c}var u=e[l]={exports:{}};n[l][0].call(u.exports,function(t){var e=n[l][1][t];return r(e?e:t)},u,u.exports,t,n,e,o)}return e[l].exports}for(var a="function"==typeof require&&require,l=0;l

')}]),t("./config")},{"./config":2}],2:[function(t,n,e){var o,r,a={controller:{ContainersCtrl:t("./controller/ContainersCtrl"),DeployTabCtrl:t("./controller/DeployTabCtrl"),HeaderCtrl:t("./controller/HeaderCtrl"),LogTabCtrl:t("./controller/LogTabCtrl"),ProjectsCtrl:t("./controller/ProjectsCtrl")},filter:{unsafe:t("./filter/Unsafe")},factory:{socket:t("./factory/Socket")}};for(o in a)for(r in a[o])angular.module("dockership")[o](r,a[o][r])},{"./controller/ContainersCtrl":3,"./controller/DeployTabCtrl":4,"./controller/HeaderCtrl":5,"./controller/LogTabCtrl":6,"./controller/ProjectsCtrl":7,"./factory/Socket":8,"./filter/Unsafe":9}],3:[function(t,n,e){n.exports=["$scope","$modalInstance","$http","project","containers",function(t,n,e,o,r){t.project=o,t.containers=r,t.cancel=function(){n.dismiss("cancel")}}]},{}],4:[function(t,n,e){n.exports=["$scope","$http","$rootScope","socket","ansi2html",function(t,n,e,o,r){t.log={},t.current="latest",e.pendingDeployments=0,o.addHandler("deploy",function(n){var o=n.project+" "+n.environment+" "+n.date.slice(0,16);t.current=o,void 0==t.log[o]&&(e.pendingDeployments++,t.log[o]=""),t.log[o]+=t.ansii?r.toHtml(n.log):n.log})}]},{}],5:[function(t,n,e){n.exports=["$scope","$http",function(t,n){t.loadUser=function(){n.get("/rest/user").then(function(n){t.user=n.data},function(n){t.log(n.data)})},t.loadUser()}]},{}],6:[function(t,n,e){n.exports=["$scope","$rootScope","socket","Notification",function(t,n,e,o){t.level=3,n.pendingLogs=0,t.chageLevel=function(n){t.level=n},t.filter=function(n){return n.lvl<=t.level},t.log=[],e.addHandler("log",function(e){if(t.log.unshift(e),e.lvl<4&&n.pendingLogs++,e.lvl<1){new o("[Critical Error]",{body:e.msg,icon:"/logo.png",delay:4e3})}}),t.params=function(t,n){var e=[];return angular.forEach(t,function(t,n){"t"!=n&&"msg"!=n&&"lvl"!=n&&"revision"!=n&&this.push(""+n+": "+t),"revision"==n&&this.push(""+n+": "+t.slice(0,12))},e),n?e[0].replace(/<[^>]+>/gm,""):e.join("
")}}]},{}],7:[function(t,n,e){n.exports=["$scope","$http","socket","dialogs","$modal",function(t,n,e,o,r){"use strict";t.processing=!1,e.addHandler("containers",function(n){t.processing=!1;r.open({templateUrl:"ContainersContent.html",controller:"ContainersCtrl",size:"lg",resolve:{project:function(){return""},containers:function(){return n}}})});var a=function(t){if(void 0==t)return["loading"];var n=t.Environment.DockerEndPoints.length,e=t.RunningContainers,o=t.LastRevisionLabel,r=0;if(0==e.length)return["down"];if(e.length!=n)return["down","partial"];for(var a=e.length-1;a>=0;a--){var l=e[a].Image.split(":");o.slice(0,l[1].length)!=l[1]&&r++}return r==n?["outdated"]:0!=r?["outdated","partial"]:["ok"]};e.addHandler("status",function(n){t.processing=!1,t.loaded=!0,angular.forEach(n,function(t,n){angular.forEach(t.Status,function(t,n){t.Status=a(t)})}),t.status=n}),e.addHandler("projects",function(n){t.projects=n,angular.forEach(n,function(n,e){t.taskStatus[n.Name]=n.TaskStatus}),t.loadStatus()}),t.openContainers=function(n){t.processing=!0,e.getContainers(n)},t.taskStatus=[],t.openDeploy=function(n,r){var a="Are you sure want to deploy "+n.Name+" at "+r.Name+"?",l=o.confirm("Confirm",a,{size:"md"});l.result.then(function(o){void 0==t.taskStatus[n.Name][r.Name]&&(t.taskStatus[n.Name][r.Name]={}),t.taskStatus[n.Name][r.Name].deploy=!0,e.doDeploy(n,r)})},t.loaded=!1,t.loadStatus=function(){e.getStatus()}}]},{}],8:[function(t,n,e){n.exports=["socketFactory",function(t){var n=t({url:"/socket"});return n._handlers={},n.addHandler=function(t,e){n._handlers[t]=e},n.doDeploy=function(t,e){n.send(angular.toJson({event:"deploy",request:{project:t.Name,environment:e.Name}}))},n.getContainers=function(t){n.send(angular.toJson({event:"containers",request:{project:t.Name}}))},n.getStatus=function(t){n.send(angular.toJson({event:"status",request:{}}))},n.setHandler("message",function(t){data=angular.fromJson(t.data),n._handlers[data.event](data.result)}),n}]},{}],9:[function(t,n,e){n.exports=["$sce",function(t){return function(n){return t.trustAsHtml(n)}}]},{}]},{},[1]); +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/http/static/app.js.map b/http/static/app.js.map new file mode 100644 index 0000000..ac66e5e --- /dev/null +++ b/http/static/app.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","js/app.js","app.js","js/config.js","js/controller/ContainersCtrl.js","js/controller/DeployTabCtrl.js","js/controller/HeaderCtrl.js","js/controller/LogTabCtrl.js","js/controller/ProjectsCtrl.js","js/factory/Socket.js","js/filter/Unsafe.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","angular","run","$templateCache","put","./config",2,"componentType","component","components","controller","ContainersCtrl","DeployTabCtrl","HeaderCtrl","LogTabCtrl","ProjectsCtrl","filter","unsafe","factory","socket","./controller/ContainersCtrl","./controller/DeployTabCtrl","./controller/HeaderCtrl","./controller/LogTabCtrl","./controller/ProjectsCtrl","./factory/Socket","./filter/Unsafe",3,"$scope","$modalInstance","$http","project","containers","cancel","dismiss",4,"$rootScope","ansi2html","log","current","pendingDeployments","addHandler","result","key","environment","date","slice","undefined","ansii","toHtml",5,"loadUser","get","then","res","user","data","msg",6,"Notification","level","pendingLogs","chageLevel","line","lvl","unshift","body","icon","delay","params","first","strings","forEach","value","this","push","replace","join",7,"dialogs","$modal","processing","open","templateUrl","size","resolve","envStatus","status","total","Environment","DockerEndPoints","running","RunningContainers","revision","LastRevisionLabel","outdated","tmp","Image","split","loaded","Status","projects","taskStatus","Name","TaskStatus","loadStatus","openContainers","getContainers","openDeploy","dlg","confirm","btn","doDeploy","getStatus",8,"socketFactory","url","_handlers","name","handler","send","toJson","event","request","setHandler","fromJson",9,"$sce","val","trustAsHtml"],"mappings":"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","file":"app.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o' +\n '
' +\n '
' +\n '

' +\n '
' +\n '
' +\n ''\n );\n}]);\n\nrequire('./config');\n",null,"var components = {\n controller: {\n ContainersCtrl: require('./controller/ContainersCtrl'),\n DeployTabCtrl: require('./controller/DeployTabCtrl'),\n HeaderCtrl: require('./controller/HeaderCtrl'),\n LogTabCtrl: require('./controller/LogTabCtrl'),\n ProjectsCtrl: require('./controller/ProjectsCtrl')\n },\n filter: {\n unsafe: require('./filter/Unsafe')\n },\n factory: {\n socket: require('./factory/Socket')\n }\n};\n\n// bootstrap components\nvar componentType;\nvar component;\nfor (componentType in components) {\n for (component in components[componentType]) {\n angular.module('dockership')[componentType](\n component,\n components[componentType][component]\n );\n }\n}","module.exports = [\n '$scope', '$modalInstance', '$http', 'project', 'containers',\n function ($scope, $modalInstance, $http, project, containers) {\n $scope.project = project;\n $scope.containers = containers;\n\n $scope.cancel = function () {\n $modalInstance.dismiss('cancel');\n };\n }\n];","module.exports = [\n '$scope', '$http', '$rootScope', 'socket', 'ansi2html',\n function ($scope, $http, $rootScope, socket, ansi2html) {\n $scope.log = {};\n $scope.current = 'latest';\n $rootScope.pendingDeployments = 0;\n\n socket.addHandler('deploy', function (result) {\n var key = result.project + ' ' + result.environment + ' '\n + result.date.slice(0, 16);\n $scope.current = key;\n\n if ($scope.log[key] == undefined) {\n $rootScope.pendingDeployments++;\n $scope.log[key] = ''\n }\n $scope.log[key] += $scope.ansii ? ansi2html.toHtml(result.log) : result.log;\n });\n }\n];","module.exports = [\n '$scope', '$http',\n function ($scope, $http) {\n $scope.loadUser = function () {\n $http.get('/rest/user').then(function (res) {\n $scope.user = res.data;\n }, function (msg) {\n $scope.log(msg.data);\n });\n };\n\n $scope.loadUser()\n }\n];","module.exports = [\n '$scope', '$rootScope', 'socket', 'Notification',\n function ($scope, $rootScope, socket, Notification) {\n $scope.level = 3;\n $rootScope.pendingLogs = 0;\n\n $scope.chageLevel = function (level) {\n $scope.level = level;\n };\n\n $scope.filter = function (line) {\n return line.lvl <= $scope.level;\n };\n\n $scope.log = [];\n socket.addHandler('log', function (log) {\n $scope.log.unshift(log);\n if (log.lvl < 4) {\n $rootScope.pendingLogs++;\n }\n\n if (log.lvl < 1) {\n var notification = new Notification('[Critical Error]', {\n body: log.msg,\n icon: '/logo.png',\n delay: 4000\n });\n }\n });\n\n $scope.params = function (params, first) {\n var strings = [];\n angular.forEach(params, function (value, key) {\n if (key != 't' && key != 'msg' && key != 'lvl' && key != 'revision') {\n this.push('' + key + ': ' + value);\n }\n\n if (key == 'revision') {\n this.push('' + key + ': ' + value.slice(0,12));\n }\n }, strings);\n\n if (first) {\n return strings[0].replace(/<[^>]+>/gm, '');\n }\n\n return strings.join('
');\n };\n }\n];","module.exports = [\n '$scope', '$http', 'socket', 'dialogs', '$modal',\n function ($scope, $http, socket, dialogs, $modal) {\n 'use strict';\n $scope.processing = false;\n\n socket.addHandler('containers', function (result) {\n $scope.processing = false;\n var modalInstance = $modal.open({\n templateUrl: 'ContainersContent.html',\n controller: 'ContainersCtrl',\n size: 'lg',\n resolve: {\n project: function () {\n return '';\n },\n containers: function () {\n return result;\n }\n }\n });\n });\n\n var envStatus = function (status) {\n if (status == undefined) {\n return ['loading'];\n }\n\n var total = status.Environment.DockerEndPoints.length;\n var running = status.RunningContainers;\n var revision = status.LastRevisionLabel;\n var outdated = 0;\n\n if (running.length == 0) {\n return ['down']\n }\n\n if (running.length != total) {\n return ['down', 'partial']\n }\n\n for (var i = running.length - 1; i >= 0; i--) {\n var tmp = running[i].Image.split(':');\n if (revision.slice(0, tmp[1].length) != tmp[1]) {\n outdated++;\n }\n };\n\n if (outdated == total) {\n return ['outdated']\n }\n\n if (outdated != 0) {\n return ['outdated', 'partial']\n }\n\n return ['ok'];\n };\n\n socket.addHandler('status', function (result) {\n $scope.processing = false;\n $scope.loaded = true;\n\n angular.forEach(result, function (project, key) {\n angular.forEach(project.Status, function (status, key) {\n status.Status = envStatus(status);\n });\n });\n\n $scope.status = result;\n\n });\n\n socket.addHandler('projects', function (result) {\n $scope.projects = result;\n\n angular.forEach(result, function (project, key) {\n $scope.taskStatus[project.Name] = project.TaskStatus;\n });\n\n $scope.loadStatus();\n });\n\n $scope.openContainers = function (project) {\n $scope.processing = true;\n socket.getContainers(project);\n };\n\n $scope.taskStatus = [];\n $scope.openDeploy = function (project, environment) {\n var msg = 'Are you sure want to deploy ' + project.Name + ' at '\n + environment.Name + '?' ;\n var dlg = dialogs.confirm('Confirm', msg, {size: 'md'});\n dlg.result.then(function (btn){\n if ($scope.taskStatus[project.Name][environment.Name] == undefined) {\n $scope.taskStatus[project.Name][environment.Name] = {};\n }\n\n $scope.taskStatus[project.Name][environment.Name]['deploy'] = true;\n socket.doDeploy(project, environment);\n });\n };\n\n\n $scope.loaded = false;\n $scope.loadStatus = function () {\n socket.getStatus();\n };\n }\n];","module.exports = [\n 'socketFactory',\n function (socketFactory) {\n var socket = socketFactory({\n url: '/socket'\n });\n\n socket._handlers = {};\n socket.addHandler = function (name, handler) {\n socket._handlers[name] = handler;\n };\n\n socket.doDeploy = function (project, environment) {\n socket.send(angular.toJson({\n event: 'deploy',\n request: {\n project: project.Name,\n environment: environment.Name\n }\n }))\n };\n\n socket.getContainers = function (project) {\n socket.send(angular.toJson({\n event: 'containers',\n request: {project: project.Name}\n }))\n };\n\n socket.getStatus = function (project) {\n socket.send(angular.toJson({\n event: 'status',\n request: {}\n }))\n };\n\n socket.setHandler('message', function (e) {\n data = angular.fromJson(e.data);\n socket._handlers[data.event](data.result);\n });\n\n\n return socket;\n }\n];","module.exports = [\n '$sce',\n function ($sce) {\n return function (val) {\n return $sce.trustAsHtml(val);\n };\n }\n];"],"sourceRoot":"../src/js"} \ No newline at end of file diff --git a/http/static/index.html b/http/static/index.html index 2bd20c9..509c44f 100644 --- a/http/static/index.html +++ b/http/static/index.html @@ -20,8 +20,8 @@ - - + +
by Máximo Cuadros - . Under MIT License / + . Under MIT License / Logo by Caye Romero @@ -251,12 +251,18 @@
From 8db7e16f92bd7005cfc3b30bce46bf6cf3cb10bc Mon Sep 17 00:00:00 2001 From: Philip Thomas Date: Fri, 12 Jun 2015 11:57:59 +0200 Subject: [PATCH 2/2] Update makefile for gulp deployment --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0ea8625..5395c87 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,9 @@ BINDATA = go-bindata all: test build +build-assets: + cd $(BASE_PATH)/client; npm install; npm install gulp -g; gulp javascript + assets: cd $(BASE_PATH)/http; $(BINDATA) -pkg=http $(ASSETS) @@ -38,7 +41,7 @@ dependencies: $(DEPENDENCIES) $(DEPENDENCIES): $(GOGET) $@ -build: assets dependencies $(COMMANDS) +build: build-assets assets dependencies $(COMMANDS) $(COMMANDS): %: %.go $(GOCMD) build -ldflags "-X main.version $(VERSION) -X main.build \"$(BUILD)\"" $@.go