Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/gitlab/doc_url.yml2
-rw-r--r--.rubocop_todo/naming/heredoc_delimiter_naming.yml1
-rw-r--r--CHANGELOG.md17
-rw-r--r--app/models/active_session.rb11
-rw-r--r--app/models/pool_repository.rb10
-rw-r--r--app/models/project.rb2
-rw-r--r--app/services/projects/update_repository_storage_service.rb4
-rw-r--r--app/services/users/authorized_build_service.rb2
-rw-r--r--config/initializers/1_database_single_connection.rb2
-rw-r--r--config/initializers/1_postgresql_only.rb2
-rw-r--r--config/initializers/warden.rb2
-rw-r--r--doc/development/redis.md8
-rw-r--r--doc/user/application_security/policies/index.md3
-rw-r--r--doc/user/application_security/policies/scan-execution-policies.md2
-rw-r--r--doc/user/clusters/agent/user_access.md58
-rw-r--r--doc/user/profile/index.md8
-rw-r--r--lib/gitlab/database.rb53
-rw-r--r--lib/gitlab/database_warnings.rb60
-rw-r--r--lib/gitlab/patch/redis_cache_store.rb10
-rw-r--r--qa/qa/page/project/web_ide/vscode.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb12
-rw-r--r--spec/lib/gitlab/database_spec.rb90
-rw-r--r--spec/lib/gitlab/database_warnings_spec.rb96
-rw-r--r--spec/lib/gitlab/patch/redis_cache_store_spec.rb58
-rw-r--r--spec/models/active_session_spec.rb18
-rw-r--r--spec/models/pool_repository_spec.rb46
-rw-r--r--spec/models/project_spec.rb15
-rw-r--r--spec/requests/sessions_spec.rb27
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb47
-rw-r--r--spec/services/users/authorized_build_service_spec.rb8
-rw-r--r--spec/services/users/build_service_spec.rb51
-rw-r--r--spec/support/shared_examples/services/users/build_service_shared_examples.rb51
35 files changed, 466 insertions, 354 deletions
diff --git a/.rubocop_todo/gitlab/doc_url.yml b/.rubocop_todo/gitlab/doc_url.yml
index 13537a142a1..ba9d066f94c 100644
--- a/.rubocop_todo/gitlab/doc_url.yml
+++ b/.rubocop_todo/gitlab/doc_url.yml
@@ -31,7 +31,7 @@ Gitlab/DocUrl:
- 'lib/gitlab/ci/config/entry/processable.rb'
- 'lib/gitlab/config_checker/external_database_checker.rb'
- 'lib/gitlab/config_checker/puma_rugged_checker.rb'
- - 'lib/gitlab/database.rb'
+ - 'lib/gitlab/database_warnings.rb'
- 'lib/gitlab/database/migration_helpers/automatic_lock_writes_on_tables.rb'
- 'lib/gitlab/database/migration_helpers/v2.rb'
- 'lib/gitlab/database/migrations/batched_background_migration_helpers.rb'
diff --git a/.rubocop_todo/naming/heredoc_delimiter_naming.yml b/.rubocop_todo/naming/heredoc_delimiter_naming.yml
index 68129f910d1..fa60792bbdc 100644
--- a/.rubocop_todo/naming/heredoc_delimiter_naming.yml
+++ b/.rubocop_todo/naming/heredoc_delimiter_naming.yml
@@ -30,7 +30,6 @@ Naming/HeredocDelimiterNaming:
- 'lib/feature/shared.rb'
- 'lib/gitlab/cache/import/caching.rb'
- 'lib/gitlab/conflict/file_collection.rb'
- - 'lib/gitlab/database.rb'
- 'lib/gitlab/database/migration_helpers.rb'
- 'lib/gitlab/database/migration_helpers/v2.rb'
- 'lib/gitlab/exclusive_lease.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 799fdda0441..9fa29b12563 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,17 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 16.3.4 (2023-09-18)
+
+### Fixed (2 changes)
+
+- [Fix Geo secondary proxying Git pulls unnecessarily](gitlab-org/security/gitlab@d4ac7db42e80dec97fee07c50471f1e7b60d3bcc) **GitLab Enterprise Edition**
+- [Use new indexer, fix removing blobs from index](gitlab-org/security/gitlab@5d48e6871bc6f1c36b93c10f2a54cf28d6adbc65) **GitLab Enterprise Edition**
+
+### Security (1 change)
+
+- [Enforce that the policy is executed by the bot user](gitlab-org/security/gitlab@3f278f761f18ee0b14aca68e2e5f764e1e274176) ([merge request](gitlab-org/security/gitlab!3568))
+
## 16.3.3 (2023-09-12)
### Fixed (2 changes)
@@ -825,6 +836,12 @@ entry.
- [Fix test pollution in count_deployments_metric_spec](gitlab-org/gitlab@610e6a033fe9b20aabc237b18837cddf150d4d1b) ([merge request](gitlab-org/gitlab!126808))
- [Update BulkImports::PipelineBatchWorker resource boundary](gitlab-org/gitlab@7d2477d81bcc2d035be26587802706f7098b6e44) ([merge request](gitlab-org/gitlab!126696))
+## 16.2.7 (2023-09-18)
+
+### Security (1 change)
+
+- [Enforce that the policy is executed by the bot user](gitlab-org/security/gitlab@336d6829bf5268dbbb1ccdaa224ed65c431a9ed6) ([merge request](gitlab-org/security/gitlab!3569))
+
## 16.2.6 (2023-09-12)
### Fixed (3 changes)
diff --git a/app/models/active_session.rb b/app/models/active_session.rb
index 7d025fb7738..e42f9eeef23 100644
--- a/app/models/active_session.rb
+++ b/app/models/active_session.rb
@@ -102,17 +102,16 @@ class ActiveSession
# set marketing cookie when user has active session
def self.set_active_user_cookie(auth)
- auth.cookies[:about_gitlab_active_user] =
+ expiration_time = 2.weeks.from_now
+
+ auth.cookies[:gitlab_user] =
{
value: true,
- domain: Gitlab.config.gitlab.host
+ domain: Gitlab.config.gitlab.host,
+ expires: expiration_time
}
end
- def self.unset_active_user_cookie(auth)
- auth.cookies.delete :about_gitlab_active_user
- end
-
def self.list(user)
Gitlab::Redis::Sessions.with do |redis|
cleaned_up_lookup_entries(redis, user).map do |raw_session|
diff --git a/app/models/pool_repository.rb b/app/models/pool_repository.rb
index bc3898fafe7..7d043bae91c 100644
--- a/app/models/pool_repository.rb
+++ b/app/models/pool_repository.rb
@@ -8,15 +8,15 @@ class PoolRepository < ApplicationRecord
include AfterCommitQueue
belongs_to :source_project, class_name: 'Project'
- validates :source_project, presence: true
has_many :member_projects, class_name: 'Project'
after_create :set_disk_path
scope :by_source_project, ->(project) { where(source_project: project) }
- scope :by_source_project_and_shard_name, ->(project, shard_name) do
- by_source_project(project)
+ scope :by_disk_path, ->(disk_path) { where(disk_path: disk_path) }
+ scope :by_disk_path_and_shard_name, ->(disk_path, shard_name) do
+ by_disk_path(disk_path)
.for_repository_storage(shard_name)
end
@@ -101,8 +101,8 @@ class PoolRepository < ApplicationRecord
@object_pool ||= Gitlab::Git::ObjectPool.new(
shard.name,
disk_path + '.git',
- source_project.repository.raw,
- source_project.full_path
+ source_project&.repository&.raw,
+ source_project&.full_path
)
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 724a4699e4e..68196f0a757 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -2846,7 +2846,7 @@ class Project < ApplicationRecord
return if old_pool_repository.blank?
return if pool_repository_shard_matches_repository?(old_pool_repository)
- new_pool_repository = PoolRepository.by_source_project_and_shard_name(old_pool_repository.source_project, repository_storage).take!
+ new_pool_repository = PoolRepository.by_disk_path_and_shard_name(old_pool_repository.disk_path, repository_storage).take!
update!(pool_repository: new_pool_repository)
old_pool_repository.unlink_repository(repository, disconnect: !pending_delete?)
diff --git a/app/services/projects/update_repository_storage_service.rb b/app/services/projects/update_repository_storage_service.rb
index f5f6bb85995..799ae5677c3 100644
--- a/app/services/projects/update_repository_storage_service.rb
+++ b/app/services/projects/update_repository_storage_service.rb
@@ -80,8 +80,8 @@ module Projects
end
def pool_repository_exists_for?(shard_name:, pool_repository:)
- PoolRepository.by_source_project_and_shard_name(
- pool_repository.source_project,
+ PoolRepository.by_disk_path_and_shard_name(
+ pool_repository.disk_path,
shard_name
).exists?
end
diff --git a/app/services/users/authorized_build_service.rb b/app/services/users/authorized_build_service.rb
index 5029105b087..446c897fe5a 100644
--- a/app/services/users/authorized_build_service.rb
+++ b/app/services/users/authorized_build_service.rb
@@ -12,7 +12,7 @@ module Users
end
def signup_params
- super + [:skip_confirmation]
+ super + [:skip_confirmation, :external]
end
end
end
diff --git a/config/initializers/1_database_single_connection.rb b/config/initializers/1_database_single_connection.rb
index cba203ab1cc..d71c82c2ea7 100644
--- a/config/initializers/1_database_single_connection.rb
+++ b/config/initializers/1_database_single_connection.rb
@@ -1,3 +1,3 @@
# frozen_string_literal: true
-Gitlab::Database.check_single_connection_and_print_warning
+Gitlab::DatabaseWarnings.check_single_connection_and_print_warning
diff --git a/config/initializers/1_postgresql_only.rb b/config/initializers/1_postgresql_only.rb
index 3be55255ddd..f0bdbbd1884 100644
--- a/config/initializers/1_postgresql_only.rb
+++ b/config/initializers/1_postgresql_only.rb
@@ -3,4 +3,4 @@
raise "PostgreSQL is the only supported database from GitLab 12.1" unless
ApplicationRecord.database.postgresql?
-Gitlab::Database.check_postgres_version_and_print_warning
+Gitlab::DatabaseWarnings.check_postgres_version_and_print_warning
diff --git a/config/initializers/warden.rb b/config/initializers/warden.rb
index 14bcaa80064..fd3e7fb6d18 100644
--- a/config/initializers/warden.rb
+++ b/config/initializers/warden.rb
@@ -38,8 +38,6 @@ Rails.application.configure do |config|
Warden::Manager.before_logout(scope: :user) do |user, auth, opts|
user ||= auth.user
- # deletes marketing cookie when user session ends
- ActiveSession.unset_active_user_cookie(auth) if ::Gitlab.com?
# Rails CSRF protection may attempt to log out a user before that
# user even logs in
next unless user
diff --git a/doc/development/redis.md b/doc/development/redis.md
index ebc7c0271a1..19a6b8e75d4 100644
--- a/doc/development/redis.md
+++ b/doc/development/redis.md
@@ -56,7 +56,7 @@ the entry, instead of relying on the key changing.
### Multi-key commands
-GitLab supports Redis Cluster only for the Redis [rate-limiting](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/redis/rate_limiting.rb) type, introduced in [epic 823](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/823).
+GitLab supports Redis Cluster for [cache-related workloads](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/redis/cache.rb) type, introduced in [epic 878](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/878).
This imposes an additional constraint on naming: where GitLab is performing
operations that require several keys to be held on the same Redis server - for
@@ -81,6 +81,12 @@ Developers are highly encouraged to use [hash-tags](https://redis.io/docs/refere
where appropriate to facilitate future adoption of Redis Cluster in more Redis types. For example, the Namespace model uses hash-tags
for its [config cache keys](https://gitlab.com/gitlab-org/gitlab/-/blob/1a12337058f260d38405886d82da5e8bb5d8da0b/app/models/namespace.rb#L786).
+To perform multi-key commands, developers may use the [`Gitlab::Redis::CrossSlot::Pipeline`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/redis/cross_slot.rb) wrapper.
+However, this does not work for [transactions](https://redis.io/docs/interact/transactions/) as Redis Cluster does not support cross-slot transactions.
+
+For `Rails.cache`, we handle the `MGET` command found in `read_multi_get` by [patching it](https://gitlab.com/gitlab-org/gitlab/-/blob/c2bad2aac25e2f2778897bd4759506a72b118b15/lib/gitlab/patch/redis_cache_store.rb#L10) to use the `Gitlab::Redis::CrossSlot::Pipeline` wrapper.
+The minimum size of the pipeline is set to 1000 commands and it can be adjusted by using the `GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT` environment variable.
+
## Redis in structured logging
For GitLab Team Members: There are <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index 611e38446af..84c28d4008c 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -148,7 +148,8 @@ The workaround is to amend your group or instance push rules to allow branches f
- Scan result policies created at the group or sub-group level can take some time to apply to all the merge requests in the group.
- Scheduled scan execution policies run with a minimum 15 minute cadence. Learn more [about the schedule rule type](../policies/scan-execution-policies.md#schedule-rule-type).
- When scheduling pipelines, keep in mind that CRON scheduling is based on UTC on GitLab SaaS and is based on your server time for self managed instances. When testing new policies, it may appear pipelines are not running properly when in fact they are scheduled in your server's timezone.
-- When enforcing scan execution policies, security policies creates a bot in the target project that will trigger scheduled pipelines to ensure enforcement. If the bot is deleted, the target project's pipeline will default back to be triggered by the user who last updated the security policy project's `policy.yml` file. The user must have permission to trigger the pipeline in the project for the policy to be enforced, and the pipeline to run.
+- When enforcing scan execution policies, security policies creates a bot in the target project that will trigger scheduled pipelines to ensure enforcement. If the bot is
+deleted or missing, the target project's pipeline will not be executed. To recreate a security policy bot user unlink and link the security policy project again.
- You should not link a security policy project to a development project and to the group or sub-group the development project belongs to at the same time. Linking this way will result in approval rules from the Scan Result Policy not being applied to merge requests in the development project.
- When creating a Scan Result Policy, neither the array `severity_levels` nor the array `vulnerability_states` in the [scan_finding rule](../policies/scan-result-policies.md#scan_finding-rule-type) can be left empty; for a working rule, at least one entry must exist.
- When configuring pipeline and scan result policies, it's important to remember that security scans performed in manual jobs aren't verified to determine whether MR approval is required. When you run a manual job with security scans, it won't ensure approval even if vulnerabilities are introduced.
diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md
index 1e8bf426b70..ac15dfc0a47 100644
--- a/doc/user/application_security/policies/scan-execution-policies.md
+++ b/doc/user/application_security/policies/scan-execution-policies.md
@@ -141,7 +141,7 @@ This rule schedules a scan pipeline, enforcing the defined actions on the schedu
Scheduled scan pipelines are triggered by a security policy bot user that is a guest member of the project with elevated permissions for users of type `security_policy_bot` so it may carry out this task. Security policy bot users are automatically created when the security policy project is linked, and removed when the security policy project is unlinked.
-If the project does not have a security policy bot user, the scheduled scan pipeline is triggered by the user that modified the security policy project last.
+If the project does not have a security policy bot user, the scheduled scan pipeline will not be triggered. To recreate a security policy bot user unlink and link the security policy project again.
GitLab supports the following types of CRON syntax for the `cadence` field:
diff --git a/doc/user/clusters/agent/user_access.md b/doc/user/clusters/agent/user_access.md
index c0805b5e84a..21dc249b1d1 100644
--- a/doc/user/clusters/agent/user_access.md
+++ b/doc/user/clusters/agent/user_access.md
@@ -145,52 +145,48 @@ subjects:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131144) in GitLab 16.4.
-You can [configure an agent](#configure-kubernetes-access) to allow GitLab users to access a cluster with the Kubernetes API.
+You can configure an agent to allow GitLab users to access a cluster with the Kubernetes API.
-Use a [personal access token](../../profile/personal_access_tokens.md)
-with the `k8s_proxy` scope to access the cluster via `kubectl`:
+Prerequisite:
+
+- You have an agent configured with the `user_access` entry.
+
+To grant Kubernetes API access:
-1. Configure the agent with the [`user_access` entry](user_access.md).
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Operate > Kubernetes clusters** and retrieve the numerical ID of the agent you want to access. You need the ID to construct the full API token.
1. Create a [personal access token](../../profile/personal_access_tokens.md) with the `k8s_proxy` scope. You need the access token to construct the full API token.
1. Construct `kube config` entries to access the cluster:
- 1. Make sure that the proper `kube config` is selected.
- For example, you can set the `KUBECONFIG` environment variable.
- 1. Add the GitLab KAS proxy cluster to the `kube config`:
-
- ```shell
- kubectl config set-cluster gitlab --server "https://kas.gitlab.com/k8s-proxy"
- ```
+ 1. Make sure that the proper `kube config` is selected.
+ For example, you can set the `KUBECONFIG` environment variable.
+ 1. Add the GitLab KAS proxy cluster to the `kube config`:
- The `server` argument points to the KAS address of your GitLab instance.
- On GitLab.com, this is `https://kas.gitlab.com/k8s-proxy`.
- You can get the KAS address of your instance when you register an agent.
+ ```shell
+ kubectl config set-cluster <cluster_name> --server "https://kas.gitlab.com/k8s-proxy"
+ ```
- If needed, change `gitlab` to the name of your cluster.
- 1. Use your numerical agent ID and personal access token to construct an API token:
+ The `server` argument points to the KAS address of your GitLab instance.
+ On GitLab.com, this is `https://kas.gitlab.com/k8s-proxy`.
+ You can get the KAS address of your instance when you register an agent.
- ```shell
- kubectl config set-credentials gitlab-user --token "pat:<agent-id>:<token>"
- ```
+ 1. Use your numerical agent ID and personal access token to construct an API token:
- If needed, change `gitlab-user` to your credentials name.
- 1. Add the context to combine the cluster and the user:
+ ```shell
+ kubectl config set-credentials <gitlab_user> --token "pat:<agent-id>:<token>"
+ ```
- ```shell
- kubectl config set-context gitlab-agent --cluster gitlab --user gitlab-user
- ```
+ 1. Add the context to combine the cluster and the user:
- If needed, change the arguments to `cluster` and `user`. The arguments must match the cluster name and user from the previous steps.
+ ```shell
+ kubectl config set-context <gitlab_agent> --cluster <cluster_name> --user <gitlab_user>
+ ```
- You can customize the context name.
- 1. Activate the new context:
+ 1. Activate the new context:
- ```shell
- kubectl config use-context gitlab-agent
- ```
+ ```shell
+ kubectl config use-context <gitlab_agent>
+ ```
- If needed, change `gitlab-agent` to the context name you set in the last step.
1. Check that the configuration works:
```shell
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 828f37cbf43..cff18654292 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -397,15 +397,15 @@ When you sign in, three cookies are set:
- A session cookie called `_gitlab_session`.
This cookie has no set expiration date. However, it expires based on its `session_expire_delay`.
-- A session cookie called `about_gitlab_active_user`.
- This cookie is used by the [marketing site](https://about.gitlab.com/) to determine if a user has an active GitLab session. No user information is passed to the cookie and it expires with the session.
+- A session cookie called `gitlab_user`.
+ This cookie is used by the [marketing site](https://about.gitlab.com/) to determine if a user has an active GitLab session. No user information is passed to the cookie and it expires two weeks from login.
- A persistent cookie called `remember_user_token`, which is set only if you selected **Remember me** on the sign-in page.
-When you close your browser, the `_gitlab_session` and `about_gitlab_active_user` cookies are usually cleared client-side.
+When you close your browser, the `_gitlab_session` and `gitlab_user` cookies are usually cleared client-side.
When it expires or isn't available, GitLab:
- Uses the `remember_user_token`cookie to get you a new `_gitlab_session` cookie and keep you signed in, even if you close your browser.
-- Sets the `about_gitlab_active_user` to `true`.
+- Sets the `gitlab_user` to `true`.
When both the `remember_user_token` and `_gitlab_session` cookies are gone or expired, you must sign in again.
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 54eb0c0e0aa..6222155d812 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -185,59 +185,6 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- def self.check_postgres_version_and_print_warning
- return if Gitlab::Runtime.rails_runner?
-
- database_base_models.each do |name, model|
- database = Gitlab::Database::Reflection.new(model)
-
- next if database.postgresql_minimum_supported_version?
-
- Kernel.warn ERB.new(Rainbow.new.wrap(<<~EOS).red).result
-
- ██  ██  █████  ██████  ███  ██ ██ ███  ██  ██████ 
- ██  ██ ██   ██ ██   ██ ████  ██ ██ ████  ██ ██      
- ██  █  ██ ███████ ██████  ██ ██  ██ ██ ██ ██  ██ ██  ███ 
- ██ ███ ██ ██   ██ ██   ██ ██  ██ ██ ██ ██  ██ ██ ██  ██ 
-  ███ ███  ██  ██ ██  ██ ██   ████ ██ ██   ████  ██████  
-
- ******************************************************************************
- You are using PostgreSQL #{database.version} for the #{name} database, but this version of GitLab requires PostgreSQL >= <%= Gitlab::Database::MINIMUM_POSTGRES_VERSION %>.
- <% if Rails.env.development? || Rails.env.test? %>
- If using gitlab-development-kit, please find the relevant steps here:
- https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/postgresql.md#upgrade-postgresql
- <% end %>
- Please upgrade your environment to a supported PostgreSQL version. See
- https://docs.gitlab.com/ee/install/requirements.html#database for details.
- ******************************************************************************
- EOS
- rescue ActiveRecord::ActiveRecordError, PG::Error
- # ignore - happens when Rake tasks yet have to create a database, e.g. for testing
- end
- end
-
- def self.check_single_connection_and_print_warning
- return if Gitlab::Runtime.rails_runner?
- return unless database_mode == MODE_SINGLE_DATABASE
-
- Kernel.warn ERB.new(Rainbow.new.wrap(<<~EOS).red).result
-
- ██  ██  █████  ██████  ███  ██ ██ ███  ██  ██████ 
- ██  ██ ██   ██ ██   ██ ████  ██ ██ ████  ██ ██      
- ██  █  ██ ███████ ██████  ██ ██  ██ ██ ██ ██  ██ ██  ███ 
- ██ ███ ██ ██   ██ ██   ██ ██  ██ ██ ██ ██  ██ ██ ██  ██ 
-  ███ ███  ██  ██ ██  ██ ██   ████ ██ ██   ████  ██████  
-
- ******************************************************************************
- Your database has a single connection, and single connections were
- deprecated in GitLab 15.9 https://docs.gitlab.com/ee/update/deprecations.html#single-database-connection-is-deprecated.
-
- Please add a :ci section to your database, following these instructions:
- https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings.
- ******************************************************************************
- EOS
- end
-
def self.random
"RANDOM()"
end
diff --git a/lib/gitlab/database_warnings.rb b/lib/gitlab/database_warnings.rb
new file mode 100644
index 00000000000..8df60ac6404
--- /dev/null
+++ b/lib/gitlab/database_warnings.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DatabaseWarnings
+ def self.check_postgres_version_and_print_warning
+ return if Gitlab::Runtime.rails_runner?
+
+ Gitlab::Database.database_base_models.each do |name, model|
+ database = Gitlab::Database::Reflection.new(model)
+
+ next if database.postgresql_minimum_supported_version?
+
+ Kernel.warn ERB.new(Rainbow.new.wrap(<<~WARNING).red).result
+
+ ██  ██  █████  ██████  ███  ██ ██ ███  ██  ██████ 
+ ██  ██ ██   ██ ██   ██ ████  ██ ██ ████  ██ ██      
+ ██  █  ██ ███████ ██████  ██ ██  ██ ██ ██ ██  ██ ██  ███ 
+ ██ ███ ██ ██   ██ ██   ██ ██  ██ ██ ██ ██  ██ ██ ██  ██ 
+  ███ ███  ██  ██ ██  ██ ██   ████ ██ ██   ████  ██████  
+
+ ******************************************************************************
+ You are using PostgreSQL #{database.version} for the #{name} database, but this version of GitLab requires PostgreSQL >= <%= Gitlab::Database::MINIMUM_POSTGRES_VERSION %>.
+ <% if Rails.env.development? || Rails.env.test? %>
+ If using gitlab-development-kit, please find the relevant steps here:
+ https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/postgresql.md#upgrade-postgresql
+ <% end %>
+ Please upgrade your environment to a supported PostgreSQL version. See
+ https://docs.gitlab.com/ee/install/requirements.html#database for details.
+ ******************************************************************************
+ WARNING
+ rescue ActiveRecord::ActiveRecordError, PG::Error
+ # ignore - happens when Rake tasks yet have to create a database, e.g. for testing
+ end
+ end
+
+ def self.check_single_connection_and_print_warning
+ return if Gitlab::Runtime.rails_runner?
+ return unless Gitlab::Database.database_mode == Gitlab::Database::MODE_SINGLE_DATABASE
+
+ Kernel.warn ERB.new(Rainbow.new.wrap(<<~WARNING).red).result
+
+ ██  ██  █████  ██████  ███  ██ ██ ███  ██  ██████ 
+ ██  ██ ██   ██ ██   ██ ████  ██ ██ ████  ██ ██      
+ ██  █  ██ ███████ ██████  ██ ██  ██ ██ ██ ██  ██ ██  ███ 
+ ██ ███ ██ ██   ██ ██   ██ ██  ██ ██ ██ ██  ██ ██ ██  ██ 
+  ███ ███  ██  ██ ██  ██ ██   ████ ██ ██   ████  ██████  
+
+ ******************************************************************************
+ Your database has a single connection, and single connections were
+ deprecated in GitLab 15.9 https://docs.gitlab.com/ee/update/deprecations.html#single-database-connection-is-deprecated.
+
+ Please add a :ci section to your database, following these instructions:
+ https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings.
+ ******************************************************************************
+ WARNING
+ end
+ end
+end
+
+Gitlab::DatabaseWarnings.prepend_mod_with('Gitlab::DatabaseWarnings')
diff --git a/lib/gitlab/patch/redis_cache_store.rb b/lib/gitlab/patch/redis_cache_store.rb
index ea6e1f11bc9..96729056ce5 100644
--- a/lib/gitlab/patch/redis_cache_store.rb
+++ b/lib/gitlab/patch/redis_cache_store.rb
@@ -3,8 +3,6 @@
module Gitlab
module Patch
module RedisCacheStore
- PIPELINE_BATCH_SIZE = 100
-
# We will try keep patched code explicit and matching the original signature in
# https://github.com/rails/rails/blob/v6.1.7.2/activesupport/lib/active_support/cache/redis_cache_store.rb#L361
def read_multi_mget(*names) # rubocop:disable Style/ArgumentsForwarding
@@ -21,7 +19,7 @@ module Gitlab
delete_count = 0
redis.with do |conn|
- entries.each_slice(PIPELINE_BATCH_SIZE) do |subset|
+ entries.each_slice(pipeline_batch_size) do |subset|
delete_count += Gitlab::Redis::CrossSlot::Pipeline.new(conn).pipelined do |pipeline|
subset.each { |entry| pipeline.del(entry) }
end.sum
@@ -59,7 +57,7 @@ module Gitlab
end
def pipeline_mget(conn, keys)
- keys.each_slice(PIPELINE_BATCH_SIZE).flat_map do |subset|
+ keys.each_slice(pipeline_batch_size).flat_map do |subset|
Gitlab::Redis::CrossSlot::Pipeline.new(conn).pipelined do |p|
subset.each { |key| p.get(key) }
end
@@ -68,6 +66,10 @@ module Gitlab
private
+ def pipeline_batch_size
+ @pipeline_batch_size ||= [ENV['GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT'].to_i, 1000].max
+ end
+
def enable_rails_cache_pipeline_patch?
redis.with { |c| ::Gitlab::Redis::ClusterUtil.cluster?(c) }
end
diff --git a/qa/qa/page/project/web_ide/vscode.rb b/qa/qa/page/project/web_ide/vscode.rb
index 13c8bf0139f..8f257e95f3e 100644
--- a/qa/qa/page/project/web_ide/vscode.rb
+++ b/qa/qa/page/project/web_ide/vscode.rb
@@ -13,6 +13,7 @@ module QA
def has_file_explorer?
page.has_css?('.explorer-folders-view', visible: true)
+ page.has_css?('[aria-label="Files Explorer"]', visible: true)
end
def right_click_file_explorer
@@ -33,11 +34,11 @@ module QA
end
def has_upload_menu_item?
- page.has_css?('[aria-label="Upload..."]', visible: true)
+ page.has_css?('.menu-item-check', visible: true)
end
def click_upload_menu_item
- page.find('[aria-label="Upload..."]').click
+ page.find('[aria-label="Upload..."]', visible: true).click
end
def enter_file_input(file)
@@ -170,11 +171,10 @@ module QA
# We need to execute a script on the iframe to stub out the iframes body.removeChild to add it back in.
page.execute_script("document.body.removeChild = function(){};")
- right_click_file_explorer
- has_upload_menu_item?
-
# Use for stability, WebIDE inside an iframe is finnicky, webdriver sometimes moves too fast
- Support::Waiter.wait_until(max_duration: 60, retry_on_exception: true) do
+ Support::Waiter.wait_until(max_duration: 20, retry_on_exception: true) do
+ right_click_file_explorer
+ has_upload_menu_item?
click_upload_menu_item
enter_file_input(file_path)
end
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
index 2da4e30e82f..28d05fd58c0 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
@@ -67,11 +67,10 @@ module QA
context 'for personal projects' do
let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.api_client = owner_api_client
- project.name = 'qa-owner-personal-project'
- project.personal_namespace = owner.username
- end
+ create(:project,
+ name: 'qa-owner-personal-project',
+ api_client: owner_api_client,
+ personal_namespace: owner.username)
end
it_behaves_like 'adds user as owner', :personal_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352542'
@@ -80,13 +79,7 @@ module QA
context 'for group projects' do
let!(:group) { create(:group) }
-
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = group
- project.name = 'qa-owner-group-project'
- end
- end
+ let!(:project) { create(:project, name: 'qa-owner-group-project', group: group) }
it_behaves_like 'adds user as owner', :group_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366436'
it_behaves_like 'adds user as maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366435'
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
index 050cf32a8dc..9ace1a4b4f7 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
@@ -22,12 +22,7 @@ module QA
end
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-tags'
- project.initialize_with_readme = true
- project.api_client = followed_user_api_client
- project.group = group
- end
+ create(:project, :with_readme, name: 'project-for-tags', api_client: followed_user_api_client, group: group)
end
let(:merge_request) do
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
index 6895b6a3268..46e4a674f99 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
@@ -9,13 +9,7 @@ module QA
let!(:group) { create(:group, path: "group-to-test-access-termination-#{SecureRandom.hex(8)}") }
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = group
- project.name = "project-for-user-access-termination"
- project.initialize_with_readme = true
- end
- end
+ let!(:project) { create(:project, :with_readme, name: 'project-for-user-access-termination', group: group) }
context 'with terminated parent group membership' do
before do
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
index bd080381063..c0ec71c4488 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
@@ -21,11 +21,7 @@ module QA
end
let!(:sub_group_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = sub_group
- project.name = "sub-group-project-to-test-user-access"
- project.initialize_with_readme = true
- end
+ create(:project, :with_readme, name: 'sub-group-project-to-test-user-access', group: sub_group)
end
before do
@@ -57,11 +53,7 @@ module QA
context 'when added to sub-group' do
let!(:parent_group_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = parent_group
- project.name = "parent-group-project-to-test-user-access"
- project.initialize_with_readme = true
- end
+ create(:project, :with_readme, name: 'parent-group-project-to-test-user-access', group: parent_group)
end
let!(:sub_group_user) { create(:user, api_client: admin_api_client) }
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 5af8f8c7bdd..6dd7d29ab42 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -198,96 +198,6 @@ RSpec.describe Gitlab::Database, feature_category: :database do
end
end
- describe '.check_postgres_version_and_print_warning' do
- let(:reflect) { instance_spy(Gitlab::Database::Reflection) }
-
- subject { described_class.check_postgres_version_and_print_warning }
-
- before do
- allow(Gitlab::Database::Reflection)
- .to receive(:new)
- .and_return(reflect)
- end
-
- it 'prints a warning if not compliant with minimum postgres version' do
- allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(false)
-
- expect(Kernel)
- .to receive(:warn)
- .with(/You are using PostgreSQL/)
- .exactly(described_class.database_base_models.length)
- .times
-
- subject
- end
-
- it 'doesnt print a warning if compliant with minimum postgres version' do
- allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(true)
-
- expect(Kernel).not_to receive(:warn).with(/You are using PostgreSQL/)
-
- subject
- end
-
- it 'doesnt print a warning in Rails runner environment' do
- allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(false)
- allow(Gitlab::Runtime).to receive(:rails_runner?).and_return(true)
-
- expect(Kernel).not_to receive(:warn).with(/You are using PostgreSQL/)
-
- subject
- end
-
- it 'ignores ActiveRecord errors' do
- allow(reflect).to receive(:postgresql_minimum_supported_version?).and_raise(ActiveRecord::ActiveRecordError)
-
- expect { subject }.not_to raise_error
- end
-
- it 'ignores Postgres errors' do
- allow(reflect).to receive(:postgresql_minimum_supported_version?).and_raise(PG::Error)
-
- expect { subject }.not_to raise_error
- end
- end
-
- describe '.check_single_connection_and_print_warning' do
- subject { described_class.check_single_connection_and_print_warning }
-
- it 'prints a warning if single connection' do
- allow(described_class).to receive(:database_mode).and_return(::Gitlab::Database::MODE_SINGLE_DATABASE)
-
- expect(Kernel).to receive(:warn).with(/Your database has a single connection/)
-
- subject
- end
-
- it 'does not print a warning if single ci connection' do
- allow(described_class).to receive(:database_mode).and_return(::Gitlab::Database::MODE_SINGLE_DATABASE_CI_CONNECTION)
-
- expect(Kernel).not_to receive(:warn)
-
- subject
- end
-
- it 'does not print a warning if multiple connection' do
- allow(described_class).to receive(:database_mode).and_return(::Gitlab::Database::MODE_MULTIPLE_DATABASES)
-
- expect(Kernel).not_to receive(:warn)
-
- subject
- end
-
- it 'does not print a warning in Rails runner environment' do
- allow(described_class).to receive(:database_mode).and_return(::Gitlab::Database::MODE_SINGLE_DATABASE)
- allow(Gitlab::Runtime).to receive(:rails_runner?).and_return(true)
-
- expect(Kernel).not_to receive(:warn)
-
- subject
- end
- end
-
describe '.db_config_for_connection' do
context 'when the regular connection is used' do
it 'returns db_config' do
diff --git a/spec/lib/gitlab/database_warnings_spec.rb b/spec/lib/gitlab/database_warnings_spec.rb
new file mode 100644
index 00000000000..6658190b94c
--- /dev/null
+++ b/spec/lib/gitlab/database_warnings_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::DatabaseWarnings, feature_category: :database do
+ describe '.check_postgres_version_and_print_warning' do
+ let(:reflect) { instance_spy(Gitlab::Database::Reflection) }
+
+ subject { described_class.check_postgres_version_and_print_warning }
+
+ before do
+ allow(Gitlab::Database::Reflection)
+ .to receive(:new)
+ .and_return(reflect)
+ end
+
+ it 'prints a warning if not compliant with minimum postgres version' do
+ allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(false)
+
+ expect(Kernel)
+ .to receive(:warn)
+ .with(/You are using PostgreSQL/)
+ .exactly(Gitlab::Database.database_base_models.length)
+ .times
+
+ subject
+ end
+
+ it 'does not print a warning if compliant with minimum postgres version' do
+ allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(true)
+
+ expect(Kernel).not_to receive(:warn).with(/You are using PostgreSQL/)
+
+ subject
+ end
+
+ it 'does not print a warning in Rails runner environment' do
+ allow(reflect).to receive(:postgresql_minimum_supported_version?).and_return(false)
+ allow(Gitlab::Runtime).to receive(:rails_runner?).and_return(true)
+
+ expect(Kernel).not_to receive(:warn).with(/You are using PostgreSQL/)
+
+ subject
+ end
+
+ it 'ignores ActiveRecord errors' do
+ allow(reflect).to receive(:postgresql_minimum_supported_version?).and_raise(ActiveRecord::ActiveRecordError)
+
+ expect { subject }.not_to raise_error
+ end
+
+ it 'ignores Postgres errors' do
+ allow(reflect).to receive(:postgresql_minimum_supported_version?).and_raise(PG::Error)
+
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ describe '.check_single_connection_and_print_warning' do
+ subject { described_class.check_single_connection_and_print_warning }
+
+ it 'prints a warning if single connection' do
+ allow(Gitlab::Database).to receive(:database_mode).and_return(Gitlab::Database::MODE_SINGLE_DATABASE)
+
+ expect(Kernel).to receive(:warn).with(/Your database has a single connection/)
+
+ subject
+ end
+
+ it 'does not print a warning if single ci connection' do
+ allow(Gitlab::Database).to receive(:database_mode)
+ .and_return(Gitlab::Database::MODE_SINGLE_DATABASE_CI_CONNECTION)
+
+ expect(Kernel).not_to receive(:warn)
+
+ subject
+ end
+
+ it 'does not print a warning if multiple connection' do
+ allow(Gitlab::Database).to receive(:database_mode).and_return(Gitlab::Database::MODE_MULTIPLE_DATABASES)
+
+ expect(Kernel).not_to receive(:warn)
+
+ subject
+ end
+
+ it 'does not print a warning in Rails runner environment' do
+ allow(Gitlab::Database).to receive(:database_mode).and_return(Gitlab::Database::MODE_SINGLE_DATABASE)
+ allow(Gitlab::Runtime).to receive(:rails_runner?).and_return(true)
+
+ expect(Kernel).not_to receive(:warn)
+
+ subject
+ end
+ end
+end
diff --git a/spec/lib/gitlab/patch/redis_cache_store_spec.rb b/spec/lib/gitlab/patch/redis_cache_store_spec.rb
index e36ea64e21d..21c256fdbbe 100644
--- a/spec/lib/gitlab/patch/redis_cache_store_spec.rb
+++ b/spec/lib/gitlab/patch/redis_cache_store_spec.rb
@@ -34,23 +34,53 @@ RSpec.describe Gitlab::Patch::RedisCacheStore, :use_clean_rails_redis_caching, f
end
context 'when reading large amount of keys' do
- it 'batches get into pipelines of 100' do
- cache.redis.with do |redis|
- normal_cluster = !redis.is_a?(Gitlab::Redis::MultiStore) && Gitlab::Redis::ClusterUtil.cluster?(redis)
- multistore_cluster = redis.is_a?(Gitlab::Redis::MultiStore) &&
- ::Gitlab::Redis::ClusterUtil.cluster?(redis.default_store)
+ let(:input_size) { 2000 }
+ let(:chunk_size) { 1000 }
+
+ shared_examples 'read large amount of keys' do
+ it 'breaks the input into 2 chunks for redis cluster' do
+ cache.redis.with do |redis|
+ normal_cluster = !redis.is_a?(Gitlab::Redis::MultiStore) && Gitlab::Redis::ClusterUtil.cluster?(redis)
+ multistore_cluster = redis.is_a?(Gitlab::Redis::MultiStore) &&
+ ::Gitlab::Redis::ClusterUtil.cluster?(redis.default_store)
+
+ if normal_cluster || multistore_cluster
+ expect_next_instances_of(Gitlab::Redis::CrossSlot::Pipeline, 2) do |pipeline|
+ obj = instance_double(::Redis)
+ expect(pipeline).to receive(:pipelined).and_yield(obj)
+ expect(obj).to receive(:get).exactly(chunk_size).times
+ end
+ else
+ expect(redis).to receive(:mget).and_call_original
+ end
+ end
- if normal_cluster || multistore_cluster
- expect(redis).to receive(:pipelined).at_least(2).and_call_original
- else
- expect(redis).to receive(:mget).and_call_original
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ cache.read_multi(*Array.new(input_size) { |i| i })
end
end
+ end
- Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
- cache.read_multi(*Array.new(101) { |i| i })
+ context 'when GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT is smaller than the default' do
+ before do
+ stub_env('GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT', 10)
end
+
+ it_behaves_like 'read large amount of keys'
end
+
+ context 'when GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT is larger than the default' do
+ let(:input_size) { 4000 }
+ let(:chunk_size) { 2000 }
+
+ before do
+ stub_env('GITLAB_REDIS_CLUSTER_PIPELINE_BATCH_LIMIT', chunk_size)
+ end
+
+ it_behaves_like 'read large amount of keys'
+ end
+
+ it_behaves_like 'read large amount of keys'
end
end
@@ -89,7 +119,7 @@ RSpec.describe Gitlab::Patch::RedisCacheStore, :use_clean_rails_redis_caching, f
context 'when deleting large amount of keys' do
before do
- 200.times { |i| cache.write(i, i) }
+ 2000.times { |i| cache.write(i, i) }
end
it 'calls pipeline multiple times' do
@@ -105,9 +135,9 @@ RSpec.describe Gitlab::Patch::RedisCacheStore, :use_clean_rails_redis_caching, f
expect(
Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
- cache.delete_multi(Array(0..199))
+ cache.delete_multi(Array(0..1999))
end
- ).to eq(200)
+ ).to eq(2000)
end
end
end
diff --git a/spec/models/active_session_spec.rb b/spec/models/active_session_spec.rb
index 54169c254a6..af884fdb83c 100644
--- a/spec/models/active_session_spec.rb
+++ b/spec/models/active_session_spec.rb
@@ -650,25 +650,13 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do
end
end
- describe '.set_active_user_cookie' do
+ describe '.set_active_user_cookie', :freeze_time do
let(:auth) { double(cookies: {}) }
it 'sets marketing cookie' do
described_class.set_active_user_cookie(auth)
- expect(auth.cookies[:about_gitlab_active_user][:value]).to be_truthy
- end
- end
-
- describe '.unset_active_user_cookie' do
- let(:auth) { double(cookies: {}) }
-
- before do
- described_class.set_active_user_cookie(auth)
- end
-
- it 'unsets marketing cookie' do
- described_class.unset_active_user_cookie(auth)
- expect(auth.cookies[:about_gitlab_active_user]).to be_nil
+ expect(auth.cookies[:gitlab_user][:value]).to be_truthy
+ expect(auth.cookies[:gitlab_user][:expires]).to be_within(1.minute).of(2.weeks.from_now)
end
end
end
diff --git a/spec/models/pool_repository_spec.rb b/spec/models/pool_repository_spec.rb
index 93c1e59458d..bafda406774 100644
--- a/spec/models/pool_repository_spec.rb
+++ b/spec/models/pool_repository_spec.rb
@@ -13,15 +13,17 @@ RSpec.describe PoolRepository, feature_category: :source_code_management do
let!(:pool_repository) { create(:pool_repository) }
it { is_expected.to validate_presence_of(:shard) }
- it { is_expected.to validate_presence_of(:source_project) }
end
describe 'scopes' do
let_it_be(:project1) { create(:project) }
let_it_be(:project2) { create(:project) }
let_it_be(:new_shard) { create(:shard, name: 'new') }
- let_it_be(:pool_repository1) { create(:pool_repository, source_project: project1) }
- let_it_be(:pool_repository2) { create(:pool_repository, source_project: project1, shard: new_shard) }
+ let_it_be(:pool_repository1) { create(:pool_repository, source_project: project1, disk_path: 'disk_path') }
+ let_it_be(:pool_repository2) do
+ create(:pool_repository, source_project: project1, disk_path: 'disk_path', shard: new_shard)
+ end
+
let_it_be(:another_pool_repository) { create(:pool_repository, source_project: project2) }
describe '.by_source_project' do
@@ -32,8 +34,8 @@ RSpec.describe PoolRepository, feature_category: :source_code_management do
end
end
- describe '.by_source_project_and_shard_name' do
- subject { described_class.by_source_project_and_shard_name(project1, new_shard.name) }
+ describe '.by_disk_path_and_shard_name' do
+ subject { described_class.by_disk_path_and_shard_name('disk_path', new_shard.name) }
it 'returns only a requested pool repository' do
is_expected.to match_array([pool_repository2])
@@ -91,4 +93,38 @@ RSpec.describe PoolRepository, feature_category: :source_code_management do
end
end
end
+
+ describe '#object_pool' do
+ subject { pool.object_pool }
+
+ let(:pool) { build(:pool_repository, :ready, source_project: project, disk_path: disk_path) }
+ let(:project) { build(:project) }
+ let(:disk_path) { 'disk_path' }
+
+ it 'returns an object pool instance' do
+ is_expected.to be_a_kind_of(Gitlab::Git::ObjectPool)
+
+ is_expected.to have_attributes(
+ storage: pool.shard.name,
+ relative_path: "#{pool.disk_path}.git",
+ source_repository: pool.source_project.repository.raw,
+ gl_project_path: pool.source_project.full_path
+ )
+ end
+
+ context 'when source project is missing' do
+ let(:project) { nil }
+
+ it 'returns an object pool instance' do
+ is_expected.to be_a_kind_of(Gitlab::Git::ObjectPool)
+
+ is_expected.to have_attributes(
+ storage: pool.shard.name,
+ relative_path: "#{pool.disk_path}.git",
+ source_repository: nil,
+ gl_project_path: nil
+ )
+ end
+ end
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 6193a565d76..d2419ab89fc 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -7018,8 +7018,11 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
let_it_be_with_reload(:project) { create(:project, :empty_repo) }
let_it_be(:shard_to) { create(:shard, name: 'test_second_storage') }
- let!(:pool1) { create(:pool_repository, source_project: project) }
- let!(:pool2) { create(:pool_repository, shard: shard_to, source_project: project) }
+ let(:disk_path1) { '@pool/aa/bb' }
+ let(:disk_path2) { disk_path1 }
+
+ let!(:pool1) { create(:pool_repository, disk_path: disk_path1, source_project: project) }
+ let!(:pool2) { create(:pool_repository, disk_path: disk_path2, shard: shard_to, source_project: project) }
let(:project_pool) { pool1 }
let(:repository_storage) { shard_to.name }
@@ -7077,6 +7080,14 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
expect { swap_pool_repository! }.to raise_error(ActiveRecord::RecordNotFound)
end
end
+
+ context 'when pool repository has a different disk path' do
+ let(:disk_path2) { '@pool/different' }
+
+ it 'raises record not found error' do
+ expect { swap_pool_repository! }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
end
describe '#leave_pool_repository' do
diff --git a/spec/requests/sessions_spec.rb b/spec/requests/sessions_spec.rb
index 9454d75d990..3428e607305 100644
--- a/spec/requests/sessions_spec.rb
+++ b/spec/requests/sessions_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'Sessions', feature_category: :system_access do
include SessionHelpers
- let_it_be(:user) { create(:user) }
+ let(:user) { create(:user) }
context 'for authentication', :allow_forgery_protection do
it 'logout does not require a csrf token' do
@@ -17,20 +17,20 @@ RSpec.describe 'Sessions', feature_category: :system_access do
end
end
- describe 'about_gitlab_active_user', :saas do
+ describe 'gitlab_user cookie', :saas do
+ let_it_be(:user) { create(:user) }
+
context 'when user signs in' do
it 'sets marketing cookie' do
post user_session_path(user: { login: user.username, password: user.password })
-
- expect(response.cookies['about_gitlab_active_user']).to be_present
+ expect(response.cookies['gitlab_user']).to be_present
end
end
context 'when user uses remember_me' do
it 'sets marketing cookie' do
post user_session_path(user: { login: user.username, password: user.password, remember_me: true })
-
- expect(response.cookies['about_gitlab_active_user']).to be_present
+ expect(response.cookies['gitlab_user']).to be_present
end
end
@@ -74,18 +74,6 @@ RSpec.describe 'Sessions', feature_category: :system_access do
end
end
- context 'when user signs out' do
- before do
- post user_session_path(user: { login: user.username, password: user.password })
- end
-
- it 'deletes marketing cookie' do
- post(destroy_user_session_path)
-
- expect(response.cookies['about_gitlab_active_user']).to be_nil
- end
- end
-
context 'when user is not using GitLab SaaS' do
before do
allow(::Gitlab).to receive(:com?).and_return(false)
@@ -93,8 +81,7 @@ RSpec.describe 'Sessions', feature_category: :system_access do
it 'does not set marketing cookie' do
post user_session_path(user: { login: user.username, password: user.password })
-
- expect(response.cookies['about_gitlab_active_user']).to be_nil
+ expect(response.cookies['gitlab_user']).to be_nil
end
end
end
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index d3972009d38..b30c1d30044 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -229,6 +229,27 @@ RSpec.describe Projects::UpdateRepositoryStorageService, feature_category: :sour
end
end
+ context 'when new shard has a repository pool without the root project' do
+ let!(:new_pool_repository) { create(:pool_repository, :ready, shard: shard_to, disk_path: pool_repository.disk_path) }
+
+ before do
+ pool_repository.update!(source_project: nil)
+ new_pool_repository.update!(source_project: nil)
+ end
+
+ it 'connects project to it' do
+ result = subject.execute
+ expect(result).to be_success
+
+ project.reload.cleanup
+
+ project_pool_repository = project.pool_repository
+
+ expect(project_pool_repository).to eq(new_pool_repository)
+ expect(object_pool_double).to have_received(:link).with(project.repository.raw)
+ end
+ end
+
context 'when repository does not exist' do
let(:project) { create(:project) }
let(:checksum) { nil }
@@ -266,6 +287,32 @@ RSpec.describe Projects::UpdateRepositoryStorageService, feature_category: :sour
end
end
+ context 'when project belongs to the repository pool without a root project' do
+ let!(:pool_repository) { create(:pool_repository, :ready, shard: shard_from) }
+
+ before do
+ pool_repository.update!(source_project: nil)
+ project.update!(pool_repository: pool_repository)
+ end
+
+ it 'creates a new repository pool without a root project and connects project to it' do
+ result = subject.execute
+ expect(result).to be_success
+
+ project.reload.cleanup
+
+ new_pool_repository = project.pool_repository
+
+ expect(new_pool_repository).not_to eq(pool_repository)
+ expect(new_pool_repository.shard).to eq(shard_second_storage)
+ expect(new_pool_repository.state).to eq('ready')
+ expect(new_pool_repository.source_project).to eq(nil)
+ expect(new_pool_repository.disk_path).to eq(pool_repository.disk_path)
+
+ expect(object_pool_double).to have_received(:link).with(project.repository.raw)
+ end
+ end
+
context 'when object pool checksum does not match' do
let(:new_object_pool_checksum) { 'not_match' }
diff --git a/spec/services/users/authorized_build_service_spec.rb b/spec/services/users/authorized_build_service_spec.rb
index 7eed6833cba..a96854f33d9 100644
--- a/spec/services/users/authorized_build_service_spec.rb
+++ b/spec/services/users/authorized_build_service_spec.rb
@@ -12,5 +12,13 @@ RSpec.describe Users::AuthorizedBuildService, feature_category: :user_management
it_behaves_like 'common user build items'
it_behaves_like 'current user not admin build items'
+
+ context 'for additional authorized build allowed params' do
+ before do
+ params.merge!(external: true)
+ end
+
+ it { expect(user).to be_external }
+ end
end
end
diff --git a/spec/services/users/build_service_spec.rb b/spec/services/users/build_service_spec.rb
index f3236d40412..5f1949adc32 100644
--- a/spec/services/users/build_service_spec.rb
+++ b/spec/services/users/build_service_spec.rb
@@ -16,6 +16,57 @@ RSpec.describe Users::BuildService, feature_category: :user_management do
it_behaves_like 'common user build items'
it_behaves_like 'current user not admin build items'
+
+ context 'with "user_default_external" application setting' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:user_default_external, :external, :email, :user_default_internal_regex, :result) do
+ true | nil | 'fl@example.com' | nil | true
+ true | true | 'fl@example.com' | nil | true
+ true | false | 'fl@example.com' | nil | true # admin difference
+
+ true | nil | 'fl@example.com' | '' | true
+ true | true | 'fl@example.com' | '' | true
+ true | false | 'fl@example.com' | '' | true # admin difference
+
+ true | nil | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
+ true | true | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
+ true | false | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
+
+ true | nil | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true
+ true | true | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true
+ true | false | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true # admin difference
+
+ false | nil | 'fl@example.com' | nil | false
+ false | true | 'fl@example.com' | nil | false # admin difference
+ false | false | 'fl@example.com' | nil | false
+
+ false | nil | 'fl@example.com' | '' | false
+ false | true | 'fl@example.com' | '' | false # admin difference
+ false | false | 'fl@example.com' | '' | false
+
+ false | nil | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
+ false | true | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
+ false | false | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
+
+ false | nil | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false
+ false | true | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
+ false | false | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false
+ end
+
+ with_them do
+ before do
+ stub_application_setting(user_default_external: user_default_external)
+ stub_application_setting(user_default_internal_regex: user_default_internal_regex)
+
+ params.merge!({ external: external, email: email }.compact)
+ end
+
+ it 'sets the value of Gitlab::CurrentSettings.user_default_external' do
+ expect(user.external).to eq(result)
+ end
+ end
+ end
end
context 'with non admin current_user' do
diff --git a/spec/support/shared_examples/services/users/build_service_shared_examples.rb b/spec/support/shared_examples/services/users/build_service_shared_examples.rb
index e448f2f874b..45ebc837e6d 100644
--- a/spec/support/shared_examples/services/users/build_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/users/build_service_shared_examples.rb
@@ -33,57 +33,6 @@ RSpec.shared_examples 'common user build items' do
end
RSpec.shared_examples_for 'current user not admin build items' do
- using RSpec::Parameterized::TableSyntax
-
- context 'with "user_default_external" application setting' do
- where(:user_default_external, :external, :email, :user_default_internal_regex, :result) do
- true | nil | 'fl@example.com' | nil | true
- true | true | 'fl@example.com' | nil | true
- true | false | 'fl@example.com' | nil | true # admin difference
-
- true | nil | 'fl@example.com' | '' | true
- true | true | 'fl@example.com' | '' | true
- true | false | 'fl@example.com' | '' | true # admin difference
-
- true | nil | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
- true | true | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
- true | false | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
-
- true | nil | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true
- true | true | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true
- true | false | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | true # admin difference
-
- false | nil | 'fl@example.com' | nil | false
- false | true | 'fl@example.com' | nil | false # admin difference
- false | false | 'fl@example.com' | nil | false
-
- false | nil | 'fl@example.com' | '' | false
- false | true | 'fl@example.com' | '' | false # admin difference
- false | false | 'fl@example.com' | '' | false
-
- false | nil | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
- false | true | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
- false | false | 'fl@example.com' | '^(?:(?!\.ext@).)*$\r?' | false
-
- false | nil | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false
- false | true | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false # admin difference
- false | false | 'tester.ext@domain.com' | '^(?:(?!\.ext@).)*$\r?' | false
- end
-
- with_them do
- before do
- stub_application_setting(user_default_external: user_default_external)
- stub_application_setting(user_default_internal_regex: user_default_internal_regex)
-
- params.merge!({ external: external, email: email }.compact)
- end
-
- it 'sets the value of Gitlab::CurrentSettings.user_default_external' do
- expect(user.external).to eq(result)
- end
- end
- end
-
context 'when "email_confirmation_setting" application setting is set to `hard`' do
before do
stub_application_setting_enum('email_confirmation_setting', 'hard')