gitlab-qa 6.22.0 → 7.0.2

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +32 -31
  3. data/docs/configuring_omnibus.md +208 -0
  4. data/docs/what_tests_can_be_run.md +46 -8
  5. data/gitlab-qa.gemspec +6 -4
  6. data/lib/gitlab/qa.rb +7 -0
  7. data/lib/gitlab/qa/component/base.rb +2 -2
  8. data/lib/gitlab/qa/component/elasticsearch.rb +1 -1
  9. data/lib/gitlab/qa/component/gitlab.rb +35 -24
  10. data/lib/gitlab/qa/component/internet_tunnel.rb +4 -1
  11. data/lib/gitlab/qa/component/jira.rb +1 -1
  12. data/lib/gitlab/qa/component/ldap.rb +1 -1
  13. data/lib/gitlab/qa/component/mail_hog.rb +1 -1
  14. data/lib/gitlab/qa/component/minio.rb +3 -11
  15. data/lib/gitlab/qa/component/postgresql.rb +1 -1
  16. data/lib/gitlab/qa/component/saml.rb +1 -1
  17. data/lib/gitlab/qa/component/specs.rb +10 -2
  18. data/lib/gitlab/qa/docker/engine.rb +37 -6
  19. data/lib/gitlab/qa/report/test_result.rb +5 -1
  20. data/lib/gitlab/qa/runner.rb +57 -5
  21. data/lib/gitlab/qa/runtime/env.rb +2 -0
  22. data/lib/gitlab/qa/runtime/omnibus_configuration.rb +70 -0
  23. data/lib/gitlab/qa/runtime/omnibus_configurations/default.rb +25 -0
  24. data/lib/gitlab/qa/runtime/omnibus_configurations/object_storage.rb +48 -0
  25. data/lib/gitlab/qa/runtime/omnibus_configurations/packages.rb +17 -0
  26. data/lib/gitlab/qa/scenario/cli_commands.rb +3 -3
  27. data/lib/gitlab/qa/scenario/test/instance/relative_url.rb +1 -3
  28. data/lib/gitlab/qa/scenario/test/instance/repository_storage.rb +1 -1
  29. data/lib/gitlab/qa/scenario/test/integration/actioncable.rb +1 -3
  30. data/lib/gitlab/qa/scenario/test/integration/geo.rb +4 -5
  31. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +4 -5
  32. data/lib/gitlab/qa/scenario/test/integration/group_saml.rb +1 -1
  33. data/lib/gitlab/qa/scenario/test/integration/instance_saml.rb +1 -1
  34. data/lib/gitlab/qa/scenario/test/integration/kubernetes.rb +1 -1
  35. data/lib/gitlab/qa/scenario/test/integration/ldap.rb +1 -4
  36. data/lib/gitlab/qa/scenario/test/integration/ldap_no_server.rb +1 -1
  37. data/lib/gitlab/qa/scenario/test/integration/ldap_no_tls.rb +1 -1
  38. data/lib/gitlab/qa/scenario/test/integration/ldap_tls.rb +1 -1
  39. data/lib/gitlab/qa/scenario/test/integration/mattermost.rb +1 -1
  40. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +2 -2
  41. data/lib/gitlab/qa/scenario/test/integration/smtp.rb +1 -1
  42. data/lib/gitlab/qa/scenario/test/integration/ssh_tunnel.rb +1 -1
  43. data/lib/gitlab/qa/version.rb +1 -1
  44. metadata +12 -9
  45. data/lib/gitlab/qa/scenario/test/integration/object_storage.rb +0 -64
  46. data/lib/gitlab/qa/scenario/test/integration/packages.rb +0 -36
@@ -143,6 +143,40 @@ To run EE tests, the `EE_LICENSE` environment variable needs to be set:
143
143
 
144
144
  `$ export EE_LICENSE=$(cat /path/to/GitLab.gitlab_license)`
145
145
 
146
+ ## Specifying the GitLab QA image to use
147
+
148
+ By default, `gitlab-qa` infers the QA image to use based on the GitLab image.
149
+ For instance, if you run the following:
150
+
151
+ ```
152
+ $ gitlab-qa Test::Instance::Image gitlab/gitlab-ee:12.4.0-ee.0
153
+ ```
154
+
155
+ Then, `gitlab-qa` would infer `gitlab/gitlab-ee-qa:12.4.0-ee.0` as the QA image
156
+ based on the GitLab image (note the `-qa` suffix in the image name).
157
+
158
+ In some cases, you'll want to use a specific QA image instead of letting
159
+ `gitlab-qa` infer the QA image name from the GitLab image. Such cases can be
160
+ when you're doing local debugging/testing and you want to control the QA image
161
+ name, or in the CI where the QA image might be built by a project (e.g.
162
+ `gitlab-org/gitlab`, and the GitLab image might be built by another project
163
+ (e.g. `gitlab-org/omnibus-gitlab-mirror`).
164
+
165
+ To specify the QA image to use, pass the `--qa-image QA_IMAGE` option,
166
+ as follows:
167
+
168
+ ```
169
+ $ gitlab-qa Test::Instance::Image --qa-image registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa:branch-name EE
170
+ ```
171
+
172
+ Additionally, setting the `$QA_IMAGE` environment variable achieve the same result,
173
+ without needing to pass the `--qa-image` option:
174
+
175
+ ```
176
+ $ export QA_IMAGE="registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa:branch-name"
177
+ $ gitlab-qa Test::Instance::Image EE
178
+ ```
179
+
146
180
  ## Running a specific test (or set of tests)
147
181
 
148
182
  In most of the scenarios listed below, if you don't want to run all the tests
@@ -500,6 +534,18 @@ $ gitlab-qa Test::Integration::Mattermost EE
500
534
 
501
535
  ### `Test::Integration::Packages CE|EE|<full image address>`
502
536
 
537
+ **Note: This Scenario no longer exists. See https://gitlab.com/gitlab-org/gitlab-qa/-/merge_requests/662**
538
+
539
+ To run Packages tests, you may [configure Omnibus](configuring_omnibus.md) to use the [Packages](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/lib/gitlab/qa/runtime/omnibus_configurations/packages.rb) configurator.
540
+
541
+ Example:
542
+
543
+ ```
544
+ $ export EE_LICENSE=$(cat /path/to/Geo.gitlab_license)
545
+
546
+ $ gitlab-qa Test::Instance::Image EE --omnibus-config packages
547
+ ```
548
+
503
549
  This tests the GitLab Package Registry feature by setting
504
550
  `gitlab_rails['packages_enabled'] = true` in the Omnibus configuration
505
551
  before starting the GitLab container.
@@ -513,14 +559,6 @@ which runs only the tests with `:packages` metadata.
513
559
 
514
560
  - `EE_LICENSE`: A valid EE license.
515
561
 
516
- Example:
517
-
518
- ```
519
- $ export EE_LICENSE=$(cat /path/to/Geo.gitlab_license)
520
-
521
- $ gitlab-qa Test::Integration::Packages EE
522
- ```
523
-
524
562
  ### `Test::Integration::Praefect CE|EE|<full image address>`
525
563
 
526
564
  This tests [Praefect](https://docs.gitlab.com/ee/administration/gitaly/praefect.html),
data/gitlab-qa.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'gitlab/qa/version'
@@ -5,11 +7,11 @@ require 'gitlab/qa/version'
5
7
  Gem::Specification.new do |spec|
6
8
  spec.name = 'gitlab-qa'
7
9
  spec.version = Gitlab::QA::VERSION
8
- spec.authors = ['Grzegorz Bizon']
9
- spec.email = ['grzesiek.bizon@gmail.com']
10
+ spec.authors = ['GitLab Quality']
11
+ spec.email = ['gitlab-qa@gmail.com']
10
12
 
11
13
  spec.summary = 'Integration tests for GitLab'
12
- spec.homepage = 'http://about.gitlab.com'
14
+ spec.homepage = 'http://about.gitlab.com/'
13
15
  spec.license = 'MIT'
14
16
 
15
17
  spec.files = `git ls-files -z`
@@ -31,5 +33,5 @@ Gem::Specification.new do |spec|
31
33
  spec.add_runtime_dependency 'gitlab', '~> 4.16.1'
32
34
  spec.add_runtime_dependency 'http', '4.3.0'
33
35
  spec.add_runtime_dependency 'nokogiri', '~> 1.10'
34
- spec.add_runtime_dependency 'table_print', '1.5.6'
36
+ spec.add_runtime_dependency 'table_print', '1.5.7'
35
37
  end
data/lib/gitlab/qa.rb CHANGED
@@ -8,6 +8,13 @@ module Gitlab
8
8
  autoload :Env, 'gitlab/qa/runtime/env'
9
9
  autoload :Scenario, 'gitlab/qa/runtime/scenario'
10
10
  autoload :TokenFinder, 'gitlab/qa/runtime/token_finder'
11
+ autoload :OmnibusConfiguration, 'gitlab/qa/runtime/omnibus_configuration'
12
+
13
+ module OmnibusConfigurations
14
+ autoload :Default, 'gitlab/qa/runtime/omnibus_configurations/default'
15
+ autoload :Packages, 'gitlab/qa/runtime/omnibus_configurations/packages'
16
+ autoload :ObjectStorage, 'gitlab/qa/runtime/omnibus_configurations/object_storage'
17
+ end
11
18
  end
12
19
 
13
20
  module Scenario
@@ -78,7 +78,7 @@ module Gitlab
78
78
  end
79
79
 
80
80
  def start # rubocop:disable Metrics/AbcSize
81
- docker.run(image, tag) do |command|
81
+ docker.run(image: image, tag: tag) do |command|
82
82
  command << "-d"
83
83
  command << "--name #{name}"
84
84
  command << "--net #{network}"
@@ -129,7 +129,7 @@ module Gitlab
129
129
  def pull
130
130
  return if Runtime::Env.skip_pull?
131
131
 
132
- docker.pull(image, tag)
132
+ docker.pull(image: image, tag: tag)
133
133
  end
134
134
 
135
135
  def process_exec_commands
@@ -13,7 +13,7 @@ module Gitlab
13
13
  end
14
14
 
15
15
  def start
16
- @docker.run(image, tag) do |command|
16
+ @docker.run(image: image, tag: tag) do |command|
17
17
  command << "-d"
18
18
  command << "--name #{name}"
19
19
  command << "--net #{network}"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'securerandom'
2
4
  require 'net/http'
3
5
  require 'uri'
@@ -10,39 +12,36 @@ module Gitlab
10
12
  class Gitlab < Base
11
13
  extend Forwardable
12
14
 
13
- attr_reader :release
14
- attr_accessor :tls, :disable_animations, :skip_availability_check, :runner_network
15
+ attr_reader :release, :omnibus_configuration
16
+ attr_accessor :tls, :skip_availability_check, :runner_network
15
17
  attr_writer :name, :relative_path
16
18
 
17
19
  def_delegators :release, :tag, :image, :edition
18
20
 
19
- AUTHORITY_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/authority'.freeze, __dir__)
20
- GITLAB_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/gitlab'.freeze, __dir__)
21
- GITALY_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/gitaly'.freeze, __dir__)
21
+ AUTHORITY_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/authority', __dir__)
22
+ GITLAB_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/gitlab', __dir__)
23
+ GITALY_CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates/gitaly', __dir__)
22
24
 
23
- SSL_PATH = '/etc/gitlab/ssl'.freeze
24
- TRUSTED_PATH = '/etc/gitlab/trusted-certs'.freeze
25
+ SSL_PATH = '/etc/gitlab/ssl'
26
+ TRUSTED_PATH = '/etc/gitlab/trusted-certs'
25
27
 
26
28
  def initialize
27
29
  super
28
30
 
29
- @disable_animations = true
30
31
  @skip_availability_check = false
31
32
 
32
33
  @volumes[GITLAB_CERTIFICATES_PATH] = SSL_PATH
33
34
  @volumes[AUTHORITY_CERTIFICATES_PATH] = TRUSTED_PATH
34
35
 
35
- self.release = 'CE'
36
- end
36
+ @omnibus_configuration ||= OmnibusConfiguration.new
37
37
 
38
- def omnibus_config=(config)
39
- @environment['GITLAB_OMNIBUS_CONFIG'] = config.tr("\n", ' ')
38
+ self.release = 'CE'
40
39
  end
41
40
 
42
41
  def set_formless_login_token
43
42
  return if Runtime::Env.gitlab_qa_formless_login_token.to_s.strip.empty?
44
43
 
45
- @environment['GITLAB_OMNIBUS_CONFIG'] = "gitlab_rails['env'] = { 'GITLAB_QA_FORMLESS_LOGIN_TOKEN' => '#{Runtime::Env.gitlab_qa_formless_login_token}' }; #{@environment['GITLAB_OMNIBUS_CONFIG'] || ''}"
44
+ @omnibus_configuration << "gitlab_rails['env'] = { 'GITLAB_QA_FORMLESS_LOGIN_TOKEN' => '#{Runtime::Env.gitlab_qa_formless_login_token}' }"
46
45
  end
47
46
 
48
47
  def elastic_url=(url)
@@ -95,23 +94,13 @@ module Gitlab
95
94
  end
96
95
 
97
96
  def prepare_gitlab_omnibus_config
98
- setup_disable_animations if disable_animations
99
97
  set_formless_login_token
100
- setup_application_settings_cache_expiry
101
- end
102
-
103
- def setup_disable_animations
104
- @environment['GITLAB_OMNIBUS_CONFIG'] = "gitlab_rails['gitlab_disable_animations'] = true; #{@environment['GITLAB_OMNIBUS_CONFIG'] || ''}"
105
- end
106
-
107
- def setup_application_settings_cache_expiry
108
- @environment['GITLAB_OMNIBUS_CONFIG'] = "gitlab_rails['application_settings_cache_seconds'] = 0; #{@environment['GITLAB_OMNIBUS_CONFIG'] || ''}"
109
98
  end
110
99
 
111
100
  def start # rubocop:disable Metrics/AbcSize
112
101
  ensure_configured!
113
102
 
114
- docker.run(image, tag) do |command|
103
+ docker.run(image: image, tag: tag) do |command|
115
104
  command << "-d -p #{port}"
116
105
  command << "--name #{name}"
117
106
  command << "--net #{network}"
@@ -135,6 +124,8 @@ module Gitlab
135
124
  end
136
125
 
137
126
  def reconfigure
127
+ setup_omnibus
128
+
138
129
  @docker.attach(name) do |line, wait|
139
130
  puts line
140
131
  # TODO, workaround which allows to detach from the container
@@ -170,6 +161,12 @@ module Gitlab
170
161
  raise 'Please configure an instance first!' unless [name, release, network].all?
171
162
  end
172
163
 
164
+ def setup_omnibus
165
+ @docker.write_files(name) do |f|
166
+ f.write('/etc/gitlab/gitlab.rb', @omnibus_configuration.to_s)
167
+ end
168
+ end
169
+
173
170
  class Availability
174
171
  def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
175
172
  @docker = Docker::Engine.new
@@ -209,6 +206,20 @@ module Gitlab
209
206
  @uri.scheme == 'https' ? { use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE } : {}
210
207
  end
211
208
  end
209
+
210
+ class OmnibusConfiguration
211
+ def initialize
212
+ @config = Runtime::Scenario.attributes[:omnibus_configuration].clone || []
213
+ end
214
+
215
+ def <<(configuration)
216
+ @config << configuration
217
+ end
218
+
219
+ def to_s
220
+ @config.to_s
221
+ end
222
+ end
212
223
  end
213
224
  end
214
225
  end
@@ -49,7 +49,10 @@ module Gitlab
49
49
  def start
50
50
  raise "Must set gitlab_hostname" unless @gitlab_hostname
51
51
 
52
- @docker.run(DOCKER_IMAGE, DOCKER_IMAGE_TAG, "-o StrictHostKeyChecking=no -N -R #{subdomain}:#{@gitlab_hostname}:80 #{ENV.fetch('TUNNEL_SSH_USER')}@#{tunnel_server_hostname}") do |command|
52
+ @docker.run(
53
+ image: DOCKER_IMAGE,
54
+ tag: DOCKER_IMAGE_TAG,
55
+ args: ["-o StrictHostKeyChecking=no -N -R #{subdomain}:#{@gitlab_hostname}:80 #{ENV.fetch('TUNNEL_SSH_USER')}@#{tunnel_server_hostname}"]) do |command|
53
56
  command << '-d '
54
57
  command << "--name #{name}"
55
58
  command << "--net #{network}"
@@ -16,7 +16,7 @@ module Gitlab
16
16
  end
17
17
 
18
18
  def start
19
- docker.run(image, tag) do |command|
19
+ docker.run(image: image, tag: tag) do |command|
20
20
  command << '-d '
21
21
  command << "--name #{name}"
22
22
  command << "--net #{network}"
@@ -63,7 +63,7 @@ module Gitlab
63
63
  def start
64
64
  # copy-service needed for bootstraping LDAP user:
65
65
  # https://github.com/osixia/docker-openldap#seed-ldap-database-with-ldif
66
- docker.run(image, tag, '--copy-service') do |command|
66
+ docker.run(image: image, tag: tag, args: ['--copy-service']) do |command|
67
67
  command << '-d '
68
68
  command << "--name #{name}"
69
69
  command << "--net #{network}"
@@ -19,7 +19,7 @@ module Gitlab
19
19
  end
20
20
 
21
21
  def start
22
- docker.run(image, tag) do |command|
22
+ docker.run(image: image, tag: tag) do |command|
23
23
  command << '-d '
24
24
  command << "--name #{name}"
25
25
  command << "--net #{network}"
@@ -1,5 +1,6 @@
1
1
  require 'securerandom'
2
2
  require 'fileutils'
3
+ require 'yaml'
3
4
 
4
5
  # This component sets up the Minio (https://hub.docker.com/r/minio/minio)
5
6
  # image with the proper configuration for GitLab users to use object storage.
@@ -23,18 +24,12 @@ module Gitlab
23
24
  @buckets = []
24
25
  end
25
26
 
26
- def instance
27
- raise 'Please provide a block!' unless block_given?
28
-
29
- super
30
- end
31
-
32
27
  def add_bucket(name)
33
28
  @buckets << name
34
29
  end
35
30
 
36
31
  def to_config
37
- config = YAML.safe_load <<~CFG
32
+ YAML.safe_load <<~CFG
38
33
  provider: AWS
39
34
  aws_access_key_id: #{AWS_ACCESS_KEY}
40
35
  aws_secret_access_key: #{AWS_SECRET_KEY}
@@ -43,9 +38,6 @@ module Gitlab
43
38
  endpoint: http://#{hostname}:#{port}
44
39
  path_style: true
45
40
  CFG
46
-
47
- # Quotes get eaten up when the string is set in the environment
48
- config.to_s.gsub('"', '\\"')
49
41
  end
50
42
 
51
43
  private
@@ -78,7 +70,7 @@ module Gitlab
78
70
  def start # rubocop:disable Metrics/AbcSize
79
71
  # --compat needed until https://gitlab.com/gitlab-org/gitlab-workhorse/issues/210
80
72
  # is resolved
81
- docker.run(image, tag, "server", "--compat", DATA_DIR) do |command|
73
+ docker.run(image: image, tag: tag, args: ["server", "--compat", DATA_DIR]) do |command|
82
74
  command << '-d '
83
75
  command << "--name #{name}"
84
76
  command << "--net #{network}"
@@ -10,7 +10,7 @@ module Gitlab
10
10
  end
11
11
 
12
12
  def start
13
- @docker.run(image, tag) do |command|
13
+ @docker.run(image: image, tag: tag) do |command|
14
14
  command << "-d"
15
15
  command << "--name #{name}"
16
16
  command << "--net #{network}"
@@ -34,7 +34,7 @@ module Gitlab
34
34
 
35
35
  # rubocop:disable Metrics/AbcSize
36
36
  def start
37
- docker.run(image, tag) do |command|
37
+ docker.run(image: image, tag: tag) do |command|
38
38
  command << '-d '
39
39
  command << "--name #{name}"
40
40
  command << "--net #{network}"
@@ -23,7 +23,7 @@ module Gitlab
23
23
 
24
24
  @docker.login(**release.login_params) if release.login_params
25
25
 
26
- @docker.pull(release.qa_image, release.qa_tag) unless Runtime::Env.skip_pull?
26
+ @docker.pull(image: qa_image) unless Runtime::Env.skip_pull?
27
27
 
28
28
  puts "Running test suite `#{suite}` for #{release.project_name}"
29
29
 
@@ -43,7 +43,7 @@ module Gitlab
43
43
  feature_flag_sets << [] unless feature_flag_sets.any?
44
44
 
45
45
  feature_flag_sets.each do |feature_flag_set|
46
- @docker.run(release.qa_image, release.qa_tag, suite, *args_with_flags(args, feature_flag_set)) do |command|
46
+ @docker.run(image: qa_image, args: [suite, *args_with_flags(args, feature_flag_set)]) do |command|
47
47
  command << "-t --rm --net=#{network || 'bridge'}"
48
48
 
49
49
  env.merge(Runtime::Env.variables).each do |key, value|
@@ -76,6 +76,14 @@ module Gitlab
76
76
  def skip_tests?
77
77
  Runtime::Scenario.attributes.include?(:run_tests) && !Runtime::Scenario.run_tests
78
78
  end
79
+
80
+ def qa_image
81
+ if Runtime::Scenario.attributes.include?(:qa_image)
82
+ Runtime::Scenario.qa_image
83
+ else
84
+ "#{release.qa_image}:#{release.qa_tag}"
85
+ end
86
+ end
79
87
  end
80
88
  end
81
89
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gitlab
2
4
  module QA
3
5
  module Docker
@@ -13,15 +15,15 @@ module Gitlab
13
15
  Docker::Command.execute(%(login --username "#{username}" --password "#{password}" #{registry}), mask_secrets: password)
14
16
  end
15
17
 
16
- def pull(image, tag)
17
- Docker::Command.execute("pull #{image}:#{tag}")
18
+ def pull(image:, tag: nil)
19
+ Docker::Command.execute("pull #{full_image_name(image, tag)}")
18
20
  end
19
21
 
20
- def run(image, tag, *args)
22
+ def run(image:, tag: nil, args: [])
21
23
  Docker::Command.new('run').tap do |command|
22
24
  yield command if block_given?
23
25
 
24
- command << "#{image}:#{tag}"
26
+ command << full_image_name(image, tag)
25
27
  command << args if args.any?
26
28
 
27
29
  command.execute!
@@ -36,14 +38,37 @@ module Gitlab
36
38
  false
37
39
  end
38
40
 
41
+ # Write to file(s) in the Docker container specified by @param name
42
+ # @param name The name of the Docker Container
43
+ # @example
44
+ # engine.write_files('gitlab-abc123') do |files|
45
+ # files.append('/etc/hosts', '127.0.0.1 localhost')
46
+ # files.write('/opt/other', <<~TEXT
47
+ # This is content
48
+ # That goes within /opt/other
49
+ # TEXT)
50
+ def write_files(name)
51
+ exec(name, yield(
52
+ Class.new do
53
+ def self.write(file, contents)
54
+ %(echo "#{contents}" > #{file};)
55
+ end
56
+
57
+ def self.append(file, contents)
58
+ %(echo "#{contents}" >> #{file};)
59
+ end
60
+ end
61
+ ))
62
+ end
63
+
39
64
  def exec(name, command)
40
65
  cmd = ['exec']
41
66
  cmd << '--privileged' if privileged_command?(command)
42
- Docker::Command.execute("#{cmd.join(' ')} #{name} bash -c '#{command}'")
67
+ Docker::Command.execute(%(#{cmd.join(' ')} #{name} bash -c "#{command.gsub('"', '\\"')}"))
43
68
  end
44
69
 
45
70
  def read_file(image, tag, path, &block)
46
- cat_file = "run --rm --entrypoint /bin/cat #{image}:#{tag} #{path}"
71
+ cat_file = "run --rm --entrypoint /bin/cat #{full_image_name(image, tag)} #{path}"
47
72
  Docker::Command.execute(cat_file, &block)
48
73
  end
49
74
 
@@ -94,6 +119,12 @@ module Gitlab
94
119
  def ps(name = nil)
95
120
  Docker::Command.execute(['ps', name].compact.join(' '))
96
121
  end
122
+
123
+ private
124
+
125
+ def full_image_name(image, tag)
126
+ [image, tag].compact.join(':')
127
+ end
97
128
  end
98
129
  end
99
130
  end