Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-06-06 15:15:10 +00:00
parent d8ee0721db
commit 9b5bb10544
47 changed files with 530 additions and 171 deletions

View File

@ -176,18 +176,6 @@ variables:
GET_SOURCES_ATTEMPTS: "3"
# CI_FETCH_REPO_GIT_STRATEGY: "none" is from artifacts. "clone" is from cloning
CI_FETCH_REPO_GIT_STRATEGY: "none"
BUILD_OS: "debian"
OS_VERSION: "bookworm"
UBI_VERSION: "8.6"
CHROME_VERSION: "123"
DOCKER_VERSION: "24.0.5"
RUBYGEMS_VERSION: "3.4"
BUNDLER_VERSION: "2.5"
GO_VERSION: "1.22"
NODE_VERSION: "20.12"
RUST_VERSION: "1.73"
RUBY_VERSION_DEFAULT: "3.1.5"
RUBY_VERSION_NEXT: "3.2.4"
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec/flaky/report-suite.json
FRONTEND_FIXTURES_MAPPING_PATH: crystalball/frontend_fixtures_mapping.json
@ -254,6 +242,7 @@ include:
- local: .gitlab/ci/_skip.yml
rules:
- <<: *if-merge-request-security-canonical-sync
- local: .gitlab/ci/version.yml
- local: .gitlab/ci/*.gitlab-ci.yml
rules:
- <<: *if-not-security-canonical-sync

View File

@ -5,7 +5,7 @@ workflow:
name: $PIPELINE_NAME
include:
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.10.0"
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.15.0"
inputs:
job_name: "e2e-test-report"
job_stage: "report"
@ -15,7 +15,7 @@ include:
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
allure_job_name: "${QA_RUN_TYPE}"
- project: gitlab-org/quality/pipeline-common
ref: 8.10.0
ref: 8.15.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml

13
.gitlab/ci/version.yml Normal file
View File

@ -0,0 +1,13 @@
variables:
BUILD_OS: "debian"
OS_VERSION: "bookworm"
UBI_VERSION: "8.6"
CHROME_VERSION: "123"
DOCKER_VERSION: "24.0.5"
RUBYGEMS_VERSION: "3.4"
BUNDLER_VERSION: "2.5"
GO_VERSION: "1.22"
NODE_VERSION: "20.12"
RUST_VERSION: "1.73"
RUBY_VERSION_DEFAULT: "3.1.5"
RUBY_VERSION_NEXT: "3.2.4"

View File

@ -575,17 +575,17 @@
{"name":"rouge","version":"4.2.0","platform":"ruby","checksum":"60dd666b3a223467dc72f5b7384764dfd7ad4e50b0df9eff072be58123506eba"},
{"name":"rqrcode","version":"2.2.0","platform":"ruby","checksum":"23eea88bb44c7ee6d6cab9354d08c287f7ebcdc6112e1fe7bcc2d010d1ffefc1"},
{"name":"rqrcode_core","version":"1.2.0","platform":"ruby","checksum":"cf4989dc82d24e2877984738c4ee569308625fed2a810960f1b02d68d0308d1a"},
{"name":"rspec","version":"3.13.0","platform":"ruby","checksum":"d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993"},
{"name":"rspec","version":"3.12.0","platform":"ruby","checksum":"ccc41799a43509dc0be84070e3f0410ac95cbd480ae7b6c245543eb64162399c"},
{"name":"rspec-benchmark","version":"0.6.0","platform":"ruby","checksum":"1014adb57ec2599a2455c63884229f367a2fff6a63a77fd68ce5d804c83dd6cf"},
{"name":"rspec-core","version":"3.13.0","platform":"ruby","checksum":"557792b4e88da883d580342b263d9652b6a10a12d5bda9ef967b01a48f15454c"},
{"name":"rspec-expectations","version":"3.13.0","platform":"ruby","checksum":"621d48c62262f955421eaa418130744760802cad47e781df70dba4d9f897102e"},
{"name":"rspec-mocks","version":"3.13.1","platform":"ruby","checksum":"087189899c337937bcf1d66a50dc3fc999ac88335bbeba4d385c2a38c87d7b38"},
{"name":"rspec-core","version":"3.12.2","platform":"ruby","checksum":"155b54480f28e2b2813185077fe435c2d663031616360ed3b179a9d6a55d2551"},
{"name":"rspec-expectations","version":"3.12.3","platform":"ruby","checksum":"093d18e2e7e0a2c619ef8f7343d442fc6c0793fb7897d56f16f26c8a9d244416"},
{"name":"rspec-mocks","version":"3.12.6","platform":"ruby","checksum":"de51a4148ba2ce6f1c1646a2a03e9df2f52da9a42b164f2e7467b2cbe37e07bf"},
{"name":"rspec-parameterized","version":"1.0.2","platform":"ruby","checksum":"b456dec0091924175ac13963e173cdbaa2ab3e1581a405a948addc34e3f3f4c2"},
{"name":"rspec-parameterized-core","version":"1.0.0","platform":"ruby","checksum":"287b494985e79821160af63aba4f91db8dbfa9a21cb200db34ba38f40e16ccc1"},
{"name":"rspec-parameterized-table_syntax","version":"1.0.0","platform":"ruby","checksum":"d7df951eff9c5dd367ca7d5f9ae4853bb7ab7941f9d5b35bba361d112704988c"},
{"name":"rspec-rails","version":"6.1.2","platform":"ruby","checksum":"02874ab2e3b09001742af389c48739bed8706943e453afaea5e12614a83b990b"},
{"name":"rspec-rails","version":"6.1.1","platform":"ruby","checksum":"bd949e61f89379f410ea1e43133163282f8d977c683ce6d10bf5aef6b1e995b2"},
{"name":"rspec-retry","version":"0.6.2","platform":"ruby","checksum":"6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858"},
{"name":"rspec-support","version":"3.13.1","platform":"ruby","checksum":"48877d4f15b772b7538f3693c22225f2eda490ba65a0515c4e7cf6f2f17de70f"},
{"name":"rspec-support","version":"3.12.0","platform":"ruby","checksum":"dd4d44b247ff679b95b5607ac5641d197a5f9b1d33f916123cb98fc5f917c58b"},
{"name":"rspec_junit_formatter","version":"0.6.0","platform":"ruby","checksum":"40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15"},
{"name":"rspec_profiling","version":"0.0.9","platform":"ruby","checksum":"6199be2daeaa14bac3d10d704dbb0a8df052cf046332c505603263aea24f7590"},
{"name":"rubocop","version":"1.62.1","platform":"ruby","checksum":"aeb1ec501aef5833617b3b6a1512303806218c349c28ce5b3ea72e3782ad4a35"},

View File

@ -1525,23 +1525,23 @@ GEM
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-benchmark (0.6.0)
benchmark-malloc (~> 0.2)
benchmark-perf (~> 0.6)
benchmark-trend (~> 0.4)
rspec (>= 3.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.1)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-support (~> 3.12.0)
rspec-parameterized (1.0.2)
rspec-parameterized-core (< 2)
rspec-parameterized-table_syntax (< 2)
@ -1553,17 +1553,17 @@ GEM
rspec-parameterized-table_syntax (1.0.0)
binding_of_caller
rspec-parameterized-core (< 2)
rspec-rails (6.1.2)
rspec-rails (6.1.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-core (~> 3.12)
rspec-expectations (~> 3.12)
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.13.1)
rspec-support (3.12.0)
rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0)
rspec_profiling (0.0.9)

View File

@ -0,0 +1,35 @@
# Pipeline Mini Graph
This documentation serves as a usage guide for the Pipeline Mini Graph. The Pipeline Mini Graph is used in various places throughout the platform to communicate to users the status of the relevant pipeline. Users are able to re-run jobs directly from the component or drilldown into said jobs and linked pipelines for further investigation.
The [architecture blueprint for the Pipeline Mini Graph](https://docs.gitlab.com/ee/architecture/blueprints/pipeline_mini_graph/) is available for more context. Furthermore, if you have questions about implementation of this component, please reach out to @gitlab-com/pipeline-authoring-group/frontend in your issue or MR.
## Usage
This component can be instantiated by apps supporting either REST or GraphQL
### REST Structure
This is the current version of the component used by all apps in production. The parent component lives at `app/assets/javascripts/ci/pipeline_mini_graph/legacy_pipeline_mini_graph/legacy_pipeline_mini_graph.vue`. The legacy component needs all necessary pipeline data passed into it. [This data is fetched by apps via REST endpoint](https://docs.gitlab.com/ee/api/pipelines.html#get-a-single-pipeline). To use, import this component into your code and send the following props:
| Name | Type | Required | Description |
| ---- | ---- | -------- | ----------- |
|`downstreamPipelines` | Array | false | pipelines triggered by current pipeline |
|`isMergeTrain` | Boolean | false | whether the pipeline is part of a merge train |
|`pipelinePath` | String | false | pipeline URL |
|`stages` | Array | true | stages of current pipeline |
|`updateDropdown` | Boolean | false | whether to fetch jobs when the dropdown is open |
|`upstreamPipeline` | Object | false | upstream pipeline which triggered current pipeline |
### GraphQL Structure
Note: This component currently exists behind a feature flag `ci_graphql_pipeline_mini_graph` and is under construction.
The parent component lives at`app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue`. This instance of the pipeline mini graph has self-managed data. [We use GraphQL to query for pipeline data within the component](https://docs.gitlab.com/ee/api/graphql/reference/#pipeline). It needs only the fields necessary to query for the data. To use, import this component into your code and send the following props:
| Name | Type | Required | Description |
| ---- | ---- | -------- | ----------- |
|`fullPath` | String | true | full path of the project for the queries |
|`iid` | String | true | pipeline iid for the queries |
|`isMergeTrain` | Boolean | false | whether the pipeline is part of a merge train (under consideration) |
|`pipelineEtag` | String | true | etag for caching (under consideration) |
|`pollInterval` | Number | false | interval for polling updates |

View File

@ -77,7 +77,7 @@
}
.sidebar-container {
padding: $gl-padding 0;
padding: 20px 0;
padding-right: 100px;
height: 100%;
overflow-y: scroll;
@ -100,7 +100,7 @@
&:hover {
a {
color: $black;
color: var(--black, $black);
}
}

View File

@ -1,8 +0,0 @@
---
name: github_import_lock_user_finder
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141826
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/438336
milestone: '16.9'
type: development
group: group::import and integrate
default_enabled: false

View File

@ -1,7 +1,6 @@
- title: "Single database connection is deprecated"
announcement_milestone: "15.9"
end_of_support_milestone: "17.0"
removal_milestone: "18.0"
removal_milestone: "19.0"
breaking_change: true
reporter: tkuah
stage: Enablement

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillDastPreScanVerificationsProjectId
description: Backfills sharding key `dast_pre_scan_verifications.project_id` from `dast_profiles`.
feature_category: dynamic_application_security_testing
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155076
milestone: '17.1'
queued_migration_version: 20240603121642
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -4,7 +4,7 @@ classes:
- Ci::Minutes::AdditionalPack
feature_categories:
- consumables_cost_management
description: Stores CI minutes purchases for a given namespace with fields for synchronizing
description: Stores compute minutes purchases for a given namespace with fields for synchronizing
and expiring available minutes between Customers Portal and GitLab.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62393
milestone: '14.0'

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: dast_profiles
sharding_key: project_id
belongs_to: dast_profile
desired_sharding_key_migration_job_name: BackfillDastPreScanVerificationsProjectId

View File

@ -4,7 +4,7 @@ classes:
- NamespaceStatistics
feature_categories:
- consumables_cost_management
description: Stores usage statistics for both CI minutes and a limited set of storage types for a given namespace. This should not be confused with namespace_root_storage_statistics table which holds statistics across more storage types for a group.
description: Stores usage statistics for both compute minutes and a limited set of storage types for a given namespace. This should not be confused with namespace_root_storage_statistics table which holds statistics across more storage types for a group.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/965
milestone: '9.0'
gitlab_schema: gitlab_main_cell

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddProjectIdToDastPreScanVerifications < Gitlab::Database::Migration[2.2]
milestone '17.1'
def change
add_column :dast_pre_scan_verifications, :project_id, :bigint
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexDastPreScanVerificationsOnProjectId < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
INDEX_NAME = 'index_dast_pre_scan_verifications_on_project_id'
def up
add_concurrent_index :dast_pre_scan_verifications, :project_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :dast_pre_scan_verifications, INDEX_NAME
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddDastPreScanVerificationsProjectIdFk < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :dast_pre_scan_verifications, :projects, column: :project_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :dast_pre_scan_verifications, column: :project_id
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class AddDastPreScanVerificationsProjectIdTrigger < Gitlab::Database::Migration[2.2]
milestone '17.1'
def up
install_sharding_key_assignment_trigger(
table: :dast_pre_scan_verifications,
sharding_key: :project_id,
parent_table: :dast_profiles,
parent_sharding_key: :project_id,
foreign_key: :dast_profile_id
)
end
def down
remove_sharding_key_assignment_trigger(
table: :dast_pre_scan_verifications,
sharding_key: :project_id,
parent_table: :dast_profiles,
parent_sharding_key: :project_id,
foreign_key: :dast_profile_id
)
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class QueueBackfillDastPreScanVerificationsProjectId < Gitlab::Database::Migration[2.2]
milestone '17.1'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
MIGRATION = "BackfillDastPreScanVerificationsProjectId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:dast_pre_scan_verifications,
:id,
:project_id,
:dast_profiles,
:project_id,
:dast_profile_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:dast_pre_scan_verifications,
:id,
[
:project_id,
:dast_profiles,
:project_id,
:dast_profile_id
]
)
end
end

View File

@ -0,0 +1 @@
2e47913d93f71ab057ba65fe012320959140e2fcef1e73f15e5927298ee19911

View File

@ -0,0 +1 @@
87f4bc2809d2259e70fe3b09da62faeac67aaf6440e06fea3d392791a165e1f3

View File

@ -0,0 +1 @@
c6e3a11fe9779674a739f36f2f7c40d0707b7d59cdae2f4cdc71826b5de4389a

View File

@ -0,0 +1 @@
45f9e4bbf28e5f47d0af5700760756c478bf20f6ee1ee04564b1699f237651a9

View File

@ -0,0 +1 @@
5ff679739fbce0653dc0aa73d369874f2386fd04b706bee152c07717db08695f

View File

@ -1185,6 +1185,22 @@ RETURN NEW;
END
$$;
CREATE FUNCTION trigger_c5eec113ea76() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW."project_id" IS NULL THEN
SELECT "project_id"
INTO NEW."project_id"
FROM "dast_profiles"
WHERE "dast_profiles"."id" = NEW."dast_profile_id";
END IF;
RETURN NEW;
END
$$;
CREATE FUNCTION trigger_c8bc8646bce9() RETURNS trigger
LANGUAGE plpgsql
AS $$
@ -8371,7 +8387,8 @@ CREATE TABLE dast_pre_scan_verifications (
ci_pipeline_id bigint,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
status smallint DEFAULT 0 NOT NULL
status smallint DEFAULT 0 NOT NULL,
project_id bigint
);
CREATE SEQUENCE dast_pre_scan_verifications_id_seq
@ -25940,6 +25957,8 @@ CREATE UNIQUE INDEX index_dast_pre_scan_verifications_on_ci_pipeline_id ON dast_
CREATE INDEX index_dast_pre_scan_verifications_on_dast_profile_id ON dast_pre_scan_verifications USING btree (dast_profile_id);
CREATE INDEX index_dast_pre_scan_verifications_on_project_id ON dast_pre_scan_verifications USING btree (project_id);
CREATE INDEX index_dast_profile_schedules_active_next_run_at ON dast_profile_schedules USING btree (active, next_run_at);
CREATE UNIQUE INDEX index_dast_profile_schedules_on_dast_profile_id ON dast_profile_schedules USING btree (dast_profile_id);
@ -30650,6 +30669,8 @@ CREATE TRIGGER trigger_b4520c29ea74 BEFORE INSERT OR UPDATE ON approval_merge_re
CREATE TRIGGER trigger_c17a166692a2 BEFORE INSERT OR UPDATE ON audit_events_streaming_headers FOR EACH ROW EXECUTE FUNCTION trigger_c17a166692a2();
CREATE TRIGGER trigger_c5eec113ea76 BEFORE INSERT OR UPDATE ON dast_pre_scan_verifications FOR EACH ROW EXECUTE FUNCTION trigger_c5eec113ea76();
CREATE TRIGGER trigger_c8bc8646bce9 BEFORE INSERT OR UPDATE ON vulnerability_state_transitions FOR EACH ROW EXECUTE FUNCTION trigger_c8bc8646bce9();
CREATE TRIGGER trigger_c9090feed334 BEFORE INSERT OR UPDATE ON boards_epic_lists FOR EACH ROW EXECUTE FUNCTION trigger_c9090feed334();
@ -31752,6 +31773,9 @@ ALTER TABLE ONLY project_mirror_data
ALTER TABLE ONLY environments
ADD CONSTRAINT fk_d1c8c1da6a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY dast_pre_scan_verifications
ADD CONSTRAINT fk_d23ad33d6e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE p_ci_builds
ADD CONSTRAINT fk_d3130c9a7f FOREIGN KEY (commit_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;

View File

@ -41,6 +41,7 @@ databases. Some examples:
- Once data is migrated to the `ci` database, you cannot migrate it back.
- Significant downtime is expected for larger installations (database sizes of more 100 GB).
- Running two databases [is not yet supported with Geo](https://gitlab.com/groups/gitlab-org/-/epics/8631).
## Migrate existing installations using a script

View File

@ -71,6 +71,27 @@ This change provides additional scalability for the largest of GitLab instances,
This change applies to all installation methods: Omnibus GitLab, GitLab Helm chart, GitLab Operator, GitLab Docker images, and installation from source.
Before upgrading to GitLab 19.0, please ensure you have [migrated](https://docs.gitlab.com/ee/administration/postgresql/multiple_databases.html) to two databases.
</div>
<div class="deprecation breaking-change" data-milestone="19.0">
### Single database connection is deprecated
<div class="deprecation-notes">
- Announced in GitLab <span class="milestone">15.9</span>
- Removal in GitLab <span class="milestone">19.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/387898).
</div>
Previously, [GitLab's database](https://docs.gitlab.com/omnibus/settings/database.html)
configuration had a single `main:` section. This is being deprecated. The new
configuration has both a `main:` and a `ci:` section.
This deprecation affects users compiling GitLab from source, who will need
to [add the `ci:` section](https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings).
Omnibus, the Helm chart, and Operator will handle this configuration
automatically from GitLab 16.0 onwards.
</div>
</div>
@ -501,28 +522,6 @@ For updates and details about this deprecation, follow [this epic](https://gitla
<div class="deprecation breaking-change" data-milestone="18.0">
### Single database connection is deprecated
<div class="deprecation-notes">
- Announced in GitLab <span class="milestone">15.9</span>
- End of Support in GitLab <span class="milestone">17.0</span>
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/387898).
</div>
Previously, [GitLab's database](https://docs.gitlab.com/omnibus/settings/database.html)
configuration had a single `main:` section. This is being deprecated. The new
configuration has both a `main:` and a `ci:` section.
This deprecation affects users compiling GitLab from source, who will need
to [add the `ci:` section](https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings).
Omnibus, the Helm chart, and Operator will handle this configuration
automatically from GitLab 16.0 onwards.
</div>
<div class="deprecation breaking-change" data-milestone="18.0">
### Slack notifications integration
<div class="deprecation-notes">

View File

@ -25,10 +25,7 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f
Perform the [workaround](#undefined-column-error-upgrading-to-162-or-later) before upgrading to 16.x.
- Starting with 16.0, GitLab self-managed installations now have two database connections by default, instead of one. This change doubles the number of PostgreSQL connections. It makes self-managed versions of GitLab behave similarly to GitLab.com, and is a step toward enabling a separate database for CI features for self-managed versions of GitLab. Before upgrading to 16.0, determine if you need to [increase max connections for PostgreSQL](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
- This change applies to installation methods with Linux packages (Omnibus), GitLab Helm chart, GitLab Operator, GitLab Docker images, and self-compiled installations.
- The second database connection can be disabled:
- [Linux package and Docker installations](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
- [Helm chart and GitLab Operator installations](https://docs.gitlab.com/charts/charts/globals.html#configure-multiple-database-connections).
- [Self-compiled installations](../../install/installation.md#configure-gitlab-db-settings).
- [The second database connection can be disabled](#disable-the-second-database-connection).
- Most installations can skip 16.0, 16.1, and 16.2, as the first required stop on the upgrade path is 16.3.
In all cases, you should review the notes for those intermediate versions.
@ -1575,6 +1572,53 @@ praefect['configuration'] = {
}
```
### Disable the second database connection
In GitLab 16.0, GitLab defaults to using two database connections that point to the same PostgreSQL database.
PostgreSQL might need to be configured with a larger value for `max_connections`.
[There is a Rake task for checking if this is necessary](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
If you have PgBouncer deployed:
- The frontend pools (including file handle limits and `max_client_conn`) on your PgBouncer servers [might need to be larger](../../administration/postgresql/pgbouncer.md#fine-tuning).
- PgBouncer is single threaded. The extra connections might fully saturate a single PgBouncer daemon.
[We recommend running three load-balanced PgBouncer servers](../../administration/reference_architectures/5k_users.md#configure-pgbouncer) for all
scaled GitLab deployments, in part to address this issue.
Follow the instructions for your installation type to switch back to a single database connection:
::Tabs
:::TabTitle Linux package and Docker
1. Add this setting to `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['databases']['ci']['enable'] = false
```
1. Run `gitlab-ctl reconfigure`.
In a multi-node environment, this setting should be updated on all Rails and Sidekiq nodes.
:::TabTitle Helm chart (Kubernetes)
Set the `ci.enabled` key to `false`:
```yaml
global:
psql:
ci:
enabled: false
```
:::TabTitle Self-compiled (source)
Remove the `ci:` section from `config/database.yml`.
::EndTabs
## Long-running user type data change
GitLab 16.0 is a required stop for large GitLab instances with a lot of records in the `users` table.

View File

@ -142,7 +142,7 @@ You need at least the Developer role to edit a wiki page:
1. Select **Plan > Wiki**.
1. Go to the page you want to edit, and either:
- Use the <kbd>e</kbd> wiki [keyboard shortcut](../../shortcuts.md#wiki-pages).
- Select the edit icon (**{pencil}**).
- Select **Edit**.
1. Edit the content.
1. Select **Save changes**.
@ -162,11 +162,13 @@ Prerequisites:
1. On the left sidebar, select **Search or go to** and find your project or group.
1. Select **Plan > Wiki**.
1. Go to the page you want to delete.
1. Select the edit icon (**{pencil}**).
1. Select **Edit**.
1. Select **Delete page**.
1. Confirm the deletion.
## Move a wiki page
## Move or rename a wiki page
> - [Support for redirecting pages on move or rename](https://gitlab.com/gitlab-org/gitlab/-/issues/257892) added in GitLab 17.1 [with a flag](../../../administration/feature_flags.md) named `wiki_redirection`. Enabled by default.
Prerequisites:
@ -174,13 +176,18 @@ Prerequisites:
1. On the left sidebar, select **Search or go to** and find your project or group.
1. Select **Plan > Wiki**.
1. Go to the page you want to move.
1. Select the edit icon (**{pencil}**).
1. Add the new path to the **Title** field. For example, if you have a wiki page
called `about` under `company` and you want to move it to the wiki's root,
change the **Title** from `about` to `/about`.
1. Go to the page you want to move or rename.
1. Select **Edit**.
1. To move the page, add the new path to the **Title** field. For example,
if you have a wiki page called `About` under `Company` and you want to
move it to the wiki's root, change the **Title** from `About` to `/About`.
1. To rename the page, change the **Title**.
1. Select **Save changes**.
In GitLab 17.1 and later, when you move or rename a page, a redirect is
automatically set up from the old page to the new page. A list of redirects
is stored in the `.gitlab/redirects.yml` file in the Wiki repository.
## Export a wiki page
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/414691) in GitLab 16.3 [with a flag](../../../administration/feature_flags.md) named `print_wiki`. Disabled by default.

View File

@ -27,11 +27,12 @@ variables:
GIT_STRATEGY: "clone"
GIT_SUBMODULE_STRATEGY: "none"
GET_SOURCES_ATTEMPTS: "3"
RUBY_VERSION_DEFAULT: "3.1.5"
RUBY_VERSION_NEXT: "3.2.4"
# Default Ruby version for jobs that don't use .ruby_matrix
RUBY_VERSION: "${RUBY_VERSION_DEFAULT}"
include:
- local: .gitlab/ci/version.yml
default:
tags:
- gitlab-org

View File

@ -27,11 +27,12 @@ variables:
GIT_STRATEGY: "clone"
GIT_SUBMODULE_STRATEGY: "none"
GET_SOURCES_ATTEMPTS: "3"
RUBY_VERSION_DEFAULT: "3.1.5"
RUBY_VERSION_NEXT: "3.2.4"
# Default Ruby version for jobs that don't use .ruby_matrix
RUBY_VERSION: "${RUBY_VERSION_DEFAULT}"
include:
- local: .gitlab/ci/version.yml
default:
tags:
- gitlab-org

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillDastPreScanVerificationsProjectId < BackfillDesiredShardingKeyJob
operation_name :backfill_dast_pre_scan_verifications_project_id
feature_category :dynamic_application_security_testing
end
end
end

View File

@ -130,7 +130,7 @@ module Gitlab
email = read_email_from_cache(username)
if email.blank? && !email_fetched_for_project?(username)
feature_flag_in_lock(lease_key(username), sleep_sec: 0.2.seconds, retries: 30) do |retried|
in_lock(lease_key(username), sleep_sec: 0.2.seconds, retries: 30) do |retried|
# when retried, check the cache again as the other process that had the lease may have fetched the email
if retried
email = read_email_from_cache(username)
@ -306,14 +306,6 @@ module Gitlab
message: message
)
end
def feature_flag_in_lock(lease_key, sleep_sec:, retries:)
return yield(false) if Feature.disabled?(:github_import_lock_user_finder, project.creator)
in_lock(lease_key, sleep_sec: sleep_sec, retries: retries) do |retried|
yield(retried)
end
end
end
end
end

View File

@ -11,7 +11,7 @@ import {
darkModeTokenToHex,
mismatchAllowList,
} from './lib/tailwind_migration.mjs';
import { convertUtilsToCSSInJS } from './tailwind_all_the_way.mjs';
import { convertUtilsToCSSInJS, toMinimalUtilities } from './tailwind_all_the_way.mjs';
function darkModeResolver(str) {
return str.replace(
@ -26,10 +26,10 @@ function darkModeResolver(str) {
);
}
function compareApplicationUtilsToTailwind(appUtils, tailWind, colorResolver) {
function compareApplicationUtilsToTailwind(appUtils, tailwindCSS, colorResolver) {
let fail = 0;
const tailwind = extractRules(tailWind);
const tailwind = extractRules(tailwindCSS);
Object.keys(appUtils).forEach((selector) => {
if (mismatchAllowList.includes(selector)) {
@ -50,9 +50,33 @@ function compareApplicationUtilsToTailwind(appUtils, tailWind, colorResolver) {
});
if (fail) {
console.log(`${fail} selectors failed`);
process.exitCode = 1;
console.log(`\t${fail} selectors failed`);
} else {
console.log('\tAll good');
}
return fail;
}
function ensureNoLegacyUtilIsUsedWithATailwindModifier(minimalUtils) {
let fail = 0;
for (const [key, value] of Object.entries(minimalUtils)) {
if (key.startsWith('.\\!')) {
console.warn('Using legacy util with important modifier. This is not supported.');
console.warn(`Please migrate ${key} to a proper tailwind util.`);
fail += 1;
}
if (key.endsWith('\\')) {
console.warn(`Using legacy util with ${key} modifier. This is not supported.`);
console.warn(`Please migrate the following classes to a proper tailwind util:`);
console.warn(JSON.stringify(value, null, 2).replace(/^/gm, ' '.repeat(4)));
fail += 1;
}
}
if (fail) {
console.log(`\t${fail} legacy utils with modifiers found`);
}
return fail;
}
console.log('# Converting legacy styles to CSS-in-JS definitions');
@ -64,6 +88,8 @@ if (stats.hardcodedColors || stats.potentialMismatches) {
process.exitCode = 1;
}
let failures = 0;
console.log('# Comparing tailwind to legacy utils');
const applicationUtilsLight = extractRules(
@ -77,6 +103,20 @@ const applicationUtilsDark = extractRules(
const tailwind = loadCSSFromFile('app/assets/builds/tailwind.css');
console.log('## Comparing tailwind light mode');
compareApplicationUtilsToTailwind(applicationUtilsLight, tailwind);
failures += compareApplicationUtilsToTailwind(applicationUtilsLight, tailwind);
console.log('## Comparing tailwind dark mode');
compareApplicationUtilsToTailwind(applicationUtilsDark, tailwind, darkModeResolver);
failures += compareApplicationUtilsToTailwind(applicationUtilsDark, tailwind, darkModeResolver);
console.log('# Checking whether legacy GitLab utility classes are used with tailwind modifiers');
console.log('## Reducing utility definitions to minimally used');
const { rules } = await toMinimalUtilities();
console.log('## Running checks');
failures += ensureNoLegacyUtilIsUsedWithATailwindModifier(rules);
if (failures) {
process.exitCode = 1;
} else {
console.log('# All good Happiness. May the tailwind boost your journey');
}

View File

@ -136,7 +136,7 @@ const hardCodedColors = ${JSON.stringify(hardcodedColors, null, 2)};
/**
* Writes only the style definitions we actually need.
*/
async function toMinimalUtilities() {
export async function toMinimalUtilities() {
// We re-import the config with a `?minimal` query in order to cache-bust
// the previously loaded config, which doesn't have the latest css_in_js
const { default: tailwindConfig } = await import('../../config/tailwind.config.js?minimal');
@ -166,7 +166,7 @@ async function toMinimalUtilities() {
*/
module.exports = ${JSON.stringify(rules)}`);
return { minimalUtils };
return { minimalUtils, rules };
}
/**

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillDastPreScanVerificationsProjectId,
feature_category: :dynamic_application_security_testing,
schema: 20240603121638 do
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :dast_pre_scan_verifications }
let(:backfill_column) { :project_id }
let(:backfill_via_table) { :dast_profiles }
let(:backfill_via_column) { :project_id }
let(:backfill_via_foreign_key) { :dast_profile_id }
end
end

View File

@ -313,19 +313,6 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_shared_stat
email_for_github_username
end
context 'when github_import_lock_user_finder feature flag is disabled' do
before do
stub_feature_flags(github_import_lock_user_finder: false)
end
it 'does not lock the finder' do
expect(finder).not_to receive(:in_lock)
expect(client).to receive(:user)
email_for_github_username
end
end
context 'if the response contains an email' do
before do
allow(client).to receive(:user).and_return({ email: email })

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe QueueBackfillDastPreScanVerificationsProjectId, feature_category: :dynamic_application_security_testing do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
reversible_migration do |migration|
migration.before -> {
expect(batched_migration).not_to have_scheduled_batched_migration
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
table_name: :dast_pre_scan_verifications,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE,
gitlab_schema: :gitlab_main_cell,
job_arguments: [
:project_id,
:dast_profiles,
:project_id,
:dast_profile_id
]
)
}
end
end
end

View File

@ -9,4 +9,4 @@ rspec:
- bundle exec rake test
parallel:
matrix:
- RUBY_VERSION: ["3.1.5", "3.2.4"]
- RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]

View File

@ -9,4 +9,4 @@ rspec:
- rake test
parallel:
matrix:
- RUBY_VERSION: ["3.1.5", "3.2.4"]
- RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]

View File

@ -11,7 +11,7 @@ rspec:
- .with_redis
parallel:
matrix:
- RUBY_VERSION: ["3.1.5", "3.2.4"]
- RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]
REDIS_VERSION: ["6.0", "6.2", "7.0"]
.with_redis:

View File

@ -9,7 +9,7 @@ rspec:
- .with_redis
parallel:
matrix:
- RUBY_VERSION: ["3.1.5"] # 3.2 isn't supported yet
- RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}"] # 3.2 isn't supported yet
.with_redis:
services:

View File

@ -9,8 +9,8 @@ cmd/gitlab-workhorse/authorization_test.go:114:3: go-require: do not use require
cmd/gitlab-workhorse/authorization_test.go:115:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:116:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:120:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/config_test.go:189: cmd/gitlab-workhorse/config_test.go:189: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
cmd/gitlab-workhorse/config_test.go:331:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/config_test.go:191: cmd/gitlab-workhorse/config_test.go:191: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
cmd/gitlab-workhorse/config_test.go:333:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/jobs_test.go:37:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/jobs_test.go:42:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/listener.go:34:16: G402: TLS MinVersion too low. (gosec)
@ -164,21 +164,21 @@ internal/config/config.go:84:6: exported: exported type GoCloudConfig should hav
internal/config/config.go:88:6: exported: exported type AzureCredentials should have comment or be unexported (revive)
internal/config/config.go:93:6: exported: exported type GoogleCredentials should have comment or be unexported (revive)
internal/config/config.go:99:6: exported: exported type RedisConfig should have comment or be unexported (revive)
internal/config/config.go:110:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:116:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
internal/config/config.go:120:6: exported: exported type TLSConfig should have comment or be unexported (revive)
internal/config/config.go:127:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
internal/config/config.go:130:2: var-naming: struct field Tls should be TLS (revive)
internal/config/config.go:133:6: exported: exported type Config should have comment or be unexported (revive)
internal/config/config.go:161:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:166:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
internal/config/config.go:170:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
internal/config/config.go:177:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
internal/config/config.go:191:1: exported: exported function LoadConfig should have comment or be unexported (revive)
internal/config/config.go:200:18: G204: Subprocess launched with variable (gosec)
internal/config/config.go:218:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
internal/config/config.go:241:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
internal/config/config.go:284:8: G101: Potential hardcoded credentials (gosec)
internal/config/config.go:111:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:117:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
internal/config/config.go:121:6: exported: exported type TLSConfig should have comment or be unexported (revive)
internal/config/config.go:128:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
internal/config/config.go:131:2: var-naming: struct field Tls should be TLS (revive)
internal/config/config.go:134:6: exported: exported type Config should have comment or be unexported (revive)
internal/config/config.go:162:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:167:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
internal/config/config.go:171:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
internal/config/config.go:178:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
internal/config/config.go:192:1: exported: exported function LoadConfig should have comment or be unexported (revive)
internal/config/config.go:201:18: G204: Subprocess launched with variable (gosec)
internal/config/config.go:219:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
internal/config/config.go:242:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
internal/config/config.go:285:8: G101: Potential hardcoded credentials (gosec)
internal/dependencyproxy/dependencyproxy.go:77: Function 'Inject' is too long (70 > 60) (funlen)
internal/dependencyproxy/dependencyproxy.go:115:32: `cancelled` is a misspelling of `canceled` (misspell)
internal/dependencyproxy/dependencyproxy_test.go:101:91: unused-parameter: parameter 'r' seems to be unused, consider removing or renaming it as _ (revive)
@ -322,7 +322,7 @@ internal/redis/redis.go:1:1: ST1000: at least one file in a package should have
internal/redis/redis.go:16:2: blank-imports: a blank import should be only in a main or test package, or have a comment justifying it (revive)
internal/redis/redis.go:21:24: var-declaration: should omit type error from declaration of var errSentinelMasterAddr; it will be inferred from the right-hand side (revive)
internal/redis/redis.go:23:2: exported: exported var TotalConnections should have comment or be unexported (revive)
internal/redis/redis.go:95:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis.go:102:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis_test.go:18:2: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:23:3: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:66:15: `initialise` is a misspelling of `initialize` (misspell)

View File

@ -9,8 +9,8 @@ cmd/gitlab-workhorse/authorization_test.go:114:3: go-require: do not use require
cmd/gitlab-workhorse/authorization_test.go:115:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:116:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:120:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/config_test.go:189: cmd/gitlab-workhorse/config_test.go:189: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
cmd/gitlab-workhorse/config_test.go:331:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/config_test.go:191: cmd/gitlab-workhorse/config_test.go:191: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
cmd/gitlab-workhorse/config_test.go:333:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/jobs_test.go:37:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/jobs_test.go:42:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/listener.go:34:16: G402: TLS MinVersion too low. (gosec)
@ -164,21 +164,21 @@ internal/config/config.go:84:6: exported: exported type GoCloudConfig should hav
internal/config/config.go:88:6: exported: exported type AzureCredentials should have comment or be unexported (revive)
internal/config/config.go:93:6: exported: exported type GoogleCredentials should have comment or be unexported (revive)
internal/config/config.go:99:6: exported: exported type RedisConfig should have comment or be unexported (revive)
internal/config/config.go:110:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:116:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
internal/config/config.go:120:6: exported: exported type TLSConfig should have comment or be unexported (revive)
internal/config/config.go:127:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
internal/config/config.go:130:2: var-naming: struct field Tls should be TLS (revive)
internal/config/config.go:133:6: exported: exported type Config should have comment or be unexported (revive)
internal/config/config.go:161:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:166:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
internal/config/config.go:170:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
internal/config/config.go:177:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
internal/config/config.go:191:1: exported: exported function LoadConfig should have comment or be unexported (revive)
internal/config/config.go:200:18: G204: Subprocess launched with variable (gosec)
internal/config/config.go:218:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
internal/config/config.go:241:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
internal/config/config.go:284:8: G101: Potential hardcoded credentials (gosec)
internal/config/config.go:111:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:117:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
internal/config/config.go:121:6: exported: exported type TLSConfig should have comment or be unexported (revive)
internal/config/config.go:128:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
internal/config/config.go:131:2: var-naming: struct field Tls should be TLS (revive)
internal/config/config.go:134:6: exported: exported type Config should have comment or be unexported (revive)
internal/config/config.go:162:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
internal/config/config.go:167:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
internal/config/config.go:171:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
internal/config/config.go:178:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
internal/config/config.go:192:1: exported: exported function LoadConfig should have comment or be unexported (revive)
internal/config/config.go:201:18: G204: Subprocess launched with variable (gosec)
internal/config/config.go:219:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
internal/config/config.go:242:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
internal/config/config.go:285:8: G101: Potential hardcoded credentials (gosec)
internal/dependencyproxy/dependencyproxy.go:77: Function 'Inject' is too long (70 > 60) (funlen)
internal/dependencyproxy/dependencyproxy.go:115:32: `cancelled` is a misspelling of `canceled` (misspell)
internal/dependencyproxy/dependencyproxy_test.go:101:91: unused-parameter: parameter 'r' seems to be unused, consider removing or renaming it as _ (revive)
@ -322,7 +322,7 @@ internal/redis/redis.go:1:1: ST1000: at least one file in a package should have
internal/redis/redis.go:16:2: blank-imports: a blank import should be only in a main or test package, or have a comment justifying it (revive)
internal/redis/redis.go:21:24: var-declaration: should omit type error from declaration of var errSentinelMasterAddr; it will be inferred from the right-hand side (revive)
internal/redis/redis.go:23:2: exported: exported var TotalConnections should have comment or be unexported (revive)
internal/redis/redis.go:95:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis.go:102:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis_test.go:18:2: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:23:3: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:66:15: `initialise` is a misspelling of `initialize` (misspell)

View File

@ -38,7 +38,8 @@ trusted_cidrs_for_x_forwarded_for = ["127.0.0.1/8", "192.168.0.1/8"]
trusted_cidrs_for_propagation = ["10.0.0.1/8"]
[redis]
password = "redis password"
Password = "redis password"
SentinelUsername = "sentinel-user"
SentinelPassword = "sentinel password"
[object_storage]
provider = "test provider"
@ -74,6 +75,7 @@ key = "/path/to/private/key"
// fields in each section; that should happen in the tests of the
// internal/config package.
require.Equal(t, "redis password", cfg.Redis.Password)
require.Equal(t, "sentinel-user", cfg.Redis.SentinelUsername)
require.Equal(t, "sentinel password", cfg.Redis.SentinelPassword)
require.Equal(t, "test provider", cfg.ObjectStorageCredentials.Provider)
require.Equal(t, uint32(123), cfg.ImageResizerConfig.MaxScalerProcs, "image resizer max_scaler_procs")

View File

@ -100,6 +100,7 @@ type RedisConfig struct {
URL TomlURL
Sentinel []TomlURL
SentinelMaster string
SentinelUsername string
SentinelPassword string
Password string
DB *int

View File

@ -53,6 +53,13 @@ const (
defaultIdleTimeout = 3 * time.Minute
)
// SentinelOptions contains grouped, related values
type SentinelOptions struct {
SentinelUsername string
SentinelPassword string
Sentinels []string
}
// createDialer references https://github.com/redis/go-redis/blob/b1103e3d436b6fe98813ecbbe1f99dc8d59b06c9/options.go#L214
// it intercepts the error and tracks it via a Prometheus counter
func createDialer(sentinels []string, tlsConfig *tls.Config) func(ctx context.Context, network, addr string) (net.Conn, error) {
@ -172,12 +179,13 @@ func configureRedis(cfg *config.RedisConfig) (*redis.Client, error) {
}
func configureSentinel(cfg *config.RedisConfig) *redis.Client {
sentinelPassword, sentinels := sentinelOptions(cfg)
options := sentinelOptions(cfg)
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: cfg.SentinelMaster,
SentinelAddrs: sentinels,
SentinelAddrs: options.Sentinels,
Password: cfg.Password,
SentinelPassword: sentinelPassword,
SentinelUsername: options.SentinelUsername,
SentinelPassword: options.SentinelPassword,
DB: getOrDefault(cfg.DB, 0),
PoolSize: getOrDefault(cfg.MaxActive, defaultMaxActive),
@ -187,7 +195,7 @@ func configureSentinel(cfg *config.RedisConfig) *redis.Client {
ReadTimeout: defaultReadTimeout,
WriteTimeout: defaultWriteTimeout,
Dialer: createDialer(sentinels, nil),
Dialer: createDialer(options.Sentinels, nil),
})
client.AddHook(sentinelInstrumentationHook{})
@ -195,10 +203,13 @@ func configureSentinel(cfg *config.RedisConfig) *redis.Client {
return client
}
// sentinelOptions extracts the sentinel password and addresses in <host>:<port> format
// sentinelOptions extracts the sentinel username and password from the URLs
// and addresses in <host>:<port> format.
// the order of priority for the passwords is: SentinelPassword -> first password-in-url
func sentinelOptions(cfg *config.RedisConfig) (string, []string) {
// SentinelUsername will be the username associated with SentinelPassword.
func sentinelOptions(cfg *config.RedisConfig) SentinelOptions {
sentinels := make([]string, len(cfg.Sentinel))
sentinelUsername := cfg.SentinelUsername
sentinelPassword := cfg.SentinelPassword
for i := range cfg.Sentinel {
@ -208,10 +219,16 @@ func sentinelOptions(cfg *config.RedisConfig) (string, []string) {
if pw, exist := sentinelDetails.User.Password(); exist && len(sentinelPassword) == 0 {
// sets password using the first non-empty password
sentinelPassword = pw
// If a password is specified, a username is optional. Ensure that we use the
// username associated with the password.
if username := sentinelDetails.User.Username(); username != "" && sentinelUsername == "" {
sentinelUsername = username
}
}
}
return sentinelPassword, sentinels
return SentinelOptions{sentinelUsername, sentinelPassword, sentinels}
}
func getOrDefault(ptr *int, val int) int {

View File

@ -112,8 +112,10 @@ func TestConnectToSentinel(t *testing.T) {
func TestSentinelOptions(t *testing.T) {
testCases := []struct {
description string
inputSentinelUsername string
inputSentinelPassword string
inputSentinel []string
username string
password string
sentinels []string
}{
@ -142,6 +144,38 @@ func TestSentinelOptions(t *testing.T) {
inputSentinelPassword: "password1",
password: "password1",
},
{
description: "specific sentinel username defined",
inputSentinel: []string{"redis://localhost:26480"},
inputSentinelUsername: "username1",
inputSentinelPassword: "password1",
sentinels: []string{"localhost:26480"},
username: "username1",
password: "password1",
},
{
description: "specific sentinel username defined in url",
inputSentinel: []string{"redis://username2:password2@localhost:26480", "redis://username3:password3@localhost:26481"},
sentinels: []string{"localhost:26480", "localhost:26481"},
username: "username2",
password: "password2",
},
{
description: "usernames and passwords defined specifically and in url",
inputSentinel: []string{"tcp://someuser2:password2@localhost:26480", "tcp://someuser3:password3@localhost:26481"},
sentinels: []string{"localhost:26480", "localhost:26481"},
inputSentinelUsername: "someuser1",
inputSentinelPassword: "password1",
username: "someuser1",
password: "password1",
},
{
description: "username set for first sentinel",
inputSentinel: []string{"tcp://someuser2@localhost:26480", "tcp://someuser3:password3@localhost:26481"},
sentinels: []string{"localhost:26480", "localhost:26481"},
username: "someuser3",
password: "password3",
},
}
for _, tc := range testCases {
@ -153,13 +187,15 @@ func TestSentinelOptions(t *testing.T) {
sentinelUrls[i] = config.TomlURL{URL: *parsedURL}
}
outputPw, outputSentinels := sentinelOptions(&config.RedisConfig{
options := sentinelOptions(&config.RedisConfig{
Sentinel: sentinelUrls,
SentinelUsername: tc.inputSentinelUsername,
SentinelPassword: tc.inputSentinelPassword,
})
require.Equal(t, tc.password, outputPw)
require.Equal(t, tc.sentinels, outputSentinels)
require.Equal(t, tc.username, options.SentinelUsername)
require.Equal(t, tc.password, options.SentinelPassword)
require.Equal(t, tc.sentinels, options.Sentinels)
})
}
}