fastlane-plugin-mango 1.1.6 → 1.3.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed170b21d2657138918bb05cda96147bcec67db16311d04b179f7a897f67b0df
4
- data.tar.gz: c57446317b989992adfc8917a7e413a41f171110be888d38bde576e4bdde1a33
3
+ metadata.gz: 789e89cc42d904d6f20d595d4e4e5e536688431cef29839e784e6fbe8dfd7e13
4
+ data.tar.gz: e4143d7a96c169910ec836972f4362b0244828f1899a7837b33911b62f31e7f3
5
5
  SHA512:
6
- metadata.gz: 4486ba5047f7a8757bd93cdaed54ceb35a1cc2997da737771cce5adcde318e989e76eed1a957da5bcb2f5a13b1856723e110d621e80d62218ffdfbfe1d218b9f
7
- data.tar.gz: e8ddca2399e990354181dc65ba64d23614763a10183a73e973be87fa5a3eee4b283b2da942adb48b37ee59697d8d94c4d98a4adbf3f8e4d0467c5484d6d50f54
6
+ metadata.gz: '0243850ec81a9f5108d5c6ca0a46770238fced448407bdb0c6abacb734bc7804bedc58880275187908cf2a7993a52c635d84749d155d62265e8401788b53dcd4'
7
+ data.tar.gz: f0dc414874f535ac73ba139fe5476516bc340d5b66b78fd162b6760ca4f783e4911d18ee4d36bec31032431869d093e6e364756ad7c216e6685bd91ae7846c61
data/README.md CHANGED
@@ -78,6 +78,7 @@ The `mango` action has plenty of options to configure it.
78
78
  | `docker_image` | Name of the Docker image, that should be started and used to run your tasks. | butomo1989/docker-android-x86-5.1.1 | ❌ | `String` |
79
79
  | `container_timeout` | Timeout (in seconds) to get a healthy docker container. Depending on your `docker_image` it may take some time until it's started up and ready to use. | 450 (this equals 7.5 minutes) | ❌ | `Integer` |
80
80
  | `android_task` | A generic Android task you want to execute. | - | ❌ | `String` |
81
+ | `core_amount` | Cpu core amount while starting docker container with limited resource. | - | ✅ | `Integer` |
81
82
  | `sdk_path` | The path to your Android sdk directory. | `ANDROID_HOME` environment variable | ✅ | `String` |
82
83
  | `port_factor` | Base for calculating a unique port for noVNC. We recommend to use the `EXECUTOR_NUMBER` from your Jenkins environment. | - | ✅ | `String` |
83
84
  | `workspace_dir` | Path to the workspace to execute commands. If you want to execute your `android_task` from a different directory you have to specify `workspace_dir`. | `/root/tests/` | ✅ | `String` |
@@ -4,7 +4,9 @@ module Fastlane
4
4
  module Actions
5
5
  class RunDockerizedTaskAction < Action
6
6
  def self.run(params)
7
- UI.important("The mango plugin is working!")
7
+ UI.important('The mango plugin is working!')
8
+ workspace_dir = params[:workspace_dir]
9
+ ENV['DOCKER_CONFIG'] = "#{ENV['WORKSPACE']}/.docker"
8
10
  mango_helper = Fastlane::Helper::MangoHelper.new(params)
9
11
  mango_helper.setup_container
10
12
 
@@ -12,32 +14,32 @@ module Fastlane
12
14
 
13
15
  failure_buffer_timeout = 5
14
16
  timeout_command = "timeout #{params[:maximal_run_time] - failure_buffer_timeout}m"
15
- workspace_dir = params[:workspace_dir]
16
17
 
17
18
  android_task = params[:android_task]
18
19
  if android_task
19
- UI.success("Starting Android Task.")
20
+ UI.success('Starting Android Task.')
20
21
  bundle_install = params[:bundle_install] ? '&& bundle install ' : ''
21
22
 
22
23
  docker_commander.exec(command: "cd #{workspace_dir} #{bundle_install}&& #{timeout_command} #{android_task} || exit 1")
23
24
  end
24
-
25
25
  ensure
26
- post_actions = params[:post_actions]
27
- if post_actions && !mango_helper.kvm_disabled?
28
- docker_commander&.exec(command: "cd #{workspace_dir} && #{post_actions}")
26
+ begin
27
+ post_actions = params[:post_actions]
28
+ docker_commander&.exec(command: "cd #{workspace_dir} && #{post_actions}") if post_actions && !mango_helper.kvm_disabled?
29
+
30
+ UI.important("Cleaning up #{params[:emulator_name]} container")
31
+ docker_commander.delete_container if mango_helper&.instance_variable_get('@container')
32
+ rescue StandardError => e
33
+ puts e
29
34
  end
30
-
31
- UI.important("Cleaning up #{params[:emulator_name]} container")
32
- mango_helper.clean_container if mango_helper&.instance_variable_get('@container')
33
35
  end
34
36
 
35
37
  def self.description
36
- "Action that runs Android tasks on a specified Docker image"
38
+ 'Action that runs Android tasks on a specified Docker image'
37
39
  end
38
40
 
39
41
  def self.authors
40
- ["Serghei Moret", "Daniel Hartwich"]
42
+ ['Serghei Moret', 'Daniel Hartwich']
41
43
  end
42
44
 
43
45
  def self.return_value
@@ -50,130 +52,144 @@ module Fastlane
50
52
 
51
53
  def self.details
52
54
  # Optional:
53
- ""
55
+ ''
54
56
  end
55
57
 
56
58
  def self.available_options
57
59
  [
58
60
  FastlaneCore::ConfigItem.new(key: :container_name,
59
- env_name: "CONTAINER_NAME",
60
- description: "Name of the docker container. Will be generated randomly if not defined",
61
- optional: true,
62
- type: String),
61
+ env_name: 'CONTAINER_NAME',
62
+ description: 'Name of the docker container. Will be generated randomly if not defined',
63
+ optional: true,
64
+ type: String),
63
65
 
64
66
  FastlaneCore::ConfigItem.new(key: :no_vnc_port,
65
- env_name: "NO_VNC_PORT",
66
- description: "Port to redirect noVNC. 6080 by default",
67
+ env_name: 'NO_VNC_PORT',
68
+ description: 'Port to redirect noVNC. 6080 by default',
67
69
  default_value: 6080,
68
70
  optional: false,
69
71
  type: Integer),
70
72
 
71
73
  FastlaneCore::ConfigItem.new(key: :device_name,
72
- env_name: "DEVICE_NAME",
73
- description: "Name of the Android device. Nexus 5X by default",
74
+ env_name: 'DEVICE_NAME',
75
+ description: 'Name of the Android device. Nexus 5X by default',
74
76
  default_value: 'Nexus 5X',
75
77
  optional: false,
76
78
  type: String),
77
79
 
78
80
  FastlaneCore::ConfigItem.new(key: :emulator_name,
79
- env_name: "EMULATOR_NAME",
80
- description: "Name of the Android emulator. emulator-5554 by default",
81
+ env_name: 'EMULATOR_NAME',
82
+ description: 'Name of the Android emulator. emulator-5554 by default',
81
83
  default_value: 'emulator-5554',
82
84
  optional: false,
83
85
  type: String),
84
86
 
85
87
  FastlaneCore::ConfigItem.new(key: :docker_image,
86
- env_name: "DOCKER_IMAGE",
87
- description: "Name of the Docker image. butomo1989/docker-android-x86-5.1.1 by default",
88
+ env_name: 'DOCKER_IMAGE',
89
+ description: 'Name of the Docker image. butomo1989/docker-android-x86-5.1.1 by default',
88
90
  default_value: 'butomo1989/docker-android-x86-5.1.1',
89
91
  optional: false,
90
92
  type: String),
91
93
 
92
94
  FastlaneCore::ConfigItem.new(key: :container_timeout,
93
- env_name: "CONTAINER_TIMEOUT",
94
- description: "Timeout (in seconds) to get the healthy docker container. 450 (7.5 minutes) by default",
95
- default_value: 450,
96
- optional: false,
97
- type: Integer),
98
-
99
- FastlaneCore::ConfigItem.new(key: :android_task,
100
- env_name: "ANDROID TASK",
101
- description: "A generic Android task you want to execute",
102
- is_string: true,
103
- optional: false),
95
+ env_name: 'CONTAINER_TIMEOUT',
96
+ description: 'Timeout (in seconds) to get the healthy docker container. 450 (7.5 minutes) by default',
97
+ default_value: 450,
98
+ optional: false,
99
+ type: Integer),
100
+
101
+ FastlaneCore::ConfigItem.new(key: :android_task,
102
+ env_name: 'ANDROID TASK',
103
+ description: 'A generic Android task you want to execute',
104
+ is_string: true,
105
+ optional: false),
104
106
 
105
107
  FastlaneCore::ConfigItem.new(key: :sdk_path,
106
- env_name: "SDK_PATH",
107
- description: "The path to your Android sdk directory (root). ANDROID_HOME by default",
108
+ env_name: 'SDK_PATH',
109
+ description: 'The path to your Android sdk directory (root). ANDROID_HOME by default',
108
110
  default_value: ENV['ANDROID_HOME'],
109
111
  is_string: true,
110
112
  optional: true),
111
113
 
112
114
  FastlaneCore::ConfigItem.new(key: :port_factor,
113
- env_name: "PORT_FACTOR",
114
- description: "Base for calculating a unique port for noVNC. You can pass EXECUTOR_NUMBER from Jenkins for example, this will be unique and not clash in case of several instances running on the same machine",
115
- optional: true,
116
- type: String),
115
+ env_name: 'PORT_FACTOR',
116
+ description: 'Base for calculating a unique port for noVNC. You can pass EXECUTOR_NUMBER from Jenkins for example, this will be unique and not clash in case of several instances running on the same machine',
117
+ optional: true,
118
+ type: String),
119
+
120
+ FastlaneCore::ConfigItem.new(key: :core_amount,
121
+ env_name: 'CORE_AMOUNT',
122
+ default_value: 0,
123
+ description: 'Define if we want to start docker container with the limitation',
124
+ optional: true,
125
+ type: Integer),
117
126
 
118
127
  FastlaneCore::ConfigItem.new(key: :workspace_dir,
119
- env_name: "WORKSPACE_DIR",
128
+ env_name: 'WORKSPACE_DIR',
120
129
  default_value: '/root/tests/',
121
- description: "Path to the workspace to execute commands. If you want to execute your `android_task` from a different directory you have to specify `workspace_dir`",
130
+ description: 'Path to the workspace to execute commands. If you want to execute your `android_task` from a different directory you have to specify `workspace_dir`',
122
131
  optional: true,
123
132
  type: String),
124
133
 
125
134
  FastlaneCore::ConfigItem.new(key: :maximal_run_time,
126
- env_name: "MAXIMAL_RUN_TIME",
135
+ env_name: 'MAXIMAL_RUN_TIME',
127
136
  default_value: 60,
128
- description: "Defines the maximal time of your test run. Defaults to 60 minutes",
137
+ description: 'Defines the maximal time of your test run. Defaults to 60 minutes',
129
138
  optional: true,
130
139
  type: Integer),
131
140
 
132
141
  FastlaneCore::ConfigItem.new(key: :bundle_install,
133
- env_name: "BUNDLE_INSTALL",
142
+ env_name: 'BUNDLE_INSTALL',
134
143
  default_value: false,
135
- description: "Defines if the Android task must execute bundle install before running a build",
144
+ description: 'Defines if the Android task must execute bundle install before running a build',
136
145
  optional: true,
137
146
  type: Boolean),
138
147
 
139
148
  FastlaneCore::ConfigItem.new(key: :is_running_on_emulator,
140
- env_name: "IS_RUNNING_ON_EMULATOR",
149
+ env_name: 'IS_RUNNING_ON_EMULATOR',
141
150
  default_value: true,
142
- description: "Define if we want to run the emulator in the container",
151
+ description: 'Define if we want to run the emulator in the container',
143
152
  optional: true,
144
153
  type: Boolean),
145
154
 
146
155
  FastlaneCore::ConfigItem.new(key: :post_actions,
147
- env_name: "POST_ACTIONS",
148
- description: "Actions that will be executed after the main command has been executed",
149
- is_string: true,
150
- optional: true),
156
+ env_name: 'POST_ACTIONS',
157
+ description: 'Actions that will be executed after the main command has been executed',
158
+ is_string: true,
159
+ optional: true),
151
160
 
152
161
  FastlaneCore::ConfigItem.new(key: :pre_action,
153
- env_name: "PRE_ACTION",
154
- description: "Actions that will be executed before the docker image gets pulled",
155
- is_string: true,
156
- optional: true),
162
+ env_name: 'PRE_ACTION',
163
+ description: 'Actions that will be executed before the docker image gets pulled',
164
+ is_string: true,
165
+ optional: true),
157
166
 
158
167
  FastlaneCore::ConfigItem.new(key: :docker_registry_login,
159
- env_name: "DOCKER_REGISTRY_LOGIN",
160
- description: "Authenticating yourself to a custom Docker registry",
161
- type: String,
162
- optional: true),
168
+ env_name: 'DOCKER_REGISTRY_LOGIN',
169
+ description: 'Authenticating yourself to a custom Docker registry',
170
+ type: String,
171
+ optional: true),
163
172
 
164
173
  FastlaneCore::ConfigItem.new(key: :pull_latest_image,
165
- env_name: "PULL_LATEST_IMAGE",
166
- description: "Define if you want to pull the latest image",
167
- type: Boolean,
168
- default_value: false,
169
- optional: true),
174
+ env_name: 'PULL_LATEST_IMAGE',
175
+ description: 'Define if you want to pull the latest image',
176
+ type: Boolean,
177
+ default_value: false,
178
+ optional: true),
170
179
 
171
180
  FastlaneCore::ConfigItem.new(key: :environment_variables,
172
- env_name: "ENVIRONMENT_VARIABLES",
173
- description: "Comma seperated list of environment variables which are passed into the docker container",
174
- type: Array,
175
- default_value: [],
176
- optional: true)
181
+ env_name: 'ENVIRONMENT_VARIABLES',
182
+ description: 'Comma seperated list of environment variables which are passed into the docker container',
183
+ type: Array,
184
+ default_value: [],
185
+ optional: true),
186
+
187
+ FastlaneCore::ConfigItem.new(key: :vnc_enabled,
188
+ env_name: 'VNC_ENABLED',
189
+ description: 'A bool. True for vnc_enabled False for vnc_disabled',
190
+ type: Boolean,
191
+ default_value: true,
192
+ optional: true)
177
193
  ]
178
194
  end
179
195
  end
@@ -0,0 +1,39 @@
1
+ require 'os'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ module CpuLoadHandler
6
+ def self.print_cpu_load(load = cpu_load)
7
+ UI.important("CPU load is: #{load}") if load
8
+ end
9
+
10
+ # Gets load average of Linux machine
11
+ def self.cpu_load
12
+ load = Actions.sh('cat /proc/loadavg')
13
+ load.split(' ').first.to_f unless load.empty?
14
+ end
15
+
16
+ # Gets amount of the CPU cores
17
+ def self.cpu_core_amount
18
+ Actions.sh("cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -1")
19
+ end
20
+
21
+ # For half an hour waiting until CPU load average is less than number of cores*2 (which considers that CPU is ready)
22
+ # Raises when 30 minutes timeout exceeds
23
+ def self.wait_cpu_to_idle
24
+ if OS.linux?
25
+ 30.times do
26
+ load = cpu_load
27
+ return true if load <= cpu_core_amount.to_i * 1.5
28
+ print_cpu_load(load)
29
+ UI.important('Waiting for available resources..')
30
+ sleep 60
31
+ end
32
+ else
33
+ return true
34
+ end
35
+ raise "CPU was overloaded. Couldn't start emulator"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,10 +1,8 @@
1
1
  require 'docker'
2
- require 'os'
3
2
 
4
3
  module Fastlane
5
4
  module Helper
6
5
  class DockerCommander
7
-
8
6
  attr_accessor :container_name
9
7
 
10
8
  def initialize(container_name)
@@ -12,35 +10,43 @@ module Fastlane
12
10
  end
13
11
 
14
12
  def pull_image(docker_image_name:)
15
- handle_thin_pool_exception do
16
- Actions.sh("docker pull #{docker_image_name}")
17
- end
13
+ Actions.sh("docker pull #{docker_image_name}")
14
+ rescue StandardError => exception
15
+ prune if exception.message =~ /Create more free space in thin pool/
16
+ Actions.sh("docker pull #{docker_image_name}")
18
17
  end
19
18
 
20
- def start_container(emulator_args:, docker_image:)
19
+ def start_container(emulator_args:, docker_image:, core_amount:)
20
+ retries ||= 0
21
21
  docker_name = if container_name
22
22
  "--name #{container_name}"
23
23
  else
24
24
  ''
25
25
  end
26
+ # if core_amount value is defined then limit the container while starting
27
+ core_amount = if core_amount && core_amount > 0
28
+ "--cpus=#{core_amount}"
29
+ else
30
+ ''
31
+ end
26
32
 
27
33
  # Action.sh returns all output that the command produced but we are only
28
34
  # interested in the last line, since it contains the id of the created container.
29
35
  UI.important("Attaching #{ENV['PWD']} to the docker container")
30
- handle_thin_pool_exception do
31
- Actions.sh("docker run -v $PWD:/root/tests --privileged -t -d #{emulator_args} #{docker_name} #{docker_image}").chomp
36
+ Actions.sh("docker run -v $PWD:/root/tests --privileged -t -d #{core_amount} #{emulator_args} #{docker_name} #{docker_image}").chomp
37
+ rescue StandardError => exception
38
+ if exception.message =~ /Create more free space in thin pool/ && (retries += 1) < 2
39
+ prune
40
+ retry
32
41
  end
33
42
  end
34
43
 
35
- def stop_container
36
- Actions.sh("docker stop #{container_name}") if container_name
37
- end
38
-
39
44
  def delete_container
40
- Actions.sh("docker rm #{container_name}") if container_name
45
+ Actions.sh("docker rm -f #{container_name}") if container_name
41
46
  end
42
47
 
43
48
  def disconnect_network_bridge
49
+ UI.important('Disconnecting from the network bridge')
44
50
  Actions.sh("docker network disconnect -f bridge #{container_name}") if container_name
45
51
  rescue StandardError
46
52
  # Do nothing if the network bridge is already gone
@@ -53,25 +59,10 @@ module Fastlane
53
59
  raise('Cannot execute docker command because the container name is unknown')
54
60
  end
55
61
  end
56
-
62
+
57
63
  def prune
58
64
  Action.sh('docker system prune -f')
59
65
  end
60
-
61
- def handle_thin_pool_exception(&block)
62
- begin
63
- block.call
64
- rescue FastlaneCore::Interface::FastlaneShellError => exception
65
- retry_counter = retry_counter.to_i + 1
66
- if exception.message =~ /Create more free space in thin pool/ && retry_counter < 2
67
- prune
68
- retry
69
- else
70
- raise exception
71
- end
72
- end
73
- end
74
-
75
66
  end
76
67
  end
77
- end
68
+ end
@@ -2,9 +2,7 @@ require_relative 'docker_commander'
2
2
 
3
3
  module Fastlane
4
4
  module Helper
5
-
6
5
  class EmulatorCommander
7
-
8
6
  attr_accessor :container_name
9
7
 
10
8
  def initialize(container_name)
@@ -22,7 +20,7 @@ module Fastlane
22
20
  # it recovers after some time, so wait and retry
23
21
  retry_counter = retry_counter.to_i + 1
24
22
  if retry_counter <= 5
25
- sleep 10*retry_counter
23
+ sleep 10 * retry_counter
26
24
  retry
27
25
  else
28
26
  raise e
@@ -55,7 +53,7 @@ module Fastlane
55
53
  # it recovers after some time, so wait and retry
56
54
  retry_counter = retry_counter.to_i + 1
57
55
  if retry_counter <= 5
58
- sleep 10*retry_counter
56
+ sleep 10 * retry_counter
59
57
  retry
60
58
  else
61
59
  raise e
@@ -63,4 +61,4 @@ module Fastlane
63
61
  end
64
62
  end
65
63
  end
66
- end
64
+ end
@@ -1,14 +1,12 @@
1
- require 'docker'
2
- require 'timeout'
3
- require 'os'
4
1
  require 'net/http'
5
2
  require_relative 'docker_commander'
6
3
  require_relative 'emulator_commander'
4
+ require_relative 'cpu_load_handler'
7
5
 
8
6
  module Fastlane
9
7
  module Helper
10
8
  class MangoHelper
11
- attr_reader :container_name, :no_vnc_port, :device_name, :docker_image, :timeout, :port_factor, :maximal_run_time, :sleep_interval, :is_running_on_emulator, :environment_variables
9
+ attr_reader :container_name, :no_vnc_port, :device_name, :docker_image, :timeout, :port_factor, :maximal_run_time, :sleep_interval, :is_running_on_emulator, :environment_variables, :vnc_enabled, :core_amount
12
10
 
13
11
  def initialize(params)
14
12
  @container_name = params[:container_name]
@@ -18,6 +16,7 @@ module Fastlane
18
16
  @timeout = params[:container_timeout]
19
17
  @sdk_path = params[:sdk_path]
20
18
  @port_factor = params[:port_factor].to_i
19
+ @core_amount = params[:core_amount].to_i
21
20
  @maximal_run_time = params[:maximal_run_time]
22
21
  @sleep_interval = 5
23
22
  @container = nil
@@ -27,7 +26,7 @@ module Fastlane
27
26
  @docker_registry_login = params[:docker_registry_login]
28
27
  @pull_latest_image = params[:pull_latest_image]
29
28
  @environment_variables = params[:environment_variables]
30
-
29
+ @vnc_enabled = params[:vnc_enabled]
31
30
  @docker_commander = DockerCommander.new(container_name)
32
31
  @emulator_commander = EmulatorCommander.new(container_name)
33
32
  end
@@ -41,11 +40,11 @@ module Fastlane
41
40
  assign_unique_vnc_port if port_factor && is_running_on_emulator
42
41
 
43
42
  if container_available?
44
- @container.stop
45
- @container.delete(force: true)
43
+ UI.important('Container was already started. Stopping and removing..')
44
+ @docker_commander.delete_container
46
45
  end
47
46
 
48
- handle_ports_allocation if is_running_on_emulator
47
+ handle_ports_allocation if is_running_on_emulator && vnc_enabled
49
48
 
50
49
  pull_from_registry if @pull_latest_image
51
50
 
@@ -67,13 +66,19 @@ module Fastlane
67
66
 
68
67
  unless container_state
69
68
  UI.important("Will retry to create a healthy docker container after #{sleep_interval} seconds")
70
- @container.stop
71
- @container.delete(force: true)
69
+ @docker_commander.delete_container
72
70
  sleep @sleep_interval
73
71
  create_container
74
72
 
75
73
  unless wait_for_healthy_container
76
74
  UI.important('Container is unhealthy. Exiting..')
75
+ begin
76
+ Actions.sh("docker logs #{container_name} --tail 200")
77
+ Actions.sh("docker exec -i #{container_name} cat /var/log/supervisor/docker-android.stderr.log")
78
+ Actions.sh("docker exec -i #{container_name} cat /var/log/supervisor/supervisord.log")
79
+ rescue StandardError
80
+ # do nothing
81
+ end
77
82
  # We use code "2" as we need something than just standard error code 1, so we can differentiate the next step in CI
78
83
  exit 2
79
84
  end
@@ -101,12 +106,6 @@ module Fastlane
101
106
  @docker_commander.exec(command: 'cat kvm-ok.txt').include?('KVM acceleration can NOT be used')
102
107
  end
103
108
 
104
- # Stops and remove container
105
- def clean_container
106
- @container.stop
107
- @container.delete(force: true)
108
- end
109
-
110
109
  private
111
110
 
112
111
  # Sets path to adb
@@ -117,7 +116,7 @@ module Fastlane
117
116
  # assigns vnc port
118
117
  def assign_unique_vnc_port
119
118
  @no_vnc_port = 6080 + port_factor
120
- @host_ip_address = `hostname -I | head -n1 | awk '{print $1;}'`.delete!("\n")
119
+ @host_ip_address = `hostname -i | head -n1 | awk '{print $1;}'`.delete!("\n")
121
120
  UI.success("Port: #{@no_vnc_port} was chosen for VNC")
122
121
  UI.success("Link to VNC: http://#{@host_ip_address}:#{@no_vnc_port}")
123
122
  end
@@ -125,46 +124,45 @@ module Fastlane
125
124
  # Creates new container using params
126
125
  def create_container
127
126
  UI.important("Creating container: #{container_name}")
128
- print_cpu_load
127
+ CpuLoadHandler.print_cpu_load
129
128
  begin
130
129
  container = create_container_call
131
130
  set_container_name(container)
132
131
  rescue StandardError
133
132
  UI.important("Something went wrong while creating: #{container_name}, will retry in #{@sleep_interval} seconds")
134
- print_cpu_load
135
- @docker_commander.stop_container
133
+ CpuLoadHandler.print_cpu_load
136
134
  @docker_commander.delete_container
137
-
138
135
  sleep @sleep_interval
139
136
  container = create_container_call
140
137
  set_container_name(container)
141
138
  end
142
- get_container_instance(container)
139
+ @container = get_container_instance(container)
140
+
141
+ if @container.nil?
142
+ sleep 3
143
+ @container = get_container_instance(container)
144
+ end
143
145
  end
144
146
 
145
147
  # Gets container instance by container ID
146
148
  def get_container_instance(container)
147
149
  Docker::Container.all(all: true).each do |cont|
148
- if cont.id == container
149
- @container = cont
150
- break
151
- end
150
+ return cont if cont.id == container
152
151
  end
153
152
  end
154
153
 
155
154
  # Call to create a container. We don't use Docker API here, as it doesn't support --privileged.
156
155
  def create_container_call
157
156
  # When CPU is under load we cannot create a healthy container
158
- wait_cpu_to_idle
157
+ CpuLoadHandler.wait_cpu_to_idle
159
158
 
160
159
  additional_env = ''
161
160
  environment_variables.each do |variable|
162
- additional_env = additional_env + " -e #{variable}"
161
+ additional_env += " -e #{variable}"
163
162
  end
164
163
  emulator_args = is_running_on_emulator ? "-p #{no_vnc_port}:6080 -e DEVICE='#{device_name}'" : ''
165
164
  emulator_args = "#{emulator_args}#{additional_env}"
166
-
167
- @docker_commander.start_container(emulator_args: emulator_args, docker_image: docker_image)
165
+ @docker_commander.start_container(emulator_args: emulator_args, docker_image: docker_image, core_amount: core_amount)
168
166
  end
169
167
 
170
168
  def execute_pre_action
@@ -173,6 +171,7 @@ module Fastlane
173
171
 
174
172
  # Pull the docker images before creating a container
175
173
  def pull_from_registry
174
+ UI.important('Pulling the :latest image from the registry')
176
175
  docker_image_name = docker_image.gsub(':latest', '')
177
176
  Actions.sh(@docker_registry_login) if @docker_registry_login
178
177
  @docker_commander.pull_image(docker_image_name: docker_image_name)
@@ -189,7 +188,6 @@ module Fastlane
189
188
  if port_open?('0.0.0.0', @no_vnc_port)
190
189
  UI.important('Something went wrong. VNC port is still busy')
191
190
  sleep @sleep_interval
192
- @docker_commander.stop_container
193
191
  @docker_commander.delete_container
194
192
  end
195
193
  end
@@ -203,10 +201,6 @@ module Fastlane
203
201
  nil
204
202
  end
205
203
 
206
- def print_cpu_load(load = cpu_load)
207
- UI.important("CPU load is: #{load}")
208
- end
209
-
210
204
  # Checks if container is already available
211
205
  def container_available?
212
206
  return false unless container_name
@@ -252,6 +246,9 @@ module Fastlane
252
246
  end
253
247
  UI.important("The Container failed to load after '#{timeout}' seconds timeout. Reason: '#{@container.json['State']['Status']}'")
254
248
  false
249
+ rescue StandardError => e
250
+ puts e
251
+ false
255
252
  end
256
253
 
257
254
  # Checks if port is already openZ
@@ -263,41 +260,12 @@ module Fastlane
263
260
  false
264
261
  end
265
262
 
266
- # Gets load average of Linux machine
267
- def cpu_load
268
- load = `cat /proc/loadavg`
269
- load.split(' ').first.to_f
270
- end
271
-
272
- # Gets amount of the CPU cores
273
- def cpu_core_amount
274
- `cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -1`
275
- end
276
-
277
- # For half an hour waiting until CPU load average is less than number of cores*2 (which considers that CPU is ready)
278
- # Raises when 30 minutes timeout exceeds
279
- def wait_cpu_to_idle
280
- if OS.linux?
281
- 30.times do
282
- load = cpu_load
283
- return true if load < cpu_core_amount.to_i * 1.5
284
- print_cpu_load(load)
285
- UI.important('Waiting for available resources..')
286
- sleep 60
287
- end
288
- else
289
- return true
290
- end
291
- raise "CPU was overloaded. Couldn't start emulator"
292
- end
293
-
294
263
  # if we do not have container name, we cane use container ID that we got from create call
295
264
  def set_container_name(container)
296
265
  unless container_name
297
266
  @container_name = @emulator_commander.container_name = @docker_commander.container_name = container
298
267
  end
299
268
  end
300
-
301
269
  end
302
270
  end
303
271
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Mango
3
- VERSION = '1.1.6'.freeze
3
+ VERSION = '1.3.15'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-mango
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serghei Moret, Daniel Hartwich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2020-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docker-api
@@ -146,6 +146,7 @@ files:
146
146
  - README.md
147
147
  - lib/fastlane/plugin/mango.rb
148
148
  - lib/fastlane/plugin/mango/actions/run_dockerized_task_action.rb
149
+ - lib/fastlane/plugin/mango/helper/cpu_load_handler.rb
149
150
  - lib/fastlane/plugin/mango/helper/docker_commander.rb
150
151
  - lib/fastlane/plugin/mango/helper/emulator_commander.rb
151
152
  - lib/fastlane/plugin/mango/helper/mango_helper.rb
@@ -169,8 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
169
170
  - !ruby/object:Gem::Version
170
171
  version: '0'
171
172
  requirements: []
172
- rubyforge_project:
173
- rubygems_version: 2.7.4
173
+ rubygems_version: 3.0.6
174
174
  signing_key:
175
175
  specification_version: 4
176
176
  summary: This plugin Android tasks on docker images