gitlab-qa 8.13.1 → 8.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eff4fd2e6e9b9ab05a26c87b04de43cc2724ff6bbfcdfa55309f6ea4dd6ca22f
4
- data.tar.gz: f7c23ec439a8d5bbbcffac5942f9af3bd11761df457d6bd5316dcc2accb14d2e
3
+ metadata.gz: 222f774a1b76d96311b8f50d198073376ec3a1c3728a85c181df3c7334635cc2
4
+ data.tar.gz: 76038a8e5fb395209798fae12d58b29b297d4ea7b62b1227867b48547fa832e8
5
5
  SHA512:
6
- metadata.gz: a796e6144671878b4940c6cd529abe4bff1f2b38fe06914c069c4291932d27c2b7527603a625d5a6631f42131e87d48bd63773b7abc62a55628f006863f3acab
7
- data.tar.gz: eab90710e729b81e2ba9716462327bf770289c17c197f7743b79fb88023c6711e84751f1bb02fd62414f2ff1ec327b0e318eac060fba28f3ebaade42ee0b5847
6
+ metadata.gz: b52cf9e0f2e4ac6b7650c08cbbdc20428cf97dcb8ec4425c10d5b20c5b0b60c324336f6b39c82c01ff6ccb3a0ecc934204288dc76ceb1f677dfb7f55da73fca5
7
+ data.tar.gz: e315e743dfd37f56cde0e7eff20ae757a7bb8f254cdea861871f22fffb36e58061bbe93a213036207efc685899ad04886374e7fd497ea4bf4b31251d1b1c0071
@@ -0,0 +1,23 @@
1
+ ce:airgapped:
2
+ extends:
3
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change
4
+ - .test
5
+ - .high-capacity
6
+ - .ce-variables
7
+ - .rspec-report-opts
8
+ variables:
9
+ QA_SCENARIO: "Test::Instance::Airgapped"
10
+ QA_RSPEC_TAGS: "--tag smoke"
11
+
12
+ ee:airgapped:
13
+ extends:
14
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change
15
+ - .test
16
+ - .high-capacity
17
+ - .ee-variables
18
+ - .rspec-report-opts
19
+ variables:
20
+ QA_SCENARIO: "Test::Instance::Airgapped"
21
+ QA_RSPEC_TAGS: "--tag smoke"
22
+
23
+
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-qa (8.13.1)
4
+ gitlab-qa (8.14.0)
5
5
  activesupport (~> 6.1)
6
6
  gitlab (~> 4.18.0)
7
7
  http (~> 5.0)
@@ -95,12 +95,13 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
95
95
  | `JIRA_ADMIN_PASSWORD` |- | Password for authenticating with Jira server as admin. | No|
96
96
  | `CACHE_NAMESPACE_NAME` | `true` | Cache namespace name for groups. | No|
97
97
  | `DEPLOY_VERSION` |- | The version of GitLab being tested against. | No|
98
- | `GITLAB_QA_USER_AGENT` |- | The browser user-agent to use instead of the default Chrome user-agent. | No|
98
+ | `GITLAB_QA_USER_AGENT` |- | The browser user-agent to use instead of the default Chrome user-agent. When set to the appropriate value (stored in 1Password), this allows tests to bypass certain login challenges (e.g., reCAPTCHA and ArkoseLabs). | No|
99
99
  | `GEO_FAILOVER` | `false` | Set to `true` when a Geo secondary site has been promoted to a Geo primary site. | No|
100
100
  | `GITLAB_INITIAL_ROOT_PASSWORD` | `5iveL!fe` | Initial root password for Omnibus installations | No|
101
101
  | `COLORIZED_LOGS` | `false` | Colors GitLab QA and test logs to improve readability | No|
102
102
  | `QA_DOCKER_ADD_HOSTS` |- | Comma separated list of hosts to add to /etc/hosts in docker container | No|
103
103
  | `FIPS` |- | Set to `1` or `true` to indicate that the test is running under FIPS mode | No|
104
+ | `JH_ENV` | `false` | Set to `true` to indicate tests or scenarios are running under JH env | No|
104
105
 
105
106
  ## [Supported Remote Grid environment variables](./running_against_remote_grid.md)
106
107
 
@@ -7,7 +7,7 @@ module Gitlab
7
7
  include Scenario::Actable
8
8
 
9
9
  attr_reader :docker
10
- attr_accessor :volumes, :ports, :network, :environment, :runner_network
10
+ attr_accessor :volumes, :ports, :network, :environment, :runner_network, :airgapped_network
11
11
  attr_writer :name, :exec_commands
12
12
 
13
13
  def initialize
@@ -72,15 +72,22 @@ module Gitlab
72
72
  end
73
73
 
74
74
  def prepare_network
75
- if runner_network && !docker.network_exists?(runner_network) # rubocop:disable Style/IfUnlessModifier
76
- docker.network_create("--driver=bridge --internal #{runner_network}")
77
- end
75
+ prepare_airgapped_network
76
+ prepare_runner_network
78
77
 
79
78
  return if docker.network_exists?(network)
80
79
 
81
80
  docker.network_create(network)
82
81
  end
83
82
 
83
+ def prepare_airgapped_network
84
+ docker.network_create("--driver=bridge --internal #{network}") if airgapped_network && !docker.network_exists?(network)
85
+ end
86
+
87
+ def prepare_runner_network
88
+ docker.network_create("--driver=bridge --internal #{runner_network}") if runner_network && !docker.network_exists?(runner_network)
89
+ end
90
+
84
91
  def prepare_docker_container
85
92
  return unless docker.container_exists?(name)
