diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-04-03 13:49:54 +0300 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-04-03 14:03:16 +0300 |
commit | fd30b3d4972180b6e91d0180b140f32622c48b1d (patch) | |
tree | 9ff40552f415568869ee3ec86c2f5a276c3ab4b9 | |
parent | 6fefa794304a6233368b592422ea0fb71a2700f0 (diff) |
Ensure root container repository when visiting registry
Root container repository is a images repository that had been created
before 9.1, before we introduced multi-level images support.
-rw-r--r-- | app/controllers/projects/registry/repositories_controller.rb | 16 | ||||
-rw-r--r-- | app/models/container_repository.rb | 12 | ||||
-rw-r--r-- | spec/controllers/projects/registry/repositories_controller_spec.rb | 82 | ||||
-rw-r--r-- | spec/factories/container_repositories.rb | 4 | ||||
-rw-r--r-- | spec/models/container_repository_spec.rb | 37 |
5 files changed, 149 insertions, 2 deletions
diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index 2901d83fcef..ab4344bcf3c 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -2,6 +2,7 @@ module Projects module Registry class RepositoriesController < ::Projects::Registry::ApplicationController before_action :authorize_update_container_image!, only: [:destroy] + before_action :ensure_root_container_repository!, only: [:index] def index @images = project.container_repositories @@ -22,6 +23,21 @@ module Projects def image @image ||= project.container_repositories.find_by(id: params[:id]) end + + ## + # Container repository object for root project path. + # + # Needed to maintain a backwards compatibility. + # + def ensure_root_container_repository! + ContainerRegistry::Path.new(@project.full_path).tap do |path| + return if path.has_repository? + + ContainerRepository.build_from_path(path).tap do |repository| + repository.save if repository.has_tags? + end + end + end end end end diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb index 0cf781799e9..36158d75ae8 100644 --- a/app/models/container_repository.rb +++ b/app/models/container_repository.rb @@ -48,6 +48,10 @@ class ContainerRepository < ActiveRecord::Base tags.to_a.any? end + def root_repository? + name.empty? + end + def delete_tags! return unless has_tags? @@ -58,8 +62,12 @@ class ContainerRepository < ActiveRecord::Base end end + def self.build_from_path(path) + self.new(project: path.repository_project, + name: path.repository_name) + end + def self.create_from_path!(path) - self.create(project: path.repository_project, - name: path.repository_name) + build_from_path(path).tap(&:save!) end end diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb new file mode 100644 index 00000000000..e514f535f1d --- /dev/null +++ b/spec/controllers/projects/registry/repositories_controller_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe Projects::Registry::RepositoriesController do + let(:user) { create(:user) } + let(:project) { create(:empty_project, :private) } + + before do + sign_in(user) + end + + context 'when user has access to registry' do + before do + project.add_developer(user) + end + + describe 'GET index' do + context 'when root container repository exists' do + before do + create(:container_repository, :root, project: project) + end + + it 'does not create root container repository' do + expect { go_to_index }.not_to change { ContainerRepository.all.count } + end + end + + context 'when root container repository does not exist' do + context 'when there are tags for this repository' do + before do + stub_container_registry_tags(%w[rc1 latest]) + end + + it 'successfully renders container repositories' do + go_to_index + + expect(response).to have_http_status(:ok) + end + + it 'creates a root container repository' do + expect { go_to_index }.to change { ContainerRepository.all.count }.by(1) + expect(ContainerRepository.first).to be_root_repository + end + end + + context 'when there are no tags for this repository' do + before do + stub_container_registry_tags(*[]) + end + + it 'successfully renders container repositories' do + go_to_index + + expect(response).to have_http_status(:ok) + end + + it 'does not ensure root container repository' do + expect { go_to_index }.not_to change { ContainerRepository.all.count } + end + end + end + end + end + + context 'when user does not have access to registry' do + describe 'GET index' do + it 'responds with 404' do + go_to_index + + expect(response).to have_http_status(:not_found) + end + + it 'does not ensure root container repository' do + expect { go_to_index }.not_to change { ContainerRepository.all.count } + end + end + end + + def go_to_index + get :index, namespace_id: project.namespace, + project_id: project + end +end diff --git a/spec/factories/container_repositories.rb b/spec/factories/container_repositories.rb index 4919a03cdf2..3fcad9fd4b3 100644 --- a/spec/factories/container_repositories.rb +++ b/spec/factories/container_repositories.rb @@ -7,6 +7,10 @@ FactoryGirl.define do tags [] end + trait :root do + name '' + end + after(:build) do |repository, evaluator| next if evaluator.tags.to_a.none? diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb index 503da6556c0..b23ed8e30b6 100644 --- a/spec/models/container_repository_spec.rb +++ b/spec/models/container_repository_spec.rb @@ -98,6 +98,43 @@ describe ContainerRepository do end end + describe '#root_repository?' do + context 'when repository is a root repository' do + let(:repository) { create(:container_repository, :root) } + + it 'returns true' do + expect(repository).to be_root_repository + end + end + + context 'when repository is not a root repository' do + it 'returns false' do + expect(container_repository).not_to be_root_repository + end + end + end + + describe '.build_from_path' do + let(:path) { project.full_path + '/some/image' } + let(:repository_path) { ContainerRegistry::Path.new(path) } + + let(:repository) do + described_class.build_from_path(ContainerRegistry::Path.new(path)) + end + + it 'fabricates repository assigned to a correct project' do + expect(repository.project).to eq project + end + + it 'fabricates repository with a correct name' do + expect(repository.name).to eq 'some/image' + end + + it 'is not persisted' do + expect(repository).not_to be_persisted + end + end + describe '.create_from_path!' do let(:repository) do described_class.create_from_path!(ContainerRegistry::Path.new(path)) |