forj 1.0.10 → 1.0.11

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
  SHA1:
3
- metadata.gz: 104016c81c311f9a0f4454a0f50aadeb9e2810a2
4
- data.tar.gz: 07452ff472445eed9d882d1d8e153c75b7b27182
3
+ metadata.gz: 5c59dea68c4b93b5a88af774d515d0d5c6aece5a
4
+ data.tar.gz: ba80c68baec1fada231973d365f7bc3d46cb6306
5
5
  SHA512:
6
- metadata.gz: dc95fd28f3de676003c62a1804725ca4225199391c78096a200a048c92d02207324d19ffd6a127b9a446baafe6b16a28ca3a49c90d676e2a6db33fbf35dd75a0
7
- data.tar.gz: f1f431e9d6ebb546d1f524b921db1098ce537ec5a263ea310a87f2b6ff36fc35261d37552f8b4e0fe8568d551ee5beb9daf115b8042f689a4ca26ea0c508688f
6
+ metadata.gz: d8f0791f66cb366aef89a6845e0a8ac13869e08e3e27e659824513b0056b27950503f2c354ddf4d5b00798ea60c34e3a0d94d2e56a6da992dc6bb290319f5e12
7
+ data.tar.gz: de46007515850844f71c4dbc2d7375991c58c2be4c9118b39b432694ecb7939a9c552945fc3a5cb19d830f953c77158f7f5096228e534828647418b65e45e9cb
data/.rubocop.yml CHANGED
@@ -33,27 +33,24 @@ Style/HashSyntax:
33
33
 
34
34
  # lets start with 40, but 10 is way to small..
35
35
  Metrics/MethodLength:
36
- Max: 40
36
+ Max: 50
37
+ # If Method length is increased, class length need to be extended as well.
38
+ Metrics/ClassLength:
39
+ Max: 150
40
+
37
41
  # allow arguments to be longer than 15
38
42
  Metrics/AbcSize:
39
- Max: 40
40
- # allow nested methods and classes definition
41
- ClassAndModuleChildren:
42
- # EnforcedStyle: compact
43
- Enabled: false
43
+ Max: 50
44
+ # Perceived Complexity
45
+ Metrics/PerceivedComplexity:
46
+ Max: 9
47
+ Metrics/CyclomaticComplexity:
48
+ Max: 8
44
49
 
45
- # some files names gets an exception
50
+ # forj-docker binary name gets an exception
46
51
  Style/FileName:
47
52
  Exclude: ['Gemfile',
48
53
  'lib/forj/process/ForjProcess.rb',
49
54
  'lib/forj/ForjCore.rb',
50
55
  'lib/forj/ForjCli.rb',
51
56
  'lib/forj-settings.rb' ]
52
-
53
- # this project defines these globals
54
- Style/GlobalVars:
55
- AllowedVariables: ['$RT_GEM_BIN',
56
- '$RT_VERSION_SPEC',
57
- '$FORJ_TEMP',
58
- '$RT_VERSION',
59
- '$RT_GEM_HOME']
data/bin/forj CHANGED
@@ -21,6 +21,7 @@ require 'rubygems'
21
21
  require 'bundler/setup'
22
22
  require 'thor'
23
23
  require 'ansi'
24
+ require 'forj'
24
25
 
25
26
  APP_PATH = File.dirname(File.dirname(__FILE__))
26
27
  LIB_PATH = File.expand_path(File.join(APP_PATH, 'lib'))
@@ -148,21 +149,27 @@ If you want to check/updated them, use `forj get [-a account]`
148
149
  ' flavor : Maestro flavor to use.'
149
150
  method_option :bp_flavor, :aliases => '-b', :desc => 'config:' \
150
151
  ' bp_flavor : Blueprint nodes default flavor to use.'\
151
- "\n\n Build system options:"
152
+ "\n\nBuild system options:"
152
153
  method_option :boothook, :aliases => '-H', :desc => 'By default, ' \
153
154
  ' boothook file used is build/bin/build-tools/boothook.sh. ' \
154
155
  ' Use this option to set another one.'
155
156
  method_option :build, :aliases => '-B', :desc => 'Replace' \
156
157
  ' the default build.sh'
157
158
  method_option :branch, :aliases => '-R', :desc => 'Branch' \