86
93
 
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Component
6
+ class Gitaly < Base
7
+ extend Forwardable
8
+ using Rainbow
9
+ attr_reader :release
10
+ attr_accessor :gitaly_port, :gitlab_name, :cluster_config
11
+ attr_writer :name
12
+
13
+ def_delegators :release, :tag, :image, :edition
14
+
15
+ def initialize
16
+ super
17
+ self.release = 'EE'
18
+ @cluster_config = Component::GitalyCluster::GitalyClusterConfig.new
19
+ @gitaly_port = 8075
20
+ @ports = [gitaly_port]
21
+ end
22
+
23
+ def name
24
+ @name || "gitaly-#{SecureRandom.hex(4)}"
25
+ end
26
+
27
+ def release=(release)
28
+ @release = QA::Release.new(release)
29
+ end
30
+
31
+ def reconfigure
32
+ setup_omnibus
33
+ @docker.attach(name) do |line, wait|
34
+ # TODO, workaround which allows to detach from the container
35
+ break if /gitlab Reconfigured!/.match?(line)
36
+ end
37
+ end
38
+
39
+ def setup_omnibus
40
+ @docker.write_files(name) do |f|
41
+ f.write('/etc/gitlab/gitlab.rb', gitaly_omnibus_configuration)
42
+ end
43
+ end
44
+
45
+ def process_exec_commands
46
+ exec_commands << Support::ConfigScripts.add_git_server_hooks(docker, name)
47
+
48
+ commands = exec_commands.flatten.uniq
49
+ return if commands.empty?
50
+
51
+ Runtime::Logger.info("Running exec_commands...")
52
+ commands.each { |command| docker.exec(name, command) }
53
+ end
54
+
55
+ def gitaly_omnibus_configuration
56
+ <<~OMNIBUS
57
+ #{GitalyCluster.disable_other_omnibus_services}
58
+ praefect['enable'] = false;
59
+ prometheus['enable'] = true;
60
+ gitaly['enable'] = true;
61
+ gitaly['listen_addr'] = '0.0.0.0:#{gitaly_port}';
62
+ gitaly['prometheus_listen_addr'] = '0.0.0.0:9236';
63
+ gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN';
64
+ gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
65
+ gitlab_rails['internal_api_url'] = 'http://#{cluster_config.gitlab_name}.#{cluster_config.network}';
66
+ git_data_dirs({
67
+ '#{cluster_config.primary_node_name}' => {
68
+ 'path' => '/var/opt/gitlab/git-data'
69
+ },
70
+ '#{cluster_config.secondary_node_name}' => {
71
+ 'path' => '/var/opt/gitlab/git-data'
72
+ },
73
+ '#{cluster_config.tertiary_node_name}' => {
74
+ 'path' => '/var/opt/gitlab/git-data'
75
+ }
76
+ });
77
+ OMNIBUS
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Component
6
+ class GitalyCluster
7
+ class GitalyClusterConfig
8
+ attr_accessor :gitlab_name, :network, :airgapped_network,
9
+ :praefect_node_name, :praefect_port,
10
+ :primary_node_name, :primary_node_port,
11
+ :secondary_node_name, :secondary_node_port,
12
+ :tertiary_node_name, :tertiary_node_port,
13
+ :database_node_name, :database_port
14
+
15
+ attr_reader :praefect_addr, :primary_node_addr, :secondary_node_addr, :tertiary_node_addr, :database_node_addr
16
+
17
+ def initialize(params = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
18
+ @gitlab_name = params[:gitlab_name] || 'gitlab-gitaly-cluster'
19
+ @network = params[:network] || 'test'
20
+ @airgapped_network = params[:airgapped_network] || false
21
+
22
+ @praefect_node_name = params[:praefect_node_name] || 'praefect'
23
+ @praefect_port = params[:praefect_port] || 2305
24
+
25
+ @primary_node_name = params[:primary_node_name] || 'gitaly1'
26
+ @primary_node_port = params[:primary_node_port] || 8075
27
+
28
+ @secondary_node_name = params[:secondary_node_name] || 'gitaly2'
29
+ @secondary_node_port = params[:secondary_node_port] || 8075
30
+
31
+ @tertiary_node_name = params[:tertiary_node_name] || 'gitaly3'
32
+ @tertiary_node_port = params[:tertiary_node_port] || 8075
33
+
34
+ @database_node_name = params[:database_node_name] || 'postgres'
35
+ @database_port = params[:database_port] || 5432
36
+
37
+ @praefect_addr = "#{praefect_node_name}.#{network}"
38
+ @primary_node_addr = "#{primary_node_name}.#{network}"
39
+ @secondary_node_addr = "#{secondary_node_name}.#{network}"
40
+ @tertiary_node_addr = "#{tertiary_node_name}.#{network}"
41
+ @database_node_addr = "#{database_node_name}.#{network}"
42
+ end
43
+ end
44
+
45
+ include Scenario::Actable
46
+ using Rainbow
47
+
48
+ attr_accessor :release, :exec_commands, :gitlab_name, :config
49
+ attr_reader :gitaly_primary_node, :gitaly_secondary_node, :gitaly_tertiary_node, :praefect_node, :database_node
50
+
51
+ def initialize(config = GitalyClusterConfig.new)
52
+ @spec_suite = 'Test::Instance::All'
53
+ @env = {}
54
+ @tag = 'gitaly_cluster'
55
+ @release = 'EE'
56
+ @config = config
57
+ end
58
+
59
+ # @param [Boolean] parallel_gitaly controls whether we start gitaly nodes in parallel to improve startup time
60
+ def instance(parallel_gitaly = false)
61
+ run_gitaly_cluster(QA::Release.new(release), parallel_gitaly)
62
+ end
63
+
64
+ # @param [Boolean] parallel_gitaly controls whether we start gitaly nodes in parallel to improve startup time
65
+ def run_gitaly_cluster(release, parallel_gitaly = false)
66
+ # This also ensure that the docker network is created here, avoiding any potential race conditions later
67
+ # if the gitaly-cluster and GitLab containers attempt to create a network in parallel
68
+ @database_node = postgres
69
+
70
+ Thread.new do
71
+ Thread.current.abort_on_exception = true
72
+ start_gitaly_cluster(release, parallel_gitaly)
73
+ end
74
+ end
75
+
76
+ # @param [Boolean] parallel_gitaly controls whether we start gitaly nodes in parallel to improve startup time
77
+ def start_gitaly_cluster(release, parallel_gitaly = false) # rubocop:disable Metrics/AbcSize
78
+ Runtime::Logger.info("Starting Gitaly Cluster")
79
+
80
+ if parallel_gitaly
81
+ threads = []
82
+ threads << Thread.new { @gitaly_primary_node = gitaly(config.primary_node_name, config.primary_node_port, release) }
83
+ threads << Thread.new { @gitaly_secondary_node = gitaly(config.secondary_node_name, config.secondary_node_port, release) }
84
+ threads << Thread.new { @gitaly_tertiary_node = gitaly(config.tertiary_node_name, config.tertiary_node_port, release) }
85
+ threads.each(&:join)
86
+ else
87
+ @gitaly_primary_node = gitaly(config.primary_node_name, config.primary_node_port, release)
88
+ @gitaly_secondary_node = gitaly(config.secondary_node_name, config.secondary_node_port, release)
89
+ @gitaly_tertiary_node = gitaly(config.tertiary_node_name, config.tertiary_node_port, release)
90
+ end
91
+
92
+ @praefect_node = praefect(release)
93
+ Runtime::Logger.info("Gitaly Cluster Ready")
94
+ end
95
+
96
+ def postgres
97
+ Component::PostgreSQL.new.tap do |sql|
98
+ sql.name = config.database_node_name
99
+ sql.airgapped_network = config.airgapped_network
100
+ sql.network = config.network
101
+ sql.instance(skip_teardown: true) do
102
+ sql.run_psql '-d template1 -c "CREATE DATABASE praefect_production OWNER postgres"'
103
+ end
104
+ end
105
+ end
106
+
107
+ def gitaly(gitaly_name, port, release) # rubocop:disable Metrics/AbcSize
108
+ Component::Gitaly.new.tap do |gitaly|
109
+ gitaly.cluster_config = config
110
+ gitaly.release = release
111
+ gitaly.name = gitaly_name
112
+ gitaly.gitaly_port = port
113
+ gitaly.airgapped_network = config.airgapped_network
114
+ gitaly.network = config.network
115
+ gitaly.gitlab_name = config.gitlab_name
116
+ gitaly.instance(skip_teardown: true)
117
+ end
118
+ end
119
+
120
+ def praefect(release)
121
+ Component::Praefect.new.tap do |praefect|
122
+ praefect.cluster_config = config
123
+ praefect.name = config.praefect_node_name
124
+ praefect.airgapped_network = config.airgapped_network
125
+ praefect.network = config.network
126
+ praefect.release = release
127
+ praefect.instance(skip_teardown: true)
128
+ end
129
+ end
130
+
131
+ # Helper configuration for omnibus config to disable all non GitalyCluster related omnibus services
132
+ def self.disable_other_omnibus_services
133
+ <<~OMNIBUS
134
+ postgresql['enable'] = false;
135
+ redis['enable'] = false;
136
+ nginx['enable'] = false;
137
+ grafana['enable'] = false;
138
+ puma['enable'] = false;
139
+ sidekiq['enable'] = false;
140
+ gitlab_workhorse['enable'] = false;
141
+ gitlab_rails['rake_cache_clear'] = false;
142
+ gitlab_rails['auto_migrate'] = false;
143
+ gitlab_exporter['enable'] = false;
144
+ OMNIBUS
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -202,7 +202,7 @@ module Gitlab
202
202
  exec_commands << seed_admin_token_command if seed_admin_token
203
203
  exec_commands << seed_test_data_command if seed_db
204
204
  exec_commands << Runtime::Scenario.omnibus_exec_commands
205
- exec_commands << add_git_server_hooks unless skip_server_hooks
205
+ exec_commands << Support::ConfigScripts.add_git_server_hooks(docker, name) unless skip_server_hooks
206
206
 
207
207
  commands = exec_commands.flatten.uniq
208
208
  return if commands.empty?
@@ -280,28 +280,6 @@ module Gitlab
280
280
  ["gitlab-rails runner #{DATA_PATH}/admin_access_token_seed.rb"]
281
281
  end
282
282
 
283
- def add_git_server_hooks
284
- global_server_prereceive_hook = <<~SCRIPT
285
- #!/usr/bin/env bash
286
-
287
- if [[ \\\$GL_PROJECT_PATH =~ 'reject-prereceive' ]]; then
288
- echo 'GL-HOOK-ERR: Custom error message rejecting prereceive hook for projects with GL_PROJECT_PATH matching pattern reject-prereceive'
289
- exit 1
290
- fi
291
- SCRIPT
292
-
293
- [
294
- @docker.exec(name, 'mkdir -p /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d'),
295
- @docker.write_files(name) do |f|
296
- f.write(
297
- '/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/pre-receive.d',
298
- global_server_prereceive_hook, false
299
- )
300
- end,
301
- @docker.exec(name, 'chmod +x /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/*')
302
- ]
303
- end
304
-
305
283
  class Availability
306
284
  def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
307
285
  @docker = Docker::Engine.new
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Component
6
+ class Praefect < Base
7
+ extend Forwardable
8
+ using Rainbow
9
+ attr_reader :release
10
+ attr_accessor :cluster_config
11
+ attr_writer :name
12
+
13
+ def_delegators :release, :tag, :image, :edition
14
+
15
+ def initialize
16
+ super
17
+ self.release = 'EE'
18
+ @cluster_config = Component::GitalyCluster::GitalyClusterConfig.new
19
+ @ports = [cluster_config.praefect_port]
20
+ end
21
+
22
+ def name
23
+ @name || "praefect-#{SecureRandom.hex(4)}"
24
+ end
25
+
26
+ def release=(release)
27
+ @release = QA::Release.new(release)
28
+ end
29
+
30
+ def reconfigure
31
+ setup_omnibus
32
+ @docker.attach(name) do |line|
33
+ # TODO, workaround which allows to detach from the container
34
+ break if /gitlab Reconfigured!/.match?(line)
35
+ end
36
+ end
37
+
38
+ def setup_omnibus
39
+ @docker.write_files(name) do |f|
40
+ f.write('/etc/gitlab/gitlab.rb', praefect_omnibus_configuration)
41
+ end
42
+ end
43
+
44
+ def wait_until_ready
45
+ @docker.exec(name, 'praefect -config /var/opt/gitlab/praefect/cluster_config.toml check || true') do |resp|
46
+ Runtime::Logger.info(resp)
47
+ break if /All checks passed/.match?(line)
48
+ end
49
+ end
50
+
51
+ def praefect_omnibus_configuration # rubocop:disable Metrics/AbcSize
52
+ <<~OMNIBUS
53
+ #{GitalyCluster.disable_other_omnibus_services}
54
+ gitaly['enable'] = false;
55
+ prometheus['enable'] = true;
56
+ praefect['enable'] = true;
57
+ praefect['listen_addr'] = '0.0.0.0:#{cluster_config.praefect_port}';
58
+ praefect['prometheus_listen_addr'] = '0.0.0.0:9652';
59
+ praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN';
60
+ praefect['reconciliation_scheduling_interval'] = '10s';
61
+ praefect['database_host'] = '#{cluster_config.database_node_addr}';
62
+ praefect['database_user'] = 'postgres';
63
+ praefect['database_port'] = #{cluster_config.database_port};
64
+ praefect['database_password'] = 'SQL_PASSWORD';
65
+ praefect['database_dbname'] = 'praefect_production';
66
+ praefect['database_sslmode'] = 'disable';
67
+ praefect['database_direct_host'] = '#{cluster_config.database_node_addr}';
68
+ praefect['database_direct_port'] = #{cluster_config.database_port};
69
+ praefect['virtual_storages'] = {
70
+ 'default' => {
71
+ 'nodes' => {
72
+ '#{cluster_config.primary_node_name}' => {
73
+ 'address' => 'tcp://#{cluster_config.primary_node_addr}:#{cluster_config.primary_node_port}',
74
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN'
75
+ },
76
+ '#{cluster_config.secondary_node_name}' => {
77
+ 'address' => 'tcp://#{cluster_config.secondary_node_addr}:#{cluster_config.secondary_node_port}',
78
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN'
79
+ },
80
+ '#{cluster_config.tertiary_node_name}' => {
81
+ 'address' => 'tcp://#{cluster_config.tertiary_node_addr}:#{cluster_config.tertiary_node_port}',
82
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN'
83
+ }
84
+ }
85
+ }
86
+ };
87
+ OMNIBUS
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -7,7 +7,7 @@ module Gitlab
7
7
  class Release
8
8
  CANONICAL_REGEX = /
9
9
  \A
10
- (?<edition>ce|ee)
10
+ (?<edition>ce|ee|jh)
11
11
  (-qa)?
12
12
  (:(?<tag>.+))?
13
13
  \z
@@ -18,7 +18,7 @@ module Gitlab
18
18
  (?<registry>[^/:]+(:(?<port>\d+))?)
19
19
  (?<project>.+)
20
20
  gitlab-
21
- (?<edition>ce|ee)
21
+ (?<edition>ce|ee|jh)
22
22
  )
23
23
  (-qa)?
24
24
  (:(?<tag>.+))?
@@ -37,7 +37,7 @@ module Gitlab
37
37
  # version
38
38
  DEV_OFFICIAL_TAG_REGEX = /
39
39
  \A
40
- (?<version>\d+\.\d+.\d+(?:-rc\d+)?)-(?<edition>ce|ee)
40
+ (?<version>\d+\.\d+.\d+(?:-rc\d+)?)-(?<edition>ce|ee|jh)
41
41
  \z
42
42
  /xi.freeze
43
43
 
@@ -57,8 +57,8 @@ module Gitlab
57
57
 
58
58
  DEFAULT_TAG = 'latest'
59
59
  DEFAULT_CANONICAL_TAG = 'nightly'
60
- DEV_REGISTRY = 'dev.gitlab.org:5005'
61
- COM_REGISTRY = 'registry.gitlab.com'
60
+ DEV_REGISTRY = Gitlab::QA::Runtime::Env.qa_dev_registry
61
+ COM_REGISTRY = Gitlab::QA::Runtime::Env.qa_com_registry
62
62
 
63
63
  InvalidImageNameError = Class.new(RuntimeError)
64
64
 
@@ -138,7 +138,8 @@ module Gitlab
138
138
  'NO_ADMIN' => :no_admin,
