Fill/validate new sharding-related fields in ci_runner_machines
What does this MR do and why?
This MR adds logic to fill the runner_type
and sharding_key_id
fields in new ci_runner_machines
records, when e.g. they are retrieved as part of runner pings (POST /api/v4/runners/verify
).
This logic was first introduced in !168069 (merged) and reverted in !168575 (merged) due to a fault in the model lookup logic (example) which caused an S2 incident. The problem was that RunnerManager.safe_find_or_create_by!
was taking the runner_type
and sharding_key_id
values for creating a new record. However, since the table wasn't backfilled, the lookup would not find a record with the runner_type
and sharding_key_id
values, even though a potential match with nil values existed in the table. This resulted in a unique key constraint violation, which unfortunately didn't manifest itself in staging as it did in production (with the 404 errors).
This MR fixes the lookup and adds specs that reproduce the scenario of non-backfilled rows.
The previous code now fails with:
Failures:
1) API::Ci::Helpers::Runner#current_runner_manager when runner manager already exists when a runner manager with nil runner_type and sharding_key_id already exists reuses and updates existing runner manager
Got 1 failure and 1 other error:
1.1) Failure/Error: expect { current_runner_manager }.not_to raise_error
expected no Exception, got #<ActiveRecord::RecordNotFound: ActiveRecord::RecordNotFound> with backtrace:
# ./app/models/application_record.rb:61:in `block in safe_find_or_create_by!'
# ./app/models/application_record.rb:60:in `safe_find_or_create_by!'
# ./app/models/ci/runner.rb:520:in `ensure_manager'
# ./lib/api/ci/helpers/runner.rb:58:in `block in current_runner_manager'
# ./gems/gitlab-utils/lib/gitlab/utils/strong_memoize.rb:34:in `strong_memoize'
# ./lib/api/ci/helpers/runner.rb:56:in `current_runner_manager'
# ./spec/lib/api/ci/helpers/runner_spec.rb:93:in `block (3 levels) in <main>'
# ./spec/lib/api/ci/helpers/runner_spec.rb:116:in `block (6 levels) in <main>'
# ./spec/lib/api/ci/helpers/runner_spec.rb:116:in `block (5 levels) in <main>'
# ./spec/spec_helper.rb:475:in `block (3 levels) in <main>'
Part of #497526 (closed)
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
How to set up and validate locally
Numbered steps to set up and validate the change are strongly suggested.
Reintroduce the lookup code from the previous MR and run the tests.