diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 73d6c2f21afc8d3100be3155d5b0f104035dff03..3701a629bea23f3ecda5342949ecd9f944f219ef 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -176,7 +176,6 @@ Rails/TimeZone: - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_renamed_event_spec.rb' - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb' - 'ee/spec/lib/gitlab/geo/log_cursor/events/reset_checksum_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb' - 'ee/spec/lib/gitlab/geo/log_cursor/logger_spec.rb' - 'ee/spec/lib/gitlab/git_access_spec.rb' - 'ee/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb' diff --git a/db/post_migrate/20211021140426_remove_geo_upload_deprecated_fields.rb b/db/post_migrate/20211021140426_remove_geo_upload_deprecated_fields.rb new file mode 100644 index 0000000000000000000000000000000000000000..7d0033c0ab92fb0834f7386a3bde4c020737b981 --- /dev/null +++ b/db/post_migrate/20211021140426_remove_geo_upload_deprecated_fields.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class RemoveGeoUploadDeprecatedFields < Gitlab::Database::Migration[1.0] + disable_ddl_transaction! + + def up + with_lock_retries do + remove_column :geo_event_log, :upload_deleted_event_id, :bigint + end + end + + def down + with_lock_retries do + add_column(:geo_event_log, :upload_deleted_event_id, :bigint) unless column_exists?(:geo_event_log, :upload_deleted_event_id) + end + + add_concurrent_foreign_key :geo_event_log, :geo_upload_deleted_events, + column: :upload_deleted_event_id, + name: 'fk_c1f241c70d', + on_delete: :cascade + + add_concurrent_index :geo_event_log, + :upload_deleted_event_id, + name: 'index_geo_event_log_on_upload_deleted_event_id', + where: "(upload_deleted_event_id IS NOT NULL)" + end +end diff --git a/db/post_migrate/20211021141930_drop_geo_upload_deleted_events_table.rb b/db/post_migrate/20211021141930_drop_geo_upload_deleted_events_table.rb new file mode 100644 index 0000000000000000000000000000000000000000..b6987e68fb1eb0ac235901833a79bfd04269e2c7 --- /dev/null +++ b/db/post_migrate/20211021141930_drop_geo_upload_deleted_events_table.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class DropGeoUploadDeletedEventsTable < Gitlab::Database::Migration[1.0] + def up + drop_table :geo_upload_deleted_events + end + + def down + create_table :geo_upload_deleted_events, id: :bigserial do |t| + t.integer :upload_id, null: false, index: true + t.string :file_path, null: false + t.integer :model_id, null: false + t.string :model_type, null: false + t.string :uploader, null: false + end + end +end diff --git a/db/post_migrate/20211022160154_remove_outdated_fields_from_geo_node_status.rb b/db/post_migrate/20211022160154_remove_outdated_fields_from_geo_node_status.rb new file mode 100644 index 0000000000000000000000000000000000000000..5b117f9e4b817d2bda244e7c012eeb40c295a778 --- /dev/null +++ b/db/post_migrate/20211022160154_remove_outdated_fields_from_geo_node_status.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class RemoveOutdatedFieldsFromGeoNodeStatus < Gitlab::Database::Migration[1.0] + enable_lock_retries! + + def change + remove_column :geo_node_statuses, :attachments_count, :integer + remove_column :geo_node_statuses, :attachments_synced_count, :integer + remove_column :geo_node_statuses, :attachments_failed_count, :integer + remove_column :geo_node_statuses, :attachments_synced_missing_on_primary_count, :integer + end +end diff --git a/db/schema_migrations/20211021140426 b/db/schema_migrations/20211021140426 new file mode 100644 index 0000000000000000000000000000000000000000..c32db84a1384ee136dea70734749373ee56be558 --- /dev/null +++ b/db/schema_migrations/20211021140426 @@ -0,0 +1 @@ +bc7974917509bfbda47375299009295bc5a55970b92443dd5d7134075b161279 \ No newline at end of file diff --git a/db/schema_migrations/20211021141930 b/db/schema_migrations/20211021141930 new file mode 100644 index 0000000000000000000000000000000000000000..294e1c80aeaffcdc4fbdd6e39656d01620763981 --- /dev/null +++ b/db/schema_migrations/20211021141930 @@ -0,0 +1 @@ +483e4cbe2a0be2afbda511f2298e3715abaca29afafeeae26449fc862f49a08f \ No newline at end of file diff --git a/db/schema_migrations/20211022160154 b/db/schema_migrations/20211022160154 new file mode 100644 index 0000000000000000000000000000000000000000..2a76379bc66a08b24f1f12a991ae04a7023b21ab --- /dev/null +++ b/db/schema_migrations/20211022160154 @@ -0,0 +1 @@ +c474870a626c909da772a1c9f459f369d50658ce8f585a35e7cc3c7ef64af657 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index e0efa8b9c3948ff56e22fada838baa408a6b61a5..4c6e8ddc7901c835f9f6e28e0add6be0f8d874cf 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -14170,7 +14170,6 @@ CREATE TABLE geo_event_log ( hashed_storage_migrated_event_id bigint, lfs_object_deleted_event_id bigint, hashed_storage_attachments_event_id bigint, - upload_deleted_event_id bigint, job_artifact_deleted_event_id bigint, reset_checksum_event_id bigint, cache_invalidation_event_id bigint, @@ -14300,9 +14299,6 @@ CREATE TABLE geo_node_statuses ( lfs_objects_count integer, lfs_objects_synced_count integer, lfs_objects_failed_count integer, - attachments_count integer, - attachments_synced_count integer, - attachments_failed_count integer, last_event_id integer, last_event_date timestamp without time zone, cursor_last_event_id integer, @@ -14327,7 +14323,6 @@ CREATE TABLE geo_node_statuses ( wikis_verification_failed_count integer, lfs_objects_synced_missing_on_primary_count integer, job_artifacts_synced_missing_on_primary_count integer, - attachments_synced_missing_on_primary_count integer, repositories_checksummed_count integer, repositories_checksum_failed_count integer, repositories_checksum_mismatch_count integer, @@ -14496,24 +14491,6 @@ CREATE SEQUENCE geo_reset_checksum_events_id_seq ALTER SEQUENCE geo_reset_checksum_events_id_seq OWNED BY geo_reset_checksum_events.id; -CREATE TABLE geo_upload_deleted_events ( - id bigint NOT NULL, - upload_id integer NOT NULL, - file_path character varying NOT NULL, - model_id integer NOT NULL, - model_type character varying NOT NULL, - uploader character varying NOT NULL -); - -CREATE SEQUENCE geo_upload_deleted_events_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE geo_upload_deleted_events_id_seq OWNED BY geo_upload_deleted_events.id; - CREATE TABLE gitlab_subscription_histories ( id bigint NOT NULL, gitlab_subscription_created_at timestamp with time zone, @@ -21508,8 +21485,6 @@ ALTER TABLE ONLY geo_repository_updated_events ALTER COLUMN id SET DEFAULT nextv ALTER TABLE ONLY geo_reset_checksum_events ALTER COLUMN id SET DEFAULT nextval('geo_reset_checksum_events_id_seq'::regclass); -ALTER TABLE ONLY geo_upload_deleted_events ALTER COLUMN id SET DEFAULT nextval('geo_upload_deleted_events_id_seq'::regclass); - ALTER TABLE ONLY gitlab_subscription_histories ALTER COLUMN id SET DEFAULT nextval('gitlab_subscription_histories_id_seq'::regclass); ALTER TABLE ONLY gitlab_subscriptions ALTER COLUMN id SET DEFAULT nextval('gitlab_subscriptions_id_seq'::regclass); @@ -23127,9 +23102,6 @@ ALTER TABLE ONLY geo_repository_updated_events ALTER TABLE ONLY geo_reset_checksum_events ADD CONSTRAINT geo_reset_checksum_events_pkey PRIMARY KEY (id); -ALTER TABLE ONLY geo_upload_deleted_events - ADD CONSTRAINT geo_upload_deleted_events_pkey PRIMARY KEY (id); - ALTER TABLE ONLY gitlab_subscription_histories ADD CONSTRAINT gitlab_subscription_histories_pkey PRIMARY KEY (id); @@ -25948,8 +25920,6 @@ CREATE INDEX index_geo_event_log_on_repository_updated_event_id ON geo_event_log CREATE INDEX index_geo_event_log_on_reset_checksum_event_id ON geo_event_log USING btree (reset_checksum_event_id) WHERE (reset_checksum_event_id IS NOT NULL); -CREATE INDEX index_geo_event_log_on_upload_deleted_event_id ON geo_event_log USING btree (upload_deleted_event_id) WHERE (upload_deleted_event_id IS NOT NULL); - CREATE INDEX index_geo_hashed_storage_attachments_events_on_project_id ON geo_hashed_storage_attachments_events USING btree (project_id); CREATE INDEX index_geo_hashed_storage_migrated_events_on_project_id ON geo_hashed_storage_migrated_events USING btree (project_id); @@ -25986,8 +25956,6 @@ CREATE INDEX index_geo_repository_updated_events_on_source ON geo_repository_upd CREATE INDEX index_geo_reset_checksum_events_on_project_id ON geo_reset_checksum_events USING btree (project_id); -CREATE INDEX index_geo_upload_deleted_events_on_upload_id ON geo_upload_deleted_events USING btree (upload_id); - CREATE INDEX index_gin_ci_pending_builds_on_namespace_traversal_ids ON ci_pending_builds USING gin (namespace_traversal_ids); CREATE INDEX index_gitlab_subscription_histories_on_gitlab_subscription_id ON gitlab_subscription_histories USING btree (gitlab_subscription_id); @@ -29350,9 +29318,6 @@ ALTER TABLE ONLY design_management_versions ALTER TABLE ONLY packages_packages ADD CONSTRAINT fk_c188f0dba4 FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE SET NULL; -ALTER TABLE ONLY geo_event_log - ADD CONSTRAINT fk_c1f241c70d FOREIGN KEY (upload_deleted_event_id) REFERENCES geo_upload_deleted_events(id) ON DELETE CASCADE; - ALTER TABLE ONLY analytics_cycle_analytics_project_stages ADD CONSTRAINT fk_c3339bdfc9 FOREIGN KEY (stage_event_hash_id) REFERENCES analytics_cycle_analytics_stage_event_hashes(id) ON DELETE CASCADE; diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md index a244a92394ba0ea4adf10198a9ae17c86bde5916..2f9c1e3bc9c37363733a8acc5e9ccc9fb8e0d840 100644 --- a/doc/administration/monitoring/prometheus/gitlab_metrics.md +++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md @@ -190,9 +190,6 @@ configuration option in `gitlab.yml`. These metrics are served from the | `geo_lfs_objects` | Gauge | 10.2 | Total number of LFS objects available on primary | `url` | | `geo_lfs_objects_synced` | Gauge | 10.2 | Number of LFS objects synced on secondary | `url` | | `geo_lfs_objects_failed` | Gauge | 10.2 | Number of LFS objects failed to sync on secondary | `url` | -| `geo_attachments` | Gauge | 10.2 | Total number of file attachments available on primary | `url` | -| `geo_attachments_synced` | Gauge | 10.2 | Number of attachments synced on secondary | `url` | -| `geo_attachments_failed` | Gauge | 10.2 | Number of attachments failed to sync on secondary | `url` | | `geo_last_event_id` | Gauge | 10.2 | Database ID of the latest event log entry on the primary | `url` | | `geo_last_event_timestamp` | Gauge | 10.2 | UNIX timestamp of the latest event log entry on the primary | `url` | | `geo_cursor_last_event_id` | Gauge | 10.2 | Last database ID of the event log processed by the secondary | `url` | @@ -201,7 +198,6 @@ configuration option in `gitlab.yml`. These metrics are served from the | `geo_last_successful_status_check_timestamp` | Gauge | 10.2 | Last timestamp when the status was successfully updated | `url` | | `geo_lfs_objects_synced_missing_on_primary` | Gauge | 10.7 | Number of LFS objects marked as synced due to the file missing on the primary | `url` | | `geo_job_artifacts_synced_missing_on_primary` | Gauge | 10.7 | Number of job artifacts marked as synced due to the file missing on the primary | `url` | -| `geo_attachments_synced_missing_on_primary` | Gauge | 10.7 | Number of attachments marked as synced due to the file missing on the primary | `url` | | `geo_repositories_checksummed` | Gauge | 10.7 | Number of repositories checksummed on primary | `url` | | `geo_repositories_checksum_failed` | Gauge | 10.7 | Number of repositories failed to calculate the checksum on primary | `url` | | `geo_wikis_checksummed` | Gauge | 10.7 | Number of wikis checksummed on primary | `url` | diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md index d9b23485fd53830eb6f26f1b70eba895daf8585c..fb821824dd1583834d60181255956f2f4d8693f4 100644 --- a/doc/api/geo_nodes.md +++ b/doc/api/geo_nodes.md @@ -306,11 +306,6 @@ Example response: "health": "Healthy", "health_status": "Healthy", "missing_oauth_application": false, - "attachments_count": 1, - "attachments_synced_count": null, - "attachments_failed_count": null, - "attachments_synced_missing_on_primary_count": 0, - "attachments_synced_in_percentage": "0.00%", "db_replication_lag_seconds": null, "lfs_objects_count": 0, "lfs_objects_synced_count": null, @@ -465,11 +460,6 @@ Example response: "health": "Healthy", "health_status": "Healthy", "missing_oauth_application": false, - "attachments_count": 1, - "attachments_synced_count": 1, - "attachments_failed_count": 0, - "attachments_synced_missing_on_primary_count": 0, - "attachments_synced_in_percentage": "100.00%", "db_replication_lag_seconds": 0, "lfs_objects_count": 0, "lfs_objects_synced_count": 0, @@ -628,11 +618,6 @@ Example response: "health": "Healthy", "health_status": "Healthy", "missing_oauth_application": false, - "attachments_count": 1, - "attachments_synced_count": 1, - "attachments_failed_count": 0, - "attachments_synced_missing_on_primary_count": 0, - "attachments_synced_in_percentage": "100.00%", "db_replication_lag_seconds": 0, "lfs_objects_count": 0, "lfs_objects_synced_count": 0, diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md index 1a08bc1cffbaaaeaaed81576065c907320d24053..6ddbe2f9646dad327c4e568f9487a5af2f68ea19 100644 --- a/doc/development/service_ping/index.md +++ b/doc/development/service_ping/index.md @@ -231,10 +231,6 @@ We also collect metrics specific to [Geo](../../administration/geo/index.md) sec "repositories_replication_enabled"=>true, "repositories_synced_count"=>24, "repositories_failed_count"=>0, - "attachments_replication_enabled"=>true, - "attachments_count"=>1, - "attachments_synced_count"=>1, - "attachments_failed_count"=>0, "git_fetch_event_count_weekly"=>nil, "git_push_event_count_weekly"=>nil, ... other geo node status fields diff --git a/ee/app/controllers/admin/geo/uploads_controller.rb b/ee/app/controllers/admin/geo/uploads_controller.rb deleted file mode 100644 index 44c1049485110d5484af05e1d3477869e2af711b..0000000000000000000000000000000000000000 --- a/ee/app/controllers/admin/geo/uploads_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -class Admin::Geo::UploadsController < Admin::Geo::ApplicationController - before_action :check_license! - before_action :registries, only: [:index] - - def index - end - - def destroy - if registry.upload - flash[:alert] = s_('Geo|Could not remove tracking entry for an existing upload.') - return redirect_back_or_default(default: admin_geo_uploads_path) - end - - registry.destroy - - flash[:toast] = s_('Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed.') % { type: registry.file_type, id: registry.file_id } - redirect_back_or_default(default: admin_geo_uploads_path) - end - - private - - def registries - @registries ||= - ::Geo::UploadRegistry - .with_status(params[:sync_status]) - .with_search(params[:name]) - .fresh - .page(params[:page]) - end - - def registry - @registry ||= ::Geo::UploadRegistry.find_by_id(params[:id]) - end -end diff --git a/ee/app/finders/geo/attachment_legacy_registry_finder.rb b/ee/app/finders/geo/attachment_legacy_registry_finder.rb deleted file mode 100644 index b85c419f6bc678f59b4be8a71c9ea17c141ccfac..0000000000000000000000000000000000000000 --- a/ee/app/finders/geo/attachment_legacy_registry_finder.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Geo - class AttachmentLegacyRegistryFinder < FileRegistryFinder - def registry_class - Geo::UploadRegistry - end - end -end diff --git a/ee/app/helpers/ee/geo_helper.rb b/ee/app/helpers/ee/geo_helper.rb index c804bfb5edbf45e4169593927b27da04def742e6..7c3f821c314a4f7f5a56bb6ad79d01ad24db6ece 100644 --- a/ee/app/helpers/ee/geo_helper.rb +++ b/ee/app/helpers/ee/geo_helper.rb @@ -224,18 +224,6 @@ def replicable_types } ] - if ::Geo::UploadReplicator.disabled? - replicable_types.insert(2, { - data_type: 'blob', - data_type_title: _('File'), - title: _('Upload'), - title_plural: _('Uploads'), - name: 'attachment', - name_plural: 'attachments', - secondary_view: true - }) - end - # Adds all the SSF Data Types automatically enabled_replicator_classes.each do |replicator_class| replicable_types.push( diff --git a/ee/app/models/ee/upload.rb b/ee/app/models/ee/upload.rb index ac5eb901b0b7f3a51cbb15e2f3cdafe0006fef2f..0f9cf57fcc4f5d43e3b821184722b8fe25cd7e3a 100644 --- a/ee/app/models/ee/upload.rb +++ b/ee/app/models/ee/upload.rb @@ -14,8 +14,6 @@ module Upload with_replicator ::Geo::UploadReplicator - after_destroy :log_geo_deleted_event - scope :for_model, ->(model) { where(model_id: model.id, model_type: model.class.name) } scope :syncable, -> { with_files_stored_locally } end @@ -76,7 +74,8 @@ def other_attachments end def log_geo_deleted_event - ::Geo::UploadDeletedEventStore.new(self).create! + # Keep empty for now. Should be addressed in future + # by https://gitlab.com/gitlab-org/gitlab/issues/33817 end end end diff --git a/ee/app/models/geo/event_log.rb b/ee/app/models/geo/event_log.rb index 9c64ca6e0ff2cf24bfe51015592de574c17bfdb9..28a64622a07d4a3860d02cf7b8c15299767949ee 100644 --- a/ee/app/models/geo/event_log.rb +++ b/ee/app/models/geo/event_log.rb @@ -15,7 +15,6 @@ class EventLog < ApplicationRecord Geo::HashedStorageMigratedEvent Geo::HashedStorageAttachmentsEvent Geo::JobArtifactDeletedEvent - Geo::UploadDeletedEvent Geo::ContainerRepositoryUpdatedEvent Geo::Event].freeze @@ -55,10 +54,6 @@ class EventLog < ApplicationRecord class_name: 'Geo::JobArtifactDeletedEvent', foreign_key: :job_artifact_deleted_event_id - belongs_to :upload_deleted_event, - class_name: 'Geo::UploadDeletedEvent', - foreign_key: :upload_deleted_event_id - belongs_to :reset_checksum_event, class_name: 'Geo::ResetChecksumEvent', foreign_key: :reset_checksum_event_id @@ -101,7 +96,6 @@ def event hashed_storage_migrated_event || hashed_storage_attachments_event || job_artifact_deleted_event || - upload_deleted_event || reset_checksum_event || cache_invalidation_event || container_repository_updated_event || diff --git a/ee/app/models/geo/upload_deleted_event.rb b/ee/app/models/geo/upload_deleted_event.rb deleted file mode 100644 index d350ee61fc4954ba6668b4e0c8a1b79201af7482..0000000000000000000000000000000000000000 --- a/ee/app/models/geo/upload_deleted_event.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Geo - class UploadDeletedEvent < ApplicationRecord - include Geo::Model - include Geo::Eventable - - belongs_to :upload - - validates :upload, :file_path, :model_id, :model_type, :uploader, presence: true - - def upload_type - uploader&.sub(/Uploader\z/, '')&.underscore - end - end -end diff --git a/ee/app/models/geo/upload_registry.rb b/ee/app/models/geo/upload_registry.rb index 2fa66d0e363085460e15c7380ee91a73530d4829..50f5762e31d320db0638c4d6f35d84c3e96761fb 100644 --- a/ee/app/models/geo/upload_registry.rb +++ b/ee/app/models/geo/upload_registry.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Geo::UploadRegistry < Geo::BaseRegistry - include Geo::Syncable include ::Geo::ReplicableRegistry extend ::Gitlab::Utils::Override @@ -15,35 +14,14 @@ class Geo::UploadRegistry < Geo::BaseRegistry scope :fresh, -> { order(created_at: :desc) } - # Returns untracked uploads as well as tracked uploads that are unused. - # - # Untracked uploads is an array where each item is a tuple of [id, file_type] - # that is supposed to be synced but don't yet have a registry entry. - # - # Unused uploads is an array where each item is a tuple of [id, file_type] - # that is not supposed to be synced but already have a registry entry. For - # example: - # - # - orphaned registries - # - records that became excluded from selective sync - # - records that are in object storage, and `sync_object_storage` became - # disabled - # - # We compute both sets in this method to reduce the number of DB queries - # performed. - # - # @return [Array] the first element is an Array of untracked uploads, and the - # second element is an Array of tracked uploads that are unused. - # For example: [[[1, 'avatar'], [5, 'file']], [[3, 'attachment']]] def self.find_registry_differences(range) source = self::MODEL_CLASS.replicables_for_current_secondary(range) - .pluck(self::MODEL_CLASS.arel_table[:id], self::MODEL_CLASS.arel_table[:uploader]) - .map! { |id, uploader| [id, uploader.sub(/Uploader\z/, '').underscore] } + .pluck(self::MODEL_CLASS.arel_table[:id]) tracked = self.model_id_in(range) - .pluck(:file_id, :file_type) + .pluck(:file_id) untracked = source - tracked unused_tracked = tracked - source @@ -58,16 +36,16 @@ def self.has_create_events? end def self.insert_for_model_ids(attrs) - records = attrs.map do |file_id, file_type| - new(file_id: file_id, file_type: file_type, created_at: Time.zone.now) + records = attrs.map do |file_id| + new(file_id: file_id, created_at: Time.zone.now) end bulk_insert!(records, returns: :ids) end def self.delete_for_model_ids(attrs) - attrs.map do |file_id, file_type| - delete_worker_class.perform_async(file_type, file_id) + attrs.map do |file_id| + delete_worker_class.perform_async(:upload, file_id) end end @@ -93,62 +71,10 @@ def self.with_status(status) end def file - upload&.path || s_('Removed %{type} with id %{id}') % { type: file_type, id: file_id } + upload&.path || s_('Removed upload with id %{id}') % { id: file_id } end def project return upload.model if upload&.model.is_a?(Project) end - - # Returns a synchronization state based on existing attribute values - # - # It takes into account things like if a successful replication has been done - # if there are pending actions or existing errors - # - # @return [Symbol] :synced, :never, or :failed - def synchronization_state - return :synced if success? - return :never if retry_count.nil? - - :failed - end - - # TODO Remove this when enabling geo_upload_registry by default - # https://gitlab.com/gitlab-org/gitlab/-/issues/340617 - override :registry_consistency_worker_enabled? - def self.registry_consistency_worker_enabled? - true - end - - def self.failed - if ::Geo::UploadReplicator.enabled? - with_state(:failed) - else - where(success: false).where.not(retry_count: nil) - end - end - - def self.never_attempted_sync - if ::Geo::UploadReplicator.enabled? - pending.where(last_synced_at: nil) - else - where(success: false, retry_count: nil) - end - end - - def self.retry_due - if ::Geo::UploadReplicator.enabled? - where(arel_table[:retry_at].eq(nil).or(arel_table[:retry_at].lt(Time.current))) - else - where('retry_at is NULL OR retry_at < ?', Time.current) - end - end - - def self.synced - if ::Geo::UploadReplicator.enabled? - with_state(:synced).or(where(success: true)) - else - where(success: true) - end - end end diff --git a/ee/app/models/geo_node_status.rb b/ee/app/models/geo_node_status.rb index 9937a021e3340c82be014306a23d3a62d1215955..552e6583ac5261cc0b387ce799a4a1658f496f38 100644 --- a/ee/app/models/geo_node_status.rb +++ b/ee/app/models/geo_node_status.rb @@ -16,7 +16,7 @@ class GeoNodeStatus < ApplicationRecord attr_accessor :event_log_max_id, :repository_created_max_id, :repository_updated_max_id, :repository_deleted_max_id, :repository_renamed_max_id, :repositories_changed_max_id, :lfs_object_deleted_max_id, :job_artifact_deleted_max_id, - :lfs_objects_registry_count, :job_artifacts_registry_count, :attachments_registry_count, + :lfs_objects_registry_count, :job_artifacts_registry_count, :hashed_storage_migrated_max_id, :hashed_storage_attachments_max_id, :repositories_checked_count, :repositories_checked_failed_count @@ -64,10 +64,6 @@ def self.usage_data_fields repositories_replication_enabled repositories_synced_count repositories_failed_count - attachments_replication_enabled - attachments_count - attachments_synced_count - attachments_failed_count wikis_synced_count wikis_failed_count job_artifacts_replication_enabled @@ -81,7 +77,6 @@ def self.usage_data_fields wikis_verification_failed_count wikis_verification_total_count job_artifacts_synced_missing_on_primary_count - attachments_synced_missing_on_primary_count repositories_checksummed_count repositories_checksum_failed_count repositories_checksum_mismatch_count @@ -137,12 +132,6 @@ def self.replicator_class_prometheus_metrics job_artifacts_failed_count: 'Number of syncable job artifacts failed to sync on secondary', job_artifacts_registry_count: 'Number of job artifacts in the registry', job_artifacts_synced_missing_on_primary_count: 'Number of job artifacts marked as synced due to the file missing on the primary', - attachments_replication_enabled: 'Boolean denoting if replication is enabled for Attachments', - attachments_count: 'Total number of syncable file attachments available on primary', - attachments_synced_count: 'Number of syncable file attachments synced on secondary', - attachments_failed_count: 'Number of syncable file attachments failed to sync on secondary', - attachments_registry_count: 'Number of attachments in the registry', - attachments_synced_missing_on_primary_count: 'Number of attachments marked as synced due to the file missing on the primary', replication_slots_count: 'Total number of replication slots on the primary', replication_slots_used_count: 'Number of replication slots in use on the primary', replication_slots_max_retained_wal_bytes: 'Maximum number of bytes retained in the WAL on the primary', @@ -287,7 +276,6 @@ def initialize_feature_flags self.repository_verification_enabled = Gitlab::Geo.repository_verification_enabled? if Gitlab::Geo.secondary? - self.attachments_replication_enabled = Geo::UploadRegistry.replication_enabled? self.container_repositories_replication_enabled = Geo::ContainerRepositoryRegistry.replication_enabled? self.design_repositories_replication_enabled = Geo::DesignRegistry.replication_enabled? self.job_artifacts_replication_enabled = Geo::JobArtifactRegistry.replication_enabled? @@ -390,7 +378,6 @@ def self.add_attr_in_percentage_for_replicable_classes attr_in_percentage :wikis_checksummed, :wikis_checksummed_count, :wikis_count attr_in_percentage :wikis_verified, :wikis_verified_count, :wikis_count attr_in_percentage :job_artifacts_synced, :job_artifacts_synced_count, :job_artifacts_count - attr_in_percentage :attachments_synced, :attachments_synced_count, :attachments_count attr_in_percentage :replication_slots_used, :replication_slots_used_count, :replication_slots_count attr_in_percentage :container_repositories_synced, :container_repositories_synced_count, :container_repositories_count attr_in_percentage :design_repositories_synced, :design_repositories_synced_count, :design_repositories_count @@ -465,7 +452,6 @@ def load_secondary_data load_repositories_data load_job_artifacts_data - load_attachments_data load_container_registry_data load_designs_data load_ssf_replicable_data @@ -490,16 +476,6 @@ def load_job_artifacts_data self.job_artifacts_synced_missing_on_primary_count = job_artifacts_finder.synced_missing_on_primary_count end - def load_attachments_data - return unless attachments_replication_enabled - - self.attachments_count = attachments_finder.registry_count - self.attachments_synced_count = attachments_finder.synced_count - self.attachments_failed_count = attachments_finder.failed_count - self.attachments_registry_count = attachments_finder.registry_count - self.attachments_synced_missing_on_primary_count = attachments_finder.synced_missing_on_primary_count - end - def load_container_registry_data return unless container_repositories_replication_enabled @@ -594,10 +570,6 @@ def primary_storage_digest @primary_storage_digest ||= Gitlab::Geo.primary_node.find_or_build_status.storage_configuration_digest end - def attachments_finder - @attachments_finder ||= Geo::AttachmentLegacyRegistryFinder.new - end - def job_artifacts_finder @job_artifacts_finder ||= Geo::JobArtifactRegistryFinder.new end diff --git a/ee/app/replicators/geo/upload_replicator.rb b/ee/app/replicators/geo/upload_replicator.rb index a03fe14437f23457396e47c468a997352e93ad06..0e7de2445be1ec54dfddd00a564d613427dfe7bd 100644 --- a/ee/app/replicators/geo/upload_replicator.rb +++ b/ee/app/replicators/geo/upload_replicator.rb @@ -37,16 +37,5 @@ def self.bulk_create_delete_events_async(deleted_uploads) def carrierwave_uploader model_record.retrieve_uploader end - - # TODO: This method can be removed as part of - # https://gitlab.com/gitlab-org/gitlab/-/issues/340617 - override :registry - def registry - super.tap do |record| - # We don't really need this value for SSF, it's only needed to make - # new registry records valid for legacy code in case of disabling the feature. - record.file_type ||= model_record.uploader.delete_suffix("Uploader").underscore - end - end end end diff --git a/ee/app/services/geo/file_download_service.rb b/ee/app/services/geo/file_download_service.rb index 6af8f832542bd7c0a437d8923e54ed45f44fab26..ead356e373bd6185fc58cb3c17ff6dee0fe64c0b 100644 --- a/ee/app/services/geo/file_download_service.rb +++ b/ee/app/services/geo/file_download_service.rb @@ -2,9 +2,8 @@ module Geo # This class is responsible for: - # * Finding the appropriate Downloader class for a UploadRegistry record # * Executing the Downloader - # * Marking the UploadRegistry record as synced or needing retry + # * Marking the Registry record as synced or needing retry class FileDownloadService < BaseFileService include Gitlab::Utils::StrongMemoize @@ -36,7 +35,6 @@ def downloader private def downloader_klass - return Gitlab::Geo::Replication::FileDownloader if user_upload? return Gitlab::Geo::Replication::JobArtifactDownloader if job_artifact? fail_unimplemented_klass!(type: 'Downloader') @@ -59,11 +57,7 @@ def log_file_download(mark_as_synced, download_result, start_time) # rubocop: disable CodeReuse/ActiveRecord def registry strong_memoize(:registry) do - if job_artifact? - Geo::JobArtifactRegistry.find_or_initialize_by(artifact_id: object_db_id) - else - Geo::UploadRegistry.find_or_initialize_by(file_type: object_type, file_id: object_db_id) - end + Geo::JobArtifactRegistry.find_or_initialize_by(artifact_id: object_db_id) end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/ee/app/services/geo/file_registry_removal_service.rb b/ee/app/services/geo/file_registry_removal_service.rb index 9096128fcf2a2a8aca7e453a6d649dc3f8458047..46ecdec2e7ca76c260b7a1a11dfa0ca65b4c701e 100644 --- a/ee/app/services/geo/file_registry_removal_service.rb +++ b/ee/app/services/geo/file_registry_removal_service.rb @@ -43,8 +43,6 @@ def file_registry strong_memoize(:file_registry) do if job_artifact? ::Geo::JobArtifactRegistry.find_by(artifact_id: object_db_id) - elsif user_upload? - ::Geo::UploadRegistry.find_by(file_type: object_type, file_id: object_db_id) elsif replicator replicator.registry end @@ -89,13 +87,7 @@ def file_path next if file_uploader.nil? next file_uploader.file.path if file_uploader.object_store == ObjectStorage::Store::LOCAL - # For remote storage more juggling is needed to actually get the full path on disk - if user_upload? - upload = file_uploader.upload - file_uploader.class.absolute_path(upload) - else - file_uploader.class.absolute_path(file_uploader.file) - end + file_uploader.class.absolute_path(file_uploader.file) end end diff --git a/ee/app/services/geo/upload_deleted_event_store.rb b/ee/app/services/geo/upload_deleted_event_store.rb deleted file mode 100644 index 273d620407d8dd45cb617b4916ccaf31588c6d7f..0000000000000000000000000000000000000000 --- a/ee/app/services/geo/upload_deleted_event_store.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Geo - class UploadDeletedEventStore < EventStore - extend ::Gitlab::Utils::Override - - self.event_type = :upload_deleted_event - - attr_reader :upload - - def initialize(upload) - @upload = upload - end - - private - - def build_event - Geo::UploadDeletedEvent.new( - upload: upload, - file_path: upload.path, - model_id: upload.model_id, - model_type: upload.model_type, - uploader: upload.uploader - ) - end - - # This is called by LogHelpers to build json log with context info - # - # @see ::Gitlab::Geo::LogHelpers - def extra_log_data - { - upload_id: upload.id, - file_path: upload.path, - model_id: upload.model_id, - model_type: upload.model_type, - uploader: upload.uploader - }.compact - end - end -end diff --git a/ee/app/views/admin/geo/shared/_replication_nav.haml b/ee/app/views/admin/geo/shared/_replication_nav.haml index be945102a877029abe39aa43fd9009ca77d2b951..29c5d3b41492fed3efc47de433c8de81cb24f43e 100644 --- a/ee/app/views/admin/geo/shared/_replication_nav.haml +++ b/ee/app/views/admin/geo/shared/_replication_nav.haml @@ -10,11 +10,6 @@ = link_to admin_geo_projects_path, title: _('Projects') do %span = _('Projects') - - if ::Geo::UploadReplicator.disabled? - = nav_link(path: 'admin/geo/uploads#index', html_options: { class: 'gl-pr-2' }) do - = link_to admin_geo_uploads_path, title: _('Uploads') do - %span - = _('Uploads') = nav_link(path: 'admin/geo/designs#index', html_options: { class: 'gl-pr-2' }) do = link_to admin_geo_designs_path, title: _('Designs') do %span diff --git a/ee/app/workers/geo/file_download_dispatch_worker.rb b/ee/app/workers/geo/file_download_dispatch_worker.rb index a1cc0cad082b97180ecd399f08c253559fe883fd..3bc7d1ace16b83528cb9e92931245f4133e56621 100644 --- a/ee/app/workers/geo/file_download_dispatch_worker.rb +++ b/ee/app/workers/geo/file_download_dispatch_worker.rb @@ -71,13 +71,7 @@ def find_low_priority_jobs(batch_size:) end def job_finders - job_finders = [Geo::FileDownloadDispatchWorker::JobArtifactJobFinder.new(scheduled_file_ids(:job_artifact))] - - if ::Geo::UploadReplicator.disabled? - job_finders << Geo::FileDownloadDispatchWorker::AttachmentJobFinder.new(scheduled_file_ids(Gitlab::Geo::Replication::USER_UPLOADS_OBJECT_TYPES)) - end - - job_finders + [Geo::FileDownloadDispatchWorker::JobArtifactJobFinder.new(scheduled_file_ids(:job_artifact))] end def scheduled_file_ids(file_types) diff --git a/ee/app/workers/geo/file_download_dispatch_worker/attachment_job_finder.rb b/ee/app/workers/geo/file_download_dispatch_worker/attachment_job_finder.rb deleted file mode 100644 index de6e2f30655c54e3468c7f107d2bb88730cb568d..0000000000000000000000000000000000000000 --- a/ee/app/workers/geo/file_download_dispatch_worker/attachment_job_finder.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Geo - class FileDownloadDispatchWorker # rubocop:disable Scalability/IdempotentWorker - class AttachmentJobFinder < JobFinder # rubocop:disable Scalability/IdempotentWorker - EXCEPT_RESOURCE_IDS_KEY = :except_ids - - def registry_finder - @registry_finder ||= Geo::AttachmentLegacyRegistryFinder.new - end - - private - - # Why do we need a different `file_type` for each Uploader? Why not just use 'upload'? - # rubocop: disable CodeReuse/ActiveRecord - def convert_resource_relation_to_job_args(relation) - relation.pluck(:id, :uploader) - .map! { |id, uploader| [uploader.sub(/Uploader\z/, '').underscore, id] } - end - # rubocop: enable CodeReuse/ActiveRecord - - # rubocop: disable CodeReuse/ActiveRecord - def convert_registry_relation_to_job_args(relation) - relation.pluck(:file_type, :file_id) - end - # rubocop: enable CodeReuse/ActiveRecord - end - end -end diff --git a/ee/config/metrics/object_schemas/geo_node_usage.json b/ee/config/metrics/object_schemas/geo_node_usage.json index 97551f94bbfc4ba4aa0bd497fe63e7ab87a7aee0..7061c2466f623436ba336952646436c734b061ff 100644 --- a/ee/config/metrics/object_schemas/geo_node_usage.json +++ b/ee/config/metrics/object_schemas/geo_node_usage.json @@ -4,7 +4,6 @@ "type": "object", "properties": { "projects_count": { "type": "number", "description": "Projects count" }, - "attachments_count": { "type": "number", "description": "Attachments count" }, "lfs_objects_count": { "type": "number" }, "wikis_failed_count": { "type": "number" }, "wikis_synced_count": { "type": "number" }, @@ -13,8 +12,6 @@ "wikis_verified_count": { "type": "number" }, "pages_deployments_count": { "type": "number" }, "wikis_checksummed_count": { "type": "number" }, - "attachments_failed_count": { "type": "number" }, - "attachments_synced_count": { "type": "number" }, "lfs_objects_failed_count": { "type": "number" }, "lfs_objects_synced_count": { "type": "number" }, "pipeline_artifacts_count": { "type": "number" }, @@ -45,7 +42,6 @@ "repositories_checksummed_count": { "type": "number" }, "terraform_state_versions_count": { "type": "number" }, "wikis_verification_total_count": { "type": "number" }, - "attachments_replication_enabled": { "type": "boolean" }, "package_files_checksummed_count": { "type": "number" }, "pipeline_artifacts_failed_count": { "type": "number" }, "pipeline_artifacts_synced_count": { "type": "number" }, @@ -109,7 +105,6 @@ "pages_deployments_verification_total_count": { "type": "number" }, "snippet_repositories_checksum_failed_count": { "type": "number" }, "terraform_state_versions_checksummed_count": { "type": "number" }, - "attachments_synced_missing_on_primary_count": { "type": "number" }, "pages_deployments_verification_failed_count": { "type": "number" }, "pipeline_artifacts_verification_total_count": { "type": "number" }, "group_wiki_repositories_checksum_total_count": { "type": "number" }, diff --git a/ee/config/routes/admin.rb b/ee/config/routes/admin.rb index 70fc330039294bc111ac9d8dc6c656cc7b84582f..06770f7635a75462b6b2ac93d4229e8872e3cde9 100644 --- a/ee/config/routes/admin.rb +++ b/ee/config/routes/admin.rb @@ -70,8 +70,6 @@ resources :designs, only: [:index] - resources :uploads, only: [:index, :destroy], path: 'legacy-uploads' - get '/:replicable_name_plural', to: 'replicables#index', as: 'replicables' end diff --git a/ee/db/geo/post_migrate/20211021112221_remove_upload_legacy_fields.rb b/ee/db/geo/post_migrate/20211021112221_remove_upload_legacy_fields.rb new file mode 100644 index 0000000000000000000000000000000000000000..1252cd547fe5dfdb8e65fb31fc12026d9eb6cad3 --- /dev/null +++ b/ee/db/geo/post_migrate/20211021112221_remove_upload_legacy_fields.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class RemoveUploadLegacyFields < Gitlab::Database::Migration[1.0] + def change + remove_column :file_registry, :file_type, :string, null: false + remove_column :file_registry, :success, :boolean, null: false + remove_column :file_registry, :bytes, :integer + remove_column :file_registry, :sha256, :string + end +end diff --git a/ee/db/geo/schema_migrations/20211021112221 b/ee/db/geo/schema_migrations/20211021112221 new file mode 100644 index 0000000000000000000000000000000000000000..36c56c1b8ea7ca1a5eaeef23f1998870a1c53e2b --- /dev/null +++ b/ee/db/geo/schema_migrations/20211021112221 @@ -0,0 +1 @@ +b537418e1e9d1106f2ec388e1540ff67f19d4eb5a882770d1ce775bddbb167b4 \ No newline at end of file diff --git a/ee/db/geo/structure.sql b/ee/db/geo/structure.sql index a59a0cfcb47734ad376850e3aa043d4955984839..6792f6fa75b1c4a6742f0826789d4aad5bf53c9e 100644 --- a/ee/db/geo/structure.sql +++ b/ee/db/geo/structure.sql @@ -65,12 +65,8 @@ ALTER SEQUENCE event_log_states_event_id_seq OWNED BY event_log_states.event_id; CREATE TABLE file_registry ( id integer NOT NULL, - file_type character varying NOT NULL, file_id integer NOT NULL, - bytes bigint, - sha256 character varying, created_at timestamp without time zone NOT NULL, - success boolean DEFAULT false NOT NULL, retry_count integer DEFAULT 0, retry_at timestamp without time zone, missing_on_primary boolean DEFAULT false NOT NULL, @@ -510,14 +506,8 @@ CREATE INDEX index_design_registry_on_retry_at ON design_registry USING btree (r CREATE INDEX index_design_registry_on_state ON design_registry USING btree (state); -CREATE INDEX index_file_registry_on_file_type ON file_registry USING btree (file_type); - -CREATE UNIQUE INDEX index_file_registry_on_file_type_and_file_id ON file_registry USING btree (file_type, file_id); - CREATE INDEX index_file_registry_on_retry_at ON file_registry USING btree (retry_at); -CREATE INDEX index_file_registry_on_success ON file_registry USING btree (success); - CREATE UNIQUE INDEX index_g_wiki_repository_registry_on_group_wiki_repository_id ON group_wiki_repository_registry USING btree (group_wiki_repository_id); CREATE INDEX index_group_wiki_repository_registry_on_retry_at ON group_wiki_repository_registry USING btree (retry_at); diff --git a/ee/lib/ee/api/entities/geo_node_status.rb b/ee/lib/ee/api/entities/geo_node_status.rb index f7a2db502787f8cc2c38fee8b3a07f73584c7931..caf6def3692046bc2d245b40489ac2943a081047 100644 --- a/ee/lib/ee/api/entities/geo_node_status.rb +++ b/ee/lib/ee/api/entities/geo_node_status.rb @@ -35,7 +35,6 @@ class GeoNodeStatus < Grape::Entity expose :db_replication_lag_seconds - expose :attachments_replication_enabled, if: -> (*) { ::Geo::UploadReplicator.disabled? } expose :job_artifacts_replication_enabled expose :container_repositories_replication_enabled expose :design_repositories_replication_enabled diff --git a/ee/lib/ee/gitlab/background_migration/prune_orphaned_geo_events.rb b/ee/lib/ee/gitlab/background_migration/prune_orphaned_geo_events.rb index a0c7b9f368fddc1c3514f420250fc9ab08bfb8db..88ba02ffdbc925dbce8f4f8d46b44203cd2df8d7 100644 --- a/ee/lib/ee/gitlab/background_migration/prune_orphaned_geo_events.rb +++ b/ee/lib/ee/gitlab/background_migration/prune_orphaned_geo_events.rb @@ -17,8 +17,7 @@ module PruneOrphanedGeoEvents geo_hashed_storage_migrated_events geo_hashed_storage_attachments_events geo_lfs_object_deleted_events - geo_job_artifact_deleted_events - geo_upload_deleted_events].freeze + geo_job_artifact_deleted_events].freeze module PrunableEvent extend ActiveSupport::Concern diff --git a/ee/lib/gitlab/geo/geo_node_status_check.rb b/ee/lib/gitlab/geo/geo_node_status_check.rb index 407e7d3d12439b7e25d175e64936f3a6fa2af177..a030647ea399a71b59a38d1542df80035f9d209c 100644 --- a/ee/lib/gitlab/geo/geo_node_status_check.rb +++ b/ee/lib/gitlab/geo/geo_node_status_check.rb @@ -28,7 +28,6 @@ def print_status print_verified_repositories print_wikis_status print_verified_wikis - print_attachments_status print_ci_job_artifacts_status print_container_repositories_status print_design_repositories_status @@ -49,7 +48,6 @@ def print_replication_verification_status print_verified_repositories print_wikis_status print_verified_wikis - print_attachments_status print_ci_job_artifacts_status print_container_repositories_status print_design_repositories_status @@ -74,7 +72,6 @@ def legacy_replication_and_verification_checks_status ["repositories", Gitlab::Geo.repository_verification_enabled?], ["wikis", Gitlab::Geo.repository_verification_enabled?], ["job_artifacts", false], - ["attachments", false], ["design_repositories", false] ] @@ -252,15 +249,6 @@ def print_verified_wikis end end - def print_attachments_status - return if ::Geo::UploadReplicator.enabled? - - print 'Attachments: '.rjust(GEO_STATUS_COLUMN_WIDTH) - show_failed_value(current_node_status.attachments_failed_count) - print "#{current_node_status.attachments_synced_count}/#{current_node_status.attachments_count} " - puts using_percentage(current_node_status.attachments_synced_in_percentage) - end - def print_ci_job_artifacts_status print 'CI job artifacts: '.rjust(GEO_STATUS_COLUMN_WIDTH) show_failed_value(current_node_status.job_artifacts_failed_count) diff --git a/ee/lib/gitlab/geo/log_cursor/events/upload_deleted_event.rb b/ee/lib/gitlab/geo/log_cursor/events/upload_deleted_event.rb deleted file mode 100644 index b44b27c9e7acdadeef4da3f5b5e71bd40bad9475..0000000000000000000000000000000000000000 --- a/ee/lib/gitlab/geo/log_cursor/events/upload_deleted_event.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Geo - module LogCursor - module Events - class UploadDeletedEvent - include BaseEvent - - def process - job_id = ::Geo::FileRegistryRemovalWorker.perform_async(event.upload_type, event.upload_id) - log_event(job_id) - end - - def log_event(job_id) - super( - 'Delete upload file scheduled', - upload_id: event.upload_id, - upload_type: event.upload_type, - file_path: event.file_path, - model_id: event.model_id, - model_type: event.model_type, - job_id: job_id) - end - end - end - end - end -end diff --git a/ee/spec/controllers/admin/geo/uploads_controller_spec.rb b/ee/spec/controllers/admin/geo/uploads_controller_spec.rb deleted file mode 100644 index c6c308c503dfb5e2079d470e9777ad20af23978c..0000000000000000000000000000000000000000 --- a/ee/spec/controllers/admin/geo/uploads_controller_spec.rb +++ /dev/null @@ -1,130 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Admin::Geo::UploadsController, :geo do - include EE::GeoHelpers - - let_it_be(:admin) { create(:admin) } - let_it_be(:secondary) { create(:geo_node) } - let_it_be(:synced_registry) { create(:geo_upload_legacy_registry, :with_file, :attachment, success: true) } - let_it_be(:failed_registry) { create(:geo_upload_legacy_registry, :failed) } - let_it_be(:never_registry) { create(:geo_upload_legacy_registry, :failed, retry_count: nil) } - - def css_id(registry) - "#upload-#{registry.id}-header" - end - - before do - stub_feature_flags(geo_upload_replication: false) - - sign_in(admin) - end - - shared_examples 'license required' do - context 'without a valid license' do - it 'redirects to 403 page' do - expect(subject).to have_gitlab_http_status(:forbidden) - end - end - end - - describe '#index' do - subject { get :index } - - it_behaves_like 'license required' - - context 'with a valid license' do - render_views - - before do - stub_licensed_features(geo: true) - stub_current_geo_node(secondary) - end - - it 'renders the index template' do - expect(subject).to have_gitlab_http_status(:ok) - expect(subject).to render_template(:index) - end - - context 'without sync_status specified' do - it 'renders all registries' do - expect(subject).to have_gitlab_http_status(:ok) - expect(response.body).to have_css(css_id(synced_registry)) - expect(response.body).to have_css(css_id(failed_registry)) - expect(response.body).to have_css(css_id(never_registry)) - end - end - - context 'with sync_status=synced' do - subject { get :index, params: { sync_status: 'synced' } } - - it 'renders only synced registries' do - expect(subject).to have_gitlab_http_status(:ok) - expect(response.body).to have_css(css_id(synced_registry)) - expect(response.body).not_to have_css(css_id(failed_registry)) - expect(response.body).not_to have_css(css_id(never_registry)) - end - end - - context 'with sync_status=failed' do - subject { get :index, params: { sync_status: 'failed' } } - - it 'renders only failed registries' do - expect(subject).to have_gitlab_http_status(:ok) - expect(response.body).not_to have_css(css_id(synced_registry)) - expect(response.body).to have_css(css_id(failed_registry)) - expect(response.body).not_to have_css(css_id(never_registry)) - end - end - - # Explained via: https://gitlab.com/gitlab-org/gitlab/-/issues/216049 - context 'with sync_status=pending' do - subject { get :index, params: { sync_status: 'pending' } } - - it 'renders only never synced registries' do - expect(subject).to have_gitlab_http_status(:ok) - expect(response.body).not_to have_css(css_id(synced_registry)) - expect(response.body).not_to have_css(css_id(failed_registry)) - expect(response.body).to have_css(css_id(never_registry)) - end - end - end - end - - describe '#destroy' do - subject { delete :destroy, params: { id: registry } } - - it_behaves_like 'license required' do - let(:registry) { create(:geo_upload_legacy_registry) } - end - - context 'with a valid license' do - before do - stub_licensed_features(geo: true) - end - - context 'with an orphaned registry' do - let(:registry) { create(:geo_upload_legacy_registry, success: true) } - - it 'removes the registry' do - registry.update_column(:file_id, -1) - - expect(subject).to redirect_to(admin_geo_uploads_path) - expect(flash[:toast]).to include('was successfully removed') - expect { Geo::UploadRegistry.find(registry.id) }.to raise_error(ActiveRecord::RecordNotFound) - end - end - - context 'with a regular registry' do - let(:registry) { create(:geo_upload_legacy_registry, :avatar, :with_file, success: true) } - - it 'does not delete the registry and gives an error' do - expect(subject).to redirect_to(admin_geo_uploads_path) - expect(flash[:alert]).to include('Could not remove tracking entry') - expect { Geo::UploadRegistry.find(registry.id) }.not_to raise_error - end - end - end - end -end diff --git a/ee/spec/factories/geo/event_log.rb b/ee/spec/factories/geo/event_log.rb index 59186298ce8a1f339667e490a99ce2a8c13952cb..d59df884fc6aea23223c6dcec930b045b179664f 100644 --- a/ee/spec/factories/geo/event_log.rb +++ b/ee/spec/factories/geo/event_log.rb @@ -30,10 +30,6 @@ job_artifact_deleted_event factory: :geo_job_artifact_deleted_event end - trait :upload_deleted_event do - upload_deleted_event factory: :geo_upload_deleted_event - end - trait :reset_checksum_event do reset_checksum_event factory: :geo_reset_checksum_event end @@ -133,26 +129,6 @@ end end - factory :geo_upload_deleted_event, class: 'Geo::UploadDeletedEvent' do - upload { association(:upload) } - file_path { upload.path } - model_id { upload.model_id } - model_type { upload.model_type } - uploader { upload.uploader } - - trait :issuable_upload do - upload { association(:upload, :issuable_upload) } - end - - trait :personal_snippet do - upload { association(:upload, :personal_snippet) } - end - - trait :namespace_upload do - upload { association(:upload, :namespace_upload) } - end - end - factory :geo_reset_checksum_event, class: 'Geo::ResetChecksumEvent' do project end diff --git a/ee/spec/factories/geo/upload_registry.rb b/ee/spec/factories/geo/upload_registry.rb index f3c9d04e2daba8081620182d5c3ff094e1dfe8ff..e0cd553c90dba6e19f9b729245e1b04d785de96f 100644 --- a/ee/spec/factories/geo/upload_registry.rb +++ b/ee/spec/factories/geo/upload_registry.rb @@ -1,51 +1,9 @@ # frozen_string_literal: true -FactoryBot.define do - factory :geo_upload_legacy_registry, class: 'Geo::UploadRegistry' do - sequence(:file_id) - file_type { :file } - success { true } - - trait(:attachment) { file_type { :attachment } } - trait(:avatar) { file_type { :avatar } } - trait(:'bulk_imports/export') { file_type { :'bulk_imports/export' } } - trait(:favicon) { file_type { :favicon } } - trait(:file) { file_type { :file } } - trait(:import_export) { file_type { :import_export } } - trait(:issuable_metric_image) { file_type { :issuable_metric_image } } - trait(:namespace_file) { file_type { :namespace_file } } - trait(:personal_file) { file_type { :personal_file } } - - trait :failed do - success { false } - retry_count { 1 } - end - - trait :never_synced do - success { false } - retry_count { nil } - end - - trait :with_file do - after(:build, :stub) do |registry, _| - file = - if registry.file_type.to_sym == :job_artifact - raise NotImplementedError, 'Use create(:geo_job_artifact_registry, :with_artifact) instead' - else - create(:upload) - end - - registry.file_id = file.id - end - end - end -end - FactoryBot.define do factory :geo_upload_registry, class: 'Geo::UploadRegistry' do association(:upload, :with_file) sequence(:file_id) - file_type { :file } state { Geo::UploadRegistry.state_value(:pending) } trait :synced do diff --git a/ee/spec/factories/geo_node_statuses.rb b/ee/spec/factories/geo_node_statuses.rb index 49ec9c5890af572a2ccc4165bb343a3ee1f15630..e44b8e50b4a5cf6a6109745f2e3ae6685dc468aa 100644 --- a/ee/spec/factories/geo_node_statuses.rb +++ b/ee/spec/factories/geo_node_statuses.rb @@ -7,10 +7,6 @@ trait :healthy do status_message { nil } - attachments_count { 329 } - attachments_failed_count { 13 } - attachments_synced_count { 141 } - attachments_synced_missing_on_primary_count { 89 } job_artifacts_count { 580 } job_artifacts_failed_count { 3 } job_artifacts_synced_count { 577 } @@ -53,7 +49,6 @@ last_successful_status_check_timestamp { 2.minutes.ago } version { Gitlab::VERSION } revision { Gitlab.revision } - attachments_replication_enabled { true } container_repositories_replication_enabled { false } design_repositories_replication_enabled { true } job_artifacts_replication_enabled { false } @@ -70,7 +65,6 @@ end trait :replicated_and_verified do - attachments_failed_count { 0 } job_artifacts_failed_count { 0 } container_repositories_failed_count { 0 } design_repositories_failed_count { 0 } @@ -92,7 +86,6 @@ wikis_verified_count { 10 } wikis_verification_total_count { 10 } job_artifacts_synced_count { 10 } - attachments_synced_count { 10 } replication_slots_used_count { 10 } container_repositories_synced_count { 10 } design_repositories_synced_count { 10 } @@ -100,7 +93,6 @@ repositories_count { 10 } wikis_count { 10 } job_artifacts_count { 10 } - attachments_count { 10 } replication_slots_count { 10 } container_repositories_count { 10 } design_repositories_count { 10 } diff --git a/ee/spec/features/admin/geo/admin_geo_replication_nav_spec.rb b/ee/spec/features/admin/geo/admin_geo_replication_nav_spec.rb index 4d5d325033f5607ddae4d79b98a1cc5c9548a4c2..b77773e9b8b9d835fdbb35a407511605ccae1cc5 100644 --- a/ee/spec/features/admin/geo/admin_geo_replication_nav_spec.rb +++ b/ee/spec/features/admin/geo/admin_geo_replication_nav_spec.rb @@ -33,16 +33,6 @@ end end - describe 'visit admin/geo/replication/legacy-uploads' do - before do - stub_feature_flags(geo_upload_replication: false) - end - - it_behaves_like 'active sidebar link', 'Uploads' do - let(:path) { admin_geo_uploads_path } - end - end - describe 'visit admin/geo/replication/designs' do it_behaves_like 'active sidebar link', 'Designs' do let(:path) { admin_geo_designs_path } diff --git a/ee/spec/features/admin/geo/admin_geo_sidebar_spec.rb b/ee/spec/features/admin/geo/admin_geo_sidebar_spec.rb index 1117290af965d02878df9fae149df621f691660b..f1e5a440ec39d64ad2a3a190d4c535319bb3fd92 100644 --- a/ee/spec/features/admin/geo/admin_geo_sidebar_spec.rb +++ b/ee/spec/features/admin/geo/admin_geo_sidebar_spec.rb @@ -59,12 +59,6 @@ end end - describe 'visiting geo uploads' do - it_behaves_like 'active sidebar link', 'Replication' do - let(:path) { admin_geo_uploads_path } - end - end - describe 'visiting geo replicables' do Gitlab::Geo.enabled_replicator_classes.each do |replicator_class| it_behaves_like 'active sidebar link', 'Replication' do diff --git a/ee/spec/features/admin/geo/admin_geo_uploads_spec.rb b/ee/spec/features/admin/geo/admin_geo_uploads_spec.rb deleted file mode 100644 index 5f96c44868f30368787c47c0efb8bdb1796cafa1..0000000000000000000000000000000000000000 --- a/ee/spec/features/admin/geo/admin_geo_uploads_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'admin Geo Uploads', :js, :geo do - let!(:geo_node) { create(:geo_node) } - let!(:synced_registry) { create(:geo_upload_legacy_registry, :with_file, :attachment, success: true) } - - before do - allow(Gitlab::Geo).to receive(:license_allows?).and_return(true) - stub_feature_flags(geo_upload_replication: false) - - admin = create(:admin) - sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) - end - - describe 'visiting geo uploads initial page' do - before do - visit(admin_geo_uploads_path) - wait_for_requests - end - - it 'shows all uploads in the registry' do - page.within(find('#content-body', match: :first)) do - expect(page).to have_content(synced_registry.file) - expect(page).not_to have_content('There are no uploads to show') - end - end - - describe 'searching for a geo upload' do - it 'filters out uploads with the search term' do - fill_in :name, with: synced_registry.file - find('#project-filter-form-field').native.send_keys(:enter) - - wait_for_requests - - page.within(find('#content-body', match: :first)) do - expect(page).to have_content(synced_registry.file) - expect(page).not_to have_content('There are no uploads to show') - end - end - end - - describe 'with no registries' do - it 'shows empty state' do - fill_in :name, with: 'asdfasdf' - find('#project-filter-form-field').native.send_keys(:enter) - - wait_for_requests - - page.within(find('#content-body', match: :first)) do - expect(page).not_to have_content(synced_registry.file) - expect(page).to have_content('There are no uploads to show') - end - end - end - end - - describe 'remove an orphaned Tracking Entry' do - before do - synced_registry.upload.destroy! - visit(admin_geo_uploads_path) - wait_for_requests - end - - it 'removes an existing Geo Upload' do - card_count = page.all(:css, '.upload-card').length - - page.within(find('.upload-card', match: :first)) do - page.click_button('Remove') - end - page.within('.modal') do - page.click_button('Remove entry') - end - # Wait for remove confirmation - expect(page.find('.gl-toast')).to have_text('removed') - - expect(page.all(:css, '.upload-card').length).to be(card_count - 1) - end - end -end diff --git a/ee/spec/finders/geo/attachment_legacy_registry_finder_spec.rb b/ee/spec/finders/geo/attachment_legacy_registry_finder_spec.rb deleted file mode 100644 index 47ad832e7c3c57a0b25f43b1f8e65cdb5ac5b881..0000000000000000000000000000000000000000 --- a/ee/spec/finders/geo/attachment_legacy_registry_finder_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Geo::AttachmentLegacyRegistryFinder, :geo do - before do - stub_feature_flags(geo_upload_replication: false ) - end - - it_behaves_like 'a file registry finder' do - let_it_be(:project) { create(:project) } - - let_it_be(:replicable_1) { create(:upload, model: project) } - let_it_be(:replicable_2) { create(:upload, model: project) } - let_it_be(:replicable_3) { create(:upload, :issuable_upload, model: project) } - let_it_be(:replicable_4) { create(:upload, model: project) } - let_it_be(:replicable_5) { create(:upload, model: project) } - let_it_be(:replicable_6) { create(:upload, :personal_snippet_upload) } - let_it_be(:replicable_7) { create(:upload, :object_storage, model: project) } - let_it_be(:replicable_8) { create(:upload, :object_storage, model: project) } - let_it_be(:replicable_9) { create(:upload, :object_storage, model: project) } - - let_it_be(:registry_1) { create(:geo_upload_legacy_registry, :attachment, :failed, file_id: replicable_1.id) } - let_it_be(:registry_2) { create(:geo_upload_legacy_registry, :attachment, file_id: replicable_2.id, missing_on_primary: true) } - let_it_be(:registry_3) { create(:geo_upload_legacy_registry, :attachment, :never_synced, file_id: replicable_3.id) } - let_it_be(:registry_4) { create(:geo_upload_legacy_registry, :attachment, :failed, file_id: replicable_4.id) } - let_it_be(:registry_5) { create(:geo_upload_legacy_registry, :attachment, file_id: replicable_5.id, missing_on_primary: true, retry_at: 1.day.ago) } - let_it_be(:registry_6) { create(:geo_upload_legacy_registry, :attachment, :failed, file_id: replicable_6.id) } - let_it_be(:registry_7) { create(:geo_upload_legacy_registry, :attachment, :failed, file_id: replicable_7.id, missing_on_primary: true) } - let_it_be(:registry_8) { create(:geo_upload_legacy_registry, :attachment, :never_synced, file_id: replicable_8.id) } - end -end diff --git a/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json b/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json index d8b12eda3467396330989a02e3123431a02978e7..e1726226b4c3d56ea34d1343835a983764fc3238 100644 --- a/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json +++ b/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json @@ -6,11 +6,6 @@ "health", "health_status", "missing_oauth_application", - "attachments_replication_enabled", - "attachments_count", - "attachments_failed_count", - "attachments_synced_count", - "attachments_synced_missing_on_primary_count", "lfs_objects_count", "lfs_objects_failed_count", "lfs_objects_synced_count", @@ -188,12 +183,6 @@ "health": { "type": ["string", "null"] }, "health_status": { "type": "string" }, "missing_oauth_application": { "type": "boolean" }, - "attachments_replication_enabled": { "type": ["boolean", "null"] }, - "attachments_count": { "type": "integer" }, - "attachments_failed_count": { "type": ["integer", "null"] }, - "attachments_synced_count": { "type": ["integer", "null"] }, - "attachments_synced_missing_on_primary_count": { "type": ["integer", "null"] }, - "attachments_synced_in_percentage": { "type": "string" }, "db_replication_lag_seconds": { "type": ["integer", "null"] }, "lfs_objects_count": { "type": "integer" }, "lfs_objects_failed_count": { "type": ["integer", "null"] }, diff --git a/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb b/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb index 83c5536fc968f27c9fd22872bcdc8d96bf2e632a..4547e669e3470cab1b2a1df1deee3cea647bd7b2 100644 --- a/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb +++ b/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb @@ -55,16 +55,6 @@ end end - describe '#attachments_synced_in_percentage' do - it 'formats as percentage' do - geo_node_status.assign_attributes(attachments_count: 329, - attachments_failed_count: 25, - attachments_synced_count: 141) - - expect(subject[:attachments_synced_in_percentage]).to eq '42.86%' - end - end - describe '#job_artifacts_synced_in_percentage' do it 'formats as percentage' do geo_node_status.assign_attributes(job_artifacts_count: 256, diff --git a/ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb b/ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb deleted file mode 100644 index 6784dbec41a329a5f45560f70ef0a12f73cfee1b..0000000000000000000000000000000000000000 --- a/ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Geo::LogCursor::Events::UploadDeletedEvent, :clean_gitlab_redis_shared_state do - let(:logger) { Gitlab::Geo::LogCursor::Logger.new(described_class, Logger::INFO) } - let(:project) { create(:project) } - let(:upload_deleted_event) { create(:geo_upload_deleted_event, project: project) } - let(:event_log) { create(:geo_event_log, upload_deleted_event: upload_deleted_event) } - let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) } - - subject { described_class.new(upload_deleted_event, Time.now, logger) } - - around do |example| - Sidekiq::Testing.inline! { example.run } - end - - describe '#process' do - context 'with default handling' do - let(:event_log) { create(:geo_event_log, :upload_deleted_event) } - let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) } - let(:upload_deleted_event) { event_log.upload_deleted_event } - let(:upload) { upload_deleted_event.upload } - - it 'does not create a tracking database entry' do - expect { subject.process }.not_to change(Geo::UploadRegistry, :count) - end - - it 'removes the tracking database entry if exist' do - create(:geo_upload_legacy_registry, :avatar, file_id: upload.id) - - expect { subject.process }.to change(Geo::UploadRegistry, :count).by(-1) - end - - it_behaves_like 'logs event source info' - end - end -end diff --git a/ee/spec/models/ee/appearance_spec.rb b/ee/spec/models/ee/appearance_spec.rb index 7df04352da3155d1e6e4548cd5835a4ab7824ec3..8cc96c1c74585fdfe832412b0da993d76118fc24 100644 --- a/ee/spec/models/ee/appearance_spec.rb +++ b/ee/spec/models/ee/appearance_spec.rb @@ -21,42 +21,4 @@ it { is_expected.to allow_value(hex).for(:message_font_color) } it { is_expected.not_to allow_value('000').for(:message_font_color) } end - - context 'object storage with background upload' do - context 'when running in a Geo primary node' do - let_it_be(:primary) { create(:geo_node, :primary) } - let_it_be(:secondary) { create(:geo_node) } - - before do - stub_current_geo_node(primary) - stub_uploads_object_storage(AttachmentUploader, background_upload: true) - end - - it 'creates a Geo deleted log event for logo' do - Sidekiq::Testing.inline! do - expect do - create(:appearance, :with_logo) - end.to change(Geo::UploadDeletedEvent, :count).by(1) - end - end - - it 'creates a Geo deleted log event for header logo' do - Sidekiq::Testing.inline! do - expect do - create(:appearance, :with_header_logo) - end.to change(Geo::UploadDeletedEvent, :count).by(1) - end - end - - it 'creates only a Geo deleted log event for the migrated header logo' do - Sidekiq::Testing.inline! do - appearance = create(:appearance, :with_header_logo, :with_logo) - - expect do - appearance.update!(header_logo: fixture_file_upload('spec/fixtures/rails_sample.jpg')) - end.to change(Geo::UploadDeletedEvent, :count).by(1) - end - end - end - end end diff --git a/ee/spec/models/geo/event_log_spec.rb b/ee/spec/models/geo/event_log_spec.rb index 87d610fd8620b084fc0614da18a642c52717a661..d0e2da7e9d422dc73e4f57d5c3f8476285fd70f1 100644 --- a/ee/spec/models/geo/event_log_spec.rb +++ b/ee/spec/models/geo/event_log_spec.rb @@ -107,13 +107,6 @@ expect(subject.event).to eq job_artifact_deleted_event end - it 'returns upload_deleted_event when set' do - upload_deleted_event = build(:geo_upload_deleted_event) - subject.upload_deleted_event = upload_deleted_event - - expect(subject.event).to eq upload_deleted_event - end - it 'returns reset_checksum_event when set' do reset_checksum_event = build(:geo_reset_checksum_event) subject.reset_checksum_event = reset_checksum_event diff --git a/ee/spec/models/geo/upload_deleted_event_spec.rb b/ee/spec/models/geo/upload_deleted_event_spec.rb deleted file mode 100644 index 56a3f5cab892aba9b616de035a29c7c69609efce..0000000000000000000000000000000000000000 --- a/ee/spec/models/geo/upload_deleted_event_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Geo::UploadDeletedEvent, type: :model do - describe 'relationships' do - it { is_expected.to belong_to(:upload) } - end - - describe 'validations' do - it { is_expected.to validate_presence_of(:upload) } - it { is_expected.to validate_presence_of(:file_path) } - it { is_expected.to validate_presence_of(:model_id) } - it { is_expected.to validate_presence_of(:model_type) } - it { is_expected.to validate_presence_of(:uploader) } - end - - describe '#upload_type' do - it 'returns nil when uploader is not set' do - subject.uploader = nil - - expect(subject.upload_type).to be_nil - end - - it 'returns uploader type when uploader is set' do - subject.uploader = 'PersonalFileUploader' - - expect(subject.upload_type).to eq 'personal_file' - end - end -end diff --git a/ee/spec/models/geo/upload_registry_spec.rb b/ee/spec/models/geo/upload_registry_spec.rb index 932004fbae37d554ec5dd9c0151cbe4d8f9f7190..389d043fdbae09b21784bc9c958f7671058d134f 100644 --- a/ee/spec/models/geo/upload_registry_spec.rb +++ b/ee/spec/models/geo/upload_registry_spec.rb @@ -2,174 +2,6 @@ require 'spec_helper' -RSpec.describe Geo::UploadRegistry, :geo do - include EE::GeoHelpers - - before do - stub_feature_flags(geo_upload_replication: false) - end - - it_behaves_like 'a BulkInsertSafe model', Geo::UploadRegistry do - let(:valid_items_for_bulk_insertion) { build_list(:geo_upload_legacy_registry, 10, created_at: Time.zone.now) } - let(:invalid_items_for_bulk_insertion) { [] } # class does not have any validations defined - end - - it 'finds associated Upload record' do - registry = create(:geo_upload_legacy_registry, :attachment, :with_file) - - expect(described_class.find(registry.id).upload).to be_an_instance_of(Upload) - end - - describe '.find_registry_differences' do - let_it_be(:secondary) { create(:geo_node) } - let_it_be(:project) { create(:project) } - let_it_be(:upload_1) { create(:upload, model: project) } - let_it_be(:upload_2) { create(:upload, model: project) } - let_it_be(:upload_3) { create(:upload, :issuable_upload, model: project) } - let_it_be(:upload_4) { create(:upload, model: project) } - let_it_be(:upload_5) { create(:upload, model: project) } - let_it_be(:upload_6) { create(:upload, :personal_snippet_upload) } - let_it_be(:upload_7) { create(:upload, :object_storage, model: project) } - let_it_be(:upload_8) { create(:upload, :object_storage, model: project) } - let_it_be(:upload_9) { create(:upload, :object_storage, model: project) } - - before do - stub_current_geo_node(secondary) - end - - it 'returns untracked IDs as well as tracked IDs that are unused', :aggregate_failures do - max_id = Upload.maximum(:id) - create(:geo_upload_legacy_registry, :avatar, file_id: upload_1.id) - create(:geo_upload_legacy_registry, :file, file_id: upload_3.id) - create(:geo_upload_legacy_registry, :avatar, file_id: upload_5.id) - create(:geo_upload_legacy_registry, :personal_file, file_id: upload_6.id) - create(:geo_upload_legacy_registry, :avatar, file_id: upload_7.id) - unused_registry_1 = create(:geo_upload_legacy_registry, :attachment, file_id: max_id + 1) - unused_registry_2 = create(:geo_upload_legacy_registry, :personal_file, file_id: max_id + 2) - range = 1..(max_id + 2) - - untracked, unused = described_class.find_registry_differences(range) - - expected_untracked = [ - [upload_2.id, 'avatar'], - [upload_4.id, 'avatar'], - [upload_8.id, 'avatar'], - [upload_9.id, 'avatar'] - ] - - expected_unused = [ - [unused_registry_1.file_id, 'attachment'], - [unused_registry_2.file_id, 'personal_file'] - ] - - expect(untracked).to match_array(expected_untracked) - expect(unused).to match_array(expected_unused) - end - end - - describe '.failed' do - it 'returns registries in the failed state' do - failed = create(:geo_upload_legacy_registry, :failed) - create(:geo_upload_legacy_registry) - - expect(described_class.failed).to match_ids(failed) - end - end - - describe '.synced' do - it 'returns registries in the synced state' do - create(:geo_upload_legacy_registry, :failed) - synced = create(:geo_upload_legacy_registry) - - expect(described_class.synced).to match_ids(synced) - end - end - - describe '.retry_due' do - it 'returns registries in the synced state' do - failed = create(:geo_upload_legacy_registry, :failed) - synced = create(:geo_upload_legacy_registry) - retry_yesterday = create(:geo_upload_legacy_registry, retry_at: Date.yesterday) - create(:geo_upload_legacy_registry, retry_at: Date.tomorrow) - - expect(described_class.retry_due).to match_ids([failed, synced, retry_yesterday]) - end - end - - describe '.never_attempted_sync' do - it 'returns registries that are never synced' do - create(:geo_upload_legacy_registry, :failed) - create(:geo_upload_legacy_registry) - pending = create(:geo_upload_legacy_registry, retry_count: nil, success: false) - - expect(described_class.never_attempted_sync).to match_ids([pending]) - end - end - - describe '.with_status' do - it 'finds the registries with status "synced"' do - expect(described_class).to receive(:synced) - - described_class.with_status('synced') - end - - it 'finds the registries with status "never_attempted_sync" when filter is set to "pending"' do - expect(described_class).to receive(:never_attempted_sync) - - described_class.with_status('pending') - end - - it 'finds the registries with status "failed"' do - expect(described_class).to receive(:failed) - - described_class.with_status('failed') - end - end - - describe '.with_search' do - it 'searches registries on path' do - upload = create(:upload, path: 'uploads/-/system/project/avatar/my-awesome-avatar.png') - upload_registry = create(:geo_upload_legacy_registry, file_id: upload.id, file_type: :avatar) - - expect(described_class.with_search('awesome-avatar')).to match_ids(upload_registry) - end - end - - describe '#file' do - it 'returns the path of the upload of a registry' do - upload = create(:upload, :with_file) - registry = create(:geo_upload_legacy_registry, :file, file_id: upload.id) - - expect(registry.file).to eq(upload.path) - end - - it 'return "removed" message when the upload no longer exists' do - registry = create(:geo_upload_legacy_registry, :avatar) - - expect(registry.file).to match(/^Removed avatar with id/) - end - end - - describe '#synchronization_state' do - let_it_be(:failed) { create(:geo_upload_legacy_registry, :failed) } - let_it_be(:synced) { create(:geo_upload_legacy_registry) } - - it 'returns :synced for a successful synced registry' do - expect(synced.synchronization_state).to eq(:synced) - end - - it 'returns :never for a successful registry never synced' do - never = build(:geo_upload_legacy_registry, success: false, retry_count: nil) - - expect(never.synchronization_state).to eq(:never) - end - - it 'returns :failed for a failed registry' do - expect(failed.synchronization_state).to eq(:failed) - end - end -end - RSpec.describe Geo::UploadRegistry, :geo, type: :model do let_it_be(:registry) { create(:geo_upload_registry) } diff --git a/ee/spec/models/geo_node_status_spec.rb b/ee/spec/models/geo_node_status_spec.rb index 01dfb5aa0dbfe70612574ae4d15a6bf2ef009062..d2b5176f7260776035327ce418909318c8478e2d 100644 --- a/ee/spec/models/geo_node_status_spec.rb +++ b/ee/spec/models/geo_node_status_spec.rb @@ -144,50 +144,6 @@ end end - describe '#attachments_synced_count' do - it 'only counts successful syncs' do - create_list(:user, 3, avatar: fixture_file_upload('spec/fixtures/dk.png', 'image/png')) - uploads = Upload.pluck(:id) - - create(:geo_upload_registry, :synced, file_id: uploads[0]) - create(:geo_upload_registry, :synced, file_id: uploads[1]) - create(:geo_upload_registry, :failed, file_id: uploads[2]) - - expect(subject.attachments_synced_count).to eq(2) - end - end - - describe '#attachments_failed_count' do - it 'counts failed avatars, attachment, personal snippets and files' do - # These two should be ignored - create(:geo_lfs_object_registry, :failed) - create(:geo_upload_registry) - - create(:geo_upload_registry, :failed) - create(:geo_upload_registry, :failed) - - expect(subject.attachments_failed_count).to eq(2) - end - end - - describe '#attachments_synced_in_percentage' do - it 'returns 0 when no registries are available' do - expect(subject.attachments_synced_in_percentage).to eq(0) - end - - it 'returns the right percentage' do - create_list(:user, 4, avatar: fixture_file_upload('spec/fixtures/dk.png', 'image/png')) - uploads = Upload.pluck(:id) - - create(:geo_upload_registry, :synced, file_id: uploads[0]) - create(:geo_upload_registry, :synced, file_id: uploads[1]) - create(:geo_upload_registry, :failed, file_id: uploads[2]) - create(:geo_upload_registry, :started, file_id: uploads[3]) - - expect(subject.attachments_synced_in_percentage).to be_within(0.0001).of(50) - end - end - describe '#db_replication_lag_seconds' do it 'returns the set replication lag if secondary' do allow(Gitlab::Geo).to receive(:secondary?).and_return(true) @@ -979,7 +935,6 @@ result = described_class.from_json(data) expect(result.id).to be_nil - expect(result.attachments_count).to eq(status.attachments_count) expect(result.cursor_last_event_date).to eq(Time.zone.at(status.cursor_last_event_timestamp)) expect(result.storage_shards.count).to eq(Settings.repositories.storages.count) end @@ -1327,12 +1282,6 @@ stub_current_geo_node(primary) end - it 'does not call AttachmentLegacyRegistryFinder#registry_count' do - expect_any_instance_of(Geo::AttachmentLegacyRegistryFinder).not_to receive(:registry_count) - - subject - end - it 'does not call JobArtifactRegistryFinder#registry_count' do expect_any_instance_of(Geo::JobArtifactRegistryFinder).not_to receive(:registry_count) @@ -1341,12 +1290,6 @@ end context 'on the secondary' do - it 'calls AttachmentLegacyRegistryFinder#registry_count' do - expect_any_instance_of(Geo::AttachmentLegacyRegistryFinder).to receive(:registry_count).twice - - subject - end - it 'calls JobArtifactRegistryFinder#registry_count' do expect_any_instance_of(Geo::JobArtifactRegistryFinder).to receive(:registry_count).twice diff --git a/ee/spec/models/note_spec.rb b/ee/spec/models/note_spec.rb index 89b30b88554b412994c46a888c88de01c1d0004b..fc7acc58c5d0a8ecb1d1f5e8d2edd5112c98b91b 100644 --- a/ee/spec/models/note_spec.rb +++ b/ee/spec/models/note_spec.rb @@ -91,29 +91,6 @@ end end - context 'object storage with background upload' do - before do - stub_uploads_object_storage(AttachmentUploader, background_upload: true) - end - - context 'when running in a Geo primary node' do - let_it_be(:primary) { create(:geo_node, :primary) } - let_it_be(:secondary) { create(:geo_node) } - - before do - stub_current_geo_node(primary) - end - - it 'creates a Geo deleted log event for attachment' do - Sidekiq::Testing.inline! do - expect do - create(:note, :with_attachment) - end.to change(Geo::UploadDeletedEvent, :count).by(1) - end - end - end - end - describe '#resource_parent' do it 'returns group for epic notes' do group = create(:group) diff --git a/ee/spec/models/upload_spec.rb b/ee/spec/models/upload_spec.rb index 0b331dec601ad23795061d67fe148bf15e28e0bb..e274c9bb2ec3d81f2bbf68628b99d7be0388a41e 100644 --- a/ee/spec/models/upload_spec.rb +++ b/ee/spec/models/upload_spec.rb @@ -93,12 +93,6 @@ let_it_be(:primary) { create(:geo_node, :primary) } let_it_be(:secondary) { create(:geo_node) } - it 'logs an event to the Geo event log' do - stub_current_geo_node(primary) - - expect { subject.destroy }.to change(Geo::UploadDeletedEvent, :count).by(1) - end - it 'logs an event to the Geo event log when bulk removal is used', :sidekiq_inline do stub_current_geo_node(primary) diff --git a/ee/spec/requests/api/geo_spec.rb b/ee/spec/requests/api/geo_spec.rb index 1459f45c2633be292eace6e323a61da1038370c4..79121cd2d91ba712bf69967d9ced539820779768 100644 --- a/ee/spec/requests/api/geo_spec.rb +++ b/ee/spec/requests/api/geo_spec.rb @@ -317,11 +317,6 @@ design_repositories_count: 100, design_repositories_synced_count: 50, design_repositories_failed_count: 12, - attachments_count: 30, - attachments_synced_count: 30, - attachments_failed_count: 25, - attachments_synced_missing_on_primary_count: 6, - attachments_replication_enabled: false, container_repositories_replication_enabled: true, design_repositories_replication_enabled: false, job_artifacts_replication_enabled: true, diff --git a/ee/spec/routing/admin_routing_spec.rb b/ee/spec/routing/admin_routing_spec.rb index 3d10f3975395dad2c51bf1b00bf072d6608ac339..2df3fa313efc41e8f6eae46aa4a320885f4f9bd9 100644 --- a/ee/spec/routing/admin_routing_spec.rb +++ b/ee/spec/routing/admin_routing_spec.rb @@ -26,18 +26,6 @@ end end - describe Admin::Geo::UploadsController, 'routing' do - let!(:upload_registry) { create(:geo_upload_legacy_registry, :with_file, :attachment, success: true) } - - it 'routes / to #index' do - expect(get('/admin/geo/replication/legacy-uploads')).to route_to('admin/geo/uploads#index') - end - - it 'routes delete /:id to #destroy' do - expect(delete("/admin/geo/replication/legacy-uploads/#{upload_registry.id}")).to route_to('admin/geo/uploads#destroy', id: upload_registry.to_param) - end - end - describe Admin::Geo::DesignsController, 'routing' do it 'routes / to #index' do expect(get('/admin/geo/replication/designs')).to route_to('admin/geo/designs#index') diff --git a/ee/spec/services/geo/file_download_service_spec.rb b/ee/spec/services/geo/file_download_service_spec.rb index c51da4d33e67e225e363cdf408a4469d0243a047..f3b5be7429b4629a5a129678ef0fc099b28dd9b2 100644 --- a/ee/spec/services/geo/file_download_service_spec.rb +++ b/ee/spec/services/geo/file_download_service_spec.rb @@ -11,19 +11,9 @@ before do stub_current_geo_node(secondary) - - stub_feature_flags(geo_upload_replication: false) end describe '#downloader' do - Gitlab::Geo::Replication::USER_UPLOADS_OBJECT_TYPES.each do |object_type| - it "returns a FileDownloader given object_type is #{object_type}" do - subject = described_class.new(object_type, 1) - - expect(subject.downloader).to be_a(Gitlab::Geo::Replication::FileDownloader) - end - end - it "returns a JobArtifactDownloader given object_type is job_artifact" do subject = described_class.new('job_artifact', 1) @@ -36,135 +26,61 @@ stub_transfer_result(bytes_downloaded: 0, success: false) end - shared_examples_for 'a service that sets next retry time capped at some value' do - it 'ensures the next retry time is capped properly' do - download_service.execute - - expect(registry_entry.reload).to have_attributes( - retry_at: be_within(100.seconds).of(1.hour.from_now), - retry_count: 32 - ) - end - end - context 'with job_artifacts' do - let!(:registry_entry) do + let!(:geo_job_artifact_registry) do create(:geo_job_artifact_registry, success: false, retry_count: 31, artifact_id: file.id) end let(:file) { create(:ci_job_artifact) } let(:download_service) { described_class.new('job_artifact', file.id) } - it_behaves_like 'a service that sets next retry time capped at some value' - end + it 'ensures the next retry time is capped properly' do + download_service.execute - context 'with uploads' do - let!(:registry_entry) do - create(:geo_upload_legacy_registry, :avatar, success: false, file_id: file.id, retry_count: 31) + expect(geo_job_artifact_registry.reload).to have_attributes( + retry_at: be_within(100.seconds).of(1.hour.from_now), + retry_count: 32 + ) end - - let(:file) { create(:upload) } - let(:download_service) { described_class.new('avatar', file.id) } - - it_behaves_like 'a service that sets next retry time capped at some value' end end - shared_examples_for 'a service that handles orphaned uploads' do |file_type| - let(:download_service) { described_class.new(file_type, file.id) } - let(:registry) { Geo::UploadRegistry } - - before do - stub_exclusive_lease("file_download_service:#{file_type}:#{file.id}", - timeout: Geo::FileDownloadService::LEASE_TIMEOUT) - - file.update_column(:model_id, 22222) # Not-existing record - end - - it 'marks upload as successful and missing_on_primary' do - expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, - :download_time_s, - download_success: true, - bytes_downloaded: 0, - primary_missing_file: true)).and_call_original - - expect { download_service.execute }.to change { registry.synced.missing_on_primary.count }.by(1) - end - end - - shared_examples_for 'a service that downloads the file and registers the sync result' do |file_type| - let(:download_service) { described_class.new(file_type, file.id) } + describe '#execute' do + context 'job artifacts' do + let(:file) { create(:ci_job_artifact) } + let(:download_service) { described_class.new('job_artifact', file.id) } - let(:registry) do - case file_type - when 'job_artifact' + let(:registry) do Geo::JobArtifactRegistry - else - Geo::UploadRegistry end - end - - subject(:execute!) { download_service.execute } - before do - stub_exclusive_lease("file_download_service:#{file_type}:#{file.id}", - timeout: Geo::FileDownloadService::LEASE_TIMEOUT) - end + subject(:execute!) { download_service.execute } - context 'for a new file' do - context 'when the downloader fails before attempting a transfer' do - it 'logs that the download failed before attempting a transfer' do - result = double(:result, success: false, bytes_downloaded: 0, primary_missing_file: false, failed_before_transfer: true, reason: 'Something went wrong') - downloader = double(:downloader, execute: result) - allow(download_service).to receive(:downloader).and_return(downloader) - - expect(Gitlab::Geo::Logger) - .to receive(:info) - .with(hash_including(:message, :download_time_s, download_success: false, reason: 'Something went wrong', bytes_downloaded: 0, failed_before_transfer: true)) - .and_call_original - - execute! - end + before do + stub_exclusive_lease("file_download_service:job_artifact:#{file.id}", + timeout: Geo::FileDownloadService::LEASE_TIMEOUT) end - context 'when the downloader attempts a transfer' do - context 'when the file is successfully downloaded' do - before do - stub_transfer_result(bytes_downloaded: 100, success: true) - end + context 'for a new file' do + context 'when the downloader fails before attempting a transfer' do + it 'logs that the download failed before attempting a transfer' do + result = double(:result, success: false, bytes_downloaded: 0, primary_missing_file: false, failed_before_transfer: true, reason: 'Something went wrong') + downloader = double(:downloader, execute: result) + allow(download_service).to receive(:downloader).and_return(downloader) - it 'registers the file' do - expect { execute! }.to change { registry.count }.by(1) - end + expect(Gitlab::Geo::Logger) + .to receive(:info) + .with(hash_including(:message, :download_time_s, download_success: false, reason: 'Something went wrong', bytes_downloaded: 0, failed_before_transfer: true)) + .and_call_original - it 'marks the file as synced' do - expect { execute! }.to change { registry.synced.count }.by(1) - end - - it 'does not mark the file as missing on the primary' do execute! - - expect(registry.last.missing_on_primary).to be_falsey - end - - it 'logs the result' do - expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100)).and_call_original - - execute! - end - - it 'resets the retry fields' do - execute! - - expect(registry.last.reload.retry_count).to eq(0) - expect(registry.last.retry_at).to be_nil end end - context 'when the file fails to download' do - context 'when the file is missing on the primary' do + context 'when the downloader attempts a transfer' do + context 'when the file is successfully downloaded' do before do - stub_transfer_result(bytes_downloaded: 100, success: true, primary_missing_file: true) + stub_transfer_result(bytes_downloaded: 100, success: true) end it 'registers the file' do @@ -175,115 +91,102 @@ expect { execute! }.to change { registry.synced.count }.by(1) end - it 'marks the file as missing on the primary' do + it 'does not mark the file as missing on the primary' do execute! - expect(registry.last.missing_on_primary).to be_truthy + expect(registry.last.missing_on_primary).to be_falsey end it 'logs the result' do - expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100, primary_missing_file: true)).and_call_original + expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100)).and_call_original execute! end - it 'sets a retry date and increments the retry count' do - freeze_time do - execute! + it 'resets the retry fields' do + execute! - expect(registry.last.reload.retry_count).to eq(1) - expect(registry.last.retry_at > Time.current).to be_truthy - end + expect(registry.last.reload.retry_count).to eq(0) + expect(registry.last.retry_at).to be_nil end end - context 'when the file is not missing on the primary' do - before do - stub_transfer_result(bytes_downloaded: 0, success: false) - end - - it 'registers the file' do - expect { execute! }.to change { registry.count }.by(1) - end - - it 'marks the file as failed to sync' do - expect { execute! }.to change { registry.failed.count }.by(1) - end + context 'when the file fails to download' do + context 'when the file is missing on the primary' do + before do + stub_transfer_result(bytes_downloaded: 100, success: true, primary_missing_file: true) + end - it 'does not mark the file as missing on the primary' do - execute! + it 'registers the file' do + expect { execute! }.to change { registry.count }.by(1) + end - expect(registry.last.missing_on_primary).to be_falsey - end + it 'marks the file as synced' do + expect { execute! }.to change { registry.synced.count }.by(1) + end - it 'sets a retry date and increments the retry count' do - freeze_time do + it 'marks the file as missing on the primary' do execute! - expect(registry.last.reload.retry_count).to eq(1) - expect(registry.last.retry_at > Time.current).to be_truthy + expect(registry.last.missing_on_primary).to be_truthy end - end - end - end - end - end - context 'for a registered file that failed to sync' do - let!(:registry_entry) do - case file_type - when 'job_artifact' - create(:geo_job_artifact_registry, success: false, artifact_id: file.id, retry_count: 3, retry_at: 1.hour.ago) - else - create(:geo_upload_legacy_registry, file_type.to_sym, success: false, file_id: file.id, retry_count: 3, retry_at: 1.hour.ago) - end - end + it 'logs the result' do + expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100, primary_missing_file: true)).and_call_original - context 'when the file is successfully downloaded' do - before do - stub_transfer_result(bytes_downloaded: 100, success: true) - end + execute! + end - it 'does not register a new file' do - expect { execute! }.not_to change { registry.count } - end + it 'sets a retry date and increments the retry count' do + freeze_time do + execute! - it 'marks the file as synced' do - expect { execute! }.to change { registry.synced.count }.by(1) - end + expect(registry.last.reload.retry_count).to eq(1) + expect(registry.last.retry_at > Time.current).to be_truthy + end + end + end - it 'resets the retry fields' do - execute! + context 'when the file is not missing on the primary' do + before do + stub_transfer_result(bytes_downloaded: 0, success: false) + end - expect(registry_entry.reload.retry_count).to eq(0) - expect(registry_entry.retry_at).to be_nil - end + it 'registers the file' do + expect { execute! }.to change { registry.count }.by(1) + end - context 'when the file was marked as missing on the primary' do - before do - registry_entry.update_column(:missing_on_primary, true) - end + it 'marks the file as failed to sync' do + expect { execute! }.to change { registry.failed.count }.by(1) + end - it 'marks the file as no longer missing on the primary' do - execute! + it 'does not mark the file as missing on the primary' do + execute! - expect(registry_entry.reload.missing_on_primary).to be_falsey - end - end + expect(registry.last.missing_on_primary).to be_falsey + end - context 'when the file was not marked as missing on the primary' do - it 'does not mark the file as missing on the primary' do - execute! + it 'sets a retry date and increments the retry count' do + freeze_time do + execute! - expect(registry_entry.reload.missing_on_primary).to be_falsey + expect(registry.last.reload.retry_count).to eq(1) + expect(registry.last.retry_at > Time.current).to be_truthy + end + end + end end end end - context 'when the file fails to download' do - context 'when the file is missing on the primary' do + context 'for a registered file that failed to sync' do + let!(:geo_job_artifact_registry) do + create(:geo_job_artifact_registry, success: false, artifact_id: file.id, retry_count: 3, retry_at: 1.hour.ago) + end + + context 'when the file is successfully downloaded' do before do - stub_transfer_result(bytes_downloaded: 100, success: true, primary_missing_file: true) + stub_transfer_result(bytes_downloaded: 100, success: true) end it 'does not register a new file' do @@ -294,167 +197,119 @@ expect { execute! }.to change { registry.synced.count }.by(1) end - it 'marks the file as missing on the primary' do + it 'resets the retry fields' do execute! - expect(registry_entry.reload.missing_on_primary).to be_truthy + expect(geo_job_artifact_registry.reload.retry_count).to eq(0) + expect(geo_job_artifact_registry.retry_at).to be_nil end - it 'logs the result' do - expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100, primary_missing_file: true)).and_call_original - - execute! - end + context 'when the file was marked as missing on the primary' do + before do + geo_job_artifact_registry.update_column(:missing_on_primary, true) + end - it 'sets a retry date and increments the retry count' do - freeze_time do + it 'marks the file as no longer missing on the primary' do execute! - expect(registry_entry.reload.retry_count).to eq(4) - expect(registry_entry.retry_at > Time.current).to be_truthy + expect(geo_job_artifact_registry.reload.missing_on_primary).to be_falsey end end - it 'sets a retry date with a maximum of about 4 hours' do - registry_entry.update!(retry_count: 100, retry_at: 1.minute.ago) - - freeze_time do + context 'when the file was not marked as missing on the primary' do + it 'does not mark the file as missing on the primary' do execute! - expect(registry_entry.reload.retry_at).to be_within(3.minutes).of(4.hours.from_now) + expect(geo_job_artifact_registry.reload.missing_on_primary).to be_falsey end end end - context 'when the file is not missing on the primary' do - before do - stub_transfer_result(bytes_downloaded: 0, success: false) - end - - it 'does not register a new file' do - expect { execute! }.not_to change { registry.count } - end - - it 'does not change the success flag' do - expect { execute! }.not_to change { registry.failed.count } - end + context 'when the file fails to download' do + context 'when the file is missing on the primary' do + before do + stub_transfer_result(bytes_downloaded: 100, success: true, primary_missing_file: true) + end - it 'does not mark the file as missing on the primary' do - execute! + it 'does not register a new file' do + expect { execute! }.not_to change { registry.count } + end - expect(registry_entry.reload.missing_on_primary).to be_falsey - end + it 'marks the file as synced' do + expect { execute! }.to change { registry.synced.count }.by(1) + end - it 'sets a retry date and increments the retry count' do - freeze_time do + it 'marks the file as missing on the primary' do execute! - expect(registry_entry.reload.retry_count).to eq(4) - expect(registry_entry.retry_at > Time.current).to be_truthy + expect(geo_job_artifact_registry.reload.missing_on_primary).to be_truthy end - end - it 'sets a retry date with a maximum of about 1 hour' do - registry_entry.update!(retry_count: 100, retry_at: 1.minute.ago) + it 'logs the result' do + expect(Gitlab::Geo::Logger).to receive(:info).with(hash_including(:message, :download_time_s, download_success: true, bytes_downloaded: 100, primary_missing_file: true)).and_call_original - freeze_time do execute! - - expect(registry_entry.reload.retry_at).to be_within(3.minutes).of(1.hour.from_now) end - end - end - end - end - end - describe '#execute' do - context 'user avatar' do - let(:file) { create(:upload, model: build(:user)) } - - it_behaves_like "a service that downloads the file and registers the sync result", 'avatar' - it_behaves_like 'a service that handles orphaned uploads', 'avatar' - end - - context 'group avatar' do - let(:file) { create(:upload, model: build(:group)) } - - it_behaves_like "a service that downloads the file and registers the sync result", 'avatar' - it_behaves_like 'a service that handles orphaned uploads', 'avatar' - end - - context 'project avatar' do - let(:file) { create(:upload, model: build(:project)) } - - it_behaves_like "a service that downloads the file and registers the sync result", 'avatar' - it_behaves_like 'a service that handles orphaned uploads', 'avatar' - end - - context 'with an attachment' do - let(:file) { create(:upload, :attachment_upload) } - - it_behaves_like "a service that downloads the file and registers the sync result", 'attachment' - it_behaves_like 'a service that handles orphaned uploads', 'attachment' - end - - context 'with a favicon' do - let(:file) { create(:upload, :favicon_upload) } - - it_behaves_like "a service that downloads the file and registers the sync result", 'favicon' - it_behaves_like 'a service that handles orphaned uploads', 'favicon' - end + it 'sets a retry date and increments the retry count' do + freeze_time do + execute! - context 'with a snippet' do - let(:file) { create(:upload, :personal_snippet_upload) } + expect(geo_job_artifact_registry.reload.retry_count).to eq(4) + expect(geo_job_artifact_registry.retry_at > Time.current).to be_truthy + end + end - it_behaves_like "a service that downloads the file and registers the sync result", 'personal_file' - it_behaves_like 'a service that handles orphaned uploads', 'personal_file' - end + it 'sets a retry date with a maximum of about 4 hours' do + geo_job_artifact_registry.update!(retry_count: 100, retry_at: 1.minute.ago) - context 'with file upload' do - let(:file) { create(:upload, :issuable_upload) } + freeze_time do + execute! - it_behaves_like "a service that downloads the file and registers the sync result", 'file' - it_behaves_like 'a service that handles orphaned uploads', 'file' - end + expect(geo_job_artifact_registry.reload.retry_at).to be_within(3.minutes).of(4.hours.from_now) + end + end + end - context 'with namespace file upload' do - let(:file) { create(:upload, :namespace_upload) } + context 'when the file is not missing on the primary' do + before do + stub_transfer_result(bytes_downloaded: 0, success: false) + end - it_behaves_like "a service that downloads the file and registers the sync result", 'namespace_file' - it_behaves_like 'a service that handles orphaned uploads', 'namespace_file' - end + it 'does not register a new file' do + expect { execute! }.not_to change { registry.count } + end - context 'with an incident metrics upload' do - let(:file) { create(:upload, :issue_metric_image) } + it 'does not change the success flag' do + expect { execute! }.not_to change { registry.failed.count } + end - it_behaves_like 'a service that downloads the file and registers the sync result', 'issuable_metric_image' - it_behaves_like 'a service that handles orphaned uploads', 'issuable_metric_image' - end + it 'does not mark the file as missing on the primary' do + execute! - context 'job artifacts' do - it_behaves_like "a service that downloads the file and registers the sync result", 'job_artifact' do - let(:file) { create(:ci_job_artifact) } - end - end + expect(geo_job_artifact_registry.reload.missing_on_primary).to be_falsey + end - context 'Import/Export' do - let(:file) { create(:upload, model: build(:import_export_upload)) } + it 'sets a retry date and increments the retry count' do + freeze_time do + execute! - it_behaves_like "a service that downloads the file and registers the sync result", 'import_export' - it_behaves_like 'a service that handles orphaned uploads', 'import_export' - end + expect(geo_job_artifact_registry.reload.retry_count).to eq(4) + expect(geo_job_artifact_registry.retry_at > Time.current).to be_truthy + end + end - context 'with bulk imports export upload' do - let(:file) { create(:upload, model: build(:bulk_import_export_upload)) } + it 'sets a retry date with a maximum of about 1 hour' do + geo_job_artifact_registry.update!(retry_count: 100, retry_at: 1.minute.ago) - it_behaves_like 'a service that downloads the file and registers the sync result', :'bulk_imports/export' - it_behaves_like 'a service that handles orphaned uploads', :'bulk_imports/export' - end + freeze_time do + execute! - context 'bad object type' do - it 'raises an error' do - expect { described_class.new(:bad, 1).execute }.to raise_error(NotImplementedError) + expect(geo_job_artifact_registry.reload.retry_at).to be_within(3.minutes).of(1.hour.from_now) + end + end + end + end end end end diff --git a/ee/spec/services/geo/file_registry_removal_service_spec.rb b/ee/spec/services/geo/file_registry_removal_service_spec.rb index 828b1b5b0b91b8f36931483bc972232ae902bcd9..79046deccfd286f5e6ceca7e7353a61df9c18992 100644 --- a/ee/spec/services/geo/file_registry_removal_service_spec.rb +++ b/ee/spec/services/geo/file_registry_removal_service_spec.rb @@ -21,42 +21,6 @@ described_class.new(:lfs, 99).execute end - shared_examples 'removes' do - subject(:service) { described_class.new(registry.file_type, registry.file_id) } - - before do - stub_exclusive_lease("file_registry_removal_service:#{registry.file_type}:#{registry.file_id}", - timeout: Geo::FileRegistryRemovalService::LEASE_TIMEOUT) - end - - it 'file from disk' do - expect do - service.execute - end.to change { File.exist?(file_path) }.from(true).to(false) - end - - it 'deletes registry entry' do - expect do - service.execute - end.to change(Geo::UploadRegistry, :count).by(-1) - end - end - - shared_examples 'removes registry entry' do - subject(:service) { described_class.new(registry.file_type, registry.file_id) } - - before do - stub_exclusive_lease("file_registry_removal_service:#{registry.file_type}:#{registry.file_id}", - timeout: Geo::FileRegistryRemovalService::LEASE_TIMEOUT) - end - - it 'deletes registry entry' do - expect do - service.execute - end.to change(Geo::UploadRegistry, :count).by(-1) - end - end - shared_examples 'removes artifact' do subject(:service) { described_class.new('job_artifact', registry.artifact_id) } @@ -221,158 +185,6 @@ end end - context 'with avatar' do - let!(:upload) { create(:user, :with_avatar).avatar.upload } - let!(:registry) { create(:geo_upload_legacy_registry, :avatar, file_id: upload.id) } - let!(:file_path) { upload.retrieve_uploader.file.path } - - it_behaves_like 'removes' - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(AvatarUploader) - upload.update_column(:store, AvatarUploader::Store::REMOTE) - end - - context 'with object storage enabled' do - it_behaves_like 'removes' - end - - context 'with object storage disabled' do - before do - stub_uploads_object_storage(AvatarUploader, enabled: false) - end - - it_behaves_like 'removes registry entry' - end - end - end - - context 'with attachment' do - let!(:upload) { create(:note, :with_attachment).attachment.upload } - let!(:registry) { create(:geo_upload_legacy_registry, :attachment, file_id: upload.id) } - let!(:file_path) { upload.retrieve_uploader.file.path } - - it_behaves_like 'removes' - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(AttachmentUploader) - upload.update_column(:store, AttachmentUploader::Store::REMOTE) - end - - context 'with object storage enabled' do - it_behaves_like 'removes' - end - - context 'with object storage disabled' do - before do - stub_uploads_object_storage(AttachmentUploader, enabled: false) - end - - it_behaves_like 'removes registry entry' - end - end - end - - context 'with namespace_file' do - let_it_be(:group) { create(:group) } - - let(:file) { fixture_file_upload('spec/fixtures/dk.png', 'image/png') } - let!(:upload) do - NamespaceFileUploader.new(group).store!(file) - Upload.find_by(model: group, uploader: NamespaceFileUploader.name) - end - - let!(:registry) { create(:geo_upload_legacy_registry, :namespace_file, file_id: upload.id) } - let!(:file_path) { upload.retrieve_uploader.file.path } - - it_behaves_like 'removes' - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(NamespaceFileUploader) - upload.update_column(:store, NamespaceFileUploader::Store::REMOTE) - end - - context 'with object storage enabled' do - it_behaves_like 'removes' - end - - context 'with object storage disabled' do - before do - stub_uploads_object_storage(NamespaceFileUploader, enabled: false) - end - - it_behaves_like 'removes registry entry' - end - end - end - - context 'with personal_file' do - let(:snippet) { create(:personal_snippet) } - let(:file) { fixture_file_upload('spec/fixtures/dk.png', 'image/png') } - let!(:upload) do - PersonalFileUploader.new(snippet).store!(file) - Upload.find_by(model: snippet, uploader: PersonalFileUploader.name) - end - - let!(:registry) { create(:geo_upload_legacy_registry, :personal_file, file_id: upload.id) } - let!(:file_path) { upload.retrieve_uploader.file.path } - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(PersonalFileUploader) - upload.update_column(:store, PersonalFileUploader::Store::REMOTE) - end - - context 'with object storage enabled' do - it_behaves_like 'removes' - end - - context 'with object storage disabled' do - before do - stub_uploads_object_storage(PersonalFileUploader, enabled: false) - end - - it_behaves_like 'removes registry entry' - end - end - end - - context 'with favicon' do - let(:appearance) { create(:appearance) } - let(:file) { fixture_file_upload('spec/fixtures/dk.png', 'image/png') } - let!(:upload) do - FaviconUploader.new(appearance).store!(file) - Upload.find_by(model: appearance, uploader: FaviconUploader.name) - end - - let!(:registry) { create(:geo_upload_legacy_registry, :favicon, file_id: upload.id) } - let!(:file_path) { upload.retrieve_uploader.file.path } - - it_behaves_like 'removes' - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(FaviconUploader) - upload.update_column(:store, FaviconUploader::Store::REMOTE) - end - - context 'with object storage enabled' do - it_behaves_like 'removes' - end - - context 'with object storage disabled' do - before do - stub_uploads_object_storage(FaviconUploader, enabled: false) - end - - it_behaves_like 'removes registry entry' - end - end - end - context 'with package file' do let(:package_file) { create(:package_file_with_file) } let!(:registry) { create(:geo_package_file_registry, package_file: package_file) } @@ -407,30 +219,28 @@ end end - context 'with Uploads(after migrating to SSF)' do + context 'with uploads' do let!(:upload) { create(:user, :with_avatar).avatar.upload } let!(:registry) { create(:geo_upload_registry, file_id: upload.id) } let!(:file_path) { upload.retrieve_uploader.file.path } - it_behaves_like 'removes' - - context 'migrated to object storage' do - before do - stub_uploads_object_storage(AvatarUploader) - upload.update_column(:store, AvatarUploader::Store::REMOTE) - end + subject(:service) { described_class.new('upload', registry.file_id) } - context 'with object storage enabled' do - it_behaves_like 'removes' - end + before do + stub_exclusive_lease("file_registry_removal_service:upload:#{registry.file_id}", + timeout: Geo::FileRegistryRemovalService::LEASE_TIMEOUT) + end - context 'with object storage disabled' do - before do - stub_uploads_object_storage(AvatarUploader, enabled: false) - end + it 'file from disk' do + expect do + service.execute + end.to change { File.exist?(file_path) }.from(true).to(false) + end - it_behaves_like 'removes registry entry' - end + it 'deletes registry entry' do + expect do + service.execute + end.to change(Geo::UploadRegistry, :count).by(-1) end end end diff --git a/ee/spec/services/geo/metrics_update_service_spec.rb b/ee/spec/services/geo/metrics_update_service_spec.rb index 90213357e35bd5f18e2b1727ac1ec33f68a34a3c..a54fef7f3711fa2d1109bd2d7be51f55d0418d39 100644 --- a/ee/spec/services/geo/metrics_update_service_spec.rb +++ b/ee/spec/services/geo/metrics_update_service_spec.rb @@ -36,10 +36,6 @@ design_repositories_count: 100, design_repositories_synced_count: 50, design_repositories_failed_count: 12, - attachments_count: 30, - attachments_synced_count: 30, - attachments_failed_count: 25, - attachments_synced_missing_on_primary_count: 6, last_event_id: 2, last_event_date: event_date, cursor_last_event_id: 1, @@ -63,7 +59,6 @@ projects_count: 10, lfs_objects_count: 100, job_artifacts_count: 100, - attachments_count: 30, container_repositories_count: 100, last_event_id: 2, last_event_date: event_date, @@ -171,10 +166,6 @@ expect(metric_value(:geo_job_artifacts_synced)).to eq(50) expect(metric_value(:geo_job_artifacts_failed)).to eq(12) expect(metric_value(:geo_job_artifacts_synced_missing_on_primary)).to eq(5) - expect(metric_value(:geo_attachments)).to eq(30) - expect(metric_value(:geo_attachments_synced)).to eq(30) - expect(metric_value(:geo_attachments_failed)).to eq(25) - expect(metric_value(:geo_attachments_synced_missing_on_primary)).to eq(6) expect(metric_value(:geo_last_event_id)).to eq(2) expect(metric_value(:geo_last_event_timestamp)).to eq(event_date.to_i) expect(metric_value(:geo_cursor_last_event_id)).to eq(1) diff --git a/ee/spec/services/geo/upload_deleted_event_store_spec.rb b/ee/spec/services/geo/upload_deleted_event_store_spec.rb deleted file mode 100644 index 9405b5480223c5bc5f3391bf46563d0a7ec22456..0000000000000000000000000000000000000000 --- a/ee/spec/services/geo/upload_deleted_event_store_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Geo::UploadDeletedEventStore do - include EE::GeoHelpers - - let_it_be(:secondary_node) { create(:geo_node) } - - let(:upload) { create(:upload) } - - subject { described_class.new(upload) } - - describe '#create!' do - it_behaves_like 'a Geo event store', Geo::UploadDeletedEvent do - let(:file_subject) { upload } - end - - context 'when running on a primary node' do - before do - stub_primary_node - end - - it 'tracks upload attributes' do - subject.create! - - expect(Geo::UploadDeletedEvent.last).to have_attributes( - upload_id: upload.id, - file_path: upload.path, - model_id: upload.model_id, - model_type: upload.model_type, - uploader: upload.uploader - ) - end - end - end -end diff --git a/ee/spec/support/shared_examples/lib/gitlab/middleware/allowlisted_admin_geo_requests_shared_examples.rb b/ee/spec/support/shared_examples/lib/gitlab/middleware/allowlisted_admin_geo_requests_shared_examples.rb index da479907f139b358047cf3e536fce80a3f38f34a..35d7ac381304a1b245986b560d5511944fb9f352 100644 --- a/ee/spec/support/shared_examples/lib/gitlab/middleware/allowlisted_admin_geo_requests_shared_examples.rb +++ b/ee/spec/support/shared_examples/lib/gitlab/middleware/allowlisted_admin_geo_requests_shared_examples.rb @@ -24,7 +24,5 @@ it_behaves_like 'allowlisted request', :post, '/admin/geo/replication/projects/resync_all' it_behaves_like 'allowlisted request', :post, '/admin/geo/replication/projects/1/force_redownload' - - it_behaves_like 'allowlisted request', :delete, '/admin/geo/replication/legacy-uploads/1' end end diff --git a/ee/spec/uploaders/every_gitlab_uploader_spec.rb b/ee/spec/uploaders/every_gitlab_uploader_spec.rb index 9eb09a1a03ee357309ef24529fd8389c9df599c3..7c36853ee9d479c4805e1f86bbacc3b924381216 100644 --- a/ee/spec/uploaders/every_gitlab_uploader_spec.rb +++ b/ee/spec/uploaders/every_gitlab_uploader_spec.rb @@ -84,7 +84,12 @@ def known_unimplemented_uploader?(uploader) def handled_by_ssf?(uploader) replicable_name = replicable_name_for(uploader) - replicable_names.include?(replicable_name) + replicable_names.include?(replicable_name) || uploads?(uploader) + end + + def uploads?(uploader) + upload_name = uploader.name.delete_suffix('Uploader').underscore + Gitlab::Geo::Replication.object_type_from_user_uploads?(upload_name) end def object_types diff --git a/ee/spec/workers/geo/file_download_dispatch_worker_spec.rb b/ee/spec/workers/geo/file_download_dispatch_worker_spec.rb index 649c5b04322a4f1d3c3234b7506acb7ff9fb102d..b1329e6931589b34bec7ed15644346e80e588a6c 100644 --- a/ee/spec/workers/geo/file_download_dispatch_worker_spec.rb +++ b/ee/spec/workers/geo/file_download_dispatch_worker_spec.rb @@ -18,8 +18,6 @@ WebMock.stub_request(:get, /primary-geo-node/).to_return(status: 200, body: "", headers: {}) - stub_feature_flags(geo_upload_replication: false) - allow(Geo::FileDownloadWorker).to receive(:with_status).and_return(Geo::FileDownloadWorker) end @@ -48,113 +46,6 @@ subject.perform end - context 'with attachments (Upload records)' do - let(:upload) { create(:upload) } - - it 'performs Geo::FileDownloadWorker for unsynced attachments' do - create(:geo_upload_legacy_registry, :avatar, :never_synced, file_id: upload.id) - - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', upload.id) - - subject.perform - end - - it 'performs Geo::FileDownloadWorker for failed-sync attachments' do - create(:geo_upload_legacy_registry, :avatar, :failed, file_id: upload.id, bytes: 0) - - expect(Geo::FileDownloadWorker).to receive(:perform_async) - .with('avatar', upload.id).once.and_return(spy) - - subject.perform - end - - it 'does not perform Geo::FileDownloadWorker for synced attachments' do - create(:geo_upload_legacy_registry, :avatar, file_id: upload.id, bytes: 1234) - - expect(Geo::FileDownloadWorker).not_to receive(:perform_async) - - subject.perform - end - - it 'does not perform Geo::FileDownloadWorker for synced attachments even with 0 bytes downloaded' do - create(:geo_upload_legacy_registry, :avatar, file_id: upload.id, bytes: 0) - - expect(Geo::FileDownloadWorker).not_to receive(:perform_async) - - subject.perform - end - - context 'with a failed file' do - let(:failed_registry) { create(:geo_upload_legacy_registry, :avatar, :failed, file_id: non_existing_record_id) } - - it 'does not stall backfill' do - unsynced_registry = create(:geo_upload_legacy_registry, :avatar, :with_file, :never_synced) - - stub_const('Geo::Scheduler::SchedulerWorker::DB_RETRIEVE_BATCH_SIZE', 1) - - expect(Geo::FileDownloadWorker).not_to receive(:perform_async).with('avatar', failed_registry.file_id) - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', unsynced_registry.file_id) - - subject.perform - end - - it 'retries failed files' do - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', failed_registry.file_id) - - subject.perform - end - - it 'does not retry failed files when retry_at is tomorrow' do - failed_registry = create(:geo_upload_legacy_registry, :avatar, :failed, file_id: non_existing_record_id, retry_at: Date.tomorrow) - - expect(Geo::FileDownloadWorker).not_to receive(:perform_async).with('avatar', failed_registry.file_id) - - subject.perform - end - - it 'retries failed files when retry_at is in the past' do - failed_registry = create(:geo_upload_legacy_registry, :avatar, :failed, file_id: non_existing_record_id, retry_at: Date.yesterday) - - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', failed_registry.file_id) - - subject.perform - end - end - - context 'with Upload files missing on the primary that are marked as synced' do - let(:synced_upload_with_file_missing_on_primary) { create(:upload) } - - before do - Geo::UploadRegistry.create!(file_type: :avatar, file_id: synced_upload_with_file_missing_on_primary.id, bytes: 1234, success: true, missing_on_primary: true) - end - - it 'retries the files if there is spare capacity' do - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', synced_upload_with_file_missing_on_primary.id) - - subject.perform - end - - it 'does not retry those files if there is no spare capacity' do - unsynced_registry = create(:geo_upload_legacy_registry, :avatar, :with_file, :never_synced) - expect(subject).to receive(:db_retrieve_batch_size).and_return(1).twice - - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', unsynced_registry.file_id) - - subject.perform - end - - it 'does not retry those files if they are already scheduled' do - unsynced_registry = create(:geo_upload_legacy_registry, :avatar, :with_file, :never_synced) - - scheduled_jobs = [{ type: 'avatar', id: synced_upload_with_file_missing_on_primary.id, job_id: 'foo' }] - expect(subject).to receive(:scheduled_jobs).and_return(scheduled_jobs).at_least(1) - expect(Geo::FileDownloadWorker).to receive(:perform_async).with('avatar', unsynced_registry.file_id) - - subject.perform - end - end - end - context 'with job artifacts' do it 'performs Geo::FileDownloadWorker for unsynced job artifacts' do registry = create(:geo_job_artifact_registry, :with_artifact, :never_synced) @@ -280,14 +171,9 @@ result_object = double(:result, success: true, bytes_downloaded: 100, primary_missing_file: false) allow_any_instance_of(::Gitlab::Geo::Replication::BaseTransfer).to receive(:download_from_primary).and_return(result_object) - create_list(:geo_upload_legacy_registry, 2, :avatar, :with_file, :never_synced) - create_list(:geo_upload_legacy_registry, 2, :attachment, :with_file, :never_synced) - create(:geo_upload_legacy_registry, :favicon, :with_file, :never_synced) - create(:geo_upload_legacy_registry, :import_export, :with_file, :never_synced) - create(:geo_upload_legacy_registry, :personal_file, :with_file, :never_synced) - create(:geo_job_artifact_registry, :with_artifact, :never_synced) + create_list(:geo_job_artifact_registry, 6, :with_artifact, :never_synced) - expect(Geo::FileDownloadWorker).to receive(:perform_async).exactly(8).times.and_call_original + expect(Geo::FileDownloadWorker).to receive(:perform_async).exactly(6).times.and_call_original # For 10 downloads, we expect four database reloads: # 1. Load the first batch of 5. # 2. 4 get sent out, 1 remains. This triggers another reload, which loads in the next 5. diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml index c0ba2c58a41dc7e0d48cc15b6f98c5177804ea79..ee5039ccab8389bc65b521130b6e53252c346fa5 100644 --- a/lib/gitlab/database/gitlab_schemas.yml +++ b/lib/gitlab/database/gitlab_schemas.yml @@ -220,7 +220,6 @@ geo_repository_deleted_events: :gitlab_main geo_repository_renamed_events: :gitlab_main geo_repository_updated_events: :gitlab_main geo_reset_checksum_events: :gitlab_main -geo_upload_deleted_events: :gitlab_main gitlab_subscription_histories: :gitlab_main gitlab_subscriptions: :gitlab_main gpg_keys: :gitlab_main diff --git a/locale/gitlab.pot b/locale/gitlab.pot index acf25deb567c87b77ccd055e068116916b8f3e9f..bdcba188404b7783fa90f5784310cb5aee4b8b67 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -15268,9 +15268,6 @@ msgstr "" msgid "Geo|Could not remove tracking entry for an existing project." msgstr "" -msgid "Geo|Could not remove tracking entry for an existing upload." -msgstr "" - msgid "Geo|Data replication lag" msgstr "" @@ -15544,9 +15541,6 @@ msgstr "" msgid "Geo|Tracking entry for project (%{project_id}) was successfully removed." msgstr "" -msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed." -msgstr "" - msgid "Geo|URL can't be blank" msgstr "" @@ -28813,9 +28807,6 @@ msgstr "" msgid "Removed %{reviewer_text} %{reviewer_references}." msgstr "" -msgid "Removed %{type} with id %{id}" -msgstr "" - msgid "Removed all labels." msgstr "" @@ -28840,6 +28831,9 @@ msgstr "" msgid "Removed time estimate." msgstr "" +msgid "Removed upload with id %{id}" +msgstr "" + msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here." msgstr "" @@ -37122,9 +37116,6 @@ msgstr "" msgid "Uploading changes to terminal" msgstr "" -msgid "Uploads" -msgstr "" - msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently deleted after %{deletion_adjourned_period} days on %{date}. Until that time:" msgstr "" diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 7fb2723dd019c663e4af37d3bde66c361156eb47..7785233875c449abc3d0e83192254a175a7bcc4d 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -48,7 +48,6 @@ geo_node_statuses: %w[last_event_id cursor_last_event_id], geo_nodes: %w[oauth_application_id], geo_repository_deleted_events: %w[project_id], - geo_upload_deleted_events: %w[upload_id model_id], gitlab_subscription_histories: %w[gitlab_subscription_id hosted_plan_id namespace_id], identities: %w[user_id], import_failures: %w[project_id],