mirror of https://github.com/portainer/portainer
feat(registry): registry or direct url selector
parent
a41ca1fd46
commit
e00185a160
|
@ -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>
|
||||
|
@ -11,7 +26,20 @@
|
|||
<select ng-options="registry as registry.Name for registry in $ctrl.availableRegistries" ng-model="$ctrl.registry" id="image_registry"
|
||||
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 -->
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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}
|
||||
});
|
||||
}]);
|
||||
|
|
|
@ -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'},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue