diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 72498138e34..2ba4d6835c5 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -343,7 +343,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /doc/administration/logs/log_parsing.md @axil /doc/administration/logs/tracing_correlation_id.md @axil /doc/administration/maintenance_mode/ @axil -/doc/administration/merge_request_diffs.md @aqualls +/doc/administration/merge_request_diffs.md @aqualls /doc/administration/monitoring/ @msedlakjakubowski /doc/administration/monitoring/gitlab_self_monitoring_project/ @msedlakjakubowski /doc/administration/monitoring/ip_allowlist.md @sselhorn @@ -1201,6 +1201,13 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab /lib/tasks/gitlab/password.rake @gitlab-org/manage/authentication-and-authorization/approvers /lib/tasks/tokens.rake @gitlab-org/manage/authentication-and-authorization/approvers +[Manage::Workspace] +lib/api/entities/basic_project_details.rb @gitlab-org/manage/manage-workspace/backend-approvers +lib/api/entities/project_with_access.rb @gitlab-org/manage/manage-workspace/backend-approvers +lib/api/entities/project_identity.rb @gitlab-org/manage/manage-workspace/backend-approvers +lib/api/entities/project.rb @gitlab-org/manage/manage-workspace/backend-approvers +ee/lib/ee/api/entities/project.rb @gitlab-org/manage/manage-workspace/backend-approvers + [Compliance] /ee/app/services/audit_events/build_service.rb @gitlab-org/manage/compliance /ee/spec/services/audit_events/custom_audit_event_service_spec.rb @gitlab-org/manage/compliance diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 8fe106249c3..37dde065e70 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -14,14 +14,7 @@ class Admin::DashboardController < Admin::ApplicationController @groups = Group.order_id_desc.with_route.limit(10) @notices = Gitlab::ConfigChecker::PumaRuggedChecker.check @notices += Gitlab::ConfigChecker::ExternalDatabaseChecker.check - @redis_versions = [ - Gitlab::Redis::Queues, - Gitlab::Redis::SharedState, - Gitlab::Redis::Cache, - Gitlab::Redis::TraceChunks, - Gitlab::Redis::RateLimiting, - Gitlab::Redis::Sessions - ].map(&:version).uniq + @redis_versions = Gitlab::Redis::ALL_CLASSES.map(&:version).uniq end def stats diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 071378f266e..0e74ac420b4 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -11,13 +11,7 @@ class HealthController < ActionController::Base ALL_CHECKS = [ *CHECKS, Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::Redis::RedisCheck, - Gitlab::HealthChecks::Redis::CacheCheck, - Gitlab::HealthChecks::Redis::QueuesCheck, - Gitlab::HealthChecks::Redis::SharedStateCheck, - Gitlab::HealthChecks::Redis::TraceChunksCheck, - Gitlab::HealthChecks::Redis::RateLimitingCheck, - Gitlab::HealthChecks::Redis::SessionsCheck, + *Gitlab::HealthChecks::Redis::ALL_INSTANCE_CHECKS, Gitlab::HealthChecks::GitalyCheck ].freeze diff --git a/config/initializers/7_redis.rb b/config/initializers/7_redis.rb index e233c282836..1e2786db413 100644 --- a/config/initializers/7_redis.rb +++ b/config/initializers/7_redis.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'gitlab/redis' + Redis.raise_deprecations = true unless Rails.env.production? # We set the instance variable directly to suppress warnings. @@ -15,11 +17,6 @@ Redis::Client.prepend(Gitlab::Instrumentation::RedisInterceptor) # 1. Sidekiq # 2. Rails.cache # 3. HTTP clients -Gitlab::Redis::Cache.with { nil } -Gitlab::Redis::Queues.with { nil } -Gitlab::Redis::SharedState.with { nil } -Gitlab::Redis::TraceChunks.with { nil } -Gitlab::Redis::RateLimiting.with { nil } -Gitlab::Redis::Sessions.with { nil } -Gitlab::Redis::DuplicateJobs.with { nil } -Gitlab::Redis::SidekiqStatus.with { nil } +Gitlab::Redis::ALL_CLASSES.each do |redis_instance| + redis_instance.with { nil } +end diff --git a/db/post_migrate/20220826175058_fully_remove_temporary_job_trace_index.rb b/db/post_migrate/20220826175058_fully_remove_temporary_job_trace_index.rb new file mode 100644 index 00000000000..2a18e63106a --- /dev/null +++ b/db/post_migrate/20220826175058_fully_remove_temporary_job_trace_index.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class FullyRemoveTemporaryJobTraceIndex < Gitlab::Database::Migration[2.0] + INDEX_NAME = 'tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at' + + disable_ddl_transaction! + + def up + remove_concurrent_index_by_name :ci_job_artifacts, name: INDEX_NAME + end + + def down + add_concurrent_index :ci_job_artifacts, :id, name: INDEX_NAME + end +end diff --git a/db/post_migrate/20220901184106_add_not_null_to_board_group_recent_visits.rb b/db/post_migrate/20220901184106_add_not_null_to_board_group_recent_visits.rb new file mode 100644 index 00000000000..1dead32efb6 --- /dev/null +++ b/db/post_migrate/20220901184106_add_not_null_to_board_group_recent_visits.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNotNullToBoardGroupRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + add_not_null_constraint :board_group_recent_visits, :user_id, validate: false + add_not_null_constraint :board_group_recent_visits, :group_id, validate: false + add_not_null_constraint :board_group_recent_visits, :board_id, validate: false + end + + def down + remove_not_null_constraint :board_group_recent_visits, :user_id + remove_not_null_constraint :board_group_recent_visits, :board_id + remove_not_null_constraint :board_group_recent_visits, :group_id + end +end diff --git a/db/post_migrate/20220901184246_add_not_null_to_board_project_recent_visits.rb b/db/post_migrate/20220901184246_add_not_null_to_board_project_recent_visits.rb new file mode 100644 index 00000000000..4f0cb4d3d68 --- /dev/null +++ b/db/post_migrate/20220901184246_add_not_null_to_board_project_recent_visits.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNotNullToBoardProjectRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + add_not_null_constraint :board_project_recent_visits, :user_id, validate: false + add_not_null_constraint :board_project_recent_visits, :project_id, validate: false + add_not_null_constraint :board_project_recent_visits, :board_id, validate: false + end + + def down + remove_not_null_constraint :board_project_recent_visits, :user_id + remove_not_null_constraint :board_project_recent_visits, :project_id + remove_not_null_constraint :board_project_recent_visits, :board_id + end +end diff --git a/db/post_migrate/20220902111016_delete_null_records_from_board_group_recent_visits.rb b/db/post_migrate/20220902111016_delete_null_records_from_board_group_recent_visits.rb new file mode 100644 index 00000000000..4b55ecc013d --- /dev/null +++ b/db/post_migrate/20220902111016_delete_null_records_from_board_group_recent_visits.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class DeleteNullRecordsFromBoardGroupRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + restrict_gitlab_migration gitlab_schema: :gitlab_main + + def up + execute('DELETE FROM board_group_recent_visits WHERE user_id is null OR group_id is null OR board_id is null') + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20220902111038_delete_null_records_from_board_project_recent_visits.rb b/db/post_migrate/20220902111038_delete_null_records_from_board_project_recent_visits.rb new file mode 100644 index 00000000000..bb261f80f73 --- /dev/null +++ b/db/post_migrate/20220902111038_delete_null_records_from_board_project_recent_visits.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class DeleteNullRecordsFromBoardProjectRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + restrict_gitlab_migration gitlab_schema: :gitlab_main + + def up + execute('DELETE FROM board_project_recent_visits WHERE user_id is null OR project_id is null OR board_id is null') + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20220904173342_validate_not_null_constraint_board_group_recent_visits.rb b/db/post_migrate/20220904173342_validate_not_null_constraint_board_group_recent_visits.rb new file mode 100644 index 00000000000..0e5a504d0eb --- /dev/null +++ b/db/post_migrate/20220904173342_validate_not_null_constraint_board_group_recent_visits.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class ValidateNotNullConstraintBoardGroupRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + validate_not_null_constraint :board_group_recent_visits, :user_id + validate_not_null_constraint :board_group_recent_visits, :group_id + validate_not_null_constraint :board_group_recent_visits, :board_id + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20220904173430_validate_not_null_constraint_board_project_recent_visits.rb b/db/post_migrate/20220904173430_validate_not_null_constraint_board_project_recent_visits.rb new file mode 100644 index 00000000000..ff73a179f69 --- /dev/null +++ b/db/post_migrate/20220904173430_validate_not_null_constraint_board_project_recent_visits.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class ValidateNotNullConstraintBoardProjectRecentVisits < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + validate_not_null_constraint :board_project_recent_visits, :user_id + validate_not_null_constraint :board_project_recent_visits, :project_id + validate_not_null_constraint :board_project_recent_visits, :board_id + end + + def down + # no-op + end +end diff --git a/db/schema_migrations/20220826175058 b/db/schema_migrations/20220826175058 new file mode 100644 index 00000000000..55449ae1047 --- /dev/null +++ b/db/schema_migrations/20220826175058 @@ -0,0 +1 @@ +2553878c425173fc41e64723814d4bca8f3f59f98479080e74a85f327412f3d4 \ No newline at end of file diff --git a/db/schema_migrations/20220901184106 b/db/schema_migrations/20220901184106 new file mode 100644 index 00000000000..d529617762a --- /dev/null +++ b/db/schema_migrations/20220901184106 @@ -0,0 +1 @@ +3934393670a67a38e0e558f7be2cb2b2a51d268c49f5992624dedfb2bc826ee4 \ No newline at end of file diff --git a/db/schema_migrations/20220901184246 b/db/schema_migrations/20220901184246 new file mode 100644 index 00000000000..556f3ff1b3e --- /dev/null +++ b/db/schema_migrations/20220901184246 @@ -0,0 +1 @@ +fe06d38ab5a86850e5b915243dd70d0fe7fef9a61d9bd54c71651aa8eb1eb0e3 \ No newline at end of file diff --git a/db/schema_migrations/20220902111016 b/db/schema_migrations/20220902111016 new file mode 100644 index 00000000000..33ea3c75bba --- /dev/null +++ b/db/schema_migrations/20220902111016 @@ -0,0 +1 @@ +13a36d34ff1c812a8993be87721b9d9472c26cfb6fcd8f56e9aa3c59d97183a9 \ No newline at end of file diff --git a/db/schema_migrations/20220902111038 b/db/schema_migrations/20220902111038 new file mode 100644 index 00000000000..ecfad43fff1 --- /dev/null +++ b/db/schema_migrations/20220902111038 @@ -0,0 +1 @@ +65c55f8fe4037d0e492f1c2a4ff83481a0da3ab17f6c63a56c181fba5d5822ba \ No newline at end of file diff --git a/db/schema_migrations/20220904173342 b/db/schema_migrations/20220904173342 new file mode 100644 index 00000000000..951b667372c --- /dev/null +++ b/db/schema_migrations/20220904173342 @@ -0,0 +1 @@ +407fd539c6ff5cb8e71a2da80fe9dfb0002a45d5fce84a391b2332a653d6e09e \ No newline at end of file diff --git a/db/schema_migrations/20220904173430 b/db/schema_migrations/20220904173430 new file mode 100644 index 00000000000..6c1750b8784 --- /dev/null +++ b/db/schema_migrations/20220904173430 @@ -0,0 +1 @@ +28b91d351f3d23377d79116bdd268871f755675efb3df647e2bea51482e1aff8 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index fe6c6f295c4..6723db0147d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -12074,7 +12074,10 @@ CREATE TABLE board_group_recent_visits ( updated_at timestamp with time zone NOT NULL, user_id integer, board_id integer, - group_id integer + group_id integer, + CONSTRAINT check_409f6caea4 CHECK ((user_id IS NOT NULL)), + CONSTRAINT check_ddc74243ef CHECK ((group_id IS NOT NULL)), + CONSTRAINT check_fa7711a898 CHECK ((board_id IS NOT NULL)) ); CREATE SEQUENCE board_group_recent_visits_id_seq @@ -12107,7 +12110,10 @@ CREATE TABLE board_project_recent_visits ( updated_at timestamp with time zone NOT NULL, user_id integer, project_id integer, - board_id integer + board_id integer, + CONSTRAINT check_0386e26981 CHECK ((board_id IS NOT NULL)), + CONSTRAINT check_d9cc9b79da CHECK ((project_id IS NOT NULL)), + CONSTRAINT check_df7762a99a CHECK ((user_id IS NOT NULL)) ); CREATE SEQUENCE board_project_recent_visits_id_seq @@ -30763,8 +30769,6 @@ CREATE INDEX tmp_index_ci_job_artifacts_on_expire_at_where_locked_unknown ON ci_ CREATE INDEX tmp_index_ci_job_artifacts_on_id_expire_at_file_type_trace ON ci_job_artifacts USING btree (id) WHERE (((date_part('day'::text, timezone('UTC'::text, expire_at)) = ANY (ARRAY[(21)::double precision, (22)::double precision, (23)::double precision])) AND (date_part('minute'::text, timezone('UTC'::text, expire_at)) = ANY (ARRAY[(0)::double precision, (30)::double precision, (45)::double precision])) AND (date_part('second'::text, timezone('UTC'::text, expire_at)) = (0)::double precision)) OR (file_type = 3)); -CREATE INDEX tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at ON ci_job_artifacts USING btree (id) WHERE ((file_type = 3) AND (expire_at = ANY (ARRAY['2021-04-22 00:00:00+00'::timestamp with time zone, '2021-05-22 00:00:00+00'::timestamp with time zone, '2021-06-22 00:00:00+00'::timestamp with time zone, '2022-01-22 00:00:00+00'::timestamp with time zone, '2022-02-22 00:00:00+00'::timestamp with time zone, '2022-03-22 00:00:00+00'::timestamp with time zone, '2022-04-22 00:00:00+00'::timestamp with time zone]))); - CREATE INDEX tmp_index_cis_vulnerability_reads_on_id ON vulnerability_reads USING btree (id) WHERE (report_type = 7); CREATE INDEX tmp_index_container_repos_on_non_migrated ON container_repositories USING btree (project_id, id) WHERE (migration_state <> 'import_done'::text); diff --git a/doc/api/projects.md b/doc/api/projects.md index 56fa36a44f8..926d823c012 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -417,6 +417,7 @@ GET /users/:user_id/projects "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "squash_commit_template": null, @@ -539,6 +540,7 @@ GET /users/:user_id/projects "service_desk_enabled": false, "service_desk_address": null, "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "squash_commit_template": null, @@ -671,6 +673,7 @@ Example response: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "squash_commit_template": null, @@ -786,6 +789,7 @@ Example response: "service_desk_enabled": false, "service_desk_address": null, "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "squash_commit_template": null, @@ -962,6 +966,7 @@ GET /projects/:id "service_desk_address": null, "autoclose_referenced_issues": true, "suggestion_commit_message": null, + "enforce_auth_checks_on_uploads": true, "merge_commit_template": null, "squash_commit_template": null, "marked_for_deletion_at": "2020-04-03", // Deprecated and will be removed in API v5 in favor of marked_for_deletion_on @@ -1277,6 +1282,7 @@ POST /projects/user/:user_id | `default_branch` | string | **{dotted-circle}** No | The [default branch](../user/project/repository/branches/default.md) name. Requires `initialize_with_readme` to be `true`. | | `description` | string | **{dotted-circle}** No | Short project description. | | `emails_disabled` | boolean | **{dotted-circle}** No | Disable email notifications. | +| `enforce_auth_checks_on_uploads` | boolean | **{dotted-circle}** No | Enforce [auth checks](../security/user_file_uploads.md#enable-authorization-checks-for-all-media-files) on uploads. | | `external_authorization_classification_label` **(PREMIUM)** | string | **{dotted-circle}** No | The classification label for the project. | | `forking_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. | | `group_with_project_templates_id` **(PREMIUM)** | integer | **{dotted-circle}** No | For group-level custom templates, specifies ID of group from which all the custom project templates are sourced. Leave empty for instance-level templates. Requires `use_custom_template` to be true. | @@ -1370,6 +1376,7 @@ Supported attributes: | `default_branch` | string | **{dotted-circle}** No | The [default branch](../user/project/repository/branches/default.md) name. | | `description` | string | **{dotted-circle}** No | Short project description. | | `emails_disabled` | boolean | **{dotted-circle}** No | Disable email notifications. | +| `enforce_auth_checks_on_uploads` | boolean | **{dotted-circle}** No | Enforce [auth checks](../security/user_file_uploads.md#enable-authorization-checks-for-all-media-files) on uploads. | | `external_authorization_classification_label` **(PREMIUM)** | string | **{dotted-circle}** No | The classification label for the project. | | `forking_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. | | `import_url` | string | **{dotted-circle}** No | URL the repository was imported from. | @@ -1542,6 +1549,7 @@ Example responses: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", @@ -1648,6 +1656,7 @@ Example response: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", @@ -1752,6 +1761,7 @@ Example response: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", @@ -1952,6 +1962,7 @@ Example response: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", @@ -2079,6 +2090,7 @@ Example response: "merge_method": "merge", "squash_option": "default_on", "autoclose_referenced_issues": true, + "enforce_auth_checks_on_uploads": true, "suggestion_commit_message": null, "merge_commit_template": null, "container_registry_image_prefix": "registry.example.com/diaspora/diaspora-project-site", diff --git a/doc/ci/secure_files/index.md b/doc/ci/secure_files/index.md index 8e141c62ef6..0eedb4f3fc5 100644 --- a/doc/ci/secure_files/index.md +++ b/doc/ci/secure_files/index.md @@ -23,7 +23,7 @@ plain text and binary file types. You can manage secure files in the project settings, or with the [secure files API](../../api/secure_files.md). Secure files can be [downloaded and used by CI/CD jobs](#use-secure-files-in-cicd-jobs) -by using the [load-secure-files](https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/load-secure-files) +by using the [load-secure-files](https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/load-secure-files) tool. NOTE: @@ -43,7 +43,7 @@ To add a secure file to a project: ## Use secure files in CI/CD jobs -To use your secure files in a CI/CD job, you must use the [`load-secure-files`](https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/load-secure-files) +To use your secure files in a CI/CD job, you must use the [`load-secure-files`](https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/load-secure-files) tool to download the files in the job. After they are downloaded, you can use them with your other script commands. @@ -59,5 +59,5 @@ test: variables: SECURE_FILES_DOWNLOAD_PATH: './where/files/should/go/' script: - - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/load-secure-files/-/raw/main/installer" | bash + - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/load-secure-files/-/raw/main/installer" | bash ``` diff --git a/doc/development/database_review.md b/doc/development/database_review.md index 2decd304103..453f3e5e11e 100644 --- a/doc/development/database_review.md +++ b/doc/development/database_review.md @@ -116,9 +116,9 @@ the following preparations into account. - Ensure that the Database Dictionary is updated as [documented](database/database_dictionary.md). - Make migrations reversible by using the `change` method or include a `down` method when using `up`. - Include either a rollback procedure or describe how to rollback changes. -- Add the output of both migrating (`db:migrate`) and rolling back (`db:rollback`) for all migrations into the MR description. - - Ensure the down method reverts the changes in `db/structure.sql`. - - Update the migration output whenever you modify the migrations during the review process. +- Check that the [`db:check-migrations`](database/dbcheck-migrations-job.md) pipeline job has run successfully and the migration rollback behaves as expected. + - Ensure the `db:check-schema` job has run successfully and no unexpected schema changes are introduced in a rollback. This job may only trigger a warning if the schema was changed. + - Verify that the previously mentioned jobs continue to succeed whenever you modify the migrations during the review process. - Add tests for the migration in `spec/migrations` if necessary. See [Testing Rails migrations at GitLab](testing_guide/testing_migrations_guide.md) for more details. - When [high-traffic](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3) tables are involved in the migration, use the [`enable_lock_retries`](migration_style_guide.md#retry-mechanism-when-acquiring-database-locks) method to enable lock-retries. Review the relevant [examples in our documentation](migration_style_guide.md#usage-with-transactional-migrations) for use cases and solutions. - Ensure RuboCop checks are not disabled unless there's a valid reason to. diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md index 5c5482c9f10..4f40cc88ebc 100644 --- a/doc/user/application_security/security_dashboard/index.md +++ b/doc/user/application_security/security_dashboard/index.md @@ -91,15 +91,16 @@ To view vulnerabilities over time for a group: ## View project security status for a group -Use the group Security Dashboard to view the security status of projects. The security status is based -on the number of detected vulnerabilities. +Use the group Security Dashboard to view the security status of projects. To view project security status for a group: 1. On the top bar, select **Menu > Groups** and select a group. 1. Select **Security > Security Dashboard**. -Projects are [graded](#project-vulnerability-grades) by vulnerability severity. Dismissed vulnerabilities are excluded. +Each project is assigned a letter [grade](#project-vulnerability-grades) according to the highest-severity open vulnerability. +Dismissed or resolved vulnerabilities are excluded. Each project can receive only one letter grade and will appear only once +in the Project security status report. To view vulnerabilities, go to the group's [vulnerability report](../vulnerability_report/index.md). diff --git a/doc/user/project/code_intelligence.md b/doc/user/project/code_intelligence.md index 7f35caf2a68..860ebfbed14 100644 --- a/doc/user/project/code_intelligence.md +++ b/doc/user/project/code_intelligence.md @@ -17,7 +17,10 @@ development environments (IDE), including: Code Intelligence is built into GitLab and powered by [LSIF](https://lsif.dev/) (Language Server Index Format), a file format for precomputed code -intelligence data. +intelligence data. GitLab processes one LSIF file per project, and +Code Intelligence does not support different LSIF files per branch. +Follow epic [#4212, Code intelligence enhancements](https://gitlab.com/groups/gitlab-org/-/epics/4212) +for progress on upcoming enhancements. NOTE: You can automate this feature in your applications by using [Auto DevOps](../../topics/autodevops/index.md). @@ -59,13 +62,5 @@ under the **References** tab: ## Language support Generating an LSIF file requires a language server indexer implementation for the -relevant language. - -| Language | Implementation | -|---|---| -| Go | [`sourcegraph/lsif-go`](https://github.com/sourcegraph/lsif-go) | -| JavaScript | [`sourcegraph/lsif-node`](https://github.com/sourcegraph/lsif-node) | -| TypeScript | [`sourcegraph/lsif-node`](https://github.com/sourcegraph/lsif-node) | - -View a complete list of [available LSIF indexers](https://lsif.dev/#implementations-server) on their website and +relevant language. View a complete list of [available LSIF indexers](https://lsif.dev/#implementations-server) on their website and refer to their documentation to see how to generate an LSIF file for your specific language. diff --git a/doc/user/project/pages/getting_started/pages_ui.md b/doc/user/project/pages/getting_started/pages_ui.md new file mode 100644 index 00000000000..66b4f43b6b2 --- /dev/null +++ b/doc/user/project/pages/getting_started/pages_ui.md @@ -0,0 +1,58 @@ +--- +stage: Create +group: Incubation +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Tutorial: Use the GitLab UI to deploy your static site **(FREE)** + +This tutorial assumes you have a project that either: + +- Generates static sites or a client-rendered single-page application (SPA), + such as [Eleventy](https://www.11ty.dev), [Astro](https://astro.build), or [Jekyll](https://jekyllrb.com). +- Contains a framework configured for static output, such as [Next.js](https://nextjs.org), + [Nuxt.js](https://nuxtjs.org), or [SvelteKit](https://kit.svelte.dev). + +## Update your app to output files to the `public` folder + +GitLab Pages requires all files intended to be part of the published website to +be in a root-level folder called `public`. If you create this folder during the build +pipeline, committing it to Git is not required. + +For detailed instructions, read [Configure the public files folder](../public_folder.md). + +## Set up the `.gitlab-ci.yml` file + +GitLab helps you write the `.gitlab-ci.yml` needed to create your first GitLab Pages +deployment pipeline. Rather than building the file from scratch, it asks you to +provide the build commands, and creates the necessary boilerplate for you. + +To build your YAML file from the GitLab UI: + +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Settings > Pages** to display the friendly + interface **Get Started With Pages**. +1. If your framework's build process does not need one of the provided build + commands, you can either: + - Skip the step by selecting **Next**. + - Enter `:` (the bash "do nothing" command) if you still want to incorporate that + step's boilerplate into your `.gitlab-ci.yml` file. +1. Optional. Edit and adjust the generated `.gitlab-ci.yml` file as needed. +1. Commit your `.gitlab-ci.yml` to your repository. This commit triggers your first + GitLab Pages deployment. + +## Troubleshooting + +### If you can't see the "Get Started with Pages" interface + +GitLab doesn't show this interface if you have either: + +- Deployed a GitLab Pages site before. +- Committed a `.gitlab-ci.yml` through this interface at least once. + +To fix this problem: + +- If you see the message **Waiting for the Pages Pipeline to complete**, select + **Start over** to start the wizard again. +- If your project has previously deployed GitLab Pages successfully, + [manually update](pages_from_scratch.md) your `.gitlab-ci.yml`. diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index af49522efe2..1f3628b74ec 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -38,12 +38,13 @@ Learn more about To create a GitLab Pages website: -| Document | Description | -|----------|-------------| +| Document | Description | +|--------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| +| [Use the GitLab UI to create a simple `.gitlab-ci.yml`](getting_started/pages_ui.md) | Add a Pages site to an existing project. Use the UI to set up a simple `.gitlab-ci.yml`. | | [Create a `.gitlab-ci.yml` file from scratch](getting_started/pages_from_scratch.md) | Add a Pages site to an existing project. Learn how to create and configure your own CI file. | -| [Use a `.gitlab-ci.yml` template](getting_started/pages_ci_cd_template.md) | Add a Pages site to an existing project. Use a pre-populated CI template file. | -| [Fork a sample project](getting_started/pages_forked_sample_project.md) | Create a new project with Pages already configured by forking a sample project. | -| [Use a project template](getting_started/pages_new_project_template.md) | Create a new project with Pages already configured by using a template. | +| [Use a `.gitlab-ci.yml` template](getting_started/pages_ci_cd_template.md) | Add a Pages site to an existing project. Use a pre-populated CI template file. | +| [Fork a sample project](getting_started/pages_forked_sample_project.md) | Create a new project with Pages already configured by forking a sample project. | +| [Use a project template](getting_started/pages_new_project_template.md) | Create a new project with Pages already configured by using a template. | To update a GitLab Pages website: diff --git a/doc/user/project/pages/public_folder.md b/doc/user/project/pages/public_folder.md new file mode 100644 index 00000000000..f9c80875cc9 --- /dev/null +++ b/doc/user/project/pages/public_folder.md @@ -0,0 +1,153 @@ +--- +description: 'Learn how to configure the build output folder for the most +common static site generators' +stage: Create +group: Incubation +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Configure the public files folder **(FREE)** + +GitLab Pages requires all files you intend to be available in the published website to +be in a root-level folder called `public`. This page describe how +to set this up for some common static site generators. + +## Guide by framework + +### Eleventy + +For Eleventy, you should either: + +1. Add the `--output=public` flag in Eleventy's build commands, for example: + + `npx @11ty/eleventy --input=path/to/sourcefiles --output=public` + +1. Add the following to your `.eleventy.js` file: + + ```javascript + // .eleventy.js + module.exports = function(eleventyConfig) { + return { + dir: { + output: "public" + } + } + }; + ``` + +### Astro + +By default, Astro uses the `public` folder to store static assets. For GitLab Pages, +rename that folder to a collision-free alternative first: + +1. In your project directory, run: + + ```shell + mv public static + ``` + +1. Add the following to your `astro.config.mjs`. This code informs Astro about + our folder name remapping: + + ```javascript + // astro.config.mjs + export default { + // GitLab Pages requires exposed files to be located in a folder called "public". + // So we're instructing Astro to put the static build output in a folder of that name. + dist: 'public', + + // The folder name Astro uses for static files (`public`) is already reserved + // for the build output. So in deviation from the defaults we're using a folder + // called `static` instead. + public: 'static', + }; + ``` + +### SvelteKit + +NOTE: +GitLab Pages supports only static sites. For SvelteKit, +we recommend using [`adapter-static`](https://kit.svelte.dev/docs/adapters#supported-environments-static-sites). + +When using `adapter-static`, add the following to your `svelte.config.js`: + +```javascript +// svelte.config.js +import adapter from '@sveltejs/adapter-static'; + +export default { + kit: { + adapter: adapter({ + pages: 'public' + }) + } +}; +``` + +### Next.js + +NOTE: +GitLab Pages supports only static sites. For Next.js, we +recommend using Next's [Static HTML export functionality](https://nextjs.org/docs/advanced-features/static-html-export) + +Use the `-o public` flag after `next export` as the build command, for +example: + +```shell +next export -o public +``` + +### Nuxt.js + +NOTE: +GitLab Pages supports only static sites. + +1. Add the following to your `nuxt.config.js`: + + ```javascript + export default { + target: 'static', + generate: { + dir: 'public' + } + } + ``` + +1. Configure your Nuxt.js application for + [Static Site Generation](https://nuxtjs.org/docs/features/deployment-targets#static-hosting). + +### Vite + +Update your `vite.config.js` to include the following: + +```javascript +// vite.config.js +export default { + build: { + outDir: 'public' + } +} +``` + +### Webpack + +Update your `webpack.config.js` to include the following: + +```javascript +// webpack.config.js +module.exports = { + output: { + path: __dirname + '/public' + } +}; +``` + +## Should you commit the `public` folder? + +Not necessarily. However, when the GitLab Pages deploy pipeline runs, it looks +for an [artifact](../../../ci/pipelines/job_artifacts.md) of that name. So +If you set up a job that creates the `public` folder before deploy, such as by +running `npm run build`, committing the folder isn't required. + +If you prefer to build your site locally, you can commit the `public` folder and +omit the build step during the job, instead. diff --git a/doc/user/tasks.md b/doc/user/tasks.md index 1d950960ea7..f1518482c9d 100644 --- a/doc/user/tasks.md +++ b/doc/user/tasks.md @@ -13,10 +13,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w WARNING: Tasks are in [**Alpha**](../policy/alpha-beta-support.md#alpha-features). -The following list are the known limitations: +Known limitation: - [Tasks currently cannot be accessed via REST API.](https://gitlab.com/gitlab-org/gitlab/-/issues/368055) -- An issue's tasks can only currently be accessed via a reference within a description, comment, or direct URL (`.../-/work_items/[global_id]`). For the latest updates, check the [Tasks Roadmap](https://gitlab.com/groups/gitlab-org/-/epics/7103). diff --git a/lib/api/admin/batched_background_migrations.rb b/lib/api/admin/batched_background_migrations.rb index 5e03c27062b..32980c192f7 100644 --- a/lib/api/admin/batched_background_migrations.rb +++ b/lib/api/admin/batched_background_migrations.rb @@ -27,33 +27,9 @@ module API end end end - - resources 'batched_background_migrations/:id/resume' do - desc 'Resume a batched background migration' - params do - optional :database, - type: String, - values: Gitlab::Database.all_database_names, - desc: 'The name of the database', - default: 'main' - requires :id, - type: Integer, - desc: 'The batched background migration id' - end - put do - Gitlab::Database::SharedModel.using_connection(base_model.connection) do - batched_background_migration.execute! - present_entity(batched_background_migration) - end - end - end end helpers do - def batched_background_migration - @batched_background_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.find(params[:id]) - end - def base_model database = params[:database] || Gitlab::Database::MAIN_DATABASE_NAME @base_model ||= Gitlab::Database.database_base_models[database] diff --git a/lib/gitlab/health_checks/redis.rb b/lib/gitlab/health_checks/redis.rb new file mode 100644 index 00000000000..895bce5a5a9 --- /dev/null +++ b/lib/gitlab/health_checks/redis.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Gitlab + module HealthChecks + module Redis + ALL_INSTANCE_CHECKS = + ::Gitlab::Redis::ALL_CLASSES.map do |instance_class| + check_class = Class.new + check_class.extend(RedisAbstractCheck) + const_set("#{instance_class.store_name}Check", check_class) + + check_class + end + end + end +end diff --git a/lib/gitlab/health_checks/redis/cache_check.rb b/lib/gitlab/health_checks/redis/cache_check.rb deleted file mode 100644 index bd843bdaac4..00000000000 --- a/lib/gitlab/health_checks/redis/cache_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class CacheCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/queues_check.rb b/lib/gitlab/health_checks/redis/queues_check.rb deleted file mode 100644 index fb92db937dc..00000000000 --- a/lib/gitlab/health_checks/redis/queues_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class QueuesCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/rate_limiting_check.rb b/lib/gitlab/health_checks/redis/rate_limiting_check.rb deleted file mode 100644 index 0e9d94f7dff..00000000000 --- a/lib/gitlab/health_checks/redis/rate_limiting_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class RateLimitingCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/redis_abstract_check.rb b/lib/gitlab/health_checks/redis/redis_abstract_check.rb index ecad4b06ea9..9a9a4d1faba 100644 --- a/lib/gitlab/health_checks/redis/redis_abstract_check.rb +++ b/lib/gitlab/health_checks/redis/redis_abstract_check.rb @@ -10,12 +10,12 @@ module Gitlab successful?(check) end - private - def redis_instance_class_name Gitlab::Redis.const_get(redis_instance_name.camelize, false) end + private + def metric_prefix "redis_#{redis_instance_name}_ping" end diff --git a/lib/gitlab/health_checks/redis/redis_check.rb b/lib/gitlab/health_checks/redis/redis_check.rb deleted file mode 100644 index c793a939abd..00000000000 --- a/lib/gitlab/health_checks/redis/redis_check.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class RedisCheck - extend SimpleAbstractCheck - - class << self - private - - def metric_prefix - 'redis_ping' - end - - def successful?(result) - result == true - end - - def check - redis_health_checks.all?(&:check_up) - end - - def redis_health_checks - [ - Gitlab::HealthChecks::Redis::CacheCheck, - Gitlab::HealthChecks::Redis::QueuesCheck, - Gitlab::HealthChecks::Redis::SharedStateCheck, - Gitlab::HealthChecks::Redis::TraceChunksCheck, - Gitlab::HealthChecks::Redis::RateLimitingCheck, - Gitlab::HealthChecks::Redis::SessionsCheck - ] - end - end - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/sessions_check.rb b/lib/gitlab/health_checks/redis/sessions_check.rb deleted file mode 100644 index 90a4c868f40..00000000000 --- a/lib/gitlab/health_checks/redis/sessions_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class SessionsCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/shared_state_check.rb b/lib/gitlab/health_checks/redis/shared_state_check.rb deleted file mode 100644 index 80f91784b8c..00000000000 --- a/lib/gitlab/health_checks/redis/shared_state_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class SharedStateCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/health_checks/redis/trace_chunks_check.rb b/lib/gitlab/health_checks/redis/trace_chunks_check.rb deleted file mode 100644 index 9a89a1ce51d..00000000000 --- a/lib/gitlab/health_checks/redis/trace_chunks_check.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module HealthChecks - module Redis - class TraceChunksCheck - extend RedisAbstractCheck - end - end - end -end diff --git a/lib/gitlab/instrumentation/redis.rb b/lib/gitlab/instrumentation/redis.rb index 4fee779c767..a371930621d 100644 --- a/lib/gitlab/instrumentation/redis.rb +++ b/lib/gitlab/instrumentation/redis.rb @@ -4,15 +4,20 @@ module Gitlab module Instrumentation # Aggregates Redis measurements from different request storage sources. class Redis + # Actioncable has it's separate instrumentation, but isn't configurable + # in the same way as all the other instances using a class. ActionCable = Class.new(RedisBase) - Cache = Class.new(RedisBase).enable_redis_cluster_validation - Queues = Class.new(RedisBase) - SharedState = Class.new(RedisBase).enable_redis_cluster_validation - TraceChunks = Class.new(RedisBase).enable_redis_cluster_validation - RateLimiting = Class.new(RedisBase).enable_redis_cluster_validation - Sessions = Class.new(RedisBase).enable_redis_cluster_validation - STORAGES = [ActionCable, Cache, Queues, SharedState, TraceChunks, RateLimiting, Sessions].freeze + STORAGES = ( + Gitlab::Redis::ALL_CLASSES.map do |redis_instance_class| + instrumentation_class = Class.new(RedisBase) + + instrumentation_class.enable_redis_cluster_validation unless redis_instance_class == Gitlab::Redis::Queues + + const_set(redis_instance_class.store_name, instrumentation_class) + instrumentation_class + end << ActionCable + ).freeze # Milliseconds represented in seconds (from 1 millisecond to 2 seconds). QUERY_TIME_BUCKETS = [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2].freeze diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb new file mode 100644 index 00000000000..8857b544364 --- /dev/null +++ b/lib/gitlab/redis.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Gitlab + module Redis + # List all Gitlab::Redis::Wrapper descendants that are backed by an actual + # separate redis instance here. + # + # This will make sure the connection pool is initialized on application boot in + # config/initializers/7_redis.rb, instrumented, and used in health- & readiness checks. + ALL_CLASSES = [ + Gitlab::Redis::Cache, + Gitlab::Redis::Queues, + Gitlab::Redis::RateLimiting, + Gitlab::Redis::Sessions, + Gitlab::Redis::SharedState, + Gitlab::Redis::TraceChunks + ].freeze + end +end diff --git a/spec/lib/gitlab/health_checks/probes/collection_spec.rb b/spec/lib/gitlab/health_checks/probes/collection_spec.rb index 3ec54642e24..f1791375cea 100644 --- a/spec/lib/gitlab/health_checks/probes/collection_spec.rb +++ b/spec/lib/gitlab/health_checks/probes/collection_spec.rb @@ -12,13 +12,7 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do let(:checks) do [ Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::Redis::RedisCheck, - Gitlab::HealthChecks::Redis::CacheCheck, - Gitlab::HealthChecks::Redis::QueuesCheck, - Gitlab::HealthChecks::Redis::SharedStateCheck, - Gitlab::HealthChecks::Redis::TraceChunksCheck, - Gitlab::HealthChecks::Redis::RateLimitingCheck, - Gitlab::HealthChecks::Redis::SessionsCheck, + *Gitlab::HealthChecks::Redis::ALL_INSTANCE_CHECKS, Gitlab::HealthChecks::GitalyCheck ] end @@ -41,8 +35,8 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do context 'when Redis fails' do before do - allow(Gitlab::HealthChecks::Redis::RedisCheck).to receive(:readiness).and_return( - Gitlab::HealthChecks::Result.new('redis_check', false, "check error")) + allow(Gitlab::HealthChecks::Redis::SharedStateCheck).to receive(:readiness).and_return( + Gitlab::HealthChecks::Result.new('shared_state_check', false, "check error")) end it 'responds with failure' do @@ -50,14 +44,14 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do expect(subject.json[:status]).to eq('failed') expect(subject.json['cache_check']).to contain_exactly(status: 'ok') - expect(subject.json['redis_check']).to contain_exactly( + expect(subject.json['shared_state_check']).to contain_exactly( status: 'failed', message: 'check error') end end context 'when check raises exception not handled inside the check' do before do - expect(Gitlab::HealthChecks::Redis::RedisCheck).to receive(:readiness).and_raise( + expect(Gitlab::HealthChecks::Redis::CacheCheck).to receive(:readiness).and_raise( ::Redis::CannotConnectError, 'Redis down') end diff --git a/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb b/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb deleted file mode 100644 index c44bd2ed585..00000000000 --- a/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::CacheCheck do - include_examples 'simple_check', 'redis_cache_ping', 'RedisCache', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb b/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb deleted file mode 100644 index 3882e7db9d9..00000000000 --- a/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::QueuesCheck do - include_examples 'simple_check', 'redis_queues_ping', 'RedisQueues', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis/rate_limiting_check_spec.rb b/spec/lib/gitlab/health_checks/redis/rate_limiting_check_spec.rb deleted file mode 100644 index 1521fc99cde..00000000000 --- a/spec/lib/gitlab/health_checks/redis/rate_limiting_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::RateLimitingCheck do - include_examples 'simple_check', 'redis_rate_limiting_ping', 'RedisRateLimiting', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb b/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb deleted file mode 100644 index 145d573b6de..00000000000 --- a/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::RedisCheck do - include_examples 'simple_check', 'redis_ping', 'Redis', true -end diff --git a/spec/lib/gitlab/health_checks/redis/sessions_check_spec.rb b/spec/lib/gitlab/health_checks/redis/sessions_check_spec.rb deleted file mode 100644 index 82b3b33ec0a..00000000000 --- a/spec/lib/gitlab/health_checks/redis/sessions_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::SessionsCheck do - include_examples 'simple_check', 'redis_sessions_ping', 'RedisSessions', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb b/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb deleted file mode 100644 index 25917741a1c..00000000000 --- a/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::SharedStateCheck do - include_examples 'simple_check', 'redis_shared_state_ping', 'RedisSharedState', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis/trace_chunks_check_spec.rb b/spec/lib/gitlab/health_checks/redis/trace_chunks_check_spec.rb deleted file mode 100644 index 5fb5232a4dd..00000000000 --- a/spec/lib/gitlab/health_checks/redis/trace_chunks_check_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../simple_check_shared' - -RSpec.describe Gitlab::HealthChecks::Redis::TraceChunksCheck do - include_examples 'simple_check', 'redis_trace_chunks_ping', 'RedisTraceChunks', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/redis_spec.rb b/spec/lib/gitlab/health_checks/redis_spec.rb new file mode 100644 index 00000000000..2460f57a9ec --- /dev/null +++ b/spec/lib/gitlab/health_checks/redis_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +require 'spec_helper' +require_relative './simple_check_shared' + +RSpec.describe Gitlab::HealthChecks::Redis do + describe "ALL_INSTANCE_CHECKS" do + subject { described_class::ALL_INSTANCE_CHECKS } + + it { is_expected.to include(described_class::CacheCheck, described_class::QueuesCheck) } + + it "contains a check for each redis instance" do + expect(subject.map(&:redis_instance_class_name)).to contain_exactly(*Gitlab::Redis::ALL_CLASSES) + end + end + + describe 'all checks' do + described_class::ALL_INSTANCE_CHECKS.each do |check| + describe check do + include_examples 'simple_check', + "redis_#{check.redis_instance_class_name.store_name.underscore}_ping", + check.redis_instance_class_name.store_name, + 'PONG' + end + end + end +end diff --git a/spec/lib/gitlab/instrumentation/redis_spec.rb b/spec/lib/gitlab/instrumentation/redis_spec.rb index 900a079cdd2..c01d06c97b0 100644 --- a/spec/lib/gitlab/instrumentation/redis_spec.rb +++ b/spec/lib/gitlab/instrumentation/redis_spec.rb @@ -71,14 +71,10 @@ RSpec.describe Gitlab::Instrumentation::Redis do stub_storages(:detail_store, [details_row]) - expect(described_class.detail_store) - .to contain_exactly(details_row.merge(storage: 'ActionCable'), - details_row.merge(storage: 'Cache'), - details_row.merge(storage: 'Queues'), - details_row.merge(storage: 'SharedState'), - details_row.merge(storage: 'TraceChunks'), - details_row.merge(storage: 'RateLimiting'), - details_row.merge(storage: 'Sessions')) + expected_detail_stores = Gitlab::Redis::ALL_CLASSES.map(&:store_name) + .map { |store_name| details_row.merge(storage: store_name) } + expected_detail_stores << details_row.merge(storage: 'ActionCable') + expect(described_class.detail_store).to contain_exactly(*expected_detail_stores) end end end diff --git a/spec/requests/api/admin/batched_background_migrations_spec.rb b/spec/requests/api/admin/batched_background_migrations_spec.rb index dce4c19b4e7..8763089488d 100644 --- a/spec/requests/api/admin/batched_background_migrations_spec.rb +++ b/spec/requests/api/admin/batched_background_migrations_spec.rb @@ -75,52 +75,4 @@ RSpec.describe API::Admin::BatchedBackgroundMigrations do end end end - - describe 'PUT /admin/batched_background_migrations/:id/resume' do - let!(:migration) { create(:batched_background_migration, :paused) } - let(:database) { :main } - - subject(:resume) do - put api("/admin/batched_background_migrations/#{migration.id}/resume", admin), params: { database: database } - end - - it 'pauses the batched background migration' do - resume - - aggregate_failures "testing response" do - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['id']).to eq(migration.id) - expect(json_response['status']).to eq('active') - end - end - - context 'when the batched background migration does not exist' do - let(:params) { { database: database } } - - it 'returns 404' do - put api("/admin/batched_background_migrations/#{non_existing_record_id}/pause", admin), params: params - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - context 'when multiple database is enabled', :add_ci_connection do - let(:ci_model) { Ci::ApplicationRecord } - let(:database) { :ci } - - it 'uses the correct connection' do - expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(ci_model.connection).and_yield - - resume - end - end - - context 'when authenticated as a non-admin user' do - it 'returns 403' do - get api('/admin/batched_background_migrations', unauthorized_user) - - expect(response).to have_gitlab_http_status(:forbidden) - end - end - end end diff --git a/spec/requests/health_controller_spec.rb b/spec/requests/health_controller_spec.rb index fb1c0f85215..ae15b63df19 100644 --- a/spec/requests/health_controller_spec.rb +++ b/spec/requests/health_controller_spec.rb @@ -142,19 +142,29 @@ RSpec.describe HealthController do end it 'responds with readiness checks data when a failure happens' do - allow(Gitlab::HealthChecks::Redis::RedisCheck).to receive(:readiness).and_return( - Gitlab::HealthChecks::Result.new('redis_check', false, "check error")) + allow(Gitlab::HealthChecks::Redis::SharedStateCheck).to receive(:readiness).and_return( + Gitlab::HealthChecks::Result.new('shared_state_check', false, "check error")) subject expect(json_response['cache_check']).to contain_exactly({ 'status' => 'ok' }) - expect(json_response['redis_check']).to contain_exactly( + expect(json_response['shared_state_check']).to contain_exactly( { 'status' => 'failed', 'message' => 'check error' }) expect(response).to have_gitlab_http_status(:service_unavailable) expect(response.headers['X-GitLab-Custom-Error']).to eq(1) end + it 'checks all redis instances' do + expected_redis_checks = Gitlab::Redis::ALL_CLASSES.map do |redis| + { "#{redis.store_name.underscore}_check" => [{ 'status' => 'ok' }] } + end + + subject + + expect(json_response).to include(*expected_redis_checks) + end + context 'when DB is not accessible and connection raises an exception' do before do expect(Gitlab::HealthChecks::DbCheck) @@ -174,7 +184,7 @@ RSpec.describe HealthController do context 'when any exception happens during the probing' do before do - expect(Gitlab::HealthChecks::Redis::RedisCheck) + expect(Gitlab::HealthChecks::Redis::CacheCheck) .to receive(:readiness) .and_raise(::Redis::CannotConnectError, 'Redis down') end diff --git a/spec/support/redis.rb b/spec/support/redis.rb index 421079af8e0..d00d6562966 100644 --- a/spec/support/redis.rb +++ b/spec/support/redis.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +require 'gitlab/redis' RSpec.configure do |config| config.after(:each, :redis) do @@ -7,51 +8,15 @@ RSpec.configure do |config| end end - config.around(:each, :clean_gitlab_redis_cache) do |example| - redis_cache_cleanup! + Gitlab::Redis::ALL_CLASSES.each do |instance_class| + underscored_name = instance_class.store_name.underscore - example.run + config.around(:each, :"clean_gitlab_redis_#{underscored_name}") do |example| + public_send("redis_#{underscored_name}_cleanup!") - redis_cache_cleanup! - end + example.run - config.around(:each, :clean_gitlab_redis_shared_state) do |example| - redis_shared_state_cleanup! - - example.run - - redis_shared_state_cleanup! - end - - config.around(:each, :clean_gitlab_redis_queues) do |example| - redis_queues_cleanup! - - example.run - - redis_queues_cleanup! - end - - config.around(:each, :clean_gitlab_redis_trace_chunks) do |example| - redis_trace_chunks_cleanup! - - example.run - - redis_trace_chunks_cleanup! - end - - config.around(:each, :clean_gitlab_redis_rate_limiting) do |example| - redis_rate_limiting_cleanup! - - example.run - - redis_rate_limiting_cleanup! - end - - config.around(:each, :clean_gitlab_redis_sessions) do |example| - redis_sessions_cleanup! - - example.run - - redis_sessions_cleanup! + public_send("redis_#{underscored_name}_cleanup!") + end end end diff --git a/spec/support/redis/redis_helpers.rb b/spec/support/redis/redis_helpers.rb index 90c15dea1f8..34ac69236ee 100644 --- a/spec/support/redis/redis_helpers.rb +++ b/spec/support/redis/redis_helpers.rb @@ -1,36 +1,10 @@ # frozen_string_literal: true module RedisHelpers - # config/README.md - - # Usage: performance enhancement - def redis_cache_cleanup! - Gitlab::Redis::Cache.with(&:flushdb) - end - - # Usage: SideKiq, Mailroom, CI Runner, Workhorse, push services - def redis_queues_cleanup! - Gitlab::Redis::Queues.with(&:flushdb) - end - - # Usage: session state, rate limiting - def redis_shared_state_cleanup! - Gitlab::Redis::SharedState.with(&:flushdb) - end - - # Usage: CI trace chunks - def redis_trace_chunks_cleanup! - Gitlab::Redis::TraceChunks.with(&:flushdb) - end - - # Usage: rate limiting state (for Rack::Attack) - def redis_rate_limiting_cleanup! - Gitlab::Redis::RateLimiting.with(&:flushdb) - end - - # Usage: session state - def redis_sessions_cleanup! - Gitlab::Redis::Sessions.with(&:flushdb) + Gitlab::Redis::ALL_CLASSES.each do |instance_class| + define_method("redis_#{instance_class.store_name.underscore}_cleanup!") do + instance_class.with(&:flushdb) + end end # Usage: reset cached instance config