139
139
  'CHROME_DISABLE_DEV_SHM' => :chrome_disable_dev_shm,
140
140
  'COLORIZED_LOGS' => :colorized_logs,
141
- 'FIPS' => :fips
141
+ 'FIPS' => :fips,
142
+ 'JH_ENV' => :jh_env
142
143
  }.freeze
143
144
 
144
145
  ENV_VARIABLES.each do |env_name, method_name|
@@ -357,6 +358,18 @@ module Gitlab
357
358
  (env_var_value_if_defined('QA_DOCKER_ADD_HOSTS') || '').split(',')
358
359
  end
359
360
 
361
+ def jh_env?
362
+ enabled?(env_var_value_if_defined('JH_ENV'), default: false)
363
+ end
364
+
365
+ def qa_dev_registry
366
+ env_var_value_if_defined('QA_DEV_REGISTRY') || 'dev.gitlab.org:5005'
367
+ end
368
+
369
+ def qa_com_registry
370
+ env_var_value_if_defined('QA_COM_REGISTRY') || 'registry.gitlab.com'
371
+ end
372
+
360
373
  private
361
374
 
362
375
  def enabled?(value, default: true)
@@ -7,51 +7,31 @@ module Gitlab
7
7
  module Instance
8
8
  class Airgapped < Scenario::Template
