mirror of https://github.com/portainer/portainer
Merge branch 'dev'
commit
e5dab43f46
|
@ -8,6 +8,7 @@ DockerUI is a web interface to interact with the Remote API. The goal is to pro
|
||||||
|
|
||||||
###Goals
|
###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.
|
* 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.
|
||||||
|
* Consistency - The web UI should be consistent with the commands found on the CLI.
|
||||||
|
|
||||||
###Installation
|
###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.
|
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.
|
||||||
|
@ -24,8 +25,6 @@ DockerUI currently supports the v1.1 Remote API
|
||||||
|
|
||||||
|
|
||||||
###Todo:
|
###Todo:
|
||||||
I work fast so it will not be long before these changes are impelmented.
|
|
||||||
|
|
||||||
* Multiple endpoints
|
* Multiple endpoints
|
||||||
* Full repository support
|
* Full repository support
|
||||||
* Search
|
* Search
|
||||||
|
|
|
@ -87,3 +87,12 @@
|
||||||
.container-bottom {
|
.container-bottom {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
max-height:6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#response {
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
12
index.html
12
index.html
|
@ -28,16 +28,12 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div ng-include="template" ng-controller="MastheadController"></div>
|
||||||
|
|
||||||
<div ng-include="template" ng-controller="MastheadController" ></div>
|
<div id="view" ng-view></div>
|
||||||
<div id="view" ng-view>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="container-bottom"></div>
|
|
||||||
<div class="footer center well">
|
|
||||||
<p>Created by: <a href="http://crosbymichael.com">crosbymichael</a></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="container-bottom"></div>
|
||||||
|
<div ng-include="template" ng-controller="StatusBarController"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../assets/js/jquery.js"></script>
|
<script src="../assets/js/jquery.js"></script>
|
||||||
|
|
|
@ -12,4 +12,5 @@ angular.module('dockerui', ['dockerui.services', 'dockerui.filters'])
|
||||||
}])
|
}])
|
||||||
// This is your docker url that the api will use to make requests
|
// 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_ENDPOINT', 'http://192.168.1.9:4243\:4243')
|
||||||
.constant('DOCKER_API_VERSION', '/v1.1');
|
.constant('UI_VERSION', 'v0.1')
|
||||||
|
.constant('DOCKER_API_VERSION', 'v1.1');
|
||||||
|
|
|
@ -37,6 +37,13 @@ function DashboardController($scope, Container) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StatusBarController($scope, Settings) {
|
||||||
|
$scope.template = 'partials/statusbar.html';
|
||||||
|
|
||||||
|
$scope.uiVersion = Settings.uiVersion;
|
||||||
|
$scope.apiVersion = Settings.version;
|
||||||
|
}
|
||||||
|
|
||||||
function SideBarController($scope, Container, Settings) {
|
function SideBarController($scope, Container, Settings) {
|
||||||
$scope.template = 'partials/sidebar.html';
|
$scope.template = 'partials/sidebar.html';
|
||||||
$scope.containers = [];
|
$scope.containers = [];
|
||||||
|
@ -65,7 +72,7 @@ function SettingsController($scope, Auth, System, Docker, Settings) {
|
||||||
Auth.update(
|
Auth.update(
|
||||||
{username: $scope.auth.username, email: $scope.auth.email, password: $scope.auth.password}, function(d) {
|
{username: $scope.auth.username, email: $scope.auth.email, password: $scope.auth.password}, function(d) {
|
||||||
console.log(d);
|
console.log(d);
|
||||||
setSuccessfulResponse($scope, 'Auto information updated.', '#response');
|
setSuccessfulResponse($scope, 'Auth information updated.', '#response');
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setFailedResponse($scope, e.data, '#response');
|
setFailedResponse($scope, e.data, '#response');
|
||||||
|
@ -133,6 +140,10 @@ function ContainerController($scope, $routeParams, $location, Container) {
|
||||||
|
|
||||||
$scope.changes = [];
|
$scope.changes = [];
|
||||||
|
|
||||||
|
$scope.hasContent = function(data) {
|
||||||
|
return data !== null && data !== undefined && data.length > 1;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.getChanges = function() {
|
$scope.getChanges = function() {
|
||||||
Container.changes({id: $routeParams.id}, function(d) {
|
Container.changes({id: $routeParams.id}, function(d) {
|
||||||
$scope.changes = d;
|
$scope.changes = d;
|
||||||
|
@ -143,7 +154,10 @@ function ContainerController($scope, $routeParams, $location, Container) {
|
||||||
$scope.container = d;
|
$scope.container = d;
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
$location.path('/containers/');
|
setFailedResponse($scope, e.data, '#response');
|
||||||
|
if (e.status === 404) {
|
||||||
|
$('.detail').hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.getChanges();
|
$scope.getChanges();
|
||||||
|
@ -175,9 +189,14 @@ function ContainersController($scope, Container, Settings) {
|
||||||
|
|
||||||
function ImagesController($scope, Image) {
|
function ImagesController($scope, Image) {
|
||||||
$scope.predicate = '-Created';
|
$scope.predicate = '-Created';
|
||||||
|
$('#response').hide();
|
||||||
|
$scope.alertClass = 'block';
|
||||||
|
|
||||||
Image.query({}, function(d) {
|
Image.query({}, function(d) {
|
||||||
$scope.images = d;
|
$scope.images = d;
|
||||||
|
}, function (e) {
|
||||||
|
console.log(e);
|
||||||
|
setFailedResponse($scope, e.data, '#response');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +240,10 @@ function ImageController($scope, $routeParams, $location, Image) {
|
||||||
$scope.image = d;
|
$scope.image = d;
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
$location.path('/images/');
|
setFailedResponse($scope, e.data, '#response');
|
||||||
|
if (e.status === 404) {
|
||||||
|
$('.detail').hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.getHistory();
|
$scope.getHistory();
|
||||||
|
@ -229,17 +251,21 @@ function ImageController($scope, $routeParams, $location, Image) {
|
||||||
|
|
||||||
function StartContainerController($scope, $routeParams, $location, Container) {
|
function StartContainerController($scope, $routeParams, $location, Container) {
|
||||||
$scope.template = 'partials/startcontainer.html';
|
$scope.template = 'partials/startcontainer.html';
|
||||||
$scope.memory = 0;
|
$scope.config = {
|
||||||
$scope.memorySwap = 0;
|
memory: 0,
|
||||||
$scope.env = '';
|
memorySwap: 0,
|
||||||
$scope.dns = '';
|
env: '',
|
||||||
$scope.volumesFrom = '';
|
commands: '',
|
||||||
$scope.commands = '';
|
volumesFrom: ''
|
||||||
|
};
|
||||||
|
$scope.commandPlaceholder = '["/bin/echo", "Hello world"]';
|
||||||
|
|
||||||
$scope.launchContainer = function() {
|
$scope.launchContainer = function() {
|
||||||
|
$scope.response = '';
|
||||||
|
|
||||||
var cmds = null;
|
var cmds = null;
|
||||||
if ($scope.commands !== '') {
|
if ($scope.config.commands !== '') {
|
||||||
cmds = $scope.commands.split('\n');
|
cmds = angular.fromJson($scope.config.commands);
|
||||||
}
|
}
|
||||||
var id = $routeParams.id;
|
var id = $routeParams.id;
|
||||||
var ctor = Container;
|
var ctor = Container;
|
||||||
|
@ -248,10 +274,10 @@ function StartContainerController($scope, $routeParams, $location, Container) {
|
||||||
|
|
||||||
Container.create({
|
Container.create({
|
||||||
Image: id,
|
Image: id,
|
||||||
Memory: $scope.memory,
|
Memory: $scope.config.memory,
|
||||||
MemorySwap: $scope.memorySwap,
|
MemorySwap: $scope.config.memorySwap,
|
||||||
Cmd: cmds,
|
Cmd: cmds,
|
||||||
VolumesFrom: $scope.volumesFrom
|
VolumesFrom: $scope.config.volumesFrom
|
||||||
}, function(d) {
|
}, function(d) {
|
||||||
console.log(d);
|
console.log(d);
|
||||||
if (d.Id) {
|
if (d.Id) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ angular.module('dockerui.services', ['ngResource'])
|
||||||
create :{method: 'POST', params: {action:'create'}},
|
create :{method: 'POST', params: {action:'create'}},
|
||||||
insert :{method: 'POST', params: {id: '@id', action:'insert'}},
|
insert :{method: 'POST', params: {id: '@id', action:'insert'}},
|
||||||
push :{method: 'POST', params: {id: '@id', action:'push'}},
|
push :{method: 'POST', params: {id: '@id', action:'push'}},
|
||||||
tag :{method: 'POST', params: {id: '@id', action:'tag'}},
|
tag :{method: 'POST', params: {id: '@id', action:'tag', force: 0, repo: '@repo'}},
|
||||||
delete :{id: '@id', method: 'DELETE'}
|
delete :{id: '@id', method: 'DELETE'}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -53,11 +53,12 @@ angular.module('dockerui.services', ['ngResource'])
|
||||||
get: {method: 'GET'}
|
get: {method: 'GET'}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.factory('Settings', function(DOCKER_ENDPOINT, DOCKER_API_VERSION) {
|
.factory('Settings', function(DOCKER_ENDPOINT, DOCKER_API_VERSION, UI_VERSION) {
|
||||||
return {
|
return {
|
||||||
displayAll: false,
|
displayAll: false,
|
||||||
endpoint: DOCKER_ENDPOINT,
|
endpoint: DOCKER_ENDPOINT,
|
||||||
version: DOCKER_API_VERSION,
|
version: DOCKER_API_VERSION,
|
||||||
url: DOCKER_ENDPOINT + DOCKER_API_VERSION
|
url: DOCKER_ENDPOINT + '/' + DOCKER_API_VERSION,
|
||||||
|
uiVersion: UI_VERSION
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<div class="detail">
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
<div id="response" class="alert alert-{{ alertClass }}">
|
|
||||||
{{ response }}
|
{{ response }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
|
||||||
<h4>Container: {{ container.Id }}</h4>
|
<h4>Container: {{ container.Id }}</h4>
|
||||||
|
|
||||||
<div class="btn-group detail">
|
<div class="btn-group detail">
|
||||||
|
@ -51,7 +52,7 @@
|
||||||
|
|
||||||
<div class="well well-large">
|
<div class="well well-large">
|
||||||
<ul>
|
<ul>
|
||||||
<li ng-repeat="change in changes">
|
<li ng-repeat="change in changes | filter:hasContent">
|
||||||
<strong>{{ change.Path }}</strong> {{ change.Kind }}
|
<strong>{{ change.Path }}</strong> {{ change.Kind }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<div class="detail">
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
|
|
||||||
<div id="response" class="alert alert-{{ alertClass }}">
|
|
||||||
{{ response }}
|
{{ response }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
|
||||||
<h4>Image: {{ image.id }}</h4>
|
<h4>Image: {{ image.id }}</h4>
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
|
@ -64,15 +64,15 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<form>
|
<form class="form-inline">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Tag to Repo</legend>
|
<legend>Tag image</legend>
|
||||||
<label>Repo:</label>
|
<label>Tag:</label>
|
||||||
<input type="text" placeholder="Repo..." ng-model="tag.repo" required>
|
<input type="text" placeholder="repo..." ng-model="tag.repo">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" ng-model="tag.force"/> Force?
|
<input type="checkbox" ng-model="tag.force"/> Force?
|
||||||
</label>
|
</label>
|
||||||
<input type="button" ng-click="updateTag()" value="Update" class="btn btn-info"/>
|
<input type="button" ng-click="updateTag()" value="Tag" class="btn btn-info"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
|
||||||
<h2>Images:</h2>
|
<h2>Images:</h2>
|
||||||
|
|
||||||
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
|
{{ response }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -9,17 +9,16 @@
|
||||||
<legend>Start container from Image</legend>
|
<legend>Start container from Image</legend>
|
||||||
|
|
||||||
<label>Cmd:</label>
|
<label>Cmd:</label>
|
||||||
<textarea ng-model="commands" rows="6"></textarea>
|
<input type="text" placeholder="{{ commandPlaceholder }}" ng-model="config.commands"/>
|
||||||
<small>Place each command on a new line</small>
|
<small>Input commands as an array</small>
|
||||||
|
|
||||||
<label>Memory:</label>
|
<label>Memory:</label>
|
||||||
<input type="number" ng-model="memory"/>
|
<input type="number" ng-model="config.memory"/>
|
||||||
|
|
||||||
<label>Memory Swap:</label>
|
<label>Memory Swap:</label>
|
||||||
<input type="number" ng-model="memorySwap"/>
|
<input type="number" ng-model="config.memorySwap"/>
|
||||||
|
|
||||||
<label>Volumes From:</label>
|
<label>Volumes From:</label>
|
||||||
<input type="text" ng-model="volumesFrom"/>
|
<input type="text" ng-model="config.volumesFrom"/>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<input type="button" ng-click="launchContainer()" value="Launch" />
|
<input type="button" ng-click="launchContainer()" value="Launch" />
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="footer center well">
|
||||||
|
<p><small>Docker API Version: <strong>{{ apiVersion }}</strong> UI Version: <strong>{{ uiVersion }}</strong> Created by: <a href="http://crosbymichael.com">crosbymichael</a></small></p>
|
||||||
|
</div>
|
Loading…
Reference in New Issue