Class: Gitlab::QA::Component::Base

Inherits:
Object
  • Object
show all
Includes:
Scenario::Actable
Defined in:
lib/gitlab/qa/component/base.rb

Constant Summary collapse

CERTIFICATES_PATH =
File.expand_path('../../../../tls_certificates', __dir__)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Scenario::Actable

#act, included

Constructor Details

#initialize ⇒ Base

Returns a new instance of Base.



22
23
24
25
26
27
28
29
30
# File 'lib/gitlab/qa/component/base.rb', line 22

def initialize
  @docker = Docker::Engine.new
  @environment = {}
  @volumes = {}
  @ports = []
  @network_aliases = []
  @exec_commands = []
  @additional_hosts = []
end

Instance Attribute Details

#additional_hosts ⇒ Object

Returns the value of attribute additional_hosts.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def additional_hosts
  @additional_hosts
end

#airgapped_network ⇒ Object

Returns the value of attribute airgapped_network.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def airgapped_network
  @airgapped_network
end

#docker ⇒ Object (readonly)

Returns the value of attribute docker.



11
12
13
# File 'lib/gitlab/qa/component/base.rb', line 11

def docker
  @docker
end

#environment ⇒ Object

Returns the value of attribute environment.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def environment
  @environment
end

#exec_commands=(value) ⇒ Object

Sets the attribute exec_commands

Parameters:

  • value —

    the value to set the attribute exec_commands to.



12
13
14
# File 'lib/gitlab/qa/component/base.rb', line 12

def exec_commands=(value)
  @exec_commands = value
end

#name ⇒ Object

Raises:

  • (NotImplementedError)


36
37
38
# File 'lib/gitlab/qa/component/base.rb', line 36

def name
  raise NotImplementedError, "#{self.class.name} must specify a default name"
end

#network ⇒ Object

Returns the value of attribute network.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def network
  @network
end

#network_aliases ⇒ Object

Returns the value of attribute network_aliases.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def network_aliases
  @network_aliases
end

#ports ⇒ Object

Returns the value of attribute ports.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def ports
  @ports
end

#runner_network ⇒ Object

Returns the value of attribute runner_network.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def runner_network
  @runner_network
end

#volumes ⇒ Object

Returns the value of attribute volumes.



13
14
15
# File 'lib/gitlab/qa/component/base.rb', line 13

def volumes
  @volumes
end

Instance Method Details

#add_network_alias(name) ⇒ Object



32
33
34
# File 'lib/gitlab/qa/component/base.rb', line 32

def add_network_alias(name)
  @network_aliases.push(name)
end

#hostname ⇒ Object



40
41
42
# File 'lib/gitlab/qa/component/base.rb', line 40

def hostname
  "#{name}.#{network}"
end

#image ⇒ Object

Raises:

  • (NotImplementedError)


44
45
46
47
48
# File 'lib/gitlab/qa/component/base.rb', line 44

def image
  return self.class.const_get('DOCKER_IMAGE') if self.class.const_defined?('DOCKER_IMAGE')

  raise NotImplementedError, "#{self.class.name} must specify a docker image as DOCKER_IMAGE"
end

#instance(skip_teardown: false) ⇒ Object Also known as: launch_and_teardown_instance



60
61
62
63
64
65
66
# File 'lib/gitlab/qa/component/base.rb', line 60

def instance(skip_teardown: false)
  instance_no_teardown do
    yield self if block_given?
  end
ensure
  teardown unless skip_teardown
end

#ip_address ⇒ Object



68
69
70
# File 'lib/gitlab/qa/component/base.rb', line 68

def ip_address
  docker.inspect(name) { |command| command << "-f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'" }
end

#prepare ⇒ Object



74
75
76
77
78
# File 'lib/gitlab/qa/component/base.rb', line 74

def prepare
  prepare_docker_image
  prepare_docker_container
  prepare_network
end

#prepare_airgapped_network ⇒ Object



92
93
94
95
96
# File 'lib/gitlab/qa/component/base.rb', line 92

def prepare_airgapped_network
  return unless airgapped_network && !docker.network_exists?(network)

  docker.network_create("--driver=bridge --internal #{network}")
end

#prepare_docker_container ⇒ Object



104
105
106
107
108
# File 'lib/gitlab/qa/component/base.rb', line 104

def prepare_docker_container
  return unless docker.container_exists?(name)

  docker.remove(name)
end

#prepare_docker_image ⇒ Object



80
81
82
# File 'lib/gitlab/qa/component/base.rb', line 80

def prepare_docker_image
  pull
end

#prepare_network ⇒ Object



84
85
86
87
88
89
90
# File 'lib/gitlab/qa/component/base.rb', line 84

def prepare_network
  prepare_airgapped_network
  prepare_runner_network
  return if docker.network_exists?(network)

  docker.network_create(network)
end

#prepare_runner_network ⇒ Object



98
99
100
101
102
# File 'lib/gitlab/qa/component/base.rb', line 98

def prepare_runner_network
  return unless runner_network && !docker.network_exists?(runner_network)

  docker.network_create("--driver=bridge --internal #{runner_network}")
end

#process_exec_commands ⇒ Object



172
173
174
# File 'lib/gitlab/qa/component/base.rb', line 172

def process_exec_commands
  exec_commands.each { |command| docker.exec(name, command) }
end

#pull ⇒ Object



166
167
168
169
170
# File 'lib/gitlab/qa/component/base.rb', line 166

def pull
  return if Runtime::Env.skip_pull?

  docker.pull(image: image, tag: tag)
end

#restart ⇒ Object



141
142
143
144
145
# File 'lib/gitlab/qa/component/base.rb', line 141

def restart
  assert_name!

  docker.restart(name)
end

#start ⇒ Object

rubocop:disable Metrics/AbcSize



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/gitlab/qa/component/base.rb', line 110

def start # rubocop:disable Metrics/AbcSize
  docker.run(image: image, tag: tag) do |command|
    command << "-d"
    command << "--name #{name}"
    command << "--net #{network}"
    command << "--hostname #{hostname}"

    @ports.each do |mapping|
      command.port(mapping)
    end

    @volumes.to_h.each do |to, from|
      command.volume(to, from, 'Z')
    end

    command.volume(*log_volume.values) unless log_volume.empty?

    @environment.to_h.each do |key, value|
      command.env(key, value)
    end

    @network_aliases.to_a.each do |network_alias|
      command << "--network-alias #{network_alias}"
    end

    @additional_hosts.each do |host|
      command << "--add-host=#{host}"
    end
  end
end

#start_instance ⇒ Object



56
57
58
# File 'lib/gitlab/qa/component/base.rb', line 56

def start_instance
  instance_no_teardown
end

#tag ⇒ Object

Raises:

  • (NotImplementedError)


50
51
52
53
54
# File 'lib/gitlab/qa/component/base.rb', line 50

def tag
  return self.class.const_get('DOCKER_IMAGE_TAG') if self.class.const_defined?('DOCKER_IMAGE_TAG')

  raise NotImplementedError, "#{self.class.name} must specify a docker image tag as DOCKER_IMAGE_TAG"
end

#teardown ⇒ Object



147
148
149
150
151
152
153
154
155
156
# File 'lib/gitlab/qa/component/base.rb', line 147

def teardown
  unless teardown?
    Runtime::Logger.info("The orchestrated docker containers have not been removed.")
    docker.ps

    return
  end

  teardown!
end

#teardown! ⇒ Object



158
159
160
161
162
163
164
# File 'lib/gitlab/qa/component/base.rb', line 158

def teardown!
  assert_name!

  return unless docker.running?(name)

  docker.remove(name)
end