9
9
  require 'resolv'
10
- attr_accessor :commands
10
+ attr_reader :config, :gitlab_air_gap_commands
11
11
 
12
12
  def initialize
13
- gitlab_ip = Resolv.getaddress('registry.gitlab.com')
14
- @commands = <<~AIRGAP_AND_VERIFY_COMMAND.split(/\n+/)
15
- # Should not fail before airgapping due to eg. DNS failure
16
- # Ping and wget check
17
- apt-get update && apt-get install -y iptables nmap
18
- nmap -sT #{gitlab_ip} -p 80 && (echo \"Regular connectivity nmap check passed.\" && exit 0) || (echo \"Regular connectivity nmap check failed.\" && exit 1)
19
- echo "Checking regular connectivity..." \
20
- && wget --retry-connrefused --waitretry=1 --read-timeout=15 --timeout=10 -t 2 http://registry.gitlab.com > /dev/null 2>&1 \
21
- && (echo "Regular connectivity wget check passed." && exit 0) || (echo "Regular connectivity wget check failed." && exit 1)
22
-
23
- iptables -P INPUT DROP && iptables -P OUTPUT DROP
24
- iptables -A INPUT -i lo -j ACCEPT && iptables -A OUTPUT -o lo -j ACCEPT # LOOPBACK
25
- iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
26
- iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
27
-
28
- # Jenkins on port 8080 and 50000
29
- iptables -A OUTPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT \
30
- && iptables -A OUTPUT -p tcp -m tcp --dport 50000 -m state --state NEW,ESTABLISHED -j ACCEPT
31
- iptables -A OUTPUT -p tcp -m tcp --sport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
32
- iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
33
- iptables -A OUTPUT -p tcp -m tcp --sport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
34
- iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
35
-
36
- # Should now fail to ping and wget, port 80 should be open
37
- nmap -sT #{gitlab_ip} -p 80 && (echo \"Airgapped network faulty. Connectivity nmap check failed.\" && exit 1) || (echo \"Connectivity nmap check passed.\" && exit 0)
38
- nmap -sT 127.0.0.1 -p 22 && (echo "Airgapped connectivity port 22 check passed." && exit 0) || (echo "Airgapped connectivity port 22 check failed." && exit 1)
39
- nmap -sT 10 127.0.0.1 -p 80 && (echo "Airgapped connectivity port 80 check passed." && exit 0) || (echo "Airgapped connectivity port 80 check failed." && exit 1)
40
- echo "Checking airgapped connectivity..." \
41
- && wget --retry-connrefused --waitretry=1 --read-timeout=15 --timeout=10 -t 2 http://registry.gitlab.com > /dev/null 2>&1 \
42
- && (echo "Airgapped network faulty. Connectivity wget check failed." && exit 1) || (echo "Airgapped network confirmed. Connectivity wget check passed." && exit 0)
43
- AIRGAP_AND_VERIFY_COMMAND
13
+ @config = Component::GitalyCluster::GitalyClusterConfig.new(
14
+ airgapped_network: true,
15
+ network: 'airgapped'
16
+ )
44
17
  end
45
18
 
46
19
  def perform(release, *rspec_args)
47
20
  Component::Gitlab.perform do |gitlab|
21
+ cluster = Component::GitalyCluster.perform do |cluster|
22
+ cluster.config = @config
23
+ cluster.instance
24
+ end
25
+ gitlab.name = config.gitlab_name
48
26
  gitlab.release = release
49
- gitlab.network = 'test'
50
- gitlab.runner_network = 'airgapped'
51
- gitlab.exec_commands = @commands
27
+ gitlab.airgapped_network = true
28
+ gitlab.network = config.network
29
+ gitlab.omnibus_configuration << gitlab_omnibus_configuration
30
+ gitlab.skip_availability_check = true # airgapped environment cannot be pinged to check health
52
31
  rspec_args << "--" unless rspec_args.include?('--')
53
32
  rspec_args << %w[--tag ~orchestrated]
54
33
  gitlab.instance do
34
+ cluster.join
55
35
  Component::Specs.perform do |specs|
56
36
  specs.suite = 'Test::Instance::Airgapped'
57
37
  specs.release = gitlab.release
@@ -62,6 +42,45 @@ module Gitlab
62
42
  end
63
43
  end
64
44
  end
45
+
46
+ private
47
+
48
+ def gitlab_omnibus_configuration
49
+ <<~OMNIBUS
50
+ external_url 'http://#{config.gitlab_name}.#{config.network}';
51
+
52
+ git_data_dirs({
53
+ 'default' => {
54
+ 'gitaly_address' => 'tcp://#{config.praefect_addr}:#{config.praefect_port}',
55
+ 'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
56
+ }
57
+ });
58
+ gitaly['enable'] = false;
59
+ gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
60
+ prometheus['scrape_configs'] = [
61
+ {
62
+ 'job_name' => 'praefect',
63
+ 'static_configs' => [
64
+ 'targets' => [
65
+ '#{config.praefect_addr}:9652'
66
+ ]
67
+ ]
68
+ },
69
+ {
70
+ 'job_name' => 'praefect-gitaly',
71
+ 'static_configs' => [
72
+ 'targets' => [
73
+ '#{config.primary_node_addr}:9236',
74
+ '#{config.secondary_node_addr}:9236',
75
+ '#{config.tertiary_node_addr}:9236'
76
+ ]
77
+ ]
78
+ }
79
+ ];
80
+ grafana['disable_login_form'] = false;
81
+ grafana['admin_password'] = 'GRAFANA_ADMIN_PASSWORD';
82
+ OMNIBUS
83
+ end
65
84
  end
