1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 00:09:40 +02:00

refactor(image): refactor the code used in image and image details controller (#705)

This commit is contained in:
Anthony Lapenna 2017-03-20 12:01:35 +01:00 committed by GitHub
parent c2e63070e6
commit 24b51a7e87
8 changed files with 245 additions and 167 deletions

View file

@ -7,7 +7,7 @@
</rd-header-content>
</rd-header>
<div class="row" ng-if="RepoTags.length > 0">
<div class="row" ng-if="image.RepoTags.length > 0">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="fa fa-tags" title="Image tags"></rd-widget-header>
@ -15,7 +15,7 @@
<form class="form-horizontal">
<div class="form-group">
<div class="row">
<div class="pull-left" ng-repeat="tag in RepoTags" style="display:table">
<div class="pull-left" ng-repeat="tag in image.RepoTags" style="display:table">
<div class="input-group col-md-1" style="padding:0 15px">
<span class="input-group-addon">{{ tag }}</span>
<span class="input-group-btn">
@ -25,7 +25,7 @@
<a data-toggle="tooltip" class="btn btn-primary interactive" title="Pull from registry" ng-click="pullImage(tag)">
<span class="fa fa-download white-icon" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" class="btn btn-primary interactive" title="Remove tag" ng-click="removeImage(tag)">
<a data-toggle="tooltip" class="btn btn-primary interactive" title="Remove tag" ng-click="removeTag(tag)">
<span class="fa fa-trash-o white-icon" aria-hidden="true"></span>
</a>
</span>
@ -36,7 +36,9 @@
<div class="form-group">
<div class="col-sm-12">
<span class="small text-muted">
Note: you can click on the upload icon to push or on the download icon to pull an image and on the trash icon to delete a tag
Note: you can click on the upload icon <span class="fa fa-upload" aria-hidden="true"></span> to push an image
or on the download icon <span class="fa fa-download" aria-hidden="true"></span> to pull an image
or on the trash icon <span class="fa fa-trash-o" aria-hidden="true"></span> to delete a tag.
</span>
</div>
</div>
@ -133,33 +135,33 @@
<tbody>
<tr>
<td>CMD</td>
<td><code>{{ image.ContainerConfig.Cmd|command }}</code></td>
<td><code>{{ image.Command|command }}</code></td>
</tr>
<tr ng-if="image.ContainerConfig.Entrypoint">
<tr ng-if="image.Entrypoint">
<td>ENTRYPOINT</td>
<td><code>{{ image.ContainerConfig.Entrypoint|command }}</code></td>
<td><code>{{ image.Entrypoint|command }}</code></td>
</tr>
<tr ng-if="image.ContainerConfig.ExposedPorts">
<tr ng-if="image.ExposedPorts.length > 0">
<td>EXPOSE</td>
<td>
<span class="label label-default space-right" ng-repeat="port in exposedPorts">
<span class="label label-default space-right" ng-repeat="port in image.ExposedPorts">
{{ port }}
</span>
</td>
</tr>
<tr ng-if="image.ContainerConfig.Volumes">
<tr ng-if="image.Volumes.length > 0">
<td>VOLUME</td>
<td>
<span class="label label-default space-right" ng-repeat="volume in volumes">
<span class="label label-default space-right" ng-repeat="volume in image.Volumes">
{{ volume }}
</span>
</td>
</tr>
<tr>
<tr ng-if="image.Env.length > 0">
<td>ENV</td>
<td>
<table class="table table-bordered table-condensed">
<tr ng-repeat="var in image.ContainerConfig.Env">
<tr ng-repeat="var in image.Env">
<td>{{ var|key: '=' }}</td>
<td>{{ var|value: '=' }}</td>
</tr>

View file

@ -1,111 +1,109 @@
angular.module('image', [])
.filter('onlylabel', function(){
return function(tag){
return tag.substr(tag.indexOf(":")+1);
.controller('ImageController', ['$scope', '$stateParams', '$state', 'ImageService', 'Messages',
function ($scope, $stateParams, $state, ImageService, Messages) {
$scope.config = {
Image: '',
Registry: ''
};
})
.controller('ImageController', ['$scope', '$stateParams', '$state', 'Image', 'ImageService', 'ImageHelper', 'Messages',
function ($scope, $stateParams, $state, Image, ImageService, ImageHelper, Messages) {
$scope.RepoTags = [];
$scope.config = {
Image: '',
Registry: ''
};
// Get RepoTags from the /images/query endpoint instead of /image/json,
// for backwards compatibility with Docker API versions older than 1.21
function getRepoTags(imageId) {
Image.query({}, function (d) {
d.forEach(function(image) {
if (image.Id === imageId && image.RepoTags[0] !== '<none>:<none>') {
$scope.RepoTags = image.RepoTags;
}
});
});
}
$scope.tagImage = function() {
$('#loadingViewSpinner').show();
var image = $scope.config.Image;
var registry = $scope.config.Registry;
$scope.tagImage = function() {
$('#loadingViewSpinner').show();
var image = $scope.config.Image;
var registry = $scope.config.Registry;
var imageConfig = ImageHelper.createImageConfigForCommit(image, registry);
Image.tag({id: $stateParams.id, tag: imageConfig.tag, repo: imageConfig.repo}, function (d) {
Messages.send('Image successfully tagged');
$('#loadingViewSpinner').hide();
$state.go('image', {id: $stateParams.id}, {reload: true});
}, function(e) {
$('#loadingViewSpinner').hide();
Messages.error("Failure", e, "Unable to tag image");
});
};
ImageService.tagImage($stateParams.id, image, registry)
.then(function success(data) {
Messages.send('Image successfully tagged');
$state.go('image', {id: $stateParams.id}, {reload: true});
})
.catch(function error(err) {
Messages.error("Failure", err, "Unable to tag image");
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
$scope.pushImage = function(tag) {
$('#loadingViewSpinner').show();
Image.push({tag: tag}, function (d) {
if (d[d.length-1].error) {
Messages.error("Unable to push image", {}, d[d.length-1].error);
} else {
Messages.send('Image successfully pushed');
}
$('#loadingViewSpinner').hide();
}, function (e) {
$('#loadingViewSpinner').hide();
Messages.error("Failure", e, "Unable to push image");
});
};
$scope.pushImage = function(tag) {
$('#loadingViewSpinner').show();
ImageService.pushImage(tag)
.then(function success() {
Messages.send('Image successfully pushed');
})
.catch(function error(err) {
Messages.error("Failure", err, "Unable to push image tag");
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
$scope.pullImage = function(tag) {
var items = tag.split(":");
var image = items[0];
tag = items[1];
$('#loadingViewSpinner').show();
ImageService.pullImage({fromImage: image, tag: tag})
.then(function success(data) {
Messages.send('Image successfully pulled');
})
.catch(function error(error){
Messages.error("Failure", error, "Unable to pull image");
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
$scope.pullImage = function(tag) {
$('#loadingViewSpinner').show();
var image = $scope.config.Image;
var registry = $scope.config.Registry;
$scope.removeImage = function (id) {
$('#loadingViewSpinner').show();
Image.remove({id: id}, function (d) {
if (d[0].message) {
$('#loadingViewSpinner').hide();
Messages.error("Unable to remove image", {}, d[0].message);
} else {
// If last message key is 'Deleted' or if it's 'Untagged' and there is only one tag associated to the image
// then assume the image is gone and send to images page
if (d[d.length-1].Deleted || (d[d.length-1].Untagged && $scope.RepoTags.length === 1)) {
Messages.send('Image successfully deleted');
$state.go('images', {}, {reload: true});
} else {
Messages.send('Tag successfully deleted');
$state.go('image', {id: $stateParams.id}, {reload: true});
}
}
}, function (e) {
$('#loadingViewSpinner').hide();
Messages.error("Failure", e, 'Unable to remove image');
});
};
ImageService.pullImage(image, registry)
.then(function success(data) {
Messages.send('Image successfully pulled', image);
})
.catch(function error(err){
Messages.error("Failure", err, "Unable to pull image");
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
$('#loadingViewSpinner').show();
Image.get({id: $stateParams.id}, function (d) {
$scope.image = d;
if (d.RepoTags) {
$scope.RepoTags = d.RepoTags;
} else {
getRepoTags(d.Id);
}
$('#loadingViewSpinner').hide();
$scope.exposedPorts = d.ContainerConfig.ExposedPorts ? Object.keys(d.ContainerConfig.ExposedPorts) : [];
$scope.volumes = d.ContainerConfig.Volumes ? Object.keys(d.ContainerConfig.Volumes) : [];
}, function (e) {
Messages.error("Failure", e, "Unable to retrieve image info");
});
$scope.removeTag = function(id) {
$('#loadingViewSpinner').show();
ImageService.deleteImage(id, false)
.then(function success() {
if ($scope.image.RepoTags.length === 1) {
Messages.send('Image successfully deleted', id);
$state.go('images', {}, {reload: true});
} else {
Messages.send('Tag successfully deleted', id);
$state.go('image', {id: $stateParams.id}, {reload: true});
}
})
.catch(function error(err) {
Messages.error("Failure", err, 'Unable to remove image');
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
$scope.removeImage = function (id) {
$('#loadingViewSpinner').show();
ImageService.deleteImage(id, false)
.then(function success() {
Messages.send('Image successfully deleted', id);
$state.go('images', {}, {reload: true});
})
.catch(function error(err) {
Messages.error("Failure", err, 'Unable to remove image');
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
};
function retrieveImageDetails() {
$('#loadingViewSpinner').show();
ImageService.image($stateParams.id)
.then(function success(data) {
$scope.image = data;
})
.catch(function error(err) {
Messages.error("Failure", err, "Unable to retrieve image details");
$state.go('images');
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
}
retrieveImageDetails();
}]);

View file

@ -1,6 +1,6 @@
angular.module('images', [])
.controller('ImagesController', ['$scope', '$state', 'Config', 'Image', 'ImageHelper', 'Messages', 'Pagination', 'ModalService',
function ($scope, $state, Config, Image, ImageHelper, Messages, Pagination, ModalService) {
.controller('ImagesController', ['$scope', '$state', 'Config', 'ImageService', 'Messages', 'Pagination', 'ModalService',
function ($scope, $state, Config, ImageService, Messages, Pagination, ModalService) {
$scope.state = {};
$scope.state.pagination_count = Pagination.getPaginationCount('images');
$scope.sortType = 'RepoTags';
@ -42,20 +42,15 @@ function ($scope, $state, Config, Image, ImageHelper, Messages, Pagination, Moda
$('#pullImageSpinner').show();
var image = $scope.config.Image;
var registry = $scope.config.Registry;
var imageConfig = ImageHelper.createImageConfigForContainer(image, registry);
Image.create(imageConfig, function (data) {
var err = data.length > 0 && data[data.length - 1].hasOwnProperty('error');
if (err) {
var detail = data[data.length - 1];
$('#pullImageSpinner').hide();
Messages.error('Error', {}, detail.error);
} else {
$('#pullImageSpinner').hide();
$state.reload();
}
}, function (e) {
ImageService.pullImage(image, registry)
.then(function success(data) {
$state.reload();
})
.catch(function error(err) {
Messages.error("Failure", err, "Unable to pull image");
})
.finally(function final() {
$('#pullImageSpinner').hide();
Messages.error("Failure", e, "Unable to pull image");
});
};
@ -79,18 +74,16 @@ function ($scope, $state, Config, Image, ImageHelper, Messages, Pagination, Moda
angular.forEach($scope.images, function (i) {
if (i.Checked) {
counter = counter + 1;
Image.remove({id: i.Id, force: force}, function (d) {
if (d[0].message) {
$('#loadImagesSpinner').hide();
Messages.error("Unable to remove image", {}, d[0].message);
} else {
Messages.send("Image deleted", i.Id);
var index = $scope.images.indexOf(i);
$scope.images.splice(index, 1);
}
complete();
}, function (e) {
Messages.error("Failure", e, 'Unable to remove image');
ImageService.deleteImage(i.Id, force)
.then(function success(data) {
Messages.send("Image deleted", i.Id);
var index = $scope.images.indexOf(i);
$scope.images.splice(index, 1);
})
.catch(function error(err) {
Messages.error("Failure", err, 'Unable to remove image');
})
.finally(function final() {
complete();
});
}
@ -98,19 +91,19 @@ function ($scope, $state, Config, Image, ImageHelper, Messages, Pagination, Moda
};
function fetchImages() {
Image.query({}, function (d) {
$scope.images = d.map(function (item) {
return new ImageViewModel(item);
});
$('#loadImagesSpinner').hide();
}, function (e) {
$('#loadImagesSpinner').hide();
Messages.error("Failure", e, "Unable to retrieve images");
$('#loadImagesSpinner').show();
ImageService.images()
.then(function success(data) {
$scope.images = data;
})
.catch(function error(err) {
Messages.error("Failure", err, "Unable to retrieve images");
$scope.images = [];
})
.finally(function final() {
$('#loadImagesSpinner').hide();
});
}
Config.$promise.then(function (c) {
fetchImages();
});
fetchImages();
}]);

View file

@ -45,14 +45,14 @@ function ($scope, $q, $state, $anchorScroll, Config, ContainerService, Container
volumeResourceControlQueries.push(ResourceControlService.setVolumeResourceControl(Authentication.getUserDetails().ID, volume.Name));
});
}
TemplateService.updateContainerConfigurationWithVolumes(templateConfiguration.container, template, data);
TemplateService.updateContainerConfigurationWithVolumes(templateConfiguration, template, data);
return $q.all(volumeResourceControlQueries)
.then(function success() {
return ImageService.pullImage(templateConfiguration.image);
return ImageService.pullImage(template.Image, template.Registry);
});
})
.then(function success(data) {
return ContainerService.createAndStartContainer(templateConfiguration.container);
return ContainerService.createAndStartContainer(templateConfiguration);
})
.then(function success(data) {
Messages.send('Container Started', data.Id);