Commit c4b8619f authored by David Fernandez's avatar David Fernandez

Update status reconcilement

When receiving irreconcilable migration states from the Container
Registry, make sure that the Rails state is coherent with that.

Example: Rails states is import_aborted and Container Registry status is
importing, the Enqueuer job should leave the image repository in the
importing state.
parent 6cb104e8
...@@ -16,8 +16,6 @@ class ContainerRepository < ApplicationRecord ...@@ -16,8 +16,6 @@ class ContainerRepository < ApplicationRecord
ABORTABLE_MIGRATION_STATES = (ACTIVE_MIGRATION_STATES + %w[pre_import_done default]).freeze ABORTABLE_MIGRATION_STATES = (ACTIVE_MIGRATION_STATES + %w[pre_import_done default]).freeze
SKIPPABLE_MIGRATION_STATES = (ABORTABLE_MIGRATION_STATES + %w[import_aborted]).freeze SKIPPABLE_MIGRATION_STATES = (ABORTABLE_MIGRATION_STATES + %w[import_aborted]).freeze
IRRECONCILABLE_MIGRATIONS_STATUSES = %w[import_in_progress pre_import_in_progress pre_import_canceled import_canceled].freeze
MIGRATION_PHASE_1_STARTED_AT = Date.new(2021, 11, 4).freeze MIGRATION_PHASE_1_STARTED_AT = Date.new(2021, 11, 4).freeze
TooManyImportsError = Class.new(StandardError) TooManyImportsError = Class.new(StandardError)
...@@ -113,7 +111,7 @@ class ContainerRepository < ApplicationRecord ...@@ -113,7 +111,7 @@ class ContainerRepository < ApplicationRecord
end end
event :start_pre_import do event :start_pre_import do
transition default: :pre_importing transition %i[default pre_importing importing import_aborted] => :pre_importing
end end
event :finish_pre_import do event :finish_pre_import do
...@@ -153,7 +151,10 @@ class ContainerRepository < ApplicationRecord ...@@ -153,7 +151,10 @@ class ContainerRepository < ApplicationRecord
container_repository.migration_pre_import_done_at = nil container_repository.migration_pre_import_done_at = nil
end end
after_transition any => :pre_importing do |container_repository| after_transition any => :pre_importing do |container_repository, transition|
forced = transition.args.first.try(:[], :forced)
next if forced
container_repository.try_import do container_repository.try_import do
container_repository.migration_pre_import container_repository.migration_pre_import
end end
...@@ -168,7 +169,10 @@ class ContainerRepository < ApplicationRecord ...@@ -168,7 +169,10 @@ class ContainerRepository < ApplicationRecord
container_repository.migration_import_done_at = nil container_repository.migration_import_done_at = nil
end end
after_transition any => :importing do |container_repository| after_transition any => :importing do |container_repository, transition|
forced = transition.args.first.try(:[], :forced)
next if forced
container_repository.try_import do container_repository.try_import do
container_repository.migration_import container_repository.migration_import
end end
...@@ -259,10 +263,10 @@ class ContainerRepository < ApplicationRecord ...@@ -259,10 +263,10 @@ class ContainerRepository < ApplicationRecord
super super
end end
def start_pre_import def start_pre_import(*args)
return false unless ContainerRegistry::Migration.enabled? return false unless ContainerRegistry::Migration.enabled?
super super(*args)
end end
def retry_pre_import def retry_pre_import
...@@ -295,8 +299,18 @@ class ContainerRepository < ApplicationRecord ...@@ -295,8 +299,18 @@ class ContainerRepository < ApplicationRecord
case status case status
when 'native' when 'native'
finish_import_as(:native_import) finish_import_as(:native_import)
when *IRRECONCILABLE_MIGRATIONS_STATUSES when 'pre_import_in_progress'
nil return if pre_importing?
start_pre_import(forced: true)
when 'import_in_progress'
return if importing?
start_import(forced: true)
when 'import_canceled', 'pre_import_canceled'
return if import_skipped?
skip_import(reason: :migration_canceled)
when 'import_complete' when 'import_complete'
finish_import finish_import
when 'import_failed' when 'import_failed'
......
...@@ -224,7 +224,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do ...@@ -224,7 +224,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
end end
end end
it_behaves_like 'transitioning from allowed states', %w[default] it_behaves_like 'transitioning from allowed states', %w[default pre_importing importing import_aborted]
it_behaves_like 'transitioning to pre_importing' it_behaves_like 'transitioning to pre_importing'
end end
......
...@@ -118,11 +118,14 @@ RSpec.shared_examples 'not hitting graphql network errors with the container reg ...@@ -118,11 +118,14 @@ RSpec.shared_examples 'not hitting graphql network errors with the container reg
end end
RSpec.shared_examples 'reconciling migration_state' do RSpec.shared_examples 'reconciling migration_state' do
shared_examples 'no action' do shared_examples 'enforcing states coherence to' do |expected_migration_state|
it 'does nothing' do it 'leaves the repository in the expected migration_state' do
expect { subject }.not_to change { repository.reload.migration_state } expect(repository.gitlab_api_client).not_to receive(:pre_import_repository)
expect(repository.gitlab_api_client).not_to receive(:import_repository)
expect(subject).to eq(nil) subject
expect(repository.reload.migration_state).to eq(expected_migration_state)
end end
end end
...@@ -155,7 +158,7 @@ RSpec.shared_examples 'reconciling migration_state' do ...@@ -155,7 +158,7 @@ RSpec.shared_examples 'reconciling migration_state' do
context 'import_in_progress response' do context 'import_in_progress response' do
let(:status) { 'import_in_progress' } let(:status) { 'import_in_progress' }
it_behaves_like 'no action' it_behaves_like 'enforcing states coherence to', 'importing'
end end
context 'import_complete response' do context 'import_complete response' do
...@@ -175,7 +178,7 @@ RSpec.shared_examples 'reconciling migration_state' do ...@@ -175,7 +178,7 @@ RSpec.shared_examples 'reconciling migration_state' do
context 'pre_import_in_progress response' do context 'pre_import_in_progress response' do
let(:status) { 'pre_import_in_progress' } let(:status) { 'pre_import_in_progress' }
it_behaves_like 'no action' it_behaves_like 'enforcing states coherence to', 'pre_importing'
end end
context 'pre_import_complete response' do context 'pre_import_complete response' do
...@@ -194,4 +197,12 @@ RSpec.shared_examples 'reconciling migration_state' do ...@@ -194,4 +197,12 @@ RSpec.shared_examples 'reconciling migration_state' do
it_behaves_like 'retrying the pre_import' it_behaves_like 'retrying the pre_import'
end end
%w[pre_import_canceled import_canceled].each do |canceled_status|
context "#{canceled_status} response" do
let(:status) { canceled_status }
it_behaves_like 'enforcing states coherence to', 'import_skipped'
end
end
end end
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