diff --git a/app/docker/components/imageRegistry/por-image-registry.controller.js b/app/docker/components/imageRegistry/por-image-registry.controller.js index 5cf3fc709..a62eb7bff 100644 --- a/app/docker/components/imageRegistry/por-image-registry.controller.js +++ b/app/docker/components/imageRegistry/por-image-registry.controller.js @@ -69,13 +69,19 @@ class porImageRegistryController { async reloadRegistries() { return this.$async(async () => { try { - const registries = await this.EndpointService.registries(this.endpoint.Id, this.namespace); - this.registries = _.concat(this.defaultRegistry, registries); + let showDefaultRegistry = false; + this.registries = await this.EndpointService.registries(this.endpoint.Id, this.namespace); + + // hide default(anonymous) dockerhub registry if user has an authenticated one + if (!this.registries.some((registry) => registry.Type === RegistryTypes.DOCKERHUB)) { + showDefaultRegistry = true; + this.registries.push(this.defaultRegistry); + } const id = this.model.Registry.Id; const registry = _.find(this.registries, { Id: id }); if (!registry) { - this.model.Registry = this.defaultRegistry; + this.model.Registry = showDefaultRegistry ? this.defaultRegistry : this.registries[0]; } } catch (err) { this.Notifications.error('Failure', err, 'Unable to retrieve registries'); diff --git a/app/portainer/services/api/registryService.js b/app/portainer/services/api/registryService.js index 34b8e882f..a398f70bf 100644 --- a/app/portainer/services/api/registryService.js +++ b/app/portainer/services/api/registryService.js @@ -107,17 +107,45 @@ angular.module('portainer.app').factory('RegistryService', [ return url; } + // findBestMatchRegistry finds out the best match registry for repository + // matching precedence: + // 1. registryId matched + // 2. both domain name and username matched (for dockerhub only) + // 3. only URL matched + // 4. pick up the first dockerhub registry + function findBestMatchRegistry(repository, registries, registryId) { + let highMatch, lowMatch; + + for (const registry of registries) { + if (registry.Id == registryId) { + return registry; + } + + if (registry.Type === RegistryTypes.DOCKERHUB) { + // try to match repository examples: + // /nginx:latest + // docker.io//nginx:latest + if (repository.startsWith(registry.Username + '/') || repository.startsWith(getURL(registry) + '/' + registry.Username + '/')) { + highMatch = registry; + } + + // try to match repository examples: + // portainer/portainer-ee:latest + // /portainer-ee:latest + lowMatch = lowMatch || registry; + } + + if (_.includes(repository, getURL(registry))) { + lowMatch = registry; + } + } + + return highMatch || lowMatch; + } + function retrievePorRegistryModelFromRepositoryWithRegistries(repository, registries, registryId) { const model = new PorImageRegistryModel(); - const registry = registries.find((reg) => { - if (registryId) { - return reg.Id === registryId; - } - if (reg.Type === RegistryTypes.DOCKERHUB) { - return _.includes(repository, reg.Username); - } - return _.includes(repository, getURL(reg)); - }); + const registry = findBestMatchRegistry(repository, registries, registryId); if (registry) { const url = getURL(registry); let lastIndex = repository.lastIndexOf(url);