mirror of https://github.com/portainer/portainer
configuration is now exposed in /config endpoint (#13)
parent
f3a5251fd4
commit
a7619b06ba
|
@ -10,6 +10,7 @@ angular.module('uifordocker', [
|
||||||
'dashboard',
|
'dashboard',
|
||||||
'container',
|
'container',
|
||||||
'containers',
|
'containers',
|
||||||
|
'docker',
|
||||||
'images',
|
'images',
|
||||||
'image',
|
'image',
|
||||||
'pullImage',
|
'pullImage',
|
||||||
|
@ -56,6 +57,11 @@ angular.module('uifordocker', [
|
||||||
templateUrl: 'app/components/containerLogs/containerlogs.html',
|
templateUrl: 'app/components/containerLogs/containerlogs.html',
|
||||||
controller: 'ContainerLogsController'
|
controller: 'ContainerLogsController'
|
||||||
})
|
})
|
||||||
|
.state('docker', {
|
||||||
|
url: '/docker/',
|
||||||
|
templateUrl: 'app/components/docker/docker.html',
|
||||||
|
controller: 'DockerController'
|
||||||
|
})
|
||||||
.state('images', {
|
.state('images', {
|
||||||
url: '/images/',
|
url: '/images/',
|
||||||
templateUrl: 'app/components/images/images.html',
|
templateUrl: 'app/components/images/images.html',
|
||||||
|
@ -113,4 +119,5 @@ angular.module('uifordocker', [
|
||||||
// You need to set this to the api endpoint without the port i.e. http://192.168.1.9
|
// You need to set this to the api endpoint without the port i.e. http://192.168.1.9
|
||||||
.constant('DOCKER_ENDPOINT', 'dockerapi')
|
.constant('DOCKER_ENDPOINT', 'dockerapi')
|
||||||
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
|
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
|
||||||
|
.constant('CONFIG_ENDPOINT', '/config')
|
||||||
.constant('UI_VERSION', 'v1.0.2');
|
.constant('UI_VERSION', 'v1.0.2');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
angular.module('dashboard')
|
angular.module('dashboard')
|
||||||
.controller('MasterCtrl', ['$scope', '$cookieStore', 'Settings', function ($scope, $cookieStore, Settings) {
|
.controller('MasterCtrl', ['$scope', '$cookieStore', 'Settings', 'Config', function ($scope, $cookieStore, Settings, Config) {
|
||||||
/**
|
/**
|
||||||
* Sidebar Toggle & Cookie Control
|
* Sidebar Toggle & Cookie Control
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,8 @@ angular.module('dashboard')
|
||||||
return window.innerWidth;
|
return window.innerWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.config = Config.get();
|
||||||
|
|
||||||
$scope.$watch($scope.getWidth, function(newValue, oldValue) {
|
$scope.$watch($scope.getWidth, function(newValue, oldValue) {
|
||||||
if (newValue >= mobileView) {
|
if (newValue >= mobileView) {
|
||||||
if (angular.isDefined($cookieStore.get('toggle'))) {
|
if (angular.isDefined($cookieStore.get('toggle'))) {
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
<rd-header>
|
||||||
|
<rd-header-title title="Engine overview">
|
||||||
|
<a data-toggle="tooltip" title="Refresh" ui-sref="docker" ui-sref-opts="{reload: true}">
|
||||||
|
<i class="fa fa-refresh" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</rd-header-title>
|
||||||
|
<rd-header-content>Docker</rd-header-content>
|
||||||
|
</rd-header>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-body>
|
||||||
|
<div class="widget-icon pull-left">
|
||||||
|
<i class="fa fa-code"></i>
|
||||||
|
</div>
|
||||||
|
<div class="title">{{ docker.Version }}</div>
|
||||||
|
<div class="comment">Docker version</div>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-body>
|
||||||
|
<div class="widget-icon pull-left">
|
||||||
|
<i class="fa fa-code"></i>
|
||||||
|
</div>
|
||||||
|
<div class="title">{{ docker.ApiVersion }}</div>
|
||||||
|
<div class="comment">API version</div>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-body>
|
||||||
|
<div class="widget-icon pull-left">
|
||||||
|
<i class="fa fa-code"></i>
|
||||||
|
</div>
|
||||||
|
<div class="title">{{ docker.GoVersion }}</div>
|
||||||
|
<div class="comment">Go version</div>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-header icon="fa-object-group" title="Cluster status"></rd-widget-header>
|
||||||
|
<rd-widget-body classes="no-padding">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Containers</td>
|
||||||
|
<td>{{ info.Containers }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Images</td>
|
||||||
|
<td>{{ info.Images }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Debug</td>
|
||||||
|
<td>{{ info.Debug }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>CPUs</td>
|
||||||
|
<td>{{ info.NCPU }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Memory</td>
|
||||||
|
<td>{{ info.MemTotal|humansize }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Operating System</td>
|
||||||
|
<td>{{ info.OperatingSystem }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Kernel Version</td>
|
||||||
|
<td>{{ info.KernelVersion }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>{{ info.ID }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Labels</td>
|
||||||
|
<td>{{ info.Labels }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>File Descriptors</td>
|
||||||
|
<td>{{ info.NFd }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Goroutines</td>
|
||||||
|
<td>{{ info.NGoroutines }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Storage Driver</td>
|
||||||
|
<td>{{ info.Driver }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Storage Driver Status</td>
|
||||||
|
<td>
|
||||||
|
<p ng-repeat="val in info.DriverStatus">
|
||||||
|
{{ val[0] }}: {{ val[1] }}
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Execution Driver</td>
|
||||||
|
<td>{{ info.ExecutionDriver }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>IPv4 Forwarding</td>
|
||||||
|
<td>{{ info.IPv4Forwarding }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Index Server Address</td>
|
||||||
|
<td>{{ info.IndexServerAddress }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Init Path</td>
|
||||||
|
<td>{{ info.InitPath }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Docker Root Directory</td>
|
||||||
|
<td>{{ info.DockerRootDir }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Init SHA1</td>
|
||||||
|
<td>{{ info.InitSha1 }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Memory Limit</td>
|
||||||
|
<td>{{ info.MemoryLimit }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Swap Limit</td>
|
||||||
|
<td>{{ info.SwapLimit }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,19 @@
|
||||||
|
angular.module('docker', [])
|
||||||
|
.controller('DockerController', ['$scope', 'Info', 'Version', 'Settings',
|
||||||
|
function ($scope, Info, Version, Settings) {
|
||||||
|
|
||||||
|
$scope.info = {};
|
||||||
|
$scope.docker = {};
|
||||||
|
|
||||||
|
$scope.order = function(sortType) {
|
||||||
|
$scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;
|
||||||
|
$scope.sortType = sortType;
|
||||||
|
};
|
||||||
|
|
||||||
|
Version.get({}, function (d) {
|
||||||
|
$scope.docker = d;
|
||||||
|
});
|
||||||
|
Info.get({}, function (d) {
|
||||||
|
$scope.info = d;
|
||||||
|
});
|
||||||
|
}]);
|
|
@ -142,6 +142,9 @@ angular.module('dockerui.services', ['ngResource', 'ngSanitize'])
|
||||||
remove: {method: 'DELETE'}
|
remove: {method: 'DELETE'}
|
||||||
});
|
});
|
||||||
}])
|
}])
|
||||||
|
.factory('Config', ['$resource', 'CONFIG_ENDPOINT', function($resource, CONFIG_ENDPOINT) {
|
||||||
|
return $resource(CONFIG_ENDPOINT);
|
||||||
|
}])
|
||||||
.factory('Settings', ['DOCKER_ENDPOINT', 'DOCKER_PORT', 'UI_VERSION', function SettingsFactory(DOCKER_ENDPOINT, DOCKER_PORT, UI_VERSION) {
|
.factory('Settings', ['DOCKER_ENDPOINT', 'DOCKER_PORT', 'UI_VERSION', function SettingsFactory(DOCKER_ENDPOINT, DOCKER_PORT, UI_VERSION) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var url = DOCKER_ENDPOINT;
|
var url = DOCKER_ENDPOINT;
|
||||||
|
|
23
dockerui.go
23
dockerui.go
|
@ -1,4 +1,4 @@
|
||||||
package main // import "github.com/cloudinovasi/cloudinovasi-ui"
|
package main // import "github.com/cloudinovasi/ui-for-docker"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/gorilla/csrf"
|
"github.com/gorilla/csrf"
|
||||||
|
@ -20,6 +21,7 @@ var (
|
||||||
endpoint = flag.String("e", "/var/run/docker.sock", "Dockerd endpoint")
|
endpoint = flag.String("e", "/var/run/docker.sock", "Dockerd endpoint")
|
||||||
addr = flag.String("p", ":9000", "Address and port to serve UI For Docker")
|
addr = flag.String("p", ":9000", "Address and port to serve UI For Docker")
|
||||||
assets = flag.String("a", ".", "Path to the assets")
|
assets = flag.String("a", ".", "Path to the assets")
|
||||||
|
swarm = flag.Bool("s", false, "Swarm mode")
|
||||||
authKey []byte
|
authKey []byte
|
||||||
authKeyFile = "authKey.dat"
|
authKeyFile = "authKey.dat"
|
||||||
)
|
)
|
||||||
|
@ -28,6 +30,10 @@ type UnixHandler struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Swarm bool `json:"swarm"`
|
||||||
|
}
|
||||||
|
|
||||||
func (h *UnixHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *UnixHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
conn, err := net.Dial("unix", h.path)
|
conn, err := net.Dial("unix", h.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -60,6 +66,10 @@ func copyHeader(dst, src http.Header) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configurationHandler(w http.ResponseWriter, r *http.Request, c Config) {
|
||||||
|
json.NewEncoder(w).Encode(c)
|
||||||
|
}
|
||||||
|
|
||||||
func createTcpHandler(e string) http.Handler {
|
func createTcpHandler(e string) http.Handler {
|
||||||
u, err := url.Parse(e)
|
u, err := url.Parse(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,7 +82,7 @@ func createUnixHandler(e string) http.Handler {
|
||||||
return &UnixHandler{e}
|
return &UnixHandler{e}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHandler(dir string, e string) http.Handler {
|
func createHandler(dir string, e string, s bool) http.Handler {
|
||||||
var (
|
var (
|
||||||
mux = http.NewServeMux()
|
mux = http.NewServeMux()
|
||||||
fileHandler = http.FileServer(http.Dir(dir))
|
fileHandler = http.FileServer(http.Dir(dir))
|
||||||
|
@ -110,8 +120,15 @@ func createHandler(dir string, e string) http.Handler {
|
||||||
csrf.Secure(false),
|
csrf.Secure(false),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
configuration := Config{
|
||||||
|
Swarm: s,
|
||||||
|
}
|
||||||
|
|
||||||
mux.Handle("/dockerapi/", http.StripPrefix("/dockerapi", h))
|
mux.Handle("/dockerapi/", http.StripPrefix("/dockerapi", h))
|
||||||
mux.Handle("/", fileHandler)
|
mux.Handle("/", fileHandler)
|
||||||
|
mux.HandleFunc("/config", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
configurationHandler(w, r, configuration)
|
||||||
|
})
|
||||||
return CSRF(csrfWrapper(mux))
|
return CSRF(csrfWrapper(mux))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +142,7 @@ func csrfWrapper(h http.Handler) http.Handler {
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
handler := createHandler(*assets, *endpoint)
|
handler := createHandler(*assets, *endpoint, *swarm)
|
||||||
if err := http.ListenAndServe(*addr, handler); err != nil {
|
if err := http.ListenAndServe(*addr, handler); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ module.exports = function (grunt) {
|
||||||
]);
|
]);
|
||||||
grunt.registerTask('test-watch', ['karma:watch']);
|
grunt.registerTask('test-watch', ['karma:watch']);
|
||||||
grunt.registerTask('run', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:run']);
|
grunt.registerTask('run', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:run']);
|
||||||
grunt.registerTask('runSwarm', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:runSwarm', 'watch:buildSwarm']);
|
grunt.registerTask('run-swarm', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:runSwarm', 'watch:buildSwarm']);
|
||||||
grunt.registerTask('run-dev', ['if:binaryNotExist', 'shell:buildImage', 'shell:run', 'watch:build']);
|
grunt.registerTask('run-dev', ['if:binaryNotExist', 'shell:buildImage', 'shell:run', 'watch:build']);
|
||||||
grunt.registerTask('clear', ['clean:app']);
|
grunt.registerTask('clear', ['clean:app']);
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ module.exports = function (grunt) {
|
||||||
command: [
|
command: [
|
||||||
'docker stop ui-for-docker',
|
'docker stop ui-for-docker',
|
||||||
'docker rm ui-for-docker',
|
'docker rm ui-for-docker',
|
||||||
'docker run --net=host -d --name ui-for-docker ui-for-docker -e http://10.0.7.11:4000'
|
'docker run --privileged -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock --name ui-for-docker ui-for-docker -s'
|
||||||
].join(';')
|
].join(';')
|
||||||
},
|
},
|
||||||
cleanImages: {
|
cleanImages: {
|
||||||
|
|
|
@ -52,9 +52,12 @@
|
||||||
<li class="sidebar-list">
|
<li class="sidebar-list">
|
||||||
<a ui-sref="volumes">Volumes <span class="menu-icon fa fa-cubes"></span></a>
|
<a ui-sref="volumes">Volumes <span class="menu-icon fa fa-cubes"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-list">
|
<li class="sidebar-list" ng-if="config.swarm">
|
||||||
<a ui-sref="swarm">Swarm <span class="menu-icon fa fa-object-group"></span></a>
|
<a ui-sref="swarm">Swarm <span class="menu-icon fa fa-object-group"></span></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="sidebar-list" ng-if="!config.swarm">
|
||||||
|
<a ui-sref="docker">Docker <span class="menu-icon fa fa-cogs"></span></a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="sidebar-footer">
|
<div class="sidebar-footer">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
|
Loading…
Reference in New Issue