158
- "name to clone for maestro.\n\nMaestro/infra bootstrap debugging:"
159
- method_option :test_box, :aliases => '-T', :desc => 'Identify a' \
160
- ' path to become your test-box repository.' \
161
- "\n " \
162
- 'Ex: if your maestro is in ~/src/forj-oss, --test_box' \
163
- ' ~/src/forj-oss/maestro build.sh and' \
164
- "\n " \
165
- 'test-box will send your local maestro repo to your box, for boot.'
159
+ "name to clone for maestro.\n\n"\
160
+ "Remote box bootstrap debugging (test-box):\n"\
161
+ 'test-box is a shell script used to connect one or more local repository'\
162
+ " to be connected to the new remote box. \n"\
163
+ 'If your box support test-box feature, at boot time, the remote box may '\
164
+ 'wait for your local repository to be sent out to the new box. '\
165
+ 'For more details on test-box, call it to get help.'
166
+ method_option :tb_path, :aliases => '-t',
167
+ :desc => 'Define the path to the test-box script. '\
168
+ 'This option superseeds the TEST_BOX '\
169
+ 'environment variable.'
170
+ method_option :test_box, :aliases => '-T', :type => :array,
171
+ :desc => "Use a local repository for test-box\n\n"\
172
+ 'Other options:'
166
173
  method_option :extra_metadata, :aliases => '-e', :desc => 'Custom' \
167
174
  ' server metadata format key1=value1,key2=value2...,keyN=valueN'
168
175
 
data/forj.gemspec CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
19
19
  s.name = 'forj'
20
20
  s.homepage = 'https://www.forj.io'
21
21
 
22
- s.version = '1.0.10'
23
- s.date = '2015-04-17'
22
+ s.version = '1.0.11'
23
+ s.date = '2015-05-22'
24
24
  s.summary = 'forj command line'
25
25
  s.description = 'forj cli - See https://www.forj.io for documentation/information'
26
26
 
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
51
51
  s.add_runtime_dependency 'json', '1.7.5'
52
52
  s.add_runtime_dependency 'bundler'
53
53
  s.add_runtime_dependency 'nokogiri','1.5.11'
54
- s.add_runtime_dependency 'lorj_cloud', '~> 0.1.0'
54
+ s.add_runtime_dependency 'lorj_cloud', '~> 0.1.1'
55
55
 
56
56
  s.add_development_dependency "rake", "~> 10.0"
57
57
  s.add_development_dependency "rspec", "~> 3.1.0"
data/forj/defaults.yaml CHANGED
@@ -13,285 +13,4 @@
13
13
  # limitations under the License.
14
14
 
15
15
  :default:
16
- :maestro_url: https://github.com/forj-oss/maestro.git
17
-
18
- # Default Infra repository to use. If missing, it will be proposed to be created.
19
- :infra_repo: ~/.forj/infra
20
-
21
- # You can set proto2b in your ~/.forj/config.yaml if you built it from maestro/build. Read the maestro/README.md to create it.
22
- :image_name: Ubuntu Precise 12.04.4 LTS Server 64-bit 20140414 (Rescue Image)
23
-
24
- # Flavor to use for Maestro
25
- :flavor: medium
26
- # Default flavor to use for all Blueprint nodes.
27
- :bp_flavor: small
28
-
29
- # Ports to open for Maestro, added to the security group
30
- :security_group: forj
31
- :ports: [22, 80, 443, 3000, 3131-3135, 4505-4506, 5000, 5666, 8000, 8080-8081, 8083, 8125, 8139-8140, 8773-8776, 9292, 29418, 35357]
32
-
33
- # Network: If network doesn't exist, forj cli will try to create it, and attach it a router.
34
- :network: forj
35
-
36
- # Users: Default user for ssh connection, if user doesn't exits, forj cli will try to get the user from the server image on it's name attribute
37
- :users: ['ubuntu', 'fedora', 'cloud-user', 'cirros', 'centos', 'cloud', 'root']
38
-
39
- # build.sh internal variables.
40
- :build_config: box
41
- :branch: master
42
- :box_name: maestro
43
-
44
16
  :provider_name: hpcloud
45
-
46
- :maestro_bootstrap_dir: build/maestro/bootstrap
47
- :description:
48
- # Description of build.sh environment variable defined by forj cli for build.sh. (~/.forj/infra/build/<Account>.build.env)
49
- :FORJ_HPC: "HPCloud cli Account used to build your Maestro box"
50
- :FORJ_HPC_COMPUTE: "HPCloud Compute service (like region-b.geo-1) used to run your Maestro Box"
51
- :FORJ_TENANT_NAME: "HPCloud Tenant name used build your <Blueprint> nodes"
52
- :FORJ_HPC_NET: "HPCloud Network name to use, while booting all boxes."
53
- :FORJ_KEYPAIR: "Keypair used to access boxes."
54
- :FORJ_SECURITY_GROUP: "Security group associated to each box"
55
- :FORJ_HPC_NOVA_KEYPUB: "Public key used by build.sh to ensure his existence on HPCloud"
56
- :FORJ_BASE_IMG: "Base image used to build all boxes"
57
- :FORJ_FLAVOR: "Flavor used to build Maestro"
58
- # DNS specific data
59
- :FORJ_DNS_TENANTID: "HPCloud Project ID to use to create DNS entries for each boxes."
60
- :FORJ_DNS_ZONE: "HPCloud Domain name service to use for each boxes DNS entries. (Ex: region-a.geo-1)"
61
- :FORJ_DNS_DOMAIN: "Domain used for DNS. Each server will be attached to a public IP. An 'A' record in the DNS service will need to be added to your HPCloud DOMAIN."
62
-
63
- # Following declares generic FORJ data to handle Fog object (compute/network/dns/...)
64
- # It defines the account file structure. section/key=value
65
- # All data can be predefined by default value (config.yaml/defaults.yaml) except
66
- # those identified by :account_exclusive: true
67
- :setup:
68
- :ask_step:
69
- - :desc: "Provider configuration:"
70
- - :desc: "Maestro Cloud compute configuration:"
71
- :explanation: |-
72
- Maestro (gardener) is currently configured to access your cloud Compute service with fog openstack.
73
- Fog openstack is compatible with hpcloud services
74
-
75
- It requires the openstack project name, user and password.
76
-
77
- - :desc: "Maestro and blueprint configuration:"
78
- :add:
79
- - :keypair_files
80
- - :ssh_user
81
- - :desc: "DNS Configuration for Maestro:"
82
- :sections:
83
- # This section define updatable data available from config.yaml. But will never be added in an account file.
84
- # Used by forj set/get functions
85
- :default:
86
- :account_name:
87
- :desc: "Default account name used by forj cli"
88
- :provider_name:
89
- :desc: "Default provider name while running forj setup. By default, hpcloud is selected."
90
- # Defines account credentials data
91
- :account:
92
- :name:
93
- :desc: "Name of the Forj cli account. use forj account rename <oldName> <NewName> to update it."
94
- :readonly: true
95
- :account_exclusive: true
96
- :provider:
97
- :desc: "Provider name attached to the forj cli account. To update it, use forj setup."
98
- :readonly: true
99
- :account_exclusive: true
100
- :default: :provider_name
101
-
102
- # Defines services
103
- :services:
104
- :compute:
105
- :desc: "Generic service identification for compute"
106
- :account_exclusive: true
107
- :account: true
108
- :ask_step: 0
109
- :network:
110
- :desc: "Generic service identification for network"
111
- :account_exclusive: true
112
- :account: true
113
- :ask_step: 0
114
-
115
- # Defines ssh keys credentials
116
- :credentials:
117
- :keypair_files:
118
- :explanation: |-
119
- A keypair is a combination of SSH public and private key files. Usually, generated in your '$HOME/.ssh/' directory.
120
- The private key is used to identify yourself to access your box via ssh.
121
- The public key is used to configure your server to authorize you to access the box with your private key.
122
- This keypair files will be copied to '$HOME/.forj/keypairs/ under <keypair_name> files for 'forj' needs.
123
-
124
- If the keypair doesn't exist locally, it will be created for you.
125
- :desc: "Base keypair file name"
126
- :default_value: "~/.ssh/<%= config[:keypair_name] %>-id_rsa"
127
- :validate_function: :forj_check_keypairs_files
128
- :account: true
129
- :ask_step: 2
130
- :after: :keypair_name
131
- :pre_step_function: :forj_cloud_keypair_coherent?
132
- :post_step_function: :forj_setup_keypairs_files
133
- :keypair_path:
134
- :desc: "Contains the full path to the :keypair_base."
135
- :default_value: "<%= Forj.keypairs_path %>"
136
- :keypair_base:
137
- :desc: "Contains the key file base name without .pem/.pub."
138
- :default_value: "<%= config[:keypair_name] %>"
139
- :keypair_name:
140
- :desc: "keypair name defined in your cloud to access your server. By default we named it 'forj'. If it doesn't exist, it will be created."
141
- :required: true
142
- :default_value: "forj"
143
- :account: true
144
- :ask_step: 2
145
- :pre_step_function: :update_keypair_config
146
- :post_step_function: :forj_check_cloud_keypair
147
- :auth_uri:
148
- :desc: "Generic service auth url"
149
- :account_exclusive: true
150
- :account: true
151
- :required: true
152
- :ask_sort: 0
153
- :account_id:
154
- :desc: "Generic Cloud Account name."
155
- :account_exclusive: true
156
- :account: true
157
- :required: true
158
- :account_key:
159
- :desc: "Generic cloud account key"
160
- :account_exclusive: true
161
- :account: true
162
- :required: true
163
- :encrypted: true
164
- :tenant:
165
- :desc: "Openstack Tenant Name (Project name)"
166
- :account_exclusive: true
167
- :account: true
168
- :required: true
169
- :ask_step: 0
170
- :os_user:
171
- :desc: "Openstack compute cloud User name"
172
- :account_exclusive: true
173
- :account: true
174
- :required: true
175
- :validate: !ruby/regexp /\w+/
176
- :ask_step: 1
177
- :default_value: "<%= (config[:provider_name] == 'openstack')?config[:account_id]:nil %>"
178
- :os_enckey:
179
- :desc: "Openstack compute cloud password"
180
- :account_exclusive: true
181
- :encrypted: true
182
- :account: true
183
- :required: true
184
- :ask_step: 1
185
- :default_value: "<%= (config[:provider_name] == 'openstack')?config[:account_key]:nil %>"
186
-
187
- # Defines DNS services for maestro
188
- :dns:
189
- :domain_name:
190
- :desc: "Domain name added to each hosts."
191
- :account_exclusive: true
192
- :account: true
193
- :post_step_function: :forj_dns_settings
194
- :ask_step: 3
195
- :dns_service:
196
- :desc: "DNS service region name Maestro will use."
197
- :account_exclusive: true
198
- :account: true
199
- :pre_step_function: :forj_dns_settings?
200
- :ask_step: 3
201
- :dns_tenant_id:
202
- :desc: "DNS Tenant ID Maestro will use"
203
- :account_exclusive: true
204
- :account: true
205
- :pre_step_function: :forj_dns_settings?
206
- :ask_step: 3
207
-
208
- :maestro:
209
- :tenant_name:
210
- :desc: "Tenant name required by fog/openstack on gardener"
211
- :account: true
212
- :validate: !ruby/regexp /^\w?[\w_:-]*$/
213
- :ask_step: 1
214
- :ask_sort: 0
215
- :default_value: "<%= (config[:provider_name] == 'openstack')?config[:tenant]:nil %>"
216
- :network_name:
217
- :desc: "Network name to attach to each forge boxes. By default we use 'forj'. If it doesn't exist, it will be created."
218
- :default: network
219
- :account: true
220
- :required: true
221
- :default_value: "forj"
222
- :ask_step: 2
223
- :security_group:
224
- :desc: "Security group name to configure and attach to each forge boxes."
225
- :account: true
226
- :validate: !ruby/regexp /^\w?\w*$/
227
- :default_value: "forj"
228
- :ask_step: 2
229
- :maestro_repo:
230
- :desc: "To use a different Maestro repository already cloned."
231
- :infra_repo:
232
- :desc: "Defines your Infra directory to use while booting."
233
- :box_name:
234
- :desc: "forj cli use 'build.sh' to create Maestro. See box_name option on build.sh to get more information. By default 'maestro'"
235
- :build_config:
236
- :desc: "forj cli use 'build.sh' to create Maestro. See build_config option on build.sh to get more information. By default 'box'"
237
- :bp_flavor:
238
- :desc: "Blueprint nodes default flavor"
239
- :explanation: |-
240
- Blueprint usually defines the required flavor for their nodes. If not, it will use this flavor as default.
241
- Usually, blueprint nodes are smaller than Maestro.
242
- :account: true
243
- :list_values:
244
- :query_type: :query_call # Will execute a query on flavor, query_params is empty for all.
245
- :object: :flavor
246
- :value: :name
247
- :validate: :list_strict
248
- :ask_step: 2
249
- :flavor_name:
250
- :explanation: 'This flavor is for Maestro only.'
251
- :desc: "Maestro Flavor name"
252
- :default: :flavor
253
- :account: true
254
- :list_values:
255
- :query_type: :query_call # Will execute a query on flavor, query_params is empty for all.
256
- :object: :flavor
257
- :value: :name
258
- :validate: :list_strict
259
- :ask_step: 2
260
- :image_name:
261
- :desc: "Image name"
262
- :explanation: |-
263
- Ubuntu image used to create Maestro and all forge boxes. Originally, Maestro uses 'Ubuntu Precise 12.04.4 LTS Server 64-bit'.
264
- You need to choose the appropriate image to make Maestro & boxes to boot normally.
265
- :account: true
266
- :ask_step: 2
267
- :list_values:
268
- :query_type: :query_call # Will execute a query on flavor, query_params is empty for all. No filter currently working.
269
- :object: :image
270
- :value: :name
271
- :validate: :list_strict
272
- :ask_step: 2
273
- :ssh_user:
274
- :desc: "User name for ssh connection of your selected image."
275
- :explanation: |-
276
- The image name you have selected has a unique SSH Account access.
277
-
278
- Thanks to the name of the image, setup assume the account name to use.
279
- If this name is incoherent with the image you choosed, please update it.
280
-
281
- Checking image '<%= config[:image_name] %>'...
282
- :account: true
283
- :ask_step: 2
284
- :after: :image_name
285
- :list_values:
286
- :query_type: :process_call # Will execute a process to query on image
287
- :query_call: :setup_ssh_user # and return the list of images and a default value.
288
- :query_params: # Transmitted as hParams
289
- :image_name: '<%= config[:image_name] %>'
290
- :ports:
291
- :desc: "List of security group rules (1 port or range of ports) to open to the external network."
292
- :branch:
293
- :desc: "Branch to use to build your forge"
294
- :bootstrap_dirs:
295
- :desc: "Additional bootstrap directories (separated by space) to add in the bootstrap loop."
296
- :bootstrap_extra_dir:
297
- :desc: "Additional bootstrap directory to add in the bootstrap loop, before :bootstrap_dirs and after maestro default bootstrap directory."
data/lib/boot.rb CHANGED
@@ -53,9 +53,9 @@ module Forj
53
53
 
54
54
  def self.load_options(options, options_map)
55
55
  options_map.each do |opt_key, ac_key|
56
- unless options[opt_key].nil?
57
- value = yield(opt_key, options[opt_key])
58
- @account.set(ac_key, options[opt_key]) unless value.nil?
56
+ if options.key?(opt_key.to_s)
57
+ value = yield(opt_key, options[opt_key.to_s])
58
+ @account.set(ac_key, value) unless value.nil?
59
59
  end
60
60
  end
61
61
  end
@@ -99,10 +99,12 @@ module Forj
99
99
  @account[:instance_name], @account[:blueprint])
100
100
  end
101
101
  end
102
+ end
103
+ # rubocop: disable Metrics/CyclomaticComplexity
104
+ # rubocop: disable Metrics/MethodLength
102
105
 
103
- # rubocop: disable Metrics/CyclomaticComplexity
104
- # rubocop: disable Metrics/MethodLength
105
-
106
+ #
107
+ module Boot
106
108
  # Boot process
107
109
  def self.boot(blueprint, on_or_name, deprecated_name, options)
108
110
  @account = Lorj::Account.new(options[:config])
@@ -125,6 +127,9 @@ module Forj
125
127
  @account[:account_name], @account[:account_name])
126
128
  end
127
129
 
130
+ options = options.to_h
131
+ options['tb_path'] = nil if options.key?('test_box') &&
132
+ !options.key?('tb_path')
128
133
  options_map = { :infra => :infra_repo,
129
134
  :key_name => :keypair_name,
130
135
  :key_path => :keypair_path,
@@ -135,22 +140,10 @@ module Forj
135
140
  :maestro_repo => :maestro_repo,
136
141
  :branch => :branch,
137
142
  :test_box => :test_box,
143
+ :tb_path => :test_box_path,
138
144
  :extra_metadata => :extra_metadata }
139
145
 
140
- load_options(options, options_map) do |key, value|
141
- case key
142
- when :test_box
143
- path = File.expand_path(value)
144
- return path if File.directory?(path)
145
- return nil
146
- end
147
- value
148
- end
149
-
150
- PrcLib.warning(
151
- 'test_box is currently disabled in this version.' \
152
- 'It will be re-activated in newer version.'
153
- ) if options[:test_box]
146
+ load_options(options, options_map) { |k, v| complete_boot_options(k, v) }
154
147
 
155
148
  validate_keypath(options)
156
149
 
@@ -166,4 +159,91 @@ module Forj
166
159
  o_cloud.create(:forge)
167
160
  end
168
161
  end
162
+ # rubocop: enable Metrics/CyclomaticComplexity
163
+ # rubocop: enable Metrics/MethodLength
164
+
165
+ #
166
+ module Boot
167
+ # Take care of special options cases for boot.
168
+ def self.complete_boot_options(key, value)
169
+ case key
170
+ when :test_box
171
+ value = tb_repo_detect(value)
172
+ when :tb_path
173
+ value = tb_bin_detect(value)
174
+ end
175
+ value
176
+ end
177
+
178
+ # Function to check the repository path passed.
179
+ def self.tb_repo_detect(paths)
180
+ res = {}
181
+ paths.each do |path|
182
+ cmd = <<-CMD
183
+ cd "#{path}"
184
+ git rev-parse --show-toplevel 2>/dev/null 1>&2
185
+ if [ $? -ne 0 ]
186
+ then
187
+ exit 1
188
+ fi
189
+ REPO_TO_ADD="$(LANG= git remote show origin -n |
190
+ awk '$1 ~ /Fetch/ { print $3 }')"
191
+ if [ "$REPO_TO_ADD" = "" ]
192
+ then
193
+ exit 1
194
+ fi
195
+ echo $REPO_TO_ADD
196
+ pwd
197
+ CMD
198
+ cmd_res = `#{cmd}`.split
199
+ # For any reason, $CHILD_STATUS is empty, while $? is not.
200
+ # Ruby bug. tested with:
201
+ # ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
202
+ # rubocop: disable Style/SpecialGlobalVars
203
+ next unless $?.exitstatus == 0
204
+ # rubocop: enable Style/SpecialGlobalVars
205
+ repo_found = cmd_res[0].match(%r{.*/(.*)(.git)?})
206
+ next unless repo_found
207
+ res[repo_found[1]] = cmd_res[1]
208
+ end
209
+ res
210
+ end
211
+
212
+ # function to detect if test-box.sh is runnable
213
+ #
214
+ # It returns the script to execute.
215
+ def self.tb_bin_detect(tb_path)
216
+ tb_path = ENV['TEST_BOX'] if tb_path.nil?
217
+ tb_path = File.expand_path(tb_path) unless tb_path.nil?
218
+
219
+ script = 'test-box.sh'
220
+ if tb_path && File.directory?(tb_path)
221
+ script_found = tb_check_bin(tb_path)
222
+ script = File.expand_path(File.join(tb_path, script))
223
+ if script_found.nil?
224
+ PrcLib.error("Test-box: '%s' is not a valid runnable script. "\
225
+ 'test-box is disabled.', script)
226
+ return nil
227
+ end
228
+ return script_found
229
+ end
230
+
231
+ script_found = nil
232
+
233
+ ENV['PATH'].split(':').each do |path|
234
+ script_found = tb_check_bin(path)
235
+ break unless script_found.nil?
236
+ end
237
+
238
+ script_found
239
+ end
240
+
241
+ # Script to check the bin and path
242
+ def self.tb_check_bin(tb_path)
243
+ script = 'test-box.sh'
244
+ script = File.expand_path(File.join(tb_path, script))
245
+ return script if File.executable?(script)
246
+ nil
247
+ end
248
+ end
169
249
  end