66
85
  end
67
86
  end
@@ -6,67 +6,24 @@ module Gitlab
6
6
  module Test
7
7
  module Integration
8
8
  class GitalyCluster < Scenario::Template
9
- attr_reader :gitlab_name, :spec_suite
10
-
11
- def initialize # rubocop:disable Metrics/AbcSize
12
- @gitlab_name = 'gitlab-gitaly-cluster'
13
-
14
- @primary_node_name = 'gitaly1'
15
- @primary_node_addr = "#{@primary_node_name}.#{@network}"
16
- @primary_node_port = 8075
17
-
18
- @secondary_node_name = 'gitaly2'
19
- @secondary_node_addr = "#{@secondary_node_name}.#{@network}"
20
- @secondary_node_port = 8075
21
-
22
- @tertiary_node_name = 'gitaly3'
23
- @tertiary_node_addr = "#{@tertiary_node_name}.#{@network}"
24
- @tertiary_node_port = 8075
25
-
26
- @praefect_node_name = 'praefect'
27
- @praefect_port = 2305
28
- @praefect_addr = "#{@praefect_node_name}.#{@network}"
29
-
30
- @database = 'postgres'
31
- @database_port = 5432
32
- @database_addr = "#{@database}.#{@network}"
9
+ attr_reader :gitlab_name, :spec_suite, :name, :config
33
10
 
11
+ def initialize
34
12
  @spec_suite = 'Test::Instance::All'
35
- @network = 'test'
36
13
  @env = {}
37
14
  @tag = 'gitaly_cluster'
15
+ @config = Component::GitalyCluster::GitalyClusterConfig.new
38
16
  end
39
17
 
40
18
  def perform(release, *rspec_args)
41
- run_gitaly_cluster(release, rspec_args)
42
- ensure
43
- @praefect_node&.teardown
44
- @sql_node&.teardown
45
- @gitaly_primary_node&.teardown
46
- @gitaly_secondary_node&.teardown
47
- @gitaly_tertiary_node&.teardown
48
- end
49
-
50
- def run_gitaly_cluster(release, rspec_args) # rubocop:disable Metrics/AbcSize
51
- # The postgres container starts in seconds so not essential to parallelize it
52
- # This also ensure that the docker network is created here, avoiding any potential race conditions later
53
- # if the gitaly-cluster and GitLab containers attempt to create a network in parallel
54
- @sql_node = postgres
55
-
56
- gitaly_cluster = Thread.new do
57
- Thread.current.abort_on_exception = true
58
- start_gitaly_cluster(release)
59
- end
60
-
61
19
  Component::Gitlab.perform do |gitlab|
62
20
  gitlab.release = QA::Release.new(release)
63
- gitlab.name = gitlab_name
64
- gitlab.network = @network
65
-
21
+ gitlab.name = config.gitlab_name
22
+ gitlab.network = config.network
66
23
  gitlab.omnibus_configuration << gitlab_omnibus_configuration
24
+ cluster = Component::GitalyCluster.perform(&:instance)
67
25
  gitlab.instance do
68
- # Wait for gitaly cluster to finish booting, before attempting to run specs
69
- gitaly_cluster.join
26
+ cluster.join
70
27
  Runtime::Logger.info('Running Gitaly Cluster specs!')
71
28
 
72
29
  if @tag
@@ -87,100 +44,13 @@ module Gitlab
87
44
 
88
45
  private
89
46
 
90
- def start_gitaly_cluster(release)
91
- Runtime::Logger.info("Starting Gitaly Cluster")
92
- @gitaly_primary_node = gitaly(@primary_node_name, @primary_node_port, release)
93
- @gitaly_secondary_node = gitaly(@secondary_node_name, @secondary_node_port, release)
94
- @gitaly_tertiary_node = gitaly(@tertiary_node_name, @tertiary_node_port, release)
95
-
96
- @praefect_node = praefect(@praefect_node_name, release)
97
- Runtime::Logger.info("Gitaly Cluster Ready")
98
- end
99
-
100
- def disable_other_services
101
- <<~OMNIBUS
102
- postgresql['enable'] = false;
103
- redis['enable'] = false;
104
- nginx['enable'] = false;
105
- prometheus['enable'] = false;
106
- grafana['enable'] = false;
107
- puma['enable'] = false;
108
- sidekiq['enable'] = false;
109
- gitlab_workhorse['enable'] = false;
110
- gitlab_rails['rake_cache_clear'] = false;
111
- gitlab_rails['auto_migrate'] = false;
112
- OMNIBUS
113
- end
114
-
115
- def praefect_omnibus_configuration
116
- <<~OMNIBUS
117
- #{disable_other_services}
118
- gitaly['enable'] = false;
119
- praefect['enable'] = true;
120
- praefect['listen_addr'] = '0.0.0.0:#{@praefect_port}';
121
- praefect['prometheus_listen_addr'] = '0.0.0.0:9652';
122
- praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN';
123
- praefect['reconciliation_scheduling_interval'] = '10s';
124
- praefect['database_host'] = '#{@database_addr}';
125
- praefect['database_user'] = 'postgres';
126
- praefect['database_port'] = #{@database_port};
127
- praefect['database_password'] = 'SQL_PASSWORD';
128
- praefect['database_dbname'] = 'praefect_production';
129
- praefect['database_sslmode'] = 'disable';
130
- praefect['database_direct_host'] = '#{@database_addr}';
131
- praefect['database_direct_port'] = #{@database_port};
132
- praefect['virtual_storages'] = {
133
- 'default' => {
134
- 'nodes' => {
135
- '#{@primary_node_name}' => {
136
- 'address' => 'tcp://#{@primary_node_addr}:#{@primary_node_port}',
137
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
138
- },
139
- '#{@secondary_node_name}' => {
140
- 'address' => 'tcp://#{@secondary_node_addr}:#{@secondary_node_port}',
141
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
142
- },
143
- '#{@tertiary_node_name}' => {
144
- 'address' => 'tcp://#{@tertiary_node_addr}:#{@tertiary_node_port}',
145
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
146
- }
147
- }
148
- }
149
- };
150
- OMNIBUS
151
- end
152
-
153
- def gitaly_omnibus_configuration(listen_port)
154
- <<~OMNIBUS
155
- #{disable_other_services.sub(/(prometheus\['enable'\]) = false/, '\1 = true')}
156
- prometheus_monitoring['enable'] = false;
157
- gitaly['enable'] = true;
158
- gitaly['listen_addr'] = '0.0.0.0:#{listen_port}';
159
- gitaly['prometheus_listen_addr'] = '0.0.0.0:9236';
160
- gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN';
161
- gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
162
- gitlab_rails['internal_api_url'] = 'http://#{@gitlab_name}.#{@network}';
163
- git_data_dirs({
164
- '#{@primary_node_name}' => {
165
- 'path' => '/var/opt/gitlab/git-data'
166
- },
167
- '#{@secondary_node_name}' => {
168
- 'path' => '/var/opt/gitlab/git-data'
169
- },
170
- '#{@tertiary_node_name}' => {
171
- 'path' => '/var/opt/gitlab/git-data'
172
- }
173
- });
174
- OMNIBUS
175
- end
176
-
177
47
  def gitlab_omnibus_configuration
178
48
  <<~OMNIBUS
179
- external_url 'http://#{@gitlab_name}.#{@network}';
49
+ external_url 'http://#{config.gitlab_name}.#{config.network}';
180
50
 
181
51
  git_data_dirs({
182
52
  'default' => {
183
- 'gitaly_address' => 'tcp://#{@praefect_addr}:#{@praefect_port}',
53
+ 'gitaly_address' => 'tcp://#{config.praefect_addr}:#{config.praefect_port}',
184
54
  'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
185
55
  }
186
56
  });
@@ -191,7 +61,7 @@ module Gitlab
191
61
  'job_name' => 'praefect',
192
62
  'static_configs' => [
193
63
  'targets' => [
194
- '#{@praefect_node_name}.#{@network}:9652'
64
+ '#{config.praefect_addr}:9652'
195
65
  ]
196
66
  ]
197
67
  },
@@ -199,9 +69,9 @@ module Gitlab
199
69
  'job_name' => 'praefect-gitaly',
200
70
  'static_configs' => [
201
71
  'targets' => [
202
- '#{@primary_node_name}.#{@network}:9236',
203
- '#{@secondary_node_name}.#{@network}:9236',
204
- '#{@tertiary_node_name}.#{@network}:9236'
72
+ '#{config.primary_node_addr}:9236',
73
+ '#{config.secondary_node_addr}:9236',
74
+ '#{config.tertiary_node_addr}:9236'
205
75
  ]
206
76
  ]
207
77
  }
@@ -210,42 +80,6 @@ module Gitlab
210
80
  grafana['admin_password'] = 'GRAFANA_ADMIN_PASSWORD';
211
81
  OMNIBUS
212
82
  end
213
-
214
- def praefect(name, release)
215
- Component::Gitlab.new.tap do |praefect|
216
- praefect.release = QA::Release.new(release)
217
- praefect.name = name
218
- praefect.network = @network
219
- praefect.skip_availability_check = true
220
- praefect.seed_admin_token = false
221
-
222
- praefect.omnibus_configuration << praefect_omnibus_configuration
223
-
224
- praefect.instance(skip_teardown: true)
225
- end
226
- end
227
-
228
- def postgres
229
- Component::PostgreSQL.new.tap do |sql|
230
- sql.name = @database
231
- sql.network = @network
232
- sql.instance(skip_teardown: true) do
233
- sql.run_psql '-d template1 -c "CREATE DATABASE praefect_production OWNER postgres"'
234
- end
235
- end
236
- end
237
-
238
- def gitaly(name, port, release)
239
- Component::Gitlab.new.tap do |gitaly|
240
- gitaly.release = QA::Release.new(release)
241
- gitaly.name = name
242
- gitaly.network = @network
243
- gitaly.skip_availability_check = true
244
- gitaly.seed_admin_token = false
245
- gitaly.omnibus_configuration << gitaly_omnibus_configuration(port)
246
- gitaly.instance(skip_teardown: true)
247
- end
248
- end
249
83
  end
250
84
  end
251
85
  end
@@ -15,17 +15,17 @@ module Gitlab
15
15
  @env = { QA_PRAEFECT_REPOSITORY_STORAGE: 'default' }
16
16
  end
17
17
 
18
- def gitlab_omnibus_configuration
18
+ def gitlab_omnibus_configuration # rubocop:disable Metrics/AbcSize
19
19
  <<~OMNIBUS
20
- external_url 'http://#{@gitlab_name}.#{@network}';
20
+ external_url 'http://#{config.gitlab_name}.#{config.network}';
21
21
 
22
22
  git_data_dirs({
23
23
  'default' => {
24
- 'gitaly_address' => 'tcp://#{@praefect_addr}:#{@praefect_port}',
24
+ 'gitaly_address' => 'tcp://#{config.praefect_addr}:#{config.praefect_port}',
25
25
  'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
26
26
  },
27
27
  'gitaly' => {
28
- 'gitaly_address' => 'tcp://#{@gitlab_name}.#{@network}:8075',
28
+ 'gitaly_address' => 'tcp://#{config.gitlab_name}.#{config.network}:8075',
29
29
  'path' => '/var/opt/gitlab/git-data'
30
30
  }
31
31
  });
