gitlab-qa 5.13.7 → 5.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +42 -1
- data/README.md +52 -5
- data/docs/what_tests_can_be_run.md +97 -5
- data/lib/gitlab/qa.rb +2 -1
- data/lib/gitlab/qa/component/base.rb +32 -7
- data/lib/gitlab/qa/component/gitlab.rb +2 -1
- data/lib/gitlab/qa/component/specs.rb +44 -12
- data/lib/gitlab/qa/docker/command.rb +15 -3
- data/lib/gitlab/qa/docker/engine.rb +17 -2
- data/lib/gitlab/qa/docker/shellout.rb +2 -2
- data/lib/gitlab/qa/release.rb +17 -4
- data/lib/gitlab/qa/runner.rb +23 -15
- data/lib/gitlab/qa/runtime/env.rb +15 -6
- data/lib/gitlab/qa/scenario/test/instance/airgapped.rb +68 -0
- data/lib/gitlab/qa/scenario/test/instance/geo.rb +0 -3
- data/lib/gitlab/qa/scenario/test/integration/geo.rb +4 -2
- data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +201 -0
- data/lib/gitlab/qa/scenario/test/integration/praefect.rb +18 -7
- data/lib/gitlab/qa/scenario/test/sanity/version.rb +1 -1
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +4 -3
- data/lib/gitlab/qa/scenario/test/integration/gitaly_ha.rb +0 -166
@@ -4,8 +4,9 @@ module Gitlab
|
|
4
4
|
class Command
|
5
5
|
attr_reader :args
|
6
6
|
|
7
|
-
def initialize(cmd = nil)
|
7
|
+
def initialize(cmd = nil, mask_secrets: nil)
|
8
8
|
@args = Array(cmd)
|
9
|
+
@mask_secrets = Array(mask_secrets)
|
9
10
|
end
|
10
11
|
|
11
12
|
def <<(*args)
|
@@ -28,6 +29,17 @@ module Gitlab
|
|
28
29
|
"docker #{@args.join(' ')}"
|
29
30
|
end
|
30
31
|
|
32
|
+
# Returns a masked string form of a Command
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# Command.new('a docker command', mask_secrets: 'command').mask_secrets #=> 'a docker *****'
|
36
|
+
# Command.new('a docker command', mask_secrets: %w[docker command]).mask_secrets #=> 'a ***** *****'
|
37
|
+
#
|
38
|
+
# @return [String] The masked command string
|
39
|
+
def mask_secrets
|
40
|
+
@mask_secrets.each_with_object(to_s) { |secret, s| s.gsub!(secret, '*****') }
|
41
|
+
end
|
42
|
+
|
31
43
|
def ==(other)
|
32
44
|
to_s == other.to_s
|
33
45
|
end
|
@@ -36,8 +48,8 @@ module Gitlab
|
|
36
48
|
Docker::Shellout.new(self).execute!(&block)
|
37
49
|
end
|
38
50
|
|
39
|
-
def self.execute(cmd, &block)
|
40
|
-
new(cmd).execute!(&block)
|
51
|
+
def self.execute(cmd, mask_secrets: nil, &block)
|
52
|
+
new(cmd, mask_secrets: mask_secrets).execute!(&block)
|
41
53
|
end
|
42
54
|
end
|
43
55
|
end
|
@@ -3,13 +3,14 @@ module Gitlab
|
|
3
3
|
module Docker
|
4
4
|
class Engine
|
5
5
|
DOCKER_HOST = ENV['DOCKER_HOST'] || 'http://localhost'
|
6
|
+
PRIVILEGED_COMMANDS = [/^iptables.*/].freeze
|
6
7
|
|
7
8
|
def hostname
|
8
9
|
URI(DOCKER_HOST).host
|
9
10
|
end
|
10
11
|
|
11
12
|
def login(username:, password:, registry:)
|
12
|
-
Docker::Command.execute(%(login --username "#{username}" --password "#{password}" #{registry}))
|
13
|
+
Docker::Command.execute(%(login --username "#{username}" --password "#{password}" #{registry}), mask_secrets: password)
|
13
14
|
end
|
14
15
|
|
15
16
|
def pull(image, tag)
|
@@ -27,8 +28,18 @@ module Gitlab
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def privileged_command?(command)
|
32
|
+
PRIVILEGED_COMMANDS.each do |privileged_regex|
|
33
|
+
return true if command.match(privileged_regex)
|
34
|
+
end
|
35
|
+
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
30
39
|
def exec(name, command)
|
31
|
-
|
40
|
+
cmd = ['exec']
|
41
|
+
cmd << '--privileged' if privileged_command?(command)
|
42
|
+
Docker::Command.execute("#{cmd.join(' ')} #{name} bash -c '#{command}'")
|
32
43
|
end
|
33
44
|
|
34
45
|
def read_file(image, tag, path, &block)
|
@@ -71,6 +82,10 @@ module Gitlab
|
|
71
82
|
def running?(name)
|
72
83
|
Docker::Command.execute("ps -f name=#{name}").include?(name)
|
73
84
|
end
|
85
|
+
|
86
|
+
def ps(name = nil)
|
87
|
+
Docker::Command.execute(['ps', name].compact.join(' '))
|
88
|
+
end
|
74
89
|
end
|
75
90
|
end
|
76
91
|
end
|
@@ -10,7 +10,7 @@ module Gitlab
|
|
10
10
|
@command = command
|
11
11
|
@output = []
|
12
12
|
|
13
|
-
puts "Docker shell command: `#{@command}`"
|
13
|
+
puts "Docker shell command: `#{@command.mask_secrets}`"
|
14
14
|
end
|
15
15
|
|
16
16
|
def execute!
|
@@ -28,7 +28,7 @@ module Gitlab
|
|
28
28
|
end
|
29
29
|
|
30
30
|
if wait.value.exited? && wait.value.exitstatus.nonzero?
|
31
|
-
raise StatusError, "Docker command `#{@command}` failed!"
|
31
|
+
raise StatusError, "Docker command `#{@command.mask_secrets}` failed!"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
data/lib/gitlab/qa/release.rb
CHANGED
@@ -136,6 +136,8 @@ module Gitlab
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def login_params
|
139
|
+
return if Runtime::Env.skip_pull?
|
140
|
+
|
139
141
|
if dev_gitlab_org?
|
140
142
|
Runtime::Env.require_qa_dev_access_token!
|
141
143
|
|
@@ -145,11 +147,18 @@ module Gitlab
|
|
145
147
|
registry: DEV_REGISTRY
|
146
148
|
}
|
147
149
|
elsif omnibus_mirror?
|
148
|
-
Runtime::Env.
|
149
|
-
|
150
|
+
username, password = if Runtime::Env.ci_job_token && Runtime::Env.ci_pipeline_source == 'pipeline'
|
151
|
+
['gitlab-ci-token', Runtime::Env.ci_job_token]
|
152
|
+
elsif Runtime::Env.qa_container_registry_access_token
|
153
|
+
[Runtime::Env.gitlab_username, Runtime::Env.qa_container_registry_access_token]
|
154
|
+
else
|
155
|
+
Runtime::Env.require_qa_access_token!
|
156
|
+
|
157
|
+
[Runtime::Env.gitlab_username, Runtime::Env.qa_access_token]
|
158
|
+
end
|
150
159
|
{
|
151
|
-
username:
|
152
|
-
password:
|
160
|
+
username: username,
|
161
|
+
password: password,
|
153
162
|
registry: COM_REGISTRY
|
154
163
|
}
|
155
164
|
end
|
@@ -167,6 +176,10 @@ module Gitlab
|
|
167
176
|
canonical? || release.match?(CUSTOM_GITLAB_IMAGE_REGEX)
|
168
177
|
end
|
169
178
|
|
179
|
+
def api_project_name
|
180
|
+
project_name.gsub('ce', 'foss').gsub('-ee', '')
|
181
|
+
end
|
182
|
+
|
170
183
|
private
|
171
184
|
|
172
185
|
def canonical?
|
data/lib/gitlab/qa/runner.rb
CHANGED
@@ -4,22 +4,20 @@ module Gitlab
|
|
4
4
|
module QA
|
5
5
|
# rubocop:disable Metrics/AbcSize
|
6
6
|
class Runner
|
7
|
-
# These options are implemented in the QA framework (i.e., in the CE/EE codebase)
|
8
|
-
# They're included here so that gitlab-qa treats them as valid options
|
9
|
-
PASS_THROUGH_OPTS = [
|
10
|
-
['--address URL', 'Address of the instance to test'],
|
11
|
-
['--enable-feature FEATURE_FLAG', 'Enable a feature before running tests'],
|
12
|
-
['--mattermost-address URL', 'Address of the Mattermost server'],
|
13
|
-
['--parallel', 'Execute tests in parallel'],
|
14
|
-
['--loop', 'Execute tests in a loop']
|
15
|
-
].freeze
|
16
|
-
|
17
7
|
def self.run(args)
|
18
|
-
|
8
|
+
Runtime::Scenario.define(:teardown, true)
|
9
|
+
Runtime::Scenario.define(:run_tests, true)
|
10
|
+
|
11
|
+
@options = OptionParser.new do |opts|
|
19
12
|
opts.banner = 'Usage: gitlab-qa [options] Scenario URL [[--] path] [rspec_options]'
|
20
13
|
|
21
|
-
|
22
|
-
|
14
|
+
opts.on('--no-teardown', 'Skip teardown of containers after the scenario completes.') do
|
15
|
+
Runtime::Scenario.define(:teardown, false)
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('--no-tests', 'Orchestrates the docker containers but does not run the tests. Implies --no-teardown') do
|
19
|
+
Runtime::Scenario.define(:run_tests, false)
|
20
|
+
Runtime::Scenario.define(:teardown, false)
|
23
21
|
end
|
24
22
|
|
25
23
|
opts.on_tail('-v', '--version', 'Show the version') do
|
@@ -33,19 +31,29 @@ module Gitlab
|
|
33
31
|
exit
|
34
32
|
end
|
35
33
|
|
36
|
-
|
34
|
+
begin
|
35
|
+
opts.parse(args)
|
36
|
+
rescue OptionParser::InvalidOption
|
37
|
+
# Ignore invalid options and options that are passed through to the tests
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
41
|
+
args.reject! { |arg| gitlab_qa_options.include?(arg) }
|
42
|
+
|
39
43
|
if args.size >= 1
|
40
44
|
Scenario
|
41
45
|
.const_get(args.shift)
|
42
46
|
.perform(*args)
|
43
47
|
else
|
44
|
-
puts options
|
48
|
+
puts @options
|
45
49
|
exit 1
|
46
50
|
end
|
47
51
|
end
|
48
52
|
# rubocop:enable Metrics/AbcSize
|
53
|
+
|
54
|
+
def self.gitlab_qa_options
|
55
|
+
@gitlab_qa_options ||= @options.top.list.map(&:long).flatten
|
56
|
+
end
|
49
57
|
end
|
50
58
|
end
|
51
59
|
end
|
@@ -6,6 +6,8 @@ module Gitlab
|
|
6
6
|
module Env
|
7
7
|
extend self
|
8
8
|
|
9
|
+
# Variables that are used in tests and are passed through to the docker container that executes the tests.
|
10
|
+
# These variables should be listed in /docs/what_tests_can_be_run.md#supported-gitlab-environment-variables
|
9
11
|
ENV_VARIABLES = {
|
10
12
|
'QA_REMOTE_GRID' => :remote_grid,
|
11
13
|
'QA_REMOTE_GRID_USERNAME' => :remote_grid_username,
|
@@ -38,6 +40,7 @@ module Gitlab
|
|
38
40
|
'SIGNUP_DISABLED' => :signup_disabled,
|
39
41
|
'QA_ADDITIONAL_REPOSITORY_STORAGE' => :qa_additional_repository_storage,
|
40
42
|
'QA_PRAEFECT_REPOSITORY_STORAGE' => :qa_praefect_repository_storage,
|
43
|
+
'QA_GITALY_NON_CLUSTER_STORAGE' => :qa_gitaly_non_cluster_storage,
|
41
44
|
'QA_COOKIES' => :qa_cookie,
|
42
45
|
'QA_DEBUG' => :qa_debug,
|
43
46
|
'QA_LOG_PATH' => :qa_log_path,
|
@@ -104,10 +107,18 @@ module Gitlab
|
|
104
107
|
ENV['CI_JOB_NAME']
|
105
108
|
end
|
106
109
|
|
110
|
+
def ci_job_token
|
111
|
+
ENV['CI_JOB_TOKEN']
|
112
|
+
end
|
113
|
+
|
107
114
|
def ci_job_url
|
108
115
|
ENV['CI_JOB_URL']
|
109
116
|
end
|
110
117
|
|
118
|
+
def ci_pipeline_source
|
119
|
+
ENV['CI_PIPELINE_SOURCE']
|
120
|
+
end
|
121
|
+
|
111
122
|
def ci_project_name
|
112
123
|
ENV['CI_PROJECT_NAME']
|
113
124
|
end
|
@@ -144,6 +155,10 @@ module Gitlab
|
|
144
155
|
ENV['GITLAB_QA_DEV_ACCESS_TOKEN']
|
145
156
|
end
|
146
157
|
|
158
|
+
def qa_container_registry_access_token
|
159
|
+
ENV['GITLAB_QA_CONTAINER_REGISTRY_ACCESS_TOKEN']
|
160
|
+
end
|
161
|
+
|
147
162
|
def host_artifacts_dir
|
148
163
|
@host_artifacts_dir ||= File.join(ENV['QA_ARTIFACTS_DIR'] || '/tmp/gitlab-qa', Runtime::Env.run_id)
|
149
164
|
end
|
@@ -207,12 +222,6 @@ module Gitlab
|
|
207
222
|
end
|
208
223
|
end
|
209
224
|
|
210
|
-
def require_gitlab_bot_multi_project_pipeline_polling_token!
|
211
|
-
return unless ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN'].to_s.strip.empty?
|
212
|
-
|
213
|
-
raise ArgumentError, "Please provide GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN"
|
214
|
-
end
|
215
|
-
|
216
225
|
def skip_pull?
|
217
226
|
enabled?(ENV['QA_SKIP_PULL'], default: false)
|
218
227
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module QA
|
3
|
+
module Scenario
|
4
|
+
module Test
|
5
|
+
module Instance
|
6
|
+
class Airgapped < Scenario::Template
|
7
|
+
require 'resolv'
|
8
|
+
attr_accessor :commands
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
gitlab_ip = Resolv.getaddress('registry.gitlab.com')
|
12
|
+
@commands = <<~AIRGAP_AND_VERIFY_COMMAND.split(/\n+/)
|
13
|
+
# Should not fail before airgapping due to eg. DNS failure
|
14
|
+
# Ping and wget check
|
15
|
+
apt-get update && apt-get install -y iptables netcat
|
16
|
+
nc -zv -w 10 #{gitlab_ip} 80 && (echo \"Regular connectivity netcat check passed.\" && exit 0) || (echo \"Regular connectivity netcat check failed.\" && exit 1)
|
17
|
+
echo "Checking regular connectivity..." \
|
18
|
+
&& wget --retry-connrefused --waitretry=1 --read-timeout=15 --timeout=10 -t 2 http://registry.gitlab.com > /dev/null 2>&1 \
|
19
|
+
&& (echo "Regular connectivity wget check passed." && exit 0) || (echo "Regular connectivity wget check failed." && exit 1)
|
20
|
+
|
21
|
+
iptables -P INPUT DROP && iptables -P OUTPUT DROP
|
22
|
+
iptables -A INPUT -i lo -j ACCEPT && iptables -A OUTPUT -o lo -j ACCEPT # LOOPBACK
|
23
|
+
iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
24
|
+
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
25
|
+
|
26
|
+
# Jenkins on port 8080 and 50000
|
27
|
+
iptables -A OUTPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT \
|
28
|
+
&& iptables -A OUTPUT -p tcp -m tcp --dport 50000 -m state --state NEW,ESTABLISHED -j ACCEPT
|
29
|
+
iptables -A OUTPUT -p tcp -m tcp --sport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
|
30
|
+
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
|
31
|
+
iptables -A OUTPUT -p tcp -m tcp --sport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
|
32
|
+
iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
|
33
|
+
|
34
|
+
# Should now fail to ping and wget, port 80 should be open
|
35
|
+
nc -zv -w 10 #{gitlab_ip} 80 && (echo \"Airgapped network faulty. Connectivity netcat check failed.\" && exit 1) || (echo \"Connectivity netcat check passed.\" && exit 0)
|
36
|
+
nc -zv -w 10 127.0.0.1 22 && (echo "Airgapped connectivity port 22 check passed." && exit 0) || (echo "Airgapped connectivity port 22 check failed." && exit 1)
|
37
|
+
nc -zv -w 10 127.0.0.1 80 && (echo "Airgapped connectivity port 80 check passed." && exit 0) || (echo "Airgapped connectivity port 80 check failed." && exit 1)
|
38
|
+
echo "Checking airgapped connectivity..." \
|
39
|
+
&& wget --retry-connrefused --waitretry=1 --read-timeout=15 --timeout=10 -t 2 http://registry.gitlab.com > /dev/null 2>&1 \
|
40
|
+
&& (echo "Airgapped network faulty. Connectivity wget check failed." && exit 1) || (echo "Airgapped network confirmed. Connectivity wget check passed." && exit 0)
|
41
|
+
AIRGAP_AND_VERIFY_COMMAND
|
42
|
+
end
|
43
|
+
|
44
|
+
def perform(release, *rspec_args)
|
45
|
+
Component::Gitlab.perform do |gitlab|
|
46
|
+
gitlab.release = release
|
47
|
+
gitlab.network = 'test'
|
48
|
+
gitlab.runner_network = 'airgapped'
|
49
|
+
gitlab.exec_commands = @commands
|
50
|
+
rspec_args << "--" unless rspec_args.include?('--')
|
51
|
+
rspec_args << %w[--tag ~orchestrated]
|
52
|
+
gitlab.instance do
|
53
|
+
Component::Specs.perform do |specs|
|
54
|
+
specs.suite = 'Test::Instance::Airgapped'
|
55
|
+
specs.release = gitlab.release
|
56
|
+
specs.network = gitlab.network
|
57
|
+
specs.runner_network = gitlab.runner_network
|
58
|
+
specs.args = [gitlab.address, *rspec_args]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -8,9 +8,6 @@ module Gitlab
|
|
8
8
|
|
9
9
|
class Geo < Scenario::Template
|
10
10
|
def perform(release, primary_address, secondary_address, *rspec_args)
|
11
|
-
# Geo requires an EE license
|
12
|
-
Runtime::Env.require_license!
|
13
|
-
|
14
11
|
Component::Specs.perform do |specs|
|
15
12
|
specs.suite = 'QA::EE::Scenario::Test::Geo'
|
16
13
|
specs.release = QA::Release.new(release)
|
@@ -27,13 +27,14 @@ module Gitlab
|
|
27
27
|
gitlab_rails['db_pool'] = 5;
|
28
28
|
gitlab_rails['geo_node_name'] = '#{primary.name}';
|
29
29
|
gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0'];
|
30
|
+
gitlab_rails['packages_enabled'] = true;
|
30
31
|
postgresql['listen_address'] = '0.0.0.0';
|
31
32
|
postgresql['max_replication_slots'] = 1;
|
32
33
|
postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0'];
|
33
34
|
postgresql['sql_user_password'] = 'e1d1469ec5f533651918b4567a3ed1ae';
|
34
35
|
postgresql['trust_auth_cidr_addresses'] = ['0.0.0.0/0','0.0.0.0/0'];
|
35
36
|
sidekiq['concurrency'] = 2;
|
36
|
-
|
37
|
+
puma['worker_processes'] = 2;
|
37
38
|
OMNIBUS
|
38
39
|
primary.exec_commands = fast_ssh_key_lookup_commands + git_lfs_install_commands
|
39
40
|
|
@@ -50,11 +51,12 @@ module Gitlab
|
|
50
51
|
gitlab_rails['db_pool'] = 5;
|
51
52
|
gitlab_rails['geo_node_name'] = '#{secondary.name}';
|
52
53
|
gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0'];
|
54
|
+
gitlab_rails['packages_enabled'] = true;
|
53
55
|
postgresql['listen_address'] = '0.0.0.0';
|
54
56
|
postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0'];
|
55
57
|
postgresql['sql_user_password'] = 'e1d1469ec5f533651918b4567a3ed1ae';
|
56
58
|
sidekiq['concurrency'] = 2;
|
57
|
-
|
59
|
+
puma['worker_processes'] = 2;
|
58
60
|
OMNIBUS
|
59
61
|
secondary.exec_commands = fast_ssh_key_lookup_commands + git_lfs_install_commands
|
60
62
|
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module QA
|
3
|
+
module Scenario
|
4
|
+
module Test
|
5
|
+
module Integration
|
6
|
+
class GitalyCluster < Scenario::Template
|
7
|
+
attr_reader :gitlab_name, :spec_suite
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@gitlab_name = 'gitlab-gitaly-ha'
|
11
|
+
@primary_node_name = 'gitaly1'
|
12
|
+
@secondary_node_name = 'gitaly2'
|
13
|
+
@tertiary_node_name = 'gitaly3'
|
14
|
+
@praefect_node_name = 'praefect'
|
15
|
+
@database = 'postgres'
|
16
|
+
@spec_suite = 'Test::Integration::GitalyHA'
|
17
|
+
@network = 'test'
|
18
|
+
end
|
19
|
+
|
20
|
+
# rubocop:disable Metrics/AbcSize
|
21
|
+
def perform(release, *rspec_args)
|
22
|
+
gitaly_primary_node = gitaly(@primary_node_name, release)
|
23
|
+
gitaly_secondary_node = gitaly(@secondary_node_name, release)
|
24
|
+
gitaly_tertiary_node = gitaly(@tertiary_node_name, release)
|
25
|
+
|
26
|
+
sql_node = Component::PostgreSQL.new.tap do |sql|
|
27
|
+
sql.name = @database
|
28
|
+
sql.network = @network
|
29
|
+
sql.instance_no_teardown do
|
30
|
+
sql.run_psql '-d template1 -c "CREATE DATABASE praefect_production OWNER postgres"'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
praefect_node = Component::Gitlab.new.tap do |praefect|
|
35
|
+
praefect.release = QA::Release.new(release)
|
36
|
+
praefect.name = @praefect_node_name
|
37
|
+
praefect.network = @network
|
38
|
+
praefect.skip_availability_check = true
|
39
|
+
|
40
|
+
praefect.omnibus_config = praefect_omnibus_configuration
|
41
|
+
|
42
|
+
praefect.instance_no_teardown
|
43
|
+
end
|
44
|
+
|
45
|
+
Component::Gitlab.perform do |gitlab|
|
46
|
+
gitlab.release = QA::Release.new(release)
|
47
|
+
gitlab.name = gitlab_name
|
48
|
+
gitlab.network = @network
|
49
|
+
|
50
|
+
gitlab.omnibus_config = gitlab_omnibus_configuration
|
51
|
+
gitlab.instance do
|
52
|
+
puts "Running Gitaly HA specs!"
|
53
|
+
|
54
|
+
Component::Specs.perform do |specs|
|
55
|
+
specs.suite = spec_suite
|
56
|
+
specs.release = gitlab.release
|
57
|
+
specs.network = gitlab.network
|
58
|
+
specs.args = [gitlab.address, *rspec_args]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
ensure
|
63
|
+
praefect_node&.teardown
|
64
|
+
sql_node&.teardown
|
65
|
+
gitaly_primary_node&.teardown
|
66
|
+
gitaly_secondary_node&.teardown
|
67
|
+
gitaly_tertiary_node&.teardown
|
68
|
+
end
|
69
|
+
# rubocop:enable Metrics/AbcSize
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def disable_other_services
|
74
|
+
<<~OMNIBUS
|
75
|
+
postgresql['enable'] = false;
|
76
|
+
redis['enable'] = false;
|
77
|
+
nginx['enable'] = false;
|
78
|
+
prometheus['enable'] = false;
|
79
|
+
grafana['enable'] = false;
|
80
|
+
puma['enable'] = false;
|
81
|
+
sidekiq['enable'] = false;
|
82
|
+
gitlab_workhorse['enable'] = false;
|
83
|
+
gitlab_rails['rake_cache_clear'] = false;
|
84
|
+
gitlab_rails['auto_migrate'] = false;
|
85
|
+
OMNIBUS
|
86
|
+
end
|
87
|
+
|
88
|
+
def praefect_omnibus_configuration
|
89
|
+
<<~OMNIBUS
|
90
|
+
#{disable_other_services}
|
91
|
+
gitaly['enable'] = false;
|
92
|
+
praefect['enable'] = true;
|
93
|
+
praefect['listen_addr'] = '0.0.0.0:2305';
|
94
|
+
praefect['prometheus_listen_addr'] = '0.0.0.0:9652';
|
95
|
+
praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN';
|
96
|
+
praefect['database_host'] = '#{@database}.#{@network}';
|
97
|
+
praefect['database_user'] = 'postgres';
|
98
|
+
praefect['database_port'] = 5432;
|
99
|
+
praefect['database_password'] = 'SQL_PASSWORD';
|
100
|
+
praefect['database_dbname'] = 'praefect_production';
|
101
|
+
praefect['database_sslmode'] = 'disable';
|
102
|
+
praefect['postgres_queue_enabled'] = true;
|
103
|
+
praefect['failover_enabled'] = true;
|
104
|
+
praefect['virtual_storages'] = {
|
105
|
+
'default' => {
|
106
|
+
'#{@primary_node_name}' => {
|
107
|
+
'address' => 'tcp://#{@primary_node_name}.#{@network}:8075',
|
108
|
+
'token' => 'PRAEFECT_INTERNAL_TOKEN',
|
109
|
+
'primary' => true
|
110
|
+
},
|
111
|
+
'#{@secondary_node_name}' => {
|
112
|
+
'address' => 'tcp://#{@secondary_node_name}.#{@network}:8075',
|
113
|
+
'token' => 'PRAEFECT_INTERNAL_TOKEN'
|
114
|
+
},
|
115
|
+
'#{@tertiary_node_name}' => {
|
116
|
+
'address' => 'tcp://#{@tertiary_node_name}.#{@network}:8075',
|
117
|
+
'token' => 'PRAEFECT_INTERNAL_TOKEN'
|
118
|
+
}
|
119
|
+
}
|
120
|
+
};
|
121
|
+
OMNIBUS
|
122
|
+
end
|
123
|
+
|
124
|
+
def gitaly_omnibus_configuration
|
125
|
+
<<~OMNIBUS
|
126
|
+
#{disable_other_services}
|
127
|
+
prometheus['enable'] = true;
|
128
|
+
prometheus_monitoring['enable'] = false;
|
129
|
+
gitaly['enable'] = true;
|
130
|
+
gitaly['listen_addr'] = '0.0.0.0:8075';
|
131
|
+
gitaly['prometheus_listen_addr'] = '0.0.0.0:9236';
|
132
|
+
gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN';
|
133
|
+
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
|
134
|
+
gitlab_rails['internal_api_url'] = 'http://#{@gitlab_name}.#{@network}';
|
135
|
+
git_data_dirs({
|
136
|
+
'#{@primary_node_name}' => {
|
137
|
+
'path' => '/var/opt/gitlab/git-data'
|
138
|
+
},
|
139
|
+
'#{@secondary_node_name}' => {
|
140
|
+
'path' => '/var/opt/gitlab/git-data'
|
141
|
+
},
|
142
|
+
'#{@tertiary_node_name}' => {
|
143
|
+
'path' => '/var/opt/gitlab/git-data'
|
144
|
+
}
|
145
|
+
});
|
146
|
+
OMNIBUS
|
147
|
+
end
|
148
|
+
|
149
|
+
def gitlab_omnibus_configuration
|
150
|
+
<<~OMNIBUS
|
151
|
+
external_url 'http://#{@gitlab_name}.#{@network}';
|
152
|
+
|
153
|
+
git_data_dirs({
|
154
|
+
'default' => {
|
155
|
+
'gitaly_address' => 'tcp://#{@praefect_node_name}.#{@network}:2305',
|
156
|
+
'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
|
157
|
+
}
|
158
|
+
});
|
159
|
+
gitaly['listen_addr'] = '0.0.0.0:8075';
|
160
|
+
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
|
161
|
+
prometheus['scrape_configs'] = [
|
162
|
+
{
|
163
|
+
'job_name' => 'praefect',
|
164
|
+
'static_configs' => [
|
165
|
+
'targets' => [
|
166
|
+
'#{@praefect_node_name}.#{@network}:9652'
|
167
|
+
]
|
168
|
+
]
|
169
|
+
},
|
170
|
+
{
|
171
|
+
'job_name' => 'praefect-gitaly',
|
172
|
+
'static_configs' => [
|
173
|
+
'targets' => [
|
174
|
+
'#{@primary_node_name}.#{@network}:9236',
|
175
|
+
'#{@secondary_node_name}.#{@network}:9236',
|
176
|
+
'#{@tertiary_node_name}.#{@network}:9236'
|
177
|
+
]
|
178
|
+
]
|
179
|
+
}
|
180
|
+
];
|
181
|
+
grafana['disable_login_form'] = false;
|
182
|
+
grafana['admin_password'] = 'GRAFANA_ADMIN_PASSWORD';
|
183
|
+
OMNIBUS
|
184
|
+
end
|
185
|
+
|
186
|
+
def gitaly(name, release)
|
187
|
+
Component::Gitlab.new.tap do |gitaly|
|
188
|
+
gitaly.release = QA::Release.new(release)
|
189
|
+
gitaly.name = name
|
190
|
+
gitaly.network = @network
|
191
|
+
gitaly.skip_availability_check = true
|
192
|
+
gitaly.omnibus_config = gitaly_omnibus_configuration
|
193
|
+
gitaly.instance_no_teardown
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|