Commit 8239bfd4 authored by Michael Kozono's avatar Michael Kozono

Merge branch 'registry-replication' into 'master'

Delete event for Docker Registry Replication

See merge request gitlab-org/gitlab-ee!16066
parents 3b9238b7 91652b13
......@@ -60,7 +60,10 @@ module Geo
def primary_tags
@primary_tags ||= begin
client.repository_tags(name)['tags'].map do |tag|
tags = client.repository_tags(name)['tags']
return [] if tags.nil?
tags.map do |tag|
{ name: tag, digest: client.repository_tag_digest(name, tag) }
end
end
......
......@@ -10,14 +10,14 @@ module ContainerRegistry
def execute
events.each do |event|
handle_push_event(event) if event['action'] == 'push'
handle_event(event) if %w(push delete).include?(event['action'])
end
end
private
def handle_push_event(event)
return unless manifest_push?(event)
def handle_event(event)
return unless manifest_push?(event) || manifest_delete?(event)
::Geo::ContainerRepositoryUpdatedEventStore.new(find_repository!(event)).create!
end
......@@ -26,6 +26,12 @@ module ContainerRegistry
event['target']['mediaType'] =~ /manifest/
end
def manifest_delete?(event)
# There is no clear indication in the event structure when we delete a top-level manifest
# except existance of "tag" key
event['target'].has_key?('tag')
end
def find_repository!(event)
repository_name = event['target']['repository']
path = ContainerRegistry::Path.new(repository_name)
......
......@@ -7,10 +7,14 @@ describe ContainerRegistry::EventHandler do
let(:container_repository) { create(:container_repository) }
let(:event_target) do
let(:event_target_for_push) do
{ 'mediaType' => 'application/vnd.docker.distribution.manifest.v2+json', 'repository' => container_repository.path }
end
let(:event_target_for_delete) do
{ 'tag' => 'latest', 'repository' => container_repository.path }
end
set(:primary_node) { create(:geo_node, :primary) }
set(:secondary_node) { create(:geo_node) }
......@@ -18,15 +22,22 @@ describe ContainerRegistry::EventHandler do
stub_current_geo_node(primary_node)
end
it 'creates event' do
push_event = { action: 'push', target: event_target }.with_indifferent_access
it 'creates event for push' do
push_event = { action: 'push', target: event_target_for_push }.with_indifferent_access
expect { described_class.new([push_event]).execute }
.to change { ::Geo::ContainerRepositoryUpdatedEvent.count }.by(1)
end
it 'ignores non-push events' do
pull_event = { action: 'pull', target: event_target }.with_indifferent_access
it 'creates event for delete' do
delete_event = { action: 'delete', target: event_target_for_delete }.with_indifferent_access
expect { described_class.new([delete_event]).execute }
.to change { ::Geo::ContainerRepositoryUpdatedEvent.count }.by(1)
end
it 'ignores pull events' do
pull_event = { action: 'pull', target: {} }.with_indifferent_access
expect { described_class.new([pull_event]).execute }
.to change { ::Geo::ContainerRepositoryUpdatedEvent.count }.by(0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment