diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION index 0f2d03f58cd..6517900b5fc 100644 --- a/GITLAB_KAS_VERSION +++ b/GITLAB_KAS_VERSION @@ -1 +1 @@ -70acd17ccd04ef784f793b1b00a84873e798b1dd +2e27a8a56fb51a7359742453a6102e0cf20711de diff --git a/db/docs/arkose_sessions.yml b/db/docs/arkose_sessions.yml new file mode 100644 index 00000000000..fd3307dd8ee --- /dev/null +++ b/db/docs/arkose_sessions.yml @@ -0,0 +1,13 @@ +--- +table_name: arkose_sessions +classes: +- Users::ArkoseSession +feature_categories: +- instance_resiliency +description: Stores the session data received when verifying an Arkose Labs session for a user +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194590 +milestone: '18.2' +gitlab_schema: gitlab_main_user +sharding_key: + user_id: users +table_size: small diff --git a/db/integer_ids_not_yet_initialized_to_bigint.yml b/db/integer_ids_not_yet_initialized_to_bigint.yml index b0b67631f1c..2b96a80c6f5 100644 --- a/db/integer_ids_not_yet_initialized_to_bigint.yml +++ b/db/integer_ids_not_yet_initialized_to_bigint.yml @@ -1,7 +1,7 @@ # -- DON'T MANUALLY EDIT -- # Contains the list of integer IDs which were converted to bigint for new installations in # https://gitlab.com/gitlab-org/gitlab/-/issues/438124, but they are still integers for existing instances. -# On initialize_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here. +# On cleanup_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here. --- alert_management_alert_user_mentions: - mentioned_groups_ids diff --git a/db/migrate/20250616064108_create_arkose_sessions.rb b/db/migrate/20250616064108_create_arkose_sessions.rb new file mode 100644 index 00000000000..6e8f332fa83 --- /dev/null +++ b/db/migrate/20250616064108_create_arkose_sessions.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class CreateArkoseSessions < Gitlab::Database::Migration[2.3] + milestone '18.2' + + def change + create_table :arkose_sessions do |t| + t.timestamptz :session_created_at, null: true + t.timestamptz :checked_answer_at, null: true + t.timestamptz :verified_at, null: false, index: true + t.references :user, null: false, foreign_key: { on_delete: :cascade }, index: true + t.integer :global_score, null: true + t.integer :custom_score, null: true + t.boolean :challenge_shown, null: false, default: false + t.boolean :challenge_solved, null: false, default: false + t.boolean :session_is_legit, null: false, default: true + t.boolean :is_tor, null: false, default: false + t.boolean :is_vpn, null: false, default: false + t.boolean :is_proxy, null: false, default: false + t.boolean :is_bot, null: false, default: false + t.text :session_xid, limit: 64, null: false, index: true + t.text :telltale_user, null: true, limit: 128 + t.text :user_agent, null: true, limit: 255 + t.text :user_language_shown, null: true, limit: 64 + t.text :device_xid, null: true, limit: 64 + t.text :telltale_list, null: false, array: true, default: [] + t.text :user_ip, null: true, limit: 64 + t.text :country, null: true, limit: 64 + t.text :region, null: true, limit: 64 + t.text :city, null: true, limit: 64 + t.text :isp, null: true, limit: 128 + t.text :connection_type, null: true, limit: 64 + t.text :risk_band, null: true, limit: 64 + t.text :risk_category, null: true, limit: 64 + end + end +end diff --git a/db/schema_migrations/20250616064108 b/db/schema_migrations/20250616064108 new file mode 100644 index 00000000000..f7f3304379a --- /dev/null +++ b/db/schema_migrations/20250616064108 @@ -0,0 +1 @@ +5f079f283cdc1757efb2f480d4979f4874ebf2619d88dc6c6778f6c8130b643e \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 0df9c3445d4..5f7d03ae302 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -10003,6 +10003,59 @@ CREATE TABLE ar_internal_metadata ( updated_at timestamp(6) without time zone NOT NULL ); +CREATE TABLE arkose_sessions ( + id bigint NOT NULL, + session_created_at timestamp with time zone, + checked_answer_at timestamp with time zone, + verified_at timestamp with time zone NOT NULL, + user_id bigint NOT NULL, + global_score integer, + custom_score integer, + challenge_shown boolean DEFAULT false NOT NULL, + challenge_solved boolean DEFAULT false NOT NULL, + session_is_legit boolean DEFAULT true NOT NULL, + is_tor boolean DEFAULT false NOT NULL, + is_vpn boolean DEFAULT false NOT NULL, + is_proxy boolean DEFAULT false NOT NULL, + is_bot boolean DEFAULT false NOT NULL, + session_xid text NOT NULL, + telltale_user text, + user_agent text, + user_language_shown text, + device_xid text, + telltale_list text[] DEFAULT '{}'::text[] NOT NULL, + user_ip text, + country text, + region text, + city text, + isp text, + connection_type text, + risk_band text, + risk_category text, + CONSTRAINT check_1a6f4682be CHECK ((char_length(user_agent) <= 255)), + CONSTRAINT check_1ccf4778d0 CHECK ((char_length(telltale_user) <= 128)), + CONSTRAINT check_20eae4e360 CHECK ((char_length(risk_band) <= 64)), + CONSTRAINT check_394c3c0153 CHECK ((char_length(session_xid) <= 64)), + CONSTRAINT check_5a92894aa9 CHECK ((char_length(device_xid) <= 64)), + CONSTRAINT check_8d83d12f95 CHECK ((char_length(user_ip) <= 64)), + CONSTRAINT check_940ffc498d CHECK ((char_length(risk_category) <= 64)), + CONSTRAINT check_9b4c7551e7 CHECK ((char_length(city) <= 64)), + CONSTRAINT check_b81756eb85 CHECK ((char_length(isp) <= 128)), + CONSTRAINT check_ba409cc401 CHECK ((char_length(region) <= 64)), + CONSTRAINT check_c745f5db92 CHECK ((char_length(country) <= 64)), + CONSTRAINT check_cd4cc1f7dc CHECK ((char_length(user_language_shown) <= 64)), + CONSTRAINT check_d4fd1df18c CHECK ((char_length(connection_type) <= 64)) +); + +CREATE SEQUENCE arkose_sessions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE arkose_sessions_id_seq OWNED BY arkose_sessions.id; + CREATE TABLE atlassian_identities ( user_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, @@ -27415,6 +27468,8 @@ ALTER TABLE ONLY approver_groups ALTER COLUMN id SET DEFAULT nextval('approver_g ALTER TABLE ONLY approvers ALTER COLUMN id SET DEFAULT nextval('approvers_id_seq'::regclass); +ALTER TABLE ONLY arkose_sessions ALTER COLUMN id SET DEFAULT nextval('arkose_sessions_id_seq'::regclass); + ALTER TABLE ONLY atlassian_identities ALTER COLUMN user_id SET DEFAULT nextval('atlassian_identities_user_id_seq'::regclass); ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass); @@ -29532,6 +29587,9 @@ ALTER TABLE ONLY approvers ALTER TABLE ONLY ar_internal_metadata ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key); +ALTER TABLE ONLY arkose_sessions + ADD CONSTRAINT arkose_sessions_pkey PRIMARY KEY (id); + ALTER TABLE ONLY atlassian_identities ADD CONSTRAINT atlassian_identities_pkey PRIMARY KEY (user_id); @@ -34594,6 +34652,12 @@ CREATE INDEX index_approvers_on_target_id_and_target_type ON approvers USING btr CREATE INDEX index_approvers_on_user_id ON approvers USING btree (user_id); +CREATE INDEX index_arkose_sessions_on_session_xid ON arkose_sessions USING btree (session_xid); + +CREATE INDEX index_arkose_sessions_on_user_id ON arkose_sessions USING btree (user_id); + +CREATE INDEX index_arkose_sessions_on_verified_at ON arkose_sessions USING btree (verified_at); + CREATE UNIQUE INDEX index_atlassian_identities_on_extern_uid ON atlassian_identities USING btree (extern_uid); CREATE UNIQUE INDEX index_audit_events_external_audit_on_verification_token ON audit_events_external_audit_event_destinations USING btree (verification_token); @@ -45738,6 +45802,9 @@ ALTER TABLE ONLY service_desk_custom_email_credentials ALTER TABLE ONLY software_license_policies ADD CONSTRAINT fk_rails_87b2247ce5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY arkose_sessions + ADD CONSTRAINT fk_rails_87ceb2456f FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; + ALTER TABLE ONLY achievements ADD CONSTRAINT fk_rails_87e990f752 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 39bcb0b4a9c..3286d4cdf95 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -6596,6 +6596,7 @@ Input type: `GroupAuditEventStreamingDestinationsUpdateInput` | Name | Type | Description | | ---- | ---- | ----------- | +| `active` | [`Boolean`](#boolean) | Active status of the destination. | | `category` | [`String`](#string) | Destination category. | | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | `config` | [`JSON`](#json) | Destination config. | @@ -7029,6 +7030,7 @@ Input type: `InstanceAuditEventStreamingDestinationsUpdateInput` | Name | Type | Description | | ---- | ---- | ----------- | +| `active` | [`Boolean`](#boolean) | Active status of the destination. | | `category` | [`String`](#string) | Destination category. | | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | `config` | [`JSON`](#json) | Destination config. | @@ -30439,6 +30441,7 @@ Represents an external destination to stream group level audit events. | Name | Type | Description | | ---- | ---- | ----------- | +| `active` | [`Boolean!`](#boolean) | Active status of the destination. | | `category` | [`String!`](#string) | Category of the external destination to send audit events to. | | `config` | [`JSON!`](#json) | Config of the external destination. | | `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. | @@ -31034,6 +31037,7 @@ Represents an external destination to stream instance level audit events. | Name | Type | Description | | ---- | ---- | ----------- | +| `active` | [`Boolean!`](#boolean) | Active status of the destination. | | `category` | [`String!`](#string) | Category of the external destination to send audit events to. | | `config` | [`JSON!`](#json) | Config of the external destination. | | `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. | @@ -49589,6 +49593,7 @@ Implementations: | Name | Type | Description | | ---- | ---- | ----------- | +| `active` | [`Boolean!`](#boolean) | Active status of the destination. | | `category` | [`String!`](#string) | Category of the external destination to send audit events to. | | `config` | [`JSON!`](#json) | Config of the external destination. | | `eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. | diff --git a/doc/development/database/avoiding_downtime_in_migrations.md b/doc/development/database/avoiding_downtime_in_migrations.md index 1d263a894a4..3bd55b2a607 100644 --- a/doc/development/database/avoiding_downtime_in_migrations.md +++ b/doc/development/database/avoiding_downtime_in_migrations.md @@ -655,7 +655,7 @@ end {{< alert type="note" >}} - With [Issue#438124](https://gitlab.com/gitlab-org/gitlab/-/issues/438124) new instances have all ID columns in bigint. - The list of IDs yet to be converted to bigint in old instances (includes `Gitlab.com` SaaS) is maintained in `db/integer_ids_not_yet_initialized_to_bigint.yml`. + The list of IDs yet to be converted to bigint in old instances (includes `Gitlab.com` SaaS) is maintained in `db/integer_ids_not_yet_initialized_to_bigint.yml`. **Do not edit this file manually** - it gets automatically updated during the [cleanup process](https://gitlab.com/gitlab-org/gitlab/-/blob/c6f4ea1bf1d693f1a0379964dd83a4bfec3e2f8d/lib/gitlab/database/migrations/conversions/bigint_converter.rb#L17-23). - Since the schema file already has all IDs in `bigint`, don't push any changes to `db/structure.sql`. {{< /alert >}} diff --git a/doc/install/package/_index.md b/doc/install/package/_index.md index 4b2da199bd2..9ec032280b9 100644 --- a/doc/install/package/_index.md +++ b/doc/install/package/_index.md @@ -135,6 +135,7 @@ release for them can be found below: | OpenSUSE 15.3 | [December 2022](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-15.10&dist=opensuse%2F15.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-15.10&dist=opensuse%2F15.3) 15.10 | | OpenSUSE 15.4 | [December 2023](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-16.7&dist=opensuse%2F15.4) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-16.7&dist=opensuse%2F15.4) 16.7 | | OpenSUSE 15.5 | [December 2024](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-17.8&dist=opensuse%2F15.5) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-17.8&dist=opensuse%2F15.5) 17.8 | +| SLES 15 SP2 | [December 2024](https://www.suse.com/lifecycle/#suse-linux-enterprise-server-15) | [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-18.1&filter=all&filter=all&dist=sles%2F15.2) | | Raspbian Wheezy | [May 2015](https://downloads.raspberrypi.org/raspbian/images/raspbian-2015-05-07/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_8.17&dist=debian%2Fwheezy) 8.17 | | Raspbian Jessie | [May 2017](https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-07-05/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_11.7&dist=debian%2Fjessie) 11.7 | | Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.3&dist=raspbian%2Fstretch) 13.3 | diff --git a/doc/install/package/suse.md b/doc/install/package/suse.md index 50b7fdd63c1..f7fdc593794 100644 --- a/doc/install/package/suse.md +++ b/doc/install/package/suse.md @@ -25,7 +25,7 @@ supported distributions and architectures. - OS requirements: - OpenSUSE Leap 15.6 - SLES 12 - - SLES 15 + - SLES 15 SP6 - See the [installation requirements](../requirements.md) to learn about the minimum hardware requirements. - Before you begin, make sure you have correctly diff --git a/lib/gitlab/database/migrations/conversions/bigint_converter.rb b/lib/gitlab/database/migrations/conversions/bigint_converter.rb index 4457c4df9c1..17ca815ed17 100644 --- a/lib/gitlab/database/migrations/conversions/bigint_converter.rb +++ b/lib/gitlab/database/migrations/conversions/bigint_converter.rb @@ -19,7 +19,7 @@ module Gitlab # -- DON'T MANUALLY EDIT -- # Contains the list of integer IDs which were converted to bigint for new installations in # https://gitlab.com/gitlab-org/gitlab/-/issues/438124, but they are still integers for existing instances. - # On initialize_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here. + # On cleanup_conversion_of_integer_to_bigint those integer IDs will be removed automatically from here. MESSAGE def initialize(migration, table, columns) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index a46867ff2d5..e1a29a0a4b6 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -6577,4 +6577,12 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category: expect(pipeline.queued_duration).to be_nil end end + + describe "association dependent" do + it_behaves_like "cleanup by a loose foreign key", on_delete: :async_nullify do + let!(:lfk_column) { :trigger_id } + let!(:parent) { create(:ci_trigger) } + let!(:model) { create(:ci_pipeline, trigger: parent) } + end + end end diff --git a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb index 2045a1d3e14..9e2161b775f 100644 --- a/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb +++ b/spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb @@ -59,10 +59,12 @@ RSpec.shared_examples 'it has loose foreign keys' do end end -RSpec.shared_examples 'cleanup by a loose foreign key' do +RSpec.shared_examples 'cleanup by a loose foreign key' do |on_delete: nil| include_context 'for loose foreign keys' it 'cleans up (delete or nullify) the model' do + expect(foreign_key_definition.on_delete).to eq(on_delete.to_sym) if on_delete.present? + puts("##+ Additional Debug Logs for LFK flakiness +##") puts("## Parent: #{parent.inspect} ##") parent.delete