@@ -45,7 +45,7 @@ module Gitlab
45
45
  'job_name' => 'praefect',
46
46
  'static_configs' => [
47
47
  'targets' => [
48
- '#{@praefect_addr}:9652'
48
+ '#{config.praefect_addr}:9652'
49
49
  ]
50
50
  ]
51
51
  },
@@ -53,9 +53,9 @@ module Gitlab
53
53
  'job_name' => 'praefect-gitaly',
54
54
  'static_configs' => [
55
55
  'targets' => [
56
- '#{@primary_node_addr}:9236',
57
- '#{@secondary_node_addr}:9236',
58
- '#{@tertiary_node_addr}:9236'
56
+ '#{config.primary_node_addr}:9236',
57
+ '#{config.secondary_node_addr}:9236',
58
+ '#{config.tertiary_node_addr}:9236'
59
59
  ]
60
60
  ]
61
61
  }
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Support
6
+ module ConfigScripts
7
+ # Add a git server hooks with a custom error message
8
+ # See https://docs.gitlab.com/ee/administration/server_hooks.html for details
9
+ def self.add_git_server_hooks(docker, name)
10
+ global_server_prereceive_hook = <<~SCRIPT
11
+ #!/usr/bin/env bash
12
+
13
+ if [[ \\\$GL_PROJECT_PATH =~ 'reject-prereceive' ]]; then
14
+ echo 'GL-HOOK-ERR: Custom error message rejecting prereceive hook for projects with GL_PROJECT_PATH matching pattern reject-prereceive'
15
+ exit 1
16
+ fi
17
+ SCRIPT
18
+
19
+ [
20
+ docker.exec(name, 'mkdir -p /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d'),
21
+ docker.write_files(name) do |f|
22
+ f.write(
23
+ '/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/pre-receive.d',
24
+ global_server_prereceive_hook, false
25
+ )
26
+ end,
27
+ docker.exec(name, 'chmod +x /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/*')
28
+ ]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '8.13.1'
5
+ VERSION = '8.14.0'
6
6
  end
7
7
  end
@@ -23,6 +23,7 @@ class GenerateQAJobs
23
23
  jobs.merge!(load_yml_contents('update', should_automatically_run?('test_instance_all')))
24
24
  jobs.merge!(load_yml_contents('omnibus_upgrade'))
25
25
  jobs.merge!(load_yml_contents('ee_previous_to_ce_update'))
26
+ jobs.merge!(load_yml_contents('airgapped', should_automatically_run?('test_instance_all')))
26
27
  jobs.merge!(load_yml_contents('mattermost', should_automatically_run?('test_integration_mattermost')))
27
28
  jobs.merge!(load_yml_contents('service_ping_disabled', should_automatically_run?('test_integration_servicepingdisabled')))
28
29
  jobs.merge!(load_yml_contents('ldap_no_tls', should_automatically_run?('test_integration_ldapnotls')))
@@ -24,7 +24,7 @@ class LicenseUsageSeed
24
24
 
25
25
  User.create!(
26
26
  email: "#{name}@test.com",
27
- password: 'password',
27
+ password: SecureRandom.hex.slice(0, 16),
28
28
  username: name,
29
29
  name: "User #{name}",
30
30
  confirmed_at: Time.current
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-qa
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.13.1
4
+ version: 8.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-23 00:00:00.000000000 Z
11
+ date: 2022-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -244,6 +244,7 @@ files:
244
244
  - ".dockerignore"
245
245
  - ".gitignore"
246
246
  - ".gitlab-ci.yml"
247
+ - ".gitlab/ci/jobs/airgapped.gitlab-ci.yml"
247
248
  - ".gitlab/ci/jobs/base.gitlab-ci.yml"
248
249
  - ".gitlab/ci/jobs/chaos.gitlab-ci.yml"
249
250
  - ".gitlab/ci/jobs/cloud_activation.gitlab-ci.yml"
@@ -328,6 +329,8 @@ files:
328
329
  - lib/gitlab/qa/component/base.rb
329
330
  - lib/gitlab/qa/component/chaos.rb
330
331
  - lib/gitlab/qa/component/elasticsearch.rb
332
+ - lib/gitlab/qa/component/gitaly.rb
333
+ - lib/gitlab/qa/component/gitaly_cluster.rb
331
334
  - lib/gitlab/qa/component/gitlab.rb
332
335
  - lib/gitlab/qa/component/jira.rb
333
336
  - lib/gitlab/qa/component/ldap.rb
@@ -336,6 +339,7 @@ files:
336
339
  - lib/gitlab/qa/component/mock_server.rb
337
340
  - lib/gitlab/qa/component/opensearch.rb
338
341
  - lib/gitlab/qa/component/postgresql.rb
342
+ - lib/gitlab/qa/component/praefect.rb
339
343
  - lib/gitlab/qa/component/preprod.rb
340
344
  - lib/gitlab/qa/component/production.rb
341
345
  - lib/gitlab/qa/component/release.rb
@@ -436,6 +440,7 @@ files:
436
440
  - lib/gitlab/qa/service/cluster_provider/k3d.rb
437
441
  - lib/gitlab/qa/service/kubernetes_cluster.rb
438
442
  - lib/gitlab/qa/slack/post_to_slack.rb
443
+ - lib/gitlab/qa/support/config_scripts.rb
439
444
  - lib/gitlab/qa/support/get_request.rb
440
445
  - lib/gitlab/qa/support/gitlab_upgrade_path.rb
441
446
  - lib/gitlab/qa/support/gitlab_version_info.rb