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.
This commit is contained in:
Grzegorz Bizon 2017-04-03 12:49:54 +02:00
parent 6fefa79430
commit fd30b3d497
5 changed files with 149 additions and 2 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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))