diff --git a/README.md b/README.md index 05e7aa42f..4f197cf88 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,40 @@ DockerUI is a web interface to interact with the Remote API. The goal is to pro ![Container](/container.png) + +###Goals +* Little to no dependencies - I really want to keep this project a pure html/js app. You can drop the docker binary on your server run so I want to be able to drop these html files on your server and go. + ###Installation Open js/app.js and change the DOCKER_ENDPOINT constant to your docker ip and port. Then host the site like any other html/js application. .constant('DOCKER_ENDPOINT', 'http://192.168.1.9:4243\:4243'); +###Remote API Version +DockerUI currently supports the v1.1 Remote API ###Stack * Angular.js * Flatstrap ( Flat Twitter Bootstrap ) +###Todo: +I work fast so it will not be long before these changes are impelmented. + +* Multiple endpoints +* Full repository support +* Search +* Create images via Dockerfile +* Push files to a container +* Unit tests + + ###License - MIT +The DockerUI code is licensed under the MIT license. Flatstrap(bootstrap) is licensed under the Apache License v2.0 and Angular.js is licensed under MIT. + + +**DockerUI:** Copyright (c) 2013 Michael Crosby. crosbymichael.com Permission is hereby granted, free of charge, to any person diff --git a/css/app.css b/css/app.css index 8c3766401..2205e2507 100644 --- a/css/app.css +++ b/css/app.css @@ -70,6 +70,11 @@ margin: 0 auto; } + .center { + width: 80%; + margin: 0 auto; + } + .btn-remove { margin: 0 auto; max-width: 70%; @@ -78,3 +83,7 @@ .actions { margin: 0 auto; } + + .container-bottom { + height: 50px; + } diff --git a/index.html b/index.html index ae5e5c990..2f44e2d3c 100644 --- a/index.html +++ b/index.html @@ -29,12 +29,13 @@
-
-
+
+
- diff --git a/js/app.js b/js/app.js index b5ea70d84..3d58e29f6 100644 --- a/js/app.js +++ b/js/app.js @@ -2,7 +2,7 @@ angular.module('dockerui', ['dockerui.services', 'dockerui.filters']) .config(['$routeProvider', function ($routeProvider) { - $routeProvider.when('/', {templateUrl: 'partials/home.html', controller: 'HomeController'}); + $routeProvider.when('/', {templateUrl: 'partials/dashboard.html', controller: 'DashboardController'}); $routeProvider.when('/containers/', {templateUrl: 'partials/containers.html', controller: 'ContainersController'}); $routeProvider.when('/containers/:id/', {templateUrl: 'partials/container.html', controller: 'ContainerController'}); $routeProvider.when('/images/', {templateUrl: 'partials/images.html', controller: 'ImagesController'}); @@ -10,4 +10,6 @@ angular.module('dockerui', ['dockerui.services', 'dockerui.filters']) $routeProvider.when('/settings', {templateUrl: 'partials/settings.html', controller: 'SettingsController'}); $routeProvider.otherwise({redirectTo: '/'}); }]) - .constant('DOCKER_ENDPOINT', 'http://192.168.1.9:4243\:4243'); + // This is your docker url that the api will use to make requests + .constant('DOCKER_ENDPOINT', 'http://192.168.1.9:4243\:4243') + .constant('DOCKER_API_VERSION', '/v1.1'); diff --git a/js/controllers.js b/js/controllers.js index b9ca6001a..88b12db02 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -33,42 +33,42 @@ function MastheadController($scope) { }; } -function HomeController() { +function DashboardController($scope, Container) { } +function SideBarController($scope, Container, Settings) { + $scope.template = 'partials/sidebar.html'; + $scope.containers = []; + $scope.endpoint = Settings.endpoint; + + Container.query({all: 0}, function(d) { + $scope.containers = d; + }); +} + function SettingsController($scope, Auth, System, Docker, Settings) { $scope.auth = {}; $scope.info = {}; $scope.docker = {}; + $scope.endpoint = Settings.endpoint; + $scope.apiVersion = Settings.version; $('#response').hide(); $scope.alertClass = 'block'; - var showAndHide = function(hide) { - $('#response').show(); - if (hide) { - setTimeout(function() { $('#response').hide();}, 5000); - } - }; - $scope.updateAuthInfo = function() { if ($scope.auth.password != $scope.auth.cpassword) { - $scope.response = 'Your passwords do not match.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Your passwords do not match.', '#response'); return; } Auth.update( {username: $scope.auth.username, email: $scope.auth.email, password: $scope.auth.password}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Auth information updated.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Auto information updated.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); }; @@ -89,52 +89,33 @@ function ContainerController($scope, $routeParams, $location, Container) { $('#response').hide(); $scope.alertClass = 'block'; - var showAndHide = function(hide) { - $('#response').show(); - if (hide) { - setTimeout(function() { $('#response').hide();}, 5000); - } - }; - $scope.start = function(){ Container.start({id: $routeParams.id}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Container started.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Container started.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); }; $scope.stop = function() { Container.stop({id: $routeParams.id}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Container stopped.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Container stopped.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); }; $scope.kill = function() { Container.kill({id: $routeParams.id}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Container killed.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Container killed.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); }; @@ -142,14 +123,10 @@ function ContainerController($scope, $routeParams, $location, Container) { if (confirm("Are you sure you want to remove the container?")) { Container.remove({id: $routeParams.id}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Container removed.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Container removed.', '#response'); }, function(e){ console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); } }; @@ -210,26 +187,15 @@ function ImageController($scope, $routeParams, $location, Image) { $('#response').hide(); $scope.alertClass = 'block'; - - var showAndHide = function(hide) { - $('#response').show(); - if (hide) { - setTimeout(function() { $('#response').hide();}, 5000); - } - }; - + $scope.remove = function() { if (confirm("Are you sure you want to delete this image?")) { Image.remove({id: $routeParams.id}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Image removed.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Image removed.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); } }; @@ -244,14 +210,10 @@ function ImageController($scope, $routeParams, $location, Image) { var tag = $scope.tag; Image.tag({id: $routeParams.id, repo: tag.repo, force: tag.force ? 1 : 0}, function(d) { console.log(d); - $scope.alertClass = 'success'; - $scope.response = 'Tag added.'; - showAndHide(true); + setSuccessfulResponse($scope, 'Tag added.', '#response'); }, function(e) { console.log(e); - $scope.alertClass = 'error'; - $scope.response = e.data; - showAndHide(false); + setFailedResponse($scope, e.data, '#response'); }); }; @@ -307,3 +269,16 @@ function StartContainerController($scope, $routeParams, $location, Container) { }); }; } + +function setSuccessfulResponse($scope, msg, msgId) { + $scope.alertClass = 'success'; + $scope.response = msg; + $(msgId).show(); + setTimeout(function() { $(msgId).hide();}, 5000); +} + +function setFailedResponse($scope, msg, msgId) { + $scope.alertClass = 'error'; + $scope.response = msg; + $(msgId).show(); +} diff --git a/js/services.js b/js/services.js index 21a15056a..3b44cfdb4 100644 --- a/js/services.js +++ b/js/services.js @@ -1,10 +1,10 @@ 'use strict'; angular.module('dockerui.services', ['ngResource']) - .factory('Container', function($resource, DOCKER_ENDPOINT) { + .factory('Container', function($resource, Settings) { // Resource for interacting with the docker containers // http://docs.docker.io/en/latest/api/docker_remote_api.html#containers - return $resource(DOCKER_ENDPOINT + '/containers/:id/:action', {}, { + return $resource(Settings.url + '/containers/:id/:action', {}, { query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true}, get :{method: 'GET', params: { action:'json'}}, start: {method: 'POST', params: {id: '@id', action: 'start'}}, @@ -16,10 +16,10 @@ angular.module('dockerui.services', ['ngResource']) remove :{method: 'DELETE', params: {id: '@id', v:0}} }); }) - .factory('Image', function($resource, DOCKER_ENDPOINT) { + .factory('Image', function($resource, Settings) { // Resource for docker images // http://docs.docker.io/en/latest/api/docker_remote_api.html#images - return $resource(DOCKER_ENDPOINT + '/images/:id/:action', {}, { + return $resource(Settings.url + '/images/:id/:action', {}, { query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true}, get :{method: 'GET', params: { action:'json'}}, search :{method: 'GET', params: { action:'search'}}, @@ -31,30 +31,33 @@ angular.module('dockerui.services', ['ngResource']) delete :{id: '@id', method: 'DELETE'} }); }) - .factory('Docker', function($resource, DOCKER_ENDPOINT) { + .factory('Docker', function($resource, Settings) { // Information for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information - return $resource(DOCKER_ENDPOINT + '/version', {}, { + return $resource(Settings.url + '/version', {}, { get: {method: 'GET'} }); }) - .factory('Auth', function($resource, DOCKER_ENDPOINT) { + .factory('Auth', function($resource, Settings) { // Auto Information for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration - return $resource(DOCKER_ENDPOINT + '/auth', {}, { + return $resource(Settings.url + '/auth', {}, { get: {method: 'GET'}, update: {method: 'POST'} }); }) - .factory('System', function($resource, DOCKER_ENDPOINT) { + .factory('System', function($resource, Settings) { // System for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information - return $resource(DOCKER_ENDPOINT + '/info', {}, { + return $resource(Settings.url + '/info', {}, { get: {method: 'GET'} }); }) - .factory('Settings', function() { + .factory('Settings', function(DOCKER_ENDPOINT, DOCKER_API_VERSION) { return { - displayAll: false + displayAll: false, + endpoint: DOCKER_ENDPOINT, + version: DOCKER_API_VERSION, + url: DOCKER_ENDPOINT + DOCKER_API_VERSION }; }); diff --git a/partials/dashboard.html b/partials/dashboard.html new file mode 100644 index 000000000..637460e30 --- /dev/null +++ b/partials/dashboard.html @@ -0,0 +1,13 @@ + +
+ +
+
+

DockerUI

+

The Linux container engine

+ Learn more. +
+
+
diff --git a/partials/home.html b/partials/home.html deleted file mode 100644 index 2afb6f24e..000000000 --- a/partials/home.html +++ /dev/null @@ -1,7 +0,0 @@ -
-

DockerUI

-

The Linux container engine

- Learn more. -
- -
diff --git a/partials/masthead.html b/partials/masthead.html index b65b11a50..7835148d5 100644 --- a/partials/masthead.html +++ b/partials/masthead.html @@ -4,7 +4,7 @@