mirror of
https://github.com/dobin/lxd-webgui
synced 2025-10-05 23:52:43 +02:00
download images and creation of container works
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
"angular-sanitize": "^1.5.1",
|
||||
"underscore": "^1.8.3",
|
||||
"angular-bootstrap": "^1.2.4",
|
||||
"ui-select": "angular-ui-select#^0.16.0"
|
||||
"ui-select": "angular-ui-select#^0.16.0",
|
||||
"components-font-awesome": "^4.5.0"
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-inverse navbar-default navbar-fixed-top" role="navigation">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
@@ -33,7 +33,7 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand navbar-left" href="#/home"><img height="20" src="img/atng.png"></a>
|
||||
<a class="navbar-brand navbar-left" href="#/home"><img height="20" src="img/logo.png"></a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
|
@@ -2,134 +2,133 @@
|
||||
|
||||
angular.module('myApp.container', ['ngRoute'])
|
||||
.config(['$routeProvider', function ($routeProvider) {
|
||||
$routeProvider.when('/containers', {
|
||||
title: 'Containers',
|
||||
templateUrl: 'modules/container/containers.html',
|
||||
controller: 'containerListCtrl',
|
||||
resolve: {
|
||||
containers: function(ContainerServices) {
|
||||
$routeProvider.when('/containers', {
|
||||
title: 'Containers',
|
||||
templateUrl: 'modules/container/containers.html',
|
||||
controller: 'containerListCtrl',
|
||||
resolve: {
|
||||
containers: function (ContainerServices) {
|
||||
return ContainerServices.getAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/container-create', {
|
||||
title: 'Containers',
|
||||
templateUrl: 'modules/container/container-create.html',
|
||||
controller: 'containerCreateCtrl',
|
||||
resolve: {
|
||||
images: function(ImageServices, $route) {
|
||||
}
|
||||
})
|
||||
.when('/container-create', {
|
||||
title: 'Containers',
|
||||
templateUrl: 'modules/container/container-create.html',
|
||||
controller: 'containerCreateCtrl',
|
||||
resolve: {
|
||||
images: function (ImageServices, $route) {
|
||||
return ImageServices.getAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/container-view/:containerName', {
|
||||
title: 'Container',
|
||||
templateUrl: 'modules/container/container-view.html',
|
||||
controller: 'containerViewCtrl',
|
||||
resolve : {
|
||||
containerState: function(ContainerServices, $route) {
|
||||
return ContainerServices.getState($route.current.params.containerName)
|
||||
},
|
||||
container: function(ContainerServices, $route) {
|
||||
return ContainerServices.getByName($route.current.params.containerName)
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/container-view/:containerName', {
|
||||
title: 'Container',
|
||||
templateUrl: 'modules/container/container-view.html',
|
||||
controller: 'containerViewCtrl',
|
||||
resolve: {
|
||||
containerState: function (ContainerServices, $route) {
|
||||
return ContainerServices.getState($route.current.params.containerName)
|
||||
},
|
||||
container: function (ContainerServices, $route) {
|
||||
return ContainerServices.getByName($route.current.params.containerName)
|
||||
}
|
||||
})
|
||||
.when('/container-edit/:containerName', {
|
||||
title: 'Container',
|
||||
templateUrl: 'modules/container/container-edit.html',
|
||||
controller: 'containerViewCtrl',
|
||||
resolve : {
|
||||
containerState: function(ContainerServices, $route) {
|
||||
return ContainerServices.getState($route.current.params.containerName)
|
||||
},
|
||||
container: function(ContainerServices, $route) {
|
||||
return ContainerServices.getByName($route.current.params.containerName)
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/container-edit/:containerName', {
|
||||
title: 'Container',
|
||||
templateUrl: 'modules/container/container-edit.html',
|
||||
controller: 'containerViewCtrl',
|
||||
resolve: {
|
||||
containerState: function (ContainerServices, $route) {
|
||||
return ContainerServices.getState($route.current.params.containerName)
|
||||
},
|
||||
container: function (ContainerServices, $route) {
|
||||
return ContainerServices.getByName($route.current.params.containerName)
|
||||
}
|
||||
})
|
||||
;
|
||||
}])
|
||||
}
|
||||
})
|
||||
;
|
||||
}])
|
||||
|
||||
|
||||
.controller('containerViewCtrl', function ($scope, $routeParams, $filter, $location, $uibModal, $route,
|
||||
containerState, container, ContainerServices)
|
||||
{
|
||||
containerState, container, ContainerServices) {
|
||||
$scope.container = container.data.metadata;
|
||||
$scope.container.state = containerState.data.metadata;
|
||||
|
||||
$scope.changeState = function(container, state) {
|
||||
ContainerServices.changeState(container.name, state);
|
||||
$scope.changeState = function (container, state) {
|
||||
ContainerServices.changeState(container.name, state);
|
||||
}
|
||||
|
||||
$scope.openEditNameDialog = function(container) {
|
||||
var modalInstance = $uibModal.open({
|
||||
$scope.openEditNameDialog = function (container) {
|
||||
var modalInstance = $uibModal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: 'modules/container/modalEditName.html',
|
||||
controller: 'genericContainerModalCtrl',
|
||||
size: 'sm',
|
||||
resolve: {
|
||||
container: function () {
|
||||
return angular.copy($scope.container);
|
||||
}
|
||||
container: function () {
|
||||
return angular.copy($scope.container);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
modalInstance.result.then(function (newContainer) {
|
||||
var newName = { name: newContainer.name };
|
||||
modalInstance.result.then(function (newContainer) {
|
||||
var newName = {name: newContainer.name};
|
||||
// rename
|
||||
ContainerServices.rename(container.name, newName).success(function(data) {
|
||||
// Move to main because location has changed
|
||||
$location.url("/containers/");
|
||||
ContainerServices.rename(container.name, newName).success(function (data) {
|
||||
// Move to main because location has changed
|
||||
$location.url("/containers/");
|
||||
});
|
||||
}, function () {
|
||||
}, function () {
|
||||
console.log('Modal dismissed at: ' + new Date());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
.controller('genericContainerModalCtrl', function ($scope, $routeParams, $filter, $location, $uibModalInstance,
|
||||
container, ContainerServices)
|
||||
{
|
||||
container, ContainerServices) {
|
||||
$scope.container = container;
|
||||
|
||||
$scope.ok = function () {
|
||||
$uibModalInstance.close($scope.container);
|
||||
$uibModalInstance.close($scope.container);
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
};
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
.controller('containerListCtrl', function ($scope, $routeParams, $filter, $location,
|
||||
ContainerServices, containers)
|
||||
{
|
||||
ContainerServices, containers) {
|
||||
$scope.containers = containers;
|
||||
|
||||
$scope.changeState = function(container, state) {
|
||||
ContainerServices.changeState(container.name, state);
|
||||
$scope.changeState = function (container, state) {
|
||||
ContainerServices.changeState(container.name, state);
|
||||
}
|
||||
|
||||
$scope.delete = function(container, state) {
|
||||
alert("Not yet implemented");
|
||||
//ContainerServices.delete(container.name, state);
|
||||
$scope.delete = function (container, state) {
|
||||
alert("Not yet implemented");
|
||||
//ContainerServices.delete(container.name, state);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
.controller('containerCreateCtrl', function ($scope, $routeParams, $filter, $location,
|
||||
ContainerServices, ImageServices, images)
|
||||
{
|
||||
ContainerServices, ImageServices, images) {
|
||||
$scope.container = {};
|
||||
$scope.selectedImage = {};
|
||||
$scope.images = images;
|
||||
console.log("L: " + JSON.stringify(images));
|
||||
|
||||
$scope.create = function() {
|
||||
alert("Not yet implemented");
|
||||
//ContainerServices.create($scope.container);
|
||||
$scope.setImage = function (image) {
|
||||
$scope.selectedImage = image;
|
||||
}
|
||||
|
||||
$scope.createContainer = function () {
|
||||
ContainerServices.create($scope.container, $scope.selectedImage);
|
||||
}
|
||||
})
|
||||
;
|
||||
|
@@ -1,99 +1,101 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('myApp.container')
|
||||
.factory('ContainerServices', ['$http', '$q', '$timeout',
|
||||
function ($http, $q, $timeout) {
|
||||
var obj = {};
|
||||
.factory('ContainerServices', ['$http', '$q', '$timeout',
|
||||
function ($http, $q, $timeout) {
|
||||
var obj = {};
|
||||
|
||||
obj.isOperationFinished = function(operationID) {
|
||||
return $http.get('https://localhost:9000/1.0/operations' + operationID);
|
||||
}
|
||||
obj.isOperationFinished = function (operationID) {
|
||||
return $http.get('https://localhost:9000/1.0/operations' + operationID);
|
||||
}
|
||||
|
||||
// Get a container
|
||||
obj.getByName = function (containerName) {
|
||||
return $http.get('https://localhost:9000/1.0/containers/' + containerName);
|
||||
}
|
||||
// Get a container
|
||||
obj.getByName = function (containerName) {
|
||||
return $http.get('https://localhost:9000/1.0/containers/' + containerName);
|
||||
}
|
||||
|
||||
// Get a container
|
||||
obj.getByUrl = function (containerUrl, callback) {
|
||||
$http.get('https://localhost:9000' + containerUrl).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
// Get a container
|
||||
obj.getByUrl = function (containerUrl, callback) {
|
||||
$http.get('https://localhost:9000' + containerUrl).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Get all containers
|
||||
obj.getAll = function() {
|
||||
// Get all containers
|
||||
obj.getAll = function () {
|
||||
return $http.get('https://localhost:9000/1.0/containers').then(function (data) {
|
||||
// {"type":"sync","status":"Success","status_code":200,
|
||||
// "metadata":["/1.0/containers/hacking"]}
|
||||
data = data.data;
|
||||
// {"type":"sync","status":"Success","status_code":200,
|
||||
// "metadata":["/1.0/containers/hacking"]}
|
||||
data = data.data;
|
||||
|
||||
if (data.status != "Success") {
|
||||
return $q.reject("Error");
|
||||
}
|
||||
if (data.status != "Success") {
|
||||
return $q.reject("Error");
|
||||
}
|
||||
|
||||
|
||||
var promises = data.metadata.map(function(containerUrl) {
|
||||
return $http.get('https://localhost:9000' + containerUrl).then(function(resp) {
|
||||
return resp.data.metadata;
|
||||
});
|
||||
});
|
||||
var promises = data.metadata.map(function (containerUrl) {
|
||||
return $http.get('https://localhost:9000' + containerUrl).then(function (resp) {
|
||||
return resp.data.metadata;
|
||||
});
|
||||
});
|
||||
|
||||
return $q.all(promises);
|
||||
return $q.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Create container:
|
||||
obj.create = function(containerData, callback) {
|
||||
$http.post('https://localhost:9000/1.0/containers').success(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
obj.create = function (containerData, imageData) {
|
||||
containerData.source = {
|
||||
type: "image",
|
||||
fingerprint: imageData.fingerprint
|
||||
};
|
||||
console.log("C: " + JSON.stringify(containerData));
|
||||
return $http.post('https://localhost:9000/1.0/containers', containerData);
|
||||
}
|
||||
|
||||
// Modify container:
|
||||
obj.modify = function(containerName, containerData, callback) {
|
||||
delete containerData['name'];
|
||||
delete containerData['status'];
|
||||
obj.modify = function (containerName, containerData, callback) {
|
||||
delete containerData['name'];
|
||||
delete containerData['status'];
|
||||
|
||||
$http.put('https://localhost:9000/1.0/containers/' + containerName, containerData).success(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
$http.put('https://localhost:9000/1.0/containers/' + containerName, containerData).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// rename container:
|
||||
obj.rename = function(containerName, containerData) {
|
||||
return $http.post('https://localhost:9000/1.0/containers/' + containerName, containerData);
|
||||
obj.rename = function (containerName, containerData) {
|
||||
return $http.post('https://localhost:9000/1.0/containers/' + containerName, containerData);
|
||||
}
|
||||
|
||||
|
||||
obj.delete = function(containerName, callback) {
|
||||
$http.delete('https://localhost:9000/1.0/containers/' + containerName).success(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
obj.delete = function (containerName, callback) {
|
||||
$http.delete('https://localhost:9000/1.0/containers/' + containerName).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** State **/
|
||||
obj.getState = function(containerName) {
|
||||
return $http.get('https://localhost:9000/1.0/containers/' + containerName + '/state');
|
||||
obj.getState = function (containerName) {
|
||||
return $http.get('https://localhost:9000/1.0/containers/' + containerName + '/state');
|
||||
}
|
||||
|
||||
obj.changeState = function(containerName, state) {
|
||||
var data =
|
||||
{
|
||||
"action": state, // State change action (stop, start, restart, freeze or unfreeze)
|
||||
"timeout": 30, // A timeout after which the state change is considered as failed
|
||||
"force": true, // Force the state change (currently only valid for stop and restart where it means killing the container)
|
||||
"stateful": false // Whether to store or restore runtime state before stopping or startiong (only valid for stop and start, defaults to false)
|
||||
}
|
||||
obj.changeState = function (containerName, state) {
|
||||
var data =
|
||||
{
|
||||
"action": state, // State change action (stop, start, restart, freeze or unfreeze)
|
||||
"timeout": 30, // A timeout after which the state change is considered as failed
|
||||
"force": true, // Force the state change (currently only valid for stop and restart where it means killing the container)
|
||||
"stateful": false // Whether to store or restore runtime state before stopping or startiong (only valid for stop and start, defaults to false)
|
||||
}
|
||||
|
||||
return $http.put('https://localhost:9000/1.0/containers/' + containerName + '/state', data);
|
||||
return $http.put('https://localhost:9000/1.0/containers/' + containerName + '/state', data);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}])
|
||||
}])
|
||||
;
|
||||
|
@@ -1,41 +1,64 @@
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> Name </td>
|
||||
<td> <input ng-model="container.name" type="text" value="{{container.name}}"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Name</td>
|
||||
<td><input ng-model="container.name" type="text" value="{{container.name}}"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Ephemeral</td>
|
||||
<td> {{container.ephemeral}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Stateful</td>
|
||||
<td> {{container.stateful}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Selected Image </td>
|
||||
<td> {{selectedImage.fingerprint | limitTo:12}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" ng-click="createContainer()">
|
||||
<i class="glyphicon glyphicon-add">Add</i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Ephemeral </td>
|
||||
<td> {{container.ephemeral}} </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Stateful </td>
|
||||
<td> {{container.stateful}} </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
Images:
|
||||
<div class="col-md-5">
|
||||
Images:
|
||||
<table class="table table-condensed">
|
||||
|
||||
<tbody>
|
||||
<tbody>
|
||||
<tr ng-repeat="image in images">
|
||||
<td>
|
||||
<b>{{image.filename}}</b>
|
||||
<input type="checkbox" ng-model="s">
|
||||
</td>
|
||||
<td>
|
||||
<b>{{image.architecture}}</b>
|
||||
{{image.fingerprint | limitTo: 12}}
|
||||
</td>
|
||||
<td>
|
||||
{{image.filename}}
|
||||
{{image.properties.description}}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" ng-click="setImage(image)">
|
||||
<i class="glyphicon glyphicon-asterisk"></i>Select
|
||||
</a>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,6 +1,4 @@
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12" ng-show="containers.length > 0">
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
@@ -13,37 +11,41 @@
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="container in containers">
|
||||
<td>
|
||||
<b>{{container.name}}</b>
|
||||
</td>
|
||||
<tr ng-repeat="container in containers">
|
||||
<td>
|
||||
<b>{{container.name}}</b>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{container.status}}
|
||||
</td>
|
||||
<td>
|
||||
{{container.status}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{container.architecture}}
|
||||
</td>
|
||||
<td>
|
||||
{{container.architecture}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{container.stateful}}
|
||||
</td>
|
||||
<td>
|
||||
{{container.stateful}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div ng-if="container.status != 'Running'">
|
||||
<a class="btn btn-sm btn-success" ng-click="changeState(container, 'start')"><i class="glyphicon glyphicon-play"></i>Start</a>
|
||||
</div>
|
||||
<div ng-if="container.status == 'Running'">
|
||||
<a class="btn btn-sm btn-danger" ng-click="changeState(container, 'stop')"><i class="glyphicon glyphicon-stop"></i>Stop</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div ng-if="container.status != 'Running'">
|
||||
<a class="btn btn-sm btn-success" ng-click="changeState(container, 'start')"><i
|
||||
class="glyphicon glyphicon-play"></i>Start</a>
|
||||
</div>
|
||||
<div ng-if="container.status == 'Running'">
|
||||
<a class="btn btn-sm btn-danger" ng-click="changeState(container, 'stop')"><i
|
||||
class="glyphicon glyphicon-stop"></i>Stop</a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" href="#/container-view/{{container.name}}"><i class="glyphicon glyphicon-edit"></i>View</a>
|
||||
<a class="btn btn-sm btn-danger" ng-click="delete(container)"><i class="glyphicon glyphicon-remove"></i>Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" href="#/container-view/{{container.name}}"><i
|
||||
class="glyphicon glyphicon-edit"></i>View</a>
|
||||
<a class="btn btn-sm btn-danger" ng-click="delete(container)"><i
|
||||
class="glyphicon glyphicon-remove"></i>Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@@ -2,36 +2,52 @@
|
||||
|
||||
angular.module('myApp.image', ['ngRoute'])
|
||||
.config(['$routeProvider', function ($routeProvider) {
|
||||
$routeProvider.when('/images', {
|
||||
title: 'Images',
|
||||
templateUrl: 'modules/image/images.html',
|
||||
controller: 'imageListCtrl',
|
||||
resolve: {
|
||||
images: function(ImageServices, $route) {
|
||||
$routeProvider.when('/images', {
|
||||
title: 'Images',
|
||||
templateUrl: 'modules/image/images.html',
|
||||
controller: 'imageListCtrl',
|
||||
resolve: {
|
||||
images: function (ImageServices, $route) {
|
||||
return ImageServices.getAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/image-view/:imageID', {
|
||||
title: 'Images',
|
||||
templateUrl: 'modules/image/image-view.html',
|
||||
controller: 'imageViewCtrl',
|
||||
resolve : {
|
||||
image: function(ImageServices, $route) {
|
||||
return ImageServices.getByFingerprint($route.current.params.imageID)
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/image-view/:imageID', {
|
||||
title: 'Images',
|
||||
templateUrl: 'modules/image/image-view.html',
|
||||
controller: 'imageViewCtrl',
|
||||
resolve: {
|
||||
image: function (ImageServices, $route) {
|
||||
return ImageServices.getByFingerprint($route.current.params.imageID)
|
||||
}
|
||||
})
|
||||
;
|
||||
}])
|
||||
}
|
||||
})
|
||||
.when('/image-add-remote', {
|
||||
title: 'Images',
|
||||
templateUrl: 'modules/image/image-add-remote.html',
|
||||
controller: 'imageAddRemoteCtrl',
|
||||
resolve: {}
|
||||
})
|
||||
;
|
||||
}])
|
||||
|
||||
|
||||
.controller('imageViewCtrl', function ($scope, $routeParams, $filter, $location, image, ImageServices) {
|
||||
$scope.image = image.data.metadata;
|
||||
$scope.image = image.data.metadata;
|
||||
})
|
||||
|
||||
.controller('imageListCtrl', function ($scope, $routeParams, $filter, $location,
|
||||
ImageServices, images)
|
||||
{
|
||||
ImageServices, images) {
|
||||
$scope.images = images;
|
||||
})
|
||||
|
||||
.controller('imageAddRemoteCtrl', function ($scope, $routeParams, $filter, $location, ImageServices) {
|
||||
$scope.addRemoteImage = function () {
|
||||
ImageServices.addRemoteImage($scope.url);
|
||||
}
|
||||
|
||||
$scope.addSourceImage = function () {
|
||||
ImageServices.addSourceImage();
|
||||
}
|
||||
})
|
||||
;
|
||||
|
@@ -51,6 +51,54 @@ angular.module('myApp.image')
|
||||
});
|
||||
}
|
||||
|
||||
obj.addRemoteImage = function(url) {
|
||||
var data = {
|
||||
"public": true,
|
||||
"filename": "test",
|
||||
"properties": {
|
||||
"os": "Ubuntu"
|
||||
},
|
||||
"source": {
|
||||
"type": "url",
|
||||
"url": url
|
||||
}
|
||||
};
|
||||
|
||||
$http.post('https://localhost:9000/1.0/images', data).then(function(data) {
|
||||
var opUrl = data.data.operation;
|
||||
$http.get('https://localhost:9000' + opUrl);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
obj.addSourceImage = function(url) {
|
||||
var data = {
|
||||
// "filename": filename, // Used for export (optional)
|
||||
"public": true, //# Whether the image can be downloaded by untrusted users (defaults to false)
|
||||
// "auto_update": true, //# Whether the image should be auto-updated (optional; defaults to false)
|
||||
// "properties": { //# Image properties (optional, applied on top of source properties)
|
||||
// "os": "Ubuntu"
|
||||
// },
|
||||
"source": {
|
||||
"type": "image",
|
||||
"mode": "pull", //# Only pull is supported for now
|
||||
"server": "https://cloud-images.ubuntu.com/releases", //# Remote server (pull mode only)
|
||||
"protocol": "simplestreams", //# Protocol (one of lxd or simplestreams, defaults to lxd)
|
||||
// "secret": "my-secret-string", // # Secret (pull mode only, private images only)
|
||||
// "certificate": "PEM certificate", //# Optional PEM certificate. If not mentioned, system CA is used.
|
||||
"fingerprint": "3f5e2f5074c2", //# Fingerprint of the image (must be set if alias isn't)
|
||||
// "alias": "ubuntu/devel", //# Name of the alias (must be set if fingerprint isn't)
|
||||
}
|
||||
}
|
||||
|
||||
$http.post('https://localhost:9000/1.0/images', data).then(function(data) {
|
||||
var opUrl = data.data.operation;
|
||||
$http.get('https://localhost:9000' + opUrl);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
return obj;
|
||||
}])
|
||||
;
|
||||
|
88
modules/image/image-add-remote.html
Normal file
88
modules/image/image-add-remote.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<div class="row">
|
||||
Remote Image:
|
||||
<div class="col-md-12">
|
||||
<table class="table table-condensed">
|
||||
<tr>
|
||||
<td class="col-md-1">Source URL
|
||||
</td>
|
||||
|
||||
<td class="col-md-7">
|
||||
<input size="64" type="text" ng-model="url">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Public?
|
||||
</td>
|
||||
|
||||
<td>True
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" ng-click="addRemoteImage()">
|
||||
<i class="glyphicon glyphicon-add"></i>Add</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
Image Source:
|
||||
<div class="col-md-12">
|
||||
<table class="table table-condensed">
|
||||
<tr>
|
||||
<td class="col-md-1">Server
|
||||
</td>
|
||||
|
||||
<td class="col-md-7">
|
||||
<input size="64" type="text" ng-model="source.server">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Protocol:
|
||||
</td>
|
||||
|
||||
<td>simplestreams
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td> Fingerprint:
|
||||
</td>
|
||||
|
||||
<td><input size="64" type="text" ng-model="source.fingerprint">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Alias:
|
||||
</td>
|
||||
|
||||
<td><input size="64" type="text" ng-model="source.alias">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-primary" ng-click="addSourceImage()"><i
|
||||
class="glyphicon glyphicon-add"></i>Add</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@@ -1,20 +1,19 @@
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12" ng-show="images.length > 0">
|
||||
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<th class="col-md-3">Filename</th>
|
||||
<th class="col-md-3">Hash</th>
|
||||
<th class="col-md-3">Description</th>
|
||||
<th class="col-md-3">Architecture</th>
|
||||
<th class="none">Stateful</th>
|
||||
<th class="none">Topic / Tags</th>
|
||||
<th class="col-md-3">Filename</th>
|
||||
<th class="none">Action</th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="image in images">
|
||||
<td>
|
||||
<b>{{image.filename}}</b>
|
||||
<b>{{image.fingerprint | limitTo:12}}</b>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@@ -22,16 +21,11 @@
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{image.architecture}}
|
||||
{{image.filename}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{image.stateful}}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="btn btn-sm btn-success" ng-click="addAsNew(image)"><i class="glyphicon glyphicon-plus"></i>Edit</a>
|
||||
<a class="btn btn-sm btn-success" href="#/image-view/{{image.fingerprint}}"><i class="glyphicon glyphicon-plus"></i>View</a>
|
||||
<a class="btn btn-sm btn-primary" href="#/image-view/{{image.fingerprint}}"><i class="glyphicon glyphicon-zoom-in"></i>View</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -40,7 +34,9 @@
|
||||
|
||||
<div class="col-md-12" ng-show="images.length == 0">
|
||||
<div class="col-md-12">
|
||||
<h4>No Containers</h4>
|
||||
<h4>No images available</h4>
|
||||
|
||||
<a class="btn btn-sm btn-success" href="#/image-add-remote"><i class="glyphicon glyphicon-plus"></i>Add Remote Image</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,38 +2,37 @@
|
||||
|
||||
angular.module('myApp.network', ['ngRoute'])
|
||||
.config(['$routeProvider', function ($routeProvider) {
|
||||
$routeProvider.when('/networks', {
|
||||
title: 'Networks',
|
||||
templateUrl: 'modules/network/networks.html',
|
||||
controller: 'networkListCtrl',
|
||||
resolve: {
|
||||
networks: function(NetworkServices) {
|
||||
$routeProvider.when('/networks', {
|
||||
title: 'Networks',
|
||||
templateUrl: 'modules/network/networks.html',
|
||||
controller: 'networkListCtrl',
|
||||
resolve: {
|
||||
networks: function (NetworkServices) {
|
||||
return NetworkServices.getAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/network-view/:networkName', {
|
||||
title: 'Networks',
|
||||
templateUrl: 'modules/network/network-view.html',
|
||||
controller: 'networkViewCtrl',
|
||||
resolve : {
|
||||
network: function(NetworkServices, $route) {
|
||||
return NetworkServices.getByName($route.current.params.networkName)
|
||||
}
|
||||
}
|
||||
})
|
||||
.when('/network-view/:networkName', {
|
||||
title: 'Networks',
|
||||
templateUrl: 'modules/network/network-view.html',
|
||||
controller: 'networkViewCtrl',
|
||||
resolve: {
|
||||
network: function (NetworkServices, $route) {
|
||||
return NetworkServices.getByName($route.current.params.networkName)
|
||||
}
|
||||
})
|
||||
;
|
||||
}])
|
||||
}
|
||||
})
|
||||
;
|
||||
}])
|
||||
|
||||
|
||||
.controller('networkViewCtrl', function ($scope, $routeParams, $filter, $location, network, NetworkServices) {
|
||||
$scope.network = network.data.metadata;
|
||||
$scope.network = network.data.metadata;
|
||||
|
||||
})
|
||||
|
||||
.controller('networkListCtrl', function ($scope, $routeParams, $filter, $location,
|
||||
NetworkServices, networks)
|
||||
{
|
||||
$scope.networks = networks;
|
||||
NetworkServices, networks) {
|
||||
$scope.networks = networks;
|
||||
})
|
||||
;
|
||||
|
@@ -1,66 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('myApp.network')
|
||||
.factory('NetworkServices', ['$http', '$q',
|
||||
function ($http, $q) {
|
||||
var obj = {};
|
||||
.factory('NetworkServices', ['$http', '$q',
|
||||
function ($http, $q) {
|
||||
var obj = {};
|
||||
|
||||
// Get a container
|
||||
obj.getByName = function (networkName) {
|
||||
// Get a container
|
||||
obj.getByName = function (networkName) {
|
||||
return $http.get('https://localhost:9000/1.0/networks/' + networkName);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a network
|
||||
obj.get = function (networkName, callback) {
|
||||
$http.get('https://localhost:9000/1.0/networks/' + networkName).success(function (data) {
|
||||
callback(data);
|
||||
// Get a network
|
||||
obj.get = function (networkName, callback) {
|
||||
$http.get('https://localhost:9000/1.0/networks/' + networkName).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
// Get a network
|
||||
obj.getByUrl = function (networkUrl, callback) {
|
||||
$http.get('https://localhost:9000' + networkUrl).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Get all networks
|
||||
obj.getAll = function () {
|
||||
return $http.get('https://localhost:9000/1.0/networks').then(function (data) {
|
||||
// {"type":"sync","status":"Success","status_code":200,
|
||||
// "metadata":["/1.0/networks/hacking"]}
|
||||
data = data.data;
|
||||
|
||||
if (data.status != "Success") {
|
||||
return $q.reject("Error");
|
||||
}
|
||||
|
||||
var promises = data.metadata.map(function (networkUrl) {
|
||||
return $http.get('https://localhost:9000' + networkUrl).then(function (resp) {
|
||||
return resp.data.metadata;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Get a network
|
||||
obj.getByUrl = function (networkUrl, callback) {
|
||||
$http.get('https://localhost:9000' + networkUrl).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
return $q.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Get all networks
|
||||
obj.getAll = function() {
|
||||
return $http.get('https://localhost:9000/1.0/networks').then(function (data) {
|
||||
// {"type":"sync","status":"Success","status_code":200,
|
||||
// "metadata":["/1.0/networks/hacking"]}
|
||||
data = data.data;
|
||||
// Create network:
|
||||
obj.create = function (networkData, callback) {
|
||||
$http.post('https://localhost:9000/1.0/networks').success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
if (data.status != "Success") {
|
||||
return $q.reject("Error");
|
||||
}
|
||||
// Modify network:
|
||||
obj.modify = function (networkName, networkData, callback) {
|
||||
$http.put('https://localhost:9000/1.0/networks/' + networkName).success(function (data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
var promises = data.metadata.map(function(networkUrl) {
|
||||
return $http.get('https://localhost:9000' + networkUrl).then(function(resp) {
|
||||
return resp.data.metadata;
|
||||
});
|
||||
});
|
||||
|
||||
return $q.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Create network:
|
||||
obj.create = function(networkData, callback) {
|
||||
$http.post('https://localhost:9000/1.0/networks').success(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
// Modify network:
|
||||
obj.modify = function(networkName, networkData, callback) {
|
||||
$http.put('https://localhost:9000/1.0/networks/' + networkName).success(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
|
||||
return obj;
|
||||
}])
|
||||
return obj;
|
||||
}])
|
||||
;
|
||||
|
Reference in New Issue
Block a user