Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
52c7972910
commit
a16109b67f
22 changed files with 238 additions and 297 deletions
|
@ -1685,6 +1685,7 @@ Gitlab/NamespacedClass:
|
|||
- 'app/uploaders/personal_file_uploader.rb'
|
||||
- 'app/validators/abstract_path_validator.rb'
|
||||
- 'app/validators/addressable_url_validator.rb'
|
||||
- 'app/validators/any_field_validator.rb'
|
||||
- 'app/validators/array_members_validator.rb'
|
||||
- 'app/validators/branch_filter_validator.rb'
|
||||
- 'app/validators/certificate_fingerprint_validator.rb'
|
||||
|
|
|
@ -474,19 +474,17 @@ export function queryToObject(query, { gatherArrays = false, legacySpacesDecode
|
|||
}
|
||||
|
||||
const decodedValue = legacySpacesDecode ? decodeURIComponent(value) : decodeUrlParameter(value);
|
||||
const decodedKey = legacySpacesDecode ? decodeURIComponent(key) : decodeUrlParameter(key);
|
||||
|
||||
if (gatherArrays && key.endsWith('[]')) {
|
||||
const decodedKey = legacySpacesDecode
|
||||
? decodeURIComponent(key.slice(0, -2))
|
||||
: decodeUrlParameter(key.slice(0, -2));
|
||||
if (gatherArrays && decodedKey.endsWith('[]')) {
|
||||
const decodedArrayKey = decodedKey.slice(0, -2);
|
||||
|
||||
if (!Array.isArray(accumulator[decodedKey])) {
|
||||
accumulator[decodedKey] = [];
|
||||
if (!Array.isArray(accumulator[decodedArrayKey])) {
|
||||
accumulator[decodedArrayKey] = [];
|
||||
}
|
||||
accumulator[decodedKey].push(decodedValue);
|
||||
} else {
|
||||
const decodedKey = legacySpacesDecode ? decodeURIComponent(key) : decodeUrlParameter(key);
|
||||
|
||||
accumulator[decodedArrayKey].push(decodedValue);
|
||||
} else {
|
||||
accumulator[decodedKey] = decodedValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This module enables a record to be valid if any field is present
|
||||
#
|
||||
# Overwrite one_of_required_fields to set one of which fields must be present
|
||||
module AnyFieldValidation
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
validate :any_field_present
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def any_field_present
|
||||
return unless one_of_required_fields.all? { |field| self[field].blank? }
|
||||
|
||||
errors.add(:base, _("At least one field of %{one_of_required_fields} must be present") %
|
||||
{ one_of_required_fields: one_of_required_fields })
|
||||
end
|
||||
|
||||
def one_of_required_fields
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
35
app/validators/any_field_validator.rb
Normal file
35
app/validators/any_field_validator.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# AnyFieldValidator
|
||||
#
|
||||
# Custom validator that checks if any of the provided
|
||||
# fields are present to ensure creation of a non-empty
|
||||
# record
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# class MyModel < ApplicationRecord
|
||||
# validates_with AnyFieldValidator, fields: %w[type name url]
|
||||
# end
|
||||
class AnyFieldValidator < ActiveModel::Validator
|
||||
def initialize(*args)
|
||||
super
|
||||
|
||||
if options[:fields].blank?
|
||||
raise 'Provide the fields options'
|
||||
end
|
||||
end
|
||||
|
||||
def validate(record)
|
||||
return unless one_of_required_fields.all? { |field| record[field].blank? }
|
||||
|
||||
record.errors.add(:base, _("At least one field of %{one_of_required_fields} must be present") %
|
||||
{ one_of_required_fields: one_of_required_fields })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def one_of_required_fields
|
||||
options[:fields]
|
||||
end
|
||||
end
|
|
@ -28,5 +28,7 @@
|
|||
= yield :before_content
|
||||
= yield
|
||||
= yield :after_content
|
||||
-# This is needed by [GitLab JH](https://gitlab.com/gitlab-jh/jh-team/gitlab-cn/-/issues/81)
|
||||
= render_if_exists "shared/footer/global_footer"
|
||||
|
||||
= render "layouts/nav/top_nav_responsive", class: 'layout-page content-wrapper-margin'
|
||||
|
|
|
@ -27,5 +27,5 @@ Gitlab::Application.config.session_store(
|
|||
secure: Gitlab.config.gitlab.https,
|
||||
httponly: true,
|
||||
expires_in: Settings.gitlab['session_expire_delay'] * 60,
|
||||
path: Rails.application.config.relative_url_root.nil? ? '/' : Gitlab::Application.config.relative_url_root
|
||||
path: Rails.application.config.relative_url_root.presence || '/'
|
||||
)
|
||||
|
|
|
@ -17,69 +17,59 @@ described, it is possible to adapt these instructions to your needs.
|
|||
|
||||
_[diagram source - GitLab employees only](https://docs.google.com/drawings/d/1z0VlizKiLNXVVVaERFwgsIOuEgjcUqDTWPdQYsE7Z4c/edit)_
|
||||
|
||||
The topology above assumes the **primary** and **secondary** Geo clusters
|
||||
The topology above assumes the **primary** and **secondary** Geo sites
|
||||
are located in two separate locations, on their own virtual network
|
||||
with private IP addresses. The network is configured such that all machines in
|
||||
one geographic location can communicate with each other using their private IP addresses.
|
||||
The IP addresses given are examples and may be different depending on the
|
||||
network topology of your deployment.
|
||||
|
||||
The only external way to access the two Geo deployments is by HTTPS at
|
||||
The only external way to access the two Geo sites is by HTTPS at
|
||||
`gitlab.us.example.com` and `gitlab.eu.example.com` in the example above.
|
||||
|
||||
NOTE:
|
||||
The **primary** and **secondary** Geo deployments must be able to communicate to each other over HTTPS.
|
||||
The **primary** and **secondary** Geo sites must be able to communicate to each other over HTTPS.
|
||||
|
||||
## Redis and PostgreSQL for multiple nodes
|
||||
|
||||
Geo supports:
|
||||
|
||||
- Redis and PostgreSQL on the **primary** node configured for multiple nodes.
|
||||
- Redis on **secondary** nodes configured for multiple nodes.
|
||||
|
||||
NOTE:
|
||||
Support for PostgreSQL on **secondary** nodes in multi-node configuration
|
||||
[is planned](https://gitlab.com/groups/gitlab-org/-/epics/2536).
|
||||
|
||||
Because of the additional complexity involved in setting up this configuration
|
||||
for PostgreSQL and Redis, it is not covered by this Geo multi-node documentation.
|
||||
|
||||
For more information on setting up a multi-node PostgreSQL cluster and Redis cluster using the Omnibus GitLab package, see:
|
||||
|
||||
- [PostgreSQL multi-node documentation](../../postgresql/replication_and_failover.md)
|
||||
- [Geo multi-node database replication](../setup/database.md#multi-node-database-replication)
|
||||
- [Redis multi-node documentation](../../redis/replication_and_failover.md)
|
||||
|
||||
NOTE:
|
||||
It is possible to use cloud hosted services for PostgreSQL and Redis, but this is beyond the scope of this document.
|
||||
|
||||
## Prerequisites: Two working GitLab multi-node clusters
|
||||
## Prerequisites: Two independently working GitLab multi-node sites
|
||||
|
||||
One cluster serves as the **primary** node. Use the
|
||||
[GitLab multi-node documentation](../../reference_architectures/index.md) to set this up. If
|
||||
One GitLab site serves as the Geo **primary** site. Use the
|
||||
[GitLab reference architectures documentation](../../reference_architectures/index.md)
|
||||
to set this up. You can use different reference architecture sizes for each Geo site. If
|
||||
you already have a working GitLab instance that is in-use, it can be used as a
|
||||
**primary**.
|
||||
**primary** site.
|
||||
|
||||
The second cluster serves as the **secondary** node. Again, use the
|
||||
[GitLab multi-node documentation](../../reference_architectures/index.md) to set this up.
|
||||
The second GitLab site serves as the Geo **secondary** site. Again, use the
|
||||
[GitLab reference architectures documentation](../../reference_architectures/index.md) to set this up.
|
||||
It's a good idea to log in and test it. However, be aware that its data is
|
||||
wiped out as part of the process of replicating from the **primary** node.
|
||||
wiped out as part of the process of replicating from the **primary** site.
|
||||
|
||||
## Configure the GitLab cluster to be the **primary** node
|
||||
## Configure a GitLab site to be the Geo **primary** site
|
||||
|
||||
The following steps enable a GitLab cluster to serve as the **primary** node.
|
||||
The following steps enable a GitLab site to serve as the Geo **primary** site.
|
||||
|
||||
### Step 1: Configure the **primary** frontend servers
|
||||
### Step 1: Configure the **primary** frontend nodes
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` and add the following:
|
||||
|
||||
```ruby
|
||||
##
|
||||
## Enable the Geo primary role
|
||||
##
|
||||
roles ['geo_primary_role']
|
||||
|
||||
##
|
||||
## The unique identifier for the Geo node.
|
||||
## The unique identifier for the Geo site. It's recommended to use a
|
||||
## physical location as a name, for example "us-east", instead of
|
||||
## "secondary" or "geo". It's case-sensitive, and most characters are
|
||||
## allowed. It should be the same for all nodes in a Geo site.
|
||||
##
|
||||
gitlab_rails['geo_node_name'] = '<node_name_here>'
|
||||
|
||||
|
@ -93,150 +83,58 @@ After making these changes, [reconfigure GitLab](../../restart_gitlab.md#omnibus
|
|||
|
||||
NOTE:
|
||||
PostgreSQL and Redis should have already been disabled on the
|
||||
application servers during normal GitLab multi-node setup. Connections
|
||||
from the application servers to services on the backend servers should
|
||||
application nodes during normal GitLab multi-node setup. Connections
|
||||
from the application nodes to services on the backend nodes should
|
||||
have also been configured. See multi-node configuration documentation for
|
||||
[PostgreSQL](../../postgresql/replication_and_failover.md#configuring-the-application-nodes)
|
||||
and [Redis](../../redis/replication_and_failover.md#example-configuration-for-the-gitlab-application).
|
||||
|
||||
### Step 2: Configure the **primary** database
|
||||
## Configure the other GitLab site to be a Geo **secondary** site
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` and add the following:
|
||||
|
||||
```ruby
|
||||
##
|
||||
## Configure the Geo primary role and the PostgreSQL role
|
||||
##
|
||||
roles ['geo_primary_role', 'postgres_role']
|
||||
```
|
||||
|
||||
## Configure a **secondary** node
|
||||
|
||||
A **secondary** cluster is similar to any other GitLab multi-node cluster, with two
|
||||
A **secondary** site is similar to any other GitLab multi-node site, with three
|
||||
major differences:
|
||||
|
||||
- The main PostgreSQL database is a read-only replica of the **primary** node's
|
||||
- The main PostgreSQL database is a read-only replica of the Geo **primary** site's
|
||||
PostgreSQL database.
|
||||
- There is also a single PostgreSQL database for the **secondary** cluster,
|
||||
called the "tracking database", which tracks the synchronization state of
|
||||
various resources.
|
||||
- There is an additional PostgreSQL database for each Geo **secondary** site,
|
||||
called the "Geo tracking database", which tracks the replication and verification
|
||||
state of various resources.
|
||||
- There is an additional GitLab service [`geo-logcursor`](../index.md#geo-log-cursor)
|
||||
|
||||
Therefore, we set up the multi-node components one by one and include deviations
|
||||
from the normal multi-node setup. However, we highly recommend configuring a
|
||||
brand-new cluster first, as if it were not part of a Geo setup. This allows
|
||||
verifying that it is a working cluster. And only then should it be modified
|
||||
for use as a Geo **secondary**. This helps to separate Geo setup problems from
|
||||
unrelated problems.
|
||||
brand-new GitLab site first, as if it were not part of a Geo setup. This allows
|
||||
verifying that it is a working GitLab site. And only then should it be modified
|
||||
for use as a Geo **secondary** site. This helps to separate Geo setup problems from
|
||||
unrelated multi-node configuration problems.
|
||||
|
||||
### Step 1: Configure the Redis and Gitaly services on the **secondary** node
|
||||
### Step 1: Configure the Redis and Gitaly services on the Geo **secondary** site
|
||||
|
||||
Configure the following services, again using the non-Geo multi-node
|
||||
documentation:
|
||||
|
||||
- [Configuring Redis for GitLab](../../redis/replication_and_failover.md#example-configuration-for-the-gitlab-application) for multiple nodes.
|
||||
- [Gitaly](../../gitaly/index.md), which stores data that is
|
||||
synchronized from the **primary** node.
|
||||
synchronized from the Geo **primary** site.
|
||||
|
||||
NOTE:
|
||||
[NFS](../../nfs.md) can be used in place of Gitaly but is not
|
||||
recommended.
|
||||
|
||||
### Step 2: Configure the main read-only replica PostgreSQL database on the **secondary** node
|
||||
### Step 2: Configure Postgres streaming replication
|
||||
|
||||
NOTE:
|
||||
The following documentation assumes the database runs on
|
||||
a single node only. Multi-node PostgreSQL on **secondary** nodes is
|
||||
[not currently supported](https://gitlab.com/groups/gitlab-org/-/epics/2536).
|
||||
|
||||
Configure the [**secondary** database](../setup/database.md) as a read-only replica of
|
||||
the **primary** database. Use the following as a guide.
|
||||
|
||||
1. Generate an MD5 hash of the desired password for the database user that the
|
||||
GitLab application uses to access the read-replica database:
|
||||
|
||||
The username (`gitlab` by default) is incorporated into the hash.
|
||||
|
||||
```shell
|
||||
gitlab-ctl pg-password-md5 gitlab
|
||||
# Enter password: <your_password_here>
|
||||
# Confirm password: <your_password_here>
|
||||
# fca0b89a972d69f00eb3ec98a5838484
|
||||
```
|
||||
|
||||
Use this hash to fill in `<md5_hash_of_your_password>` in the next step.
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` in the replica database machine, and add the
|
||||
following:
|
||||
|
||||
```ruby
|
||||
##
|
||||
## Configure the Geo secondary role and the PostgreSQL role
|
||||
##
|
||||
roles ['geo_secondary_role', 'postgres_role']
|
||||
|
||||
##
|
||||
## The unique identifier for the Geo node.
|
||||
## This should match the secondary's application node.
|
||||
##
|
||||
gitlab_rails['geo_node_name'] = '<node_name_here>'
|
||||
|
||||
##
|
||||
## Secondary address
|
||||
## - replace '<secondary_node_ip>' with the public or VPC address of your Geo secondary node
|
||||
## - replace '<tracking_database_ip>' with the public or VPC address of your Geo tracking database node
|
||||
##
|
||||
postgresql['listen_address'] = '<secondary_node_ip>'
|
||||
postgresql['md5_auth_cidr_addresses'] = ['<secondary_node_ip>/32', '<tracking_database_ip>/32']
|
||||
|
||||
##
|
||||
## Database credentials password (defined previously in primary node)
|
||||
## - replicate same values here as defined in primary node
|
||||
##
|
||||
postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
|
||||
gitlab_rails['db_password'] = '<your_password_here>'
|
||||
|
||||
##
|
||||
## When running the Geo tracking database on a separate machine, disable it
|
||||
## here and allow connections from the tracking database host. And ensure
|
||||
## the tracking database IP is in postgresql['md5_auth_cidr_addresses'] above.
|
||||
##
|
||||
geo_postgresql['enable'] = false
|
||||
|
||||
##
|
||||
## Disable all other services that aren't needed. We had to enable
|
||||
## geo_secondary_role to cause some configuration changes to postgresql, but
|
||||
## the role enables single-node services by default.
|
||||
##
|
||||
alertmanager['enable'] = false
|
||||
consul['enable'] = false
|
||||
geo_logcursor['enable'] = false
|
||||
gitaly['enable'] = false
|
||||
gitlab_exporter['enable'] = false
|
||||
gitlab_workhorse['enable'] = false
|
||||
nginx['enable'] = false
|
||||
node_exporter['enable'] = false
|
||||
pgbouncer_exporter['enable'] = false
|
||||
prometheus['enable'] = false
|
||||
redis['enable'] = false
|
||||
redis_exporter['enable'] = false
|
||||
patroni['enable'] = false
|
||||
sidekiq['enable'] = false
|
||||
sidekiq_cluster['enable'] = false
|
||||
puma['enable'] = false
|
||||
```
|
||||
|
||||
After making these changes, [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) so the changes take effect.
|
||||
Follow the [Geo database replication instructions](../setup/database.md).
|
||||
|
||||
If using an external PostgreSQL instance, refer also to
|
||||
[Geo with external PostgreSQL instances](../setup/external_database.md).
|
||||
|
||||
### Step 3: Configure the tracking database on the **secondary** node
|
||||
### Step 3: Configure the Geo tracking database on the Geo **secondary** site
|
||||
|
||||
NOTE:
|
||||
This documentation assumes the tracking database runs on
|
||||
only a single machine, rather than as a PostgreSQL cluster.
|
||||
If you want to run the Geo tracking database in a multi-node PostgreSQL cluster,
|
||||
then follow [Configuring Patroni cluster for the tracking PostgreSQL database](../setup/database.md#configuring-patroni-cluster-for-the-tracking-postgresql-database).
|
||||
|
||||
Configure the tracking database.
|
||||
If you want to run the Geo tracking database on a single node, then follow
|
||||
the instructions below.
|
||||
|
||||
1. Generate an MD5 hash of the desired password for the database user that the
|
||||
GitLab application uses to access the tracking database:
|
||||
|
@ -254,8 +152,8 @@ Configure the tracking database.
|
|||
Use this hash to fill in `<tracking_database_password_md5_hash>` in the next
|
||||
step.
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` in the tracking database machine, and add the
|
||||
following:
|
||||
1. On the machine where the Geo tracking database is intended to run, add the
|
||||
following to `/etc/gitlab/gitlab.rb`:
|
||||
|
||||
```ruby
|
||||
##
|
||||
|
@ -271,29 +169,8 @@ Configure the tracking database.
|
|||
geo_postgresql['md5_auth_cidr_addresses'] = ['<replica_database_ip>/32']
|
||||
gitlab_rails['db_host'] = '<replica_database_ip>'
|
||||
|
||||
# Prevent reconfigure from attempting to run migrations on the replica DB
|
||||
# Prevent reconfigure from attempting to run migrations on the replica database
|
||||
gitlab_rails['auto_migrate'] = false
|
||||
|
||||
##
|
||||
## Ensure unnecessary services are disabled
|
||||
##
|
||||
alertmanager['enable'] = false
|
||||
consul['enable'] = false
|
||||
geo_logcursor['enable'] = false
|
||||
gitaly['enable'] = false
|
||||
gitlab_exporter['enable'] = false
|
||||
gitlab_workhorse['enable'] = false
|
||||
nginx['enable'] = false
|
||||
node_exporter['enable'] = false
|
||||
pgbouncer_exporter['enable'] = false
|
||||
postgresql['enable'] = false
|
||||
prometheus['enable'] = false
|
||||
redis['enable'] = false
|
||||
redis_exporter['enable'] = false
|
||||
patroni['enable'] = false
|
||||
sidekiq['enable'] = false
|
||||
sidekiq_cluster['enable'] = false
|
||||
puma['enable'] = false
|
||||
```
|
||||
|
||||
After making these changes, [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) so the changes take effect.
|
||||
|
@ -301,27 +178,42 @@ After making these changes, [reconfigure GitLab](../../restart_gitlab.md#omnibus
|
|||
If using an external PostgreSQL instance, refer also to
|
||||
[Geo with external PostgreSQL instances](../setup/external_database.md).
|
||||
|
||||
### Step 4: Configure the frontend application servers on the **secondary** node
|
||||
### Step 4: Configure the frontend application nodes on the Geo **secondary** site
|
||||
|
||||
In the architecture overview, there are two machines running the GitLab
|
||||
application services. These services are enabled selectively in the
|
||||
configuration.
|
||||
In the minimal [architecture diagram](#architecture-overview) above, there are two
|
||||
machines running the GitLab application services. These services are enabled
|
||||
selectively in the configuration.
|
||||
|
||||
Configure the GitLab Rails application servers following the relevant steps
|
||||
Configure the GitLab Rails application nodes following the relevant steps
|
||||
outlined in the [reference architectures](../../reference_architectures/index.md),
|
||||
then make the following modifications:
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` on each application server in the **secondary**
|
||||
cluster, and add the following:
|
||||
1. Edit `/etc/gitlab/gitlab.rb` on each application node in the Geo **secondary**
|
||||
site, and add the following:
|
||||
|
||||
```ruby
|
||||
##
|
||||
## Enable the Geo secondary role
|
||||
## Enable GitLab application services. The application_role enables many services.
|
||||
## Alternatively, you can choose to enable or disable specific services on
|
||||
## different nodes to aid in horizontal scaling and separation of concerns.
|
||||
##
|
||||
roles ['geo_secondary_role', 'application_role']
|
||||
roles ['application_role']
|
||||
|
||||
## `application_role` already enables this. You only need this line if
|
||||
## you selectively enable individual services that depend on Rails, like
|
||||
## `puma`, `sidekiq`, `geo-logcursor`, etc.
|
||||
gitlab_rails['enable'] = true
|
||||
|
||||
##
|
||||
## The unique identifier for the Geo node.
|
||||
## Enable Geo Log Cursor service
|
||||
##
|
||||
geo_logcursor['enable'] = true
|
||||
|
||||
##
|
||||
## The unique identifier for the Geo site. It's recommended to use a
|
||||
## physical location as a name, for example "eu-west", instead of
|
||||
## "secondary" or "geo". It's case-sensitive, and most characters are
|
||||
## allowed. It should be the same for all nodes in a Geo site.
|
||||
##
|
||||
gitlab_rails['geo_node_name'] = '<node_name_here>'
|
||||
|
||||
|
@ -331,12 +223,11 @@ then make the following modifications:
|
|||
gitlab_rails['auto_migrate'] = false
|
||||
|
||||
##
|
||||
## Configure the connection to the tracking DB. And disable application
|
||||
## servers from running tracking databases.
|
||||
## Configure the connection to the tracking database
|
||||
##
|
||||
geo_secondary['enable'] = true
|
||||
geo_secondary['db_host'] = '<geo_tracking_db_host>'
|
||||
geo_secondary['db_password'] = '<geo_tracking_db_password>'
|
||||
geo_postgresql['enable'] = false
|
||||
|
||||
##
|
||||
## Configure connection to the streaming replica database, if you haven't
|
||||
|
@ -353,7 +244,7 @@ then make the following modifications:
|
|||
|
||||
##
|
||||
## If you are using custom users not managed by Omnibus, you need to specify
|
||||
## UIDs and GIDs like below, and ensure they match between servers in a
|
||||
## UIDs and GIDs like below, and ensure they match between nodes in a
|
||||
## cluster to avoid permissions issues
|
||||
##
|
||||
user['uid'] = 9000
|
||||
|
@ -369,14 +260,17 @@ If you had set up PostgreSQL cluster using the omnibus package and had set
|
|||
`postgresql['sql_user_password'] = 'md5 digest of secret'`, keep in
|
||||
mind that `gitlab_rails['db_password']` and `geo_secondary['db_password']`
|
||||
contains the plaintext passwords. This is used to let the Rails
|
||||
servers connect to the databases.
|
||||
nodes connect to the databases.
|
||||
|
||||
NOTE:
|
||||
Make sure that current node IP is listed in `postgresql['md5_auth_cidr_addresses']` setting of your remote database.
|
||||
Make sure that current node's IP is listed in
|
||||
`postgresql['md5_auth_cidr_addresses']` setting of the read-replica database to
|
||||
allow Rails on this node to connect to Postgres.
|
||||
|
||||
After making these changes [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) so the changes take effect.
|
||||
|
||||
On the secondary the following GitLab frontend services are enabled:
|
||||
In the [architecture overview](#architecture-overview) topology, the following GitLab
|
||||
services are enabled on the "frontend" nodes:
|
||||
|
||||
- `geo-logcursor`
|
||||
- `gitlab-pages`
|
||||
|
@ -388,60 +282,41 @@ On the secondary the following GitLab frontend services are enabled:
|
|||
- `sidekiq`
|
||||
- `puma`
|
||||
|
||||
Verify these services by running `sudo gitlab-ctl status` on the frontend
|
||||
application servers.
|
||||
Verify these services exist by running `sudo gitlab-ctl status` on the frontend
|
||||
application nodes.
|
||||
|
||||
### Step 5: Set up the LoadBalancer for the **secondary** node
|
||||
### Step 5: Set up the LoadBalancer for the Geo **secondary** site
|
||||
|
||||
In this topology, a load balancer is required at each geographic location to
|
||||
route traffic to the application servers.
|
||||
The minimal [architecture diagram](#architecture-overview) above shows a load
|
||||
balancer at each geographic location to route traffic to the application nodes.
|
||||
|
||||
See [Load Balancer for GitLab with multiple nodes](../../load_balancer.md) for
|
||||
more information.
|
||||
|
||||
### Step 6: Configure the backend application servers on the **secondary** node
|
||||
### Step 6: Configure the backend application nodes on the Geo **secondary** site
|
||||
|
||||
The minimal reference architecture diagram above shows all application services
|
||||
The minimal [architecture diagram](#architecture-overview) above shows all application services
|
||||
running together on the same machines. However, for multiple nodes we
|
||||
[strongly recommend running all services separately](../../reference_architectures/index.md).
|
||||
|
||||
For example, a Sidekiq server could be configured similarly to the frontend
|
||||
application servers above, with some changes to run only the `sidekiq` service:
|
||||
For example, a Sidekiq node could be configured similarly to the frontend
|
||||
application nodes above, with some changes to run only the `sidekiq` service:
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb` on each Sidekiq server in the **secondary**
|
||||
cluster, and add the following:
|
||||
1. Edit `/etc/gitlab/gitlab.rb` on each Sidekiq node in the Geo **secondary**
|
||||
site, and add the following:
|
||||
|
||||
```ruby
|
||||
##
|
||||
## Enable the Geo secondary role
|
||||
##
|
||||
roles ['geo_secondary_role']
|
||||
|
||||
##
|
||||
## Enable the Sidekiq service
|
||||
##
|
||||
sidekiq['enable'] = true
|
||||
gitlab_rails['enable'] = true
|
||||
|
||||
##
|
||||
## Ensure unnecessary services are disabled
|
||||
##
|
||||
alertmanager['enable'] = false
|
||||
consul['enable'] = false
|
||||
gitaly['enable'] = false
|
||||
gitlab_exporter['enable'] = false
|
||||
gitlab_workhorse['enable'] = false
|
||||
nginx['enable'] = false
|
||||
node_exporter['enable'] = false
|
||||
pgbouncer_exporter['enable'] = false
|
||||
postgresql['enable'] = false
|
||||
prometheus['enable'] = false
|
||||
redis['enable'] = false
|
||||
redis_exporter['enable'] = false
|
||||
patroni['enable'] = false
|
||||
puma['enable'] = false
|
||||
|
||||
##
|
||||
## The unique identifier for the Geo node.
|
||||
## The unique identifier for the Geo site. It's recommended to use a
|
||||
## physical location as a name, for example "eu-west", instead of
|
||||
## "secondary" or "geo". It's case-sensitive, and most characters are
|
||||
## allowed. It should be the same for all nodes in a Geo site.
|
||||
##
|
||||
gitlab_rails['geo_node_name'] = '<node_name_here>'
|
||||
|
||||
|
@ -451,12 +326,11 @@ application servers above, with some changes to run only the `sidekiq` service:
|
|||
gitlab_rails['auto_migrate'] = false
|
||||
|
||||
##
|
||||
## Configure the connection to the tracking DB. And disable application
|
||||
## servers from running tracking databases.
|
||||
## Configure the connection to the tracking database
|
||||
##
|
||||
geo_secondary['enable'] = true
|
||||
geo_secondary['db_host'] = '<geo_tracking_db_host>'
|
||||
geo_secondary['db_password'] = '<geo_tracking_db_password>'
|
||||
geo_postgresql['enable'] = false
|
||||
|
||||
##
|
||||
## Configure connection to the streaming replica database, if you haven't
|
||||
|
@ -473,7 +347,7 @@ application servers above, with some changes to run only the `sidekiq` service:
|
|||
|
||||
##
|
||||
## If you are using custom users not managed by Omnibus, you need to specify
|
||||
## UIDs and GIDs like below, and ensure they match between servers in a
|
||||
## UIDs and GIDs like below, and ensure they match between nodes in a
|
||||
## cluster to avoid permissions issues
|
||||
##
|
||||
user['uid'] = 9000
|
||||
|
@ -484,8 +358,8 @@ application servers above, with some changes to run only the `sidekiq` service:
|
|||
registry['gid'] = 9002
|
||||
```
|
||||
|
||||
You can similarly configure a server to run only the `geo-logcursor` service
|
||||
You can similarly configure a node to run only the `geo-logcursor` service
|
||||
with `geo_logcursor['enable'] = true` and disabling Sidekiq with
|
||||
`sidekiq['enable'] = false`.
|
||||
|
||||
These servers do not need to be attached to the load balancer.
|
||||
These nodes do not need to be attached to the load balancer.
|
||||
|
|
|
@ -207,7 +207,12 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
|
|||
```ruby
|
||||
##
|
||||
## Geo Primary role
|
||||
## - configure dependent flags automatically to enable Geo
|
||||
## - Configures Postgres settings for replication
|
||||
## - Prevents automatic upgrade of Postgres since it requires downtime of
|
||||
## streaming replication to Geo secondary sites
|
||||
## - Enables standard single-node GitLab services like NGINX, Puma, Redis,
|
||||
## Sidekiq, etc. If you are segregating services, then you will need to
|
||||
## explicitly disable unwanted services.
|
||||
##
|
||||
roles(['geo_primary_role'])
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
reading_time: true
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
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
|
||||
|
|
|
@ -152,12 +152,7 @@ comments: false
|
|||
|
||||
Each page can have additional, optional metadata (set in the
|
||||
[default.html](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/fc3577921343173d589dfa43d837b4307e4e620f/layouts/default.html#L30-52)
|
||||
Nanoc layout), which is displayed at the top of the page if defined:
|
||||
|
||||
- `reading_time`: If you want to add an indication of the approximate reading
|
||||
time of a page, you can set `reading_time` to `true`. This uses a simple
|
||||
[algorithm](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/lib/helpers/reading_time.rb)
|
||||
to calculate the reading time based on the number of words.
|
||||
Nanoc layout), which is displayed at the top of the page if defined.
|
||||
|
||||
## Move or rename a page
|
||||
|
||||
|
@ -209,8 +204,7 @@ To add a redirect:
|
|||
bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, https://example.com]"
|
||||
```
|
||||
|
||||
Alternatively, you can omit the arguments, and you'll be asked to enter
|
||||
their values:
|
||||
Alternatively, you can omit the arguments and be asked to enter their values:
|
||||
|
||||
```shell
|
||||
bundle exec rake gitlab:docs:redirect
|
||||
|
|
|
@ -71,7 +71,7 @@ module API
|
|||
|
||||
route_setting :authentication, authenticate_non_public: true
|
||||
get 'Release.gpg' do
|
||||
not_found!
|
||||
distribution_from!(project_or_group).file_signature
|
||||
end
|
||||
|
||||
# GET {projects|groups}/:id/packages/debian/dists/*distribution/Release
|
||||
|
@ -91,8 +91,7 @@ module API
|
|||
|
||||
route_setting :authentication, authenticate_non_public: true
|
||||
get 'InRelease' do
|
||||
# Signature to be added in 7.3 of https://gitlab.com/groups/gitlab-org/-/epics/6057#note_582697034
|
||||
present_carrierwave_file!(distribution_from!(project_or_group).file)
|
||||
present_carrierwave_file!(distribution_from!(project_or_group).signed_file)
|
||||
end
|
||||
|
||||
params do
|
||||
|
|
|
@ -13,8 +13,18 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
trait(:with_file) do
|
||||
file_signature do
|
||||
<<~EOF
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
ABC
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
EOF
|
||||
end
|
||||
|
||||
after(:build) do |distribution, evaluator|
|
||||
distribution.file = fixture_file_upload('spec/fixtures/packages/debian/distribution/Release')
|
||||
distribution.signed_file = fixture_file_upload('spec/fixtures/packages/debian/distribution/InRelease')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
8
spec/fixtures/packages/debian/distribution/InRelease
vendored
Normal file
8
spec/fixtures/packages/debian/distribution/InRelease
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
Codename: fixture-distribution
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
ABC
|
||||
-----BEGIN PGP SIGNATURE-----
|
|
@ -670,21 +670,23 @@ describe('URL utility', () => {
|
|||
|
||||
describe('queryToObject', () => {
|
||||
it.each`
|
||||
case | query | options | result
|
||||
${'converts query'} | ${'?one=1&two=2'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'converts query without ?'} | ${'one=1&two=2'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'removes undefined values'} | ${'?one=1&two=2&three'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'overwrites values with same key and does not change key'} | ${'?one[]=1&one[]=2&two=2&two=3'} | ${undefined} | ${{ 'one[]': '2', two: '3' }}
|
||||
${'gathers values with the same array-key, strips `[]` from key'} | ${'?one[]=1&one[]=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: ['1', '2'], two: '3' }}
|
||||
${'overwrites values with the same array-key name'} | ${'?one=1&one[]=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: ['2'], two: '3' }}
|
||||
${'overwrites values with the same key name'} | ${'?one[]=1&one=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: '2', two: '3' }}
|
||||
${'ignores plus symbols'} | ${'?search=a+b'} | ${{ legacySpacesDecode: true }} | ${{ search: 'a+b' }}
|
||||
${'ignores plus symbols in keys'} | ${'?search+term=a'} | ${{ legacySpacesDecode: true }} | ${{ 'search+term': 'a' }}
|
||||
${'ignores plus symbols when gathering arrays'} | ${'?search[]=a+b'} | ${{ gatherArrays: true, legacySpacesDecode: true }} | ${{ search: ['a+b'] }}
|
||||
${'replaces plus symbols with spaces'} | ${'?search=a+b'} | ${undefined} | ${{ search: 'a b' }}
|
||||
${'replaces plus symbols in keys with spaces'} | ${'?search+term=a'} | ${undefined} | ${{ 'search term': 'a' }}
|
||||
${'replaces plus symbols when gathering arrays'} | ${'?search[]=a+b'} | ${{ gatherArrays: true }} | ${{ search: ['a b'] }}
|
||||
${'replaces plus symbols when gathering arrays for values with same key'} | ${'?search[]=a+b&search[]=c+d'} | ${{ gatherArrays: true }} | ${{ search: ['a b', 'c d'] }}
|
||||
case | query | options | result
|
||||
${'converts query'} | ${'?one=1&two=2'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'converts query without ?'} | ${'one=1&two=2'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'removes undefined values'} | ${'?one=1&two=2&three'} | ${undefined} | ${{ one: '1', two: '2' }}
|
||||
${'overwrites values with same key and does not change key'} | ${'?one[]=1&one[]=2&two=2&two=3'} | ${undefined} | ${{ 'one[]': '2', two: '3' }}
|
||||
${'gathers values with the same array-key, strips `[]` from key'} | ${'?one[]=1&one[]=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: ['1', '2'], two: '3' }}
|
||||
${'overwrites values with the same array-key name'} | ${'?one=1&one[]=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: ['2'], two: '3' }}
|
||||
${'overwrites values with the same key name'} | ${'?one[]=1&one=2&two=2&two=3'} | ${{ gatherArrays: true }} | ${{ one: '2', two: '3' }}
|
||||
${'ignores plus symbols'} | ${'?search=a+b'} | ${{ legacySpacesDecode: true }} | ${{ search: 'a+b' }}
|
||||
${'ignores plus symbols in keys'} | ${'?search+term=a'} | ${{ legacySpacesDecode: true }} | ${{ 'search+term': 'a' }}
|
||||
${'ignores plus symbols when gathering arrays'} | ${'?search[]=a+b'} | ${{ gatherArrays: true, legacySpacesDecode: true }} | ${{ search: ['a+b'] }}
|
||||
${'replaces plus symbols with spaces'} | ${'?search=a+b'} | ${undefined} | ${{ search: 'a b' }}
|
||||
${'replaces plus symbols in keys with spaces'} | ${'?search+term=a'} | ${undefined} | ${{ 'search term': 'a' }}
|
||||
${'preserves square brackets in array params'} | ${'?search[]=a&search[]=b'} | ${{ gatherArrays: true }} | ${{ search: ['a', 'b'] }}
|
||||
${'decodes encoded square brackets in array params'} | ${'?search%5B%5D=a&search%5B%5D=b'} | ${{ gatherArrays: true }} | ${{ search: ['a', 'b'] }}
|
||||
${'replaces plus symbols when gathering arrays'} | ${'?search[]=a+b'} | ${{ gatherArrays: true }} | ${{ search: ['a b'] }}
|
||||
${'replaces plus symbols when gathering arrays for values with same key'} | ${'?search[]=a+b&search[]=c+d'} | ${{ gatherArrays: true }} | ${{ search: ['a b', 'c d'] }}
|
||||
`('$case', ({ query, options, result }) => {
|
||||
expect(urlUtils.queryToObject(query, options)).toEqual(result);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe API::DebianGroupPackages do
|
|||
describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release.gpg' do
|
||||
let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/Release.gpg" }
|
||||
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^-----BEGIN PGP SIGNATURE-----/
|
||||
end
|
||||
|
||||
describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release' do
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe API::DebianGroupPackages do
|
|||
describe 'GET groups/:id/-/packages/debian/dists/*distribution/InRelease' do
|
||||
let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/InRelease" }
|
||||
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^Codename: fixture-distribution\n$/
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^-----BEGIN PGP SIGNED MESSAGE-----/
|
||||
end
|
||||
|
||||
describe 'GET groups/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
|
||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe API::DebianProjectPackages do
|
|||
describe 'GET projects/:id/packages/debian/dists/*distribution/Release.gpg' do
|
||||
let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/Release.gpg" }
|
||||
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^-----BEGIN PGP SIGNATURE-----/
|
||||
end
|
||||
|
||||
describe 'GET projects/:id/packages/debian/dists/*distribution/Release' do
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe API::DebianProjectPackages do
|
|||
describe 'GET projects/:id/packages/debian/dists/*distribution/InRelease' do
|
||||
let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/InRelease" }
|
||||
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^Codename: fixture-distribution\n$/
|
||||
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^-----BEGIN PGP SIGNED MESSAGE-----/
|
||||
end
|
||||
|
||||
describe 'GET projects/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
|
||||
|
|
44
spec/validators/any_field_validator_spec.rb
Normal file
44
spec/validators/any_field_validator_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe AnyFieldValidator do
|
||||
context 'when validation is instantiated correctly' do
|
||||
let(:validated_class) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'vulnerabilities'
|
||||
|
||||
validates_with AnyFieldValidator, fields: %w(title description)
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error if no fields are defined' do
|
||||
validated_object = validated_class.new
|
||||
|
||||
expect(validated_object.valid?).to be_falsey
|
||||
expect(validated_object.errors.messages)
|
||||
.to eq(base: ["At least one field of %{one_of_required_fields} must be present" %
|
||||
{ one_of_required_fields: %w(title description) }])
|
||||
end
|
||||
|
||||
it 'validates if only one field is present' do
|
||||
validated_object = validated_class.new(title: 'Vulnerability title')
|
||||
|
||||
expect(validated_object.valid?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when validation is missing the fields parameter' do
|
||||
let(:invalid_class) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'vulnerabilities'
|
||||
|
||||
validates_with AnyFieldValidator
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect { invalid_class.new }.to raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue