Skip to content

Geo: Add verification for LFS objects [RUN ALL RSPEC] [RUN AS-IF-FOSS]

What does this MR do?

This MR adds verification for LFS objects.

Resolves #323286 (closed)

Database Review information

`rake db:migrate`


== 20210629143042 CreateLfsObjectStates: migrating ============================
-- table_exists?(:lfs_object_states)
   -> 0.0006s
-- create_table(:lfs_object_states, {:id=>false})
   -> 0.0205s
-- transaction_open?()
   -> 0.0000s
-- current_schema()
   -> 0.0002s
-- execute("ALTER TABLE lfs_object_states\nADD CONSTRAINT lfs_object_verification_failure_text_limit\nCHECK ( char_length(verification_failure) <= 255 )\nNOT VALID;\n")
   -> 0.0014s
-- current_schema()
   -> 0.0001s
-- execute("SET statement_timeout TO 0")
   -> 0.0010s
-- execute("ALTER TABLE lfs_object_states VALIDATE CONSTRAINT lfs_object_verification_failure_text_limit;")
   -> 0.0016s
-- execute("RESET ALL")
   -> 0.0015s
== 20210629143042 CreateLfsObjectStates: migrated (0.0455s) ===================
`rake db:rollback`

➜  gitlab git:(ag-add-verification-for-lfs-objects) ✗ rake db:rollback
== 20210629143042 CreateLfsObjectStates: reverting ============================
-- drop_table(:lfs_object_states)
   -> 0.0167s
== 20210629143042 CreateLfsObjectStates: reverted (0.0167s) ===================

`rake geo:db:migrate`

➜  gitlab git:(ag-add-verification-for-lfs-objects) ✗ rake geo:db:migrate
== 20210614100436 AddVerificationToLfsObjectRegistry: migrating ===============
-- add_column(:lfs_object_registry, :verification_started_at, :datetime_with_timezone)
   -> 0.0026s
-- add_column(:lfs_object_registry, :verified_at, :datetime_with_timezone)
   -> 0.0008s
-- add_column(:lfs_object_registry, :verification_retry_at, :datetime_with_timezone)
   -> 0.0007s
-- add_column(:lfs_object_registry, :verification_retry_count, :integer, {:default=>0})
   -> 0.0020s
-- add_column(:lfs_object_registry, :verification_state, :integer, {:limit=>2, :default=>0, :null=>false})
   -> 0.0011s
-- add_column(:lfs_object_registry, :checksum_mismatch, :boolean, {:default=>false, :null=>false})
   -> 0.0347s
-- add_column(:lfs_object_registry, :verification_checksum, :binary)
   -> 0.0008s
-- add_column(:lfs_object_registry, :verification_checksum_mismatched, :binary)
   -> 0.0006s
-- add_column(:lfs_object_registry, :verification_failure, :string, {:limit=>255})
   -> 0.0007s
== 20210614100436 AddVerificationToLfsObjectRegistry: migrated (0.0444s) ======

== 20210614100650 AddIndexesToLfsObjectRegistry: migrating ====================
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :lfs_object_id, {:name=>"index_lfs_object_registry_on_lfs_object_id", :unique=>true, :algorithm=>:concurrently})
   -> 0.0031s
-- add_index(:lfs_object_registry, :lfs_object_id, {:name=>"index_lfs_object_registry_on_lfs_object_id", :unique=>true, :algorithm=>:concurrently})
   -> 0.0036s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :retry_at, {:algorithm=>:concurrently})
   -> 0.0020s
-- add_index(:lfs_object_registry, :retry_at, {:algorithm=>:concurrently})
   -> 0.0018s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :state, {:algorithm=>:concurrently})
   -> 0.0016s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :verification_retry_at, {:name=>"lfs_object_registry_failed_verification", :order=>"NULLS FIRST", :where=>"((state = 2) AND (verification_state = 3))", :algorithm=>:concurrently})
   -> 0.0018s
-- add_index(:lfs_object_registry, :verification_retry_at, {:name=>"lfs_object_registry_failed_verification", :order=>"NULLS FIRST", :where=>"((state = 2) AND (verification_state = 3))", :algorithm=>:concurrently})
   -> 0.0016s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :verification_state, {:name=>"lfs_object_registry_needs_verification", :where=>"((state = 2)  AND (verification_state = ANY (ARRAY[0, 3])))", :algorithm=>:concurrently})
   -> 0.0018s
-- add_index(:lfs_object_registry, :verification_state, {:name=>"lfs_object_registry_needs_verification", :where=>"((state = 2)  AND (verification_state = ANY (ARRAY[0, 3])))", :algorithm=>:concurrently})
   -> 0.0017s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:lfs_object_registry, :verified_at, {:name=>"lfs_object_registry_pending_verification", :order=>"NULLS FIRST", :where=>"((state = 2) AND (verification_state = 0))", :algorithm=>:concurrently})
   -> 0.0019s
-- add_index(:lfs_object_registry, :verified_at, {:name=>"lfs_object_registry_pending_verification", :order=>"NULLS FIRST", :where=>"((state = 2) AND (verification_state = 0))", :algorithm=>:concurrently})
   -> 0.0017s
== 20210614100650 AddIndexesToLfsObjectRegistry: migrated (0.0266s) ===========
`rake geo:db:rollback STEP=2`

rake geo:db:rollback STEP=2
== 20210614100650 AddIndexesToLfsObjectRegistry: reverting ====================
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0061s
-- remove_index(:lfs_object_registry, {:algorithm=>:concurrently, :name=>"index_lfs_object_registry_on_lfs_object_id"})
   -> 0.0029s
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0018s
-- remove_index(:lfs_object_registry, {:algorithm=>:concurrently, :name=>:index_lfs_object_registry_on_retry_at})
   -> 0.0010s
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0019s
-- current_schema()
   -> 0.0001s
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0019s
-- remove_index(:lfs_object_registry, {:algorithm=>:concurrently, :name=>"lfs_object_registry_failed_verification"})
   -> 0.0011s
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0015s
-- remove_index(:lfs_object_registry, {:algorithm=>:concurrently, :name=>"lfs_object_registry_needs_verification"})
   -> 0.0009s
-- transaction_open?()
   -> 0.0000s
-- indexes(:lfs_object_registry)
   -> 0.0014s
-- remove_index(:lfs_object_registry, {:algorithm=>:concurrently, :name=>"lfs_object_registry_pending_verification"})
   -> 0.0010s
== 20210614100650 AddIndexesToLfsObjectRegistry: reverted (0.0280s) ===========

== 20210614100436 AddVerificationToLfsObjectRegistry: reverting ===============
-- remove_column(:lfs_object_registry, :verification_failure, :string, {:limit=>255})
   -> 0.0020s
-- remove_column(:lfs_object_registry, :verification_checksum_mismatched, :binary)
   -> 0.0007s
-- remove_column(:lfs_object_registry, :verification_checksum, :binary)
   -> 0.0007s
-- remove_column(:lfs_object_registry, :checksum_mismatch, :boolean, {:default=>false, :null=>false})
   -> 0.0010s
-- remove_column(:lfs_object_registry, :verification_state, :integer, {:limit=>2, :default=>0, :null=>false})
   -> 0.0008s
-- remove_column(:lfs_object_registry, :verification_retry_count, :integer, {:default=>0})
   -> 0.0009s
-- remove_column(:lfs_object_registry, :verification_retry_at, :datetime_with_timezone)
   -> 0.0006s
-- remove_column(:lfs_object_registry, :verified_at, :datetime_with_timezone)
   -> 0.0006s
-- remove_column(:lfs_object_registry, :verification_started_at, :datetime_with_timezone)
   -> 0.0006s
== 20210614100436 AddVerificationToLfsObjectRegistry: reverted (0.0106s) ======

Screenshots

Screenshot_2021-11-19_at_18.35.35

Manual Testing setup

f = Pathname.new(Rails.root.join("/Users/aakriti/Development/gdk/gitlab/file.txt")).open 
LfsObject.new(oid: "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a", size: 499013, file: f).save!
  • New object gets checksummed
  • Already existing objects were checksummed
  • Verification works on secondary?

Metrics

  1. API response curl --header "PRIVATE-TOKEN: <>" "http://127.0.0.1:3000/api/v4/geo_nodes/status"
    {
        "geo_node_id": 1,
        ...
        "lfs_objects_count": 6,
        "lfs_objects_checksum_total_count": 6,
        "lfs_objects_checksummed_count": 6,
        "lfs_objects_checksum_failed_count": 0,
        "lfs_objects_synced_count": null,
        "lfs_objects_failed_count": null,
        "lfs_objects_registry_count": null,
        "lfs_objects_verification_total_count": null,
        "lfs_objects_verified_count": null,
        "lfs_objects_verification_failed_count": null,
        ...
    }...
]
  1. Status rake task: rake geo:status
➜  gitlab git:(ag-add-verification-for-lfs-objects) ✗ rake geo:status

Name: gdk-geo
URL: http://127.0.0.1:3001
-----------------------------------------------------
                        GitLab Version: 14.0.0-pre
                              Geo Role: Secondary
                         Health Status: Healthy
                 Health Status Summary:
                                      ...
                           Lfs Objects: 5/5 (100%)
                                      ...
                  Lfs Objects Verified: 0/5 (0%)
                                      ...
                Last status report was: 33 minutes ago
  1. Prometheus
 {
  ...
    "enablement": {
      "geo_secondary_web_oauth_users": 1,
      "geo_node_usage": [
        {
          ...
          "lfs_objects_count": 5,
          "lfs_objects_checksum_total_count": null,
          "lfs_objects_checksummed_count": null,
          "lfs_objects_checksum_failed_count": null,
          "lfs_objects_synced_count": 5,
          "lfs_objects_failed_count": 0,
          "lfs_objects_registry_count": 5,
          "lfs_objects_verification_total_count": null,
          "lfs_objects_verified_count": null,
          "lfs_objects_verification_failed_count": null,
          ...
        }
      ]
    },

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team
Edited by Aakriti Gupta

Merge request reports

Loading