feat(registry): registry or direct url selector

pull/3393/head
xAt0mZ 2019-10-15 21:55:35 +02:00
parent a41ca1fd46
commit e00185a160
10 changed files with 116 additions and 96 deletions

View File

@ -1,9 +1,24 @@
<div class="form-group">
<div class="col-sm-12">
<label for="use_registry" class="control-label text-left">
Use registry
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="$ctrl.useRegistry"><i></i>
</label>
</div>
</div>
<!-- use registry -->
<div ng-if="$ctrl.useRegistry">
<div class="form-group">
<label for="image_name" ng-class="$ctrl.labelClass" class="control-label text-left">Image</label>
<div ng-class="$ctrl.inputClass">
<input type="text" class="form-control" uib-typeahead="image for image in $ctrl.availableImages | filter:$viewValue | limitTo:5"
<div class="input-group">
<span class="input-group-addon" id="registry-name">{{$ctrl.registry.URL}}</span>
<input type="text" class="form-control" aria-describedby="registry-name" uib-typeahead="image for image in $ctrl.availableImages | filter:$viewValue | limitTo:5"
ng-model="$ctrl.image" name="image_name" placeholder="e.g. myImage:myTag" required>
</div>
</div>
<label for="image_registry" class="margin-sm-top control-label text-right" ng-class="$ctrl.labelClass">
Registry
</label>
@ -12,6 +27,19 @@
class="form-control"></select>
</div>
</div>
</div>
<!-- ! use registry -->
<!-- don't use registry -->
<div ng-if="!$ctrl.useRegistry">
<div class="form-group">
<label for="image_name" ng-class="$ctrl.labelClass" class="control-label text-left">Image</label>
<div ng-class="$ctrl.inputClass">
<input type="text" class="form-control" ng-model="$ctrl.image" name="image_name" placeholder="e.g. registry:port/myImage:myTag" required>
</div>
</div>
</div>
<!-- ! don't use registry -->
<!-- info message -->
<div class="form-group" ng-show="$ctrl.form.image_name.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="$ctrl.form.image_name.$error">
@ -19,3 +47,4 @@
</div>
</div>
</div>
<!-- ! info message -->

View File

@ -1,31 +1,40 @@
import angular from 'angular';
import _ from 'lodash-es';
angular.module('portainer.docker')
.controller('porImageRegistryController', ['$q', 'RegistryService', 'DockerHubService', 'ImageService', 'Notifications',
function ($q, RegistryService, DockerHubService, ImageService, Notifications) {
var ctrl = this;
class porImageRegistryController {
/* @ngInject */
constructor($async, RegistryService, DockerHubService, ImageService, Notifications) {
this.$async = $async;
this.RegistryService = RegistryService;
this.DockerHubService = DockerHubService;
this.ImageService = ImageService;
this.Notifications = Notifications;
function initComponent() {
$q.all({
registries: RegistryService.registries(),
dockerhub: DockerHubService.dockerhub(),
availableImages: ctrl.autoComplete ? ImageService.images() : []
})
.then(function success(data) {
var dockerhub = data.dockerhub;
var registries = data.registries;
ctrl.availableImages = ImageService.getUniqueTagListFromImages(data.availableImages);
ctrl.availableRegistries = [dockerhub].concat(registries);
if (!ctrl.registry.Id) {
ctrl.registry = dockerhub;
this.onInit = this.onInit.bind(this);
}
async onInit() {
try {
const [registries, dockerhub, availableImages] = await Promise.all([this.RegistryService.registries(),
this.DockerHubService.dockerhub(),
this.autoComplete ? this.ImageService.images() : []]);
this.availableImages = this.ImageService.getUniqueTagListFromImages(availableImages);
this.availableRegistries = [dockerhub].concat(registries);
if (!this.registry.Id) {
this.registry = dockerhub;
} else {
ctrl.registry = _.find(ctrl.availableRegistries, { 'Id': ctrl.registry.Id });
this.registry = _.find(this.availableRegistries, { 'Id': this.registry.Id });
}
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retrieve registries');
}
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve registries');
});
}
initComponent();
}]);
$onInit() {
this.useRegistry = true;
return this.$async(this.onInit);
}
}
export default porImageRegistryController;
angular.module('portainer.docker').controller('porImageRegistryController', porImageRegistryController);

View File

@ -1,4 +1,4 @@
import _ from 'lodash-es';
// import _ from 'lodash-es';
angular.module('portainer.docker')
.factory('ImageHelper', [function ImageHelperFactory() {
@ -12,26 +12,26 @@ angular.module('portainer.docker')
return tag.match(/^(?![\.\-])([a-zA-Z0-9\_\.\-])+$/g);
}
helper.extractImageAndRegistryFromRepository = function(repository) {
var slashCount = _.countBy(repository)['/'];
var registry = null;
var image = repository;
if (slashCount >= 1) {
// assume something/something[/...]
registry = repository.substr(0, repository.indexOf('/'));
// assume valid DNS name or IP (contains at least one '.')
if (_.countBy(registry)['.'] > 0) {
image = repository.substr(repository.indexOf('/') + 1);
} else {
registry = null;
}
}
// helper.extractImageAndRegistryFromRepository = function(repository) {
// var slashCount = _.countBy(repository)['/'];
// var registry = null;
// var image = repository;
// if (slashCount >= 1) {
// // assume something/something[/...]
// registry = repository.substr(0, repository.indexOf('/'));
// // assume valid DNS name or IP (contains at least one '.')
// if (_.countBy(registry)['.'] > 0) {
// image = repository.substr(repository.indexOf('/') + 1);
// } else {
// registry = null;
// }
// }
return {
registry: registry,
image: image
};
};
// return {
// registry: registry,
// image: image
// };
// };
helper.getImagesNamesForDownload = function(images) {
var names = images.map(function(image) {
@ -42,34 +42,12 @@ angular.module('portainer.docker')
};
};
function extractNameAndTag(imageName, registry) {
var imageNameAndTag = imageName.split(':');
var image = imageNameAndTag[0];
var tag = imageNameAndTag[1] ? imageNameAndTag[1] : 'latest';
if (registry) {
image = registry + '/' + imageNameAndTag[0];
}
return {
image: image,
tag: tag
};
}
helper.createImageConfigForCommit = function(imageName, registry) {
var imageAndTag = extractNameAndTag(imageName, registry);
return {
repo: imageAndTag.image,
tag: imageAndTag.tag
};
};
helper.createImageConfigForContainer = function (imageName, registry) {
var imageAndTag = extractNameAndTag(imageName, registry);
void registry;
console.log(imageName);
return {
fromImage: imageAndTag.image,
tag: imageAndTag.tag
};
fromImage: imageName
}
};
helper.removeDigestFromRepository = function(repository) {

View File

@ -5,6 +5,7 @@ angular.module('portainer.docker')
endpointId: EndpointProvider.endpointID
},
{
commitContainer: {method: 'POST', params: {container: '@id', repo: '@repo', tag: '@tag'}, ignoreLoadingBar: true}
// commitContainer: {method: 'POST', params: {container: '@id', repo: '@repo', tag: '@tag'}, ignoreLoadingBar: true}
commitContainer: {method: 'POST', params: {container: '@id', repo: '@repo'}, ignoreLoadingBar: true}
});
}]);

View File

@ -15,7 +15,8 @@ function ImageFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider, HttpR
search: {method: 'GET', params: {action: 'search'}},
history: {method: 'GET', params: {action: 'history'}, isArray: true},
insert: {method: 'POST', params: {id: '@id', action: 'insert'}},
tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo', tag: '@tag'}, ignoreLoadingBar: true},
// tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo', tag: '@tag'}, ignoreLoadingBar: true},
tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo'}, ignoreLoadingBar: true},
inspect: {method: 'GET', params: {id: '@id', action: 'json'}},
push: {
method: 'POST', params: {action: 'push', id: '@tag'},

View File

@ -108,6 +108,7 @@ function ContainerServiceFactory($q, Container, ResourceControlService, LogHelpe
service.createAndStartContainer = function(configuration) {
var deferred = $q.defer();
var container;
console.log(configuration);
service.createContainer(configuration)
.then(function success(data) {
container = data;

View File

@ -128,11 +128,13 @@ angular.module('portainer.docker')
}
service.pullImage = function(image, registry, ignoreErrors) {
var imageDetails = ImageHelper.extractImageAndRegistryFromRepository(image);
var imageConfiguration = ImageHelper.createImageConfigForContainer(imageDetails.image, registry.URL);
// var imageDetails = ImageHelper.extractImageAndRegistryFromRepository(image);
// var imageConfiguration = ImageHelper.createImageConfigForContainer(imageDetails.image, registry.URL);
var authenticationDetails = registry.Authentication ? RegistryService.encodedCredentials(registry) : '';
HttpRequestHelper.setRegistryAuthenticationHeader(authenticationDetails);
var imageConfiguration = ImageHelper.createImageConfigForContainer(image, registry.URL);
if (ignoreErrors) {
return pullImageAndIgnoreErrors(imageConfiguration);
}
@ -140,8 +142,8 @@ angular.module('portainer.docker')
};
service.tagImage = function(id, image, registry) {
var imageConfig = ImageHelper.createImageConfigForCommit(image, registry);
return Image.tag({id: id, tag: imageConfig.tag, repo: imageConfig.repo}).$promise;
void registry;
return Image.tag({id: id, repo: image}).$promise;
};
service.downloadImages = function(images) {

View File

@ -133,8 +133,7 @@ function ($q, $scope, $async, $state, $timeout, $transition$, $filter, Container
var image = config.Image;
var registry = $scope.formValues.Registry;
var imageConfig = ImageHelper.createImageConfigForContainer(image, registry.URL);
config.Image = imageConfig.fromImage + ':' + imageConfig.tag;
$scope.imageConfig = imageConfig;
config.Image = imageConfig.fromImage ;//+ ':' + imageConfig.tag;
}
function preparePortBindings(config) {
@ -296,6 +295,7 @@ function ($q, $scope, $async, $state, $timeout, $transition$, $filter, Container
config.Cmd = ContainerHelper.commandStringToArray(config.Cmd);
prepareNetworkConfig(config);
prepareImageConfig(config);
console.log(config);
preparePortBindings(config);
prepareConsole(config);
prepareEnvironmentVariables(config);

View File

@ -150,11 +150,9 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co
};
$scope.commit = function () {
var image = $scope.config.Image;
const image = $scope.config.Image;
$scope.config.Image = '';
var registry = $scope.config.Registry;
var imageConfig = ImageHelper.createImageConfigForCommit(image, registry.URL);
Commit.commitContainer({id: $transition$.params().id, tag: imageConfig.tag, repo: imageConfig.repo}, function () {
Commit.commitContainer({id: $transition$.params().id, repo: image}, function () {
update();
Notifications.success('Image created', $transition$.params().id);
}, function (e) {

View File

@ -1,6 +1,7 @@
export function DockerHubViewModel(data) {
this.Name = 'DockerHub';
this.URL = '';
this.URL = 'docker.io';
// this.URL = '';
this.Authentication = data.Authentication;
this.Username = data.Username;
this.Password = data.Password;