test-kitchen 1.4.2 → 1.5.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +27 -2
- data/CHANGELOG.md +40 -1
- data/Gemfile.proxy_tests +6 -0
- data/features/kitchen_driver_discover_command.feature +6 -0
- data/features/kitchen_init_command.feature +5 -3
- data/features/step_definitions/gem_steps.rb +12 -4
- data/features/step_definitions/git_steps.rb +1 -1
- data/features/step_definitions/output_steps.rb +1 -1
- data/features/support/env.rb +13 -9
- data/lib/kitchen/cli.rb +3 -0
- data/lib/kitchen/command/driver_discover.rb +8 -0
- data/lib/kitchen/configurable.rb +32 -0
- data/lib/kitchen/driver/ssh_base.rb +18 -4
- data/lib/kitchen/generator/driver_create.rb +2 -2
- data/lib/kitchen/lazy_hash.rb +20 -0
- data/lib/kitchen/provisioner/base.rb +16 -1
- data/lib/kitchen/provisioner/chef_base.rb +42 -98
- data/lib/kitchen/provisioner/chef_solo.rb +6 -4
- data/lib/kitchen/provisioner/chef_zero.rb +7 -5
- data/lib/kitchen/transport/winrm.rb +36 -2
- data/lib/kitchen/verifier/base.rb +18 -1
- data/lib/kitchen/verifier/busser.rb +12 -5
- data/lib/kitchen/verifier/shell.rb +101 -0
- data/lib/kitchen/version.rb +1 -1
- data/spec/kitchen/configurable_spec.rb +211 -2
- data/spec/kitchen/driver/ssh_base_spec.rb +131 -8
- data/spec/kitchen/lazy_hash_spec.rb +27 -0
- data/spec/kitchen/provisioner/base_spec.rb +25 -0
- data/spec/kitchen/provisioner/chef_base_spec.rb +133 -252
- data/spec/kitchen/provisioner/chef_solo_spec.rb +17 -0
- data/spec/kitchen/provisioner/chef_zero_spec.rb +14 -2
- data/spec/kitchen/provisioner/shell_spec.rb +60 -12
- data/spec/kitchen/transport/winrm_spec.rb +50 -0
- data/spec/kitchen/verifier/base_spec.rb +26 -0
- data/spec/kitchen/verifier/busser_spec.rb +69 -3
- data/spec/kitchen/verifier/shell_spec.rb +157 -0
- data/support/busser_install_command.sh +1 -2
- data/test-kitchen.gemspec +10 -2
- metadata +86 -6
@@ -29,8 +29,8 @@ module Kitchen
|
|
29
29
|
include Logging
|
30
30
|
|
31
31
|
default_config :http_proxy, nil
|
32
|
-
|
33
32
|
default_config :https_proxy, nil
|
33
|
+
default_config :ftp_proxy, nil
|
34
34
|
|
35
35
|
default_config :root_path do |provisioner|
|
36
36
|
provisioner.windows_os? ? "$env:TEMP\\kitchen" : "/tmp/kitchen"
|
@@ -44,6 +44,8 @@ module Kitchen
|
|
44
44
|
provisioner.windows_os? ? nil : "sudo -E"
|
45
45
|
end
|
46
46
|
|
47
|
+
default_config :command_prefix, nil
|
48
|
+
|
47
49
|
expand_path_for :test_base_path
|
48
50
|
|
49
51
|
# Constructs a new provisioner by providing a configuration hash.
|
@@ -208,6 +210,19 @@ module Kitchen
|
|
208
210
|
def sudo(script)
|
209
211
|
config[:sudo] ? "#{config[:sudo_command]} #{script}" : script
|
210
212
|
end
|
213
|
+
|
214
|
+
# Conditionally prefixes a command with a command prefix.
|
215
|
+
# This should generally be done after a command has been
|
216
|
+
# conditionally prefixed by #sudo as certain platforms, such as
|
217
|
+
# Cisco Nexus, require all commands to be run with a prefix to
|
218
|
+
# obtain outbound network access.
|
219
|
+
#
|
220
|
+
# @param command [String] command to be prefixed
|
221
|
+
# @return [String] the command, conditionally prefixed with the configured prefix
|
222
|
+
# @api private
|
223
|
+
def prefix_command(script)
|
224
|
+
config[:command_prefix] ? "#{config[:command_prefix]} #{script}" : script
|
225
|
+
end
|
211
226
|
end
|
212
227
|
end
|
213
228
|
end
|
@@ -25,6 +25,9 @@ require "kitchen/provisioner/chef/berkshelf"
|
|
25
25
|
require "kitchen/provisioner/chef/common_sandbox"
|
26
26
|
require "kitchen/provisioner/chef/librarian"
|
27
27
|
require "kitchen/util"
|
28
|
+
require "mixlib/install"
|
29
|
+
require "chef-config/config"
|
30
|
+
require "chef-config/workstation_config_loader"
|
28
31
|
|
29
32
|
module Kitchen
|
30
33
|
|
@@ -40,6 +43,7 @@ module Kitchen
|
|
40
43
|
default_config :chef_omnibus_install_options, nil
|
41
44
|
default_config :run_list, []
|
42
45
|
default_config :attributes, {}
|
46
|
+
default_config :config_path, nil
|
43
47
|
default_config :log_file, nil
|
44
48
|
default_config :cookbook_files_glob, %w[
|
45
49
|
README.* metadata.{json,rb}
|
@@ -47,18 +51,6 @@ module Kitchen
|
|
47
51
|
providers/**/* recipes/**/* resources/**/* templates/**/*
|
48
52
|
].join(",")
|
49
53
|
|
50
|
-
default_config :chef_metadata_url do |provisioner|
|
51
|
-
provisioner.default_windows_chef_metadata_url if provisioner.windows_os?
|
52
|
-
end
|
53
|
-
|
54
|
-
default_config :chef_omnibus_root do |provisioner|
|
55
|
-
if provisioner.windows_os?
|
56
|
-
"$env:systemdrive\\opscode\\chef"
|
57
|
-
else
|
58
|
-
"/opt/chef"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
54
|
default_config :data_path do |provisioner|
|
63
55
|
provisioner.calculate_path("data")
|
64
56
|
end
|
@@ -94,29 +86,27 @@ module Kitchen
|
|
94
86
|
end
|
95
87
|
expand_path_for :encrypted_data_bag_secret_key_path
|
96
88
|
|
89
|
+
# Reads the local Chef::Config object (if present). We do this because
|
90
|
+
# we want to start bring Chef config and ChefDK tool config closer
|
91
|
+
# together. For example, we want to configure proxy settings in 1
|
92
|
+
# location instead of 3 configuration files.
|
93
|
+
#
|
94
|
+
# @param config [Hash] initial provided configuration
|
95
|
+
def initialize(config = {})
|
96
|
+
super(config)
|
97
|
+
|
98
|
+
ChefConfig::WorkstationConfigLoader.new(config[:config_path]).load
|
99
|
+
# This exports any proxy config present in the Chef config to
|
100
|
+
# appropriate environment variables, which Test Kitchen respects
|
101
|
+
ChefConfig::Config.export_proxies
|
102
|
+
end
|
103
|
+
|
97
104
|
# (see Base#create_sandbox)
|
98
105
|
def create_sandbox
|
99
106
|
super
|
100
107
|
Chef::CommonSandbox.new(config, sandbox_path, instance).populate
|
101
108
|
end
|
102
109
|
|
103
|
-
# @return [String] a metadata URL for the Chef Omnitruck API suitable
|
104
|
-
# for installing a Windows MSI package
|
105
|
-
def default_windows_chef_metadata_url
|
106
|
-
version = config[:require_chef_omnibus]
|
107
|
-
version = "latest" if version == true
|
108
|
-
base = if config[:chef_omnibus_url] =~ %r{/install.sh$}
|
109
|
-
"#{File.dirname(config[:chef_omnibus_url])}/"
|
110
|
-
else
|
111
|
-
"https://www.chef.io/chef/"
|
112
|
-
end
|
113
|
-
|
114
|
-
url = "#{base}#{metadata_project_from_options}"
|
115
|
-
url << "?p=windows&m=x86_64&pv=2008r2" # same pacakge for all versions
|
116
|
-
url << "&v=#{CGI.escape(version.to_s.downcase)}"
|
117
|
-
url
|
118
|
-
end
|
119
|
-
|
120
110
|
# (see Base#init_command)
|
121
111
|
def init_command
|
122
112
|
dirs = %w[
|
@@ -130,7 +120,7 @@ module Kitchen
|
|
130
120
|
init_command_vars_for_bourne(dirs)
|
131
121
|
end
|
132
122
|
|
133
|
-
shell_code_from_file(vars, "chef_base_init_command")
|
123
|
+
prefix_command(shell_code_from_file(vars, "chef_base_init_command"))
|
134
124
|
end
|
135
125
|
|
136
126
|
# (see Base#install_command)
|
@@ -139,17 +129,33 @@ module Kitchen
|
|
139
129
|
|
140
130
|
version = config[:require_chef_omnibus].to_s.downcase
|
141
131
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
132
|
+
# Passing "true" to mixlib-install currently breaks the windows metadata_url
|
133
|
+
# TODO: remove this line once https://github.com/chef/mixlib-install/pull/22
|
134
|
+
# is accepted and released
|
135
|
+
version = "" if version == "true"
|
147
136
|
|
148
|
-
|
137
|
+
installer = Mixlib::Install.new(version, powershell_shell?, install_options)
|
138
|
+
config[:chef_omnibus_root] = installer.root
|
139
|
+
prefix_command(sudo(installer.install_command))
|
149
140
|
end
|
150
141
|
|
151
142
|
private
|
152
143
|
|
144
|
+
# @return [Hash] an option hash for the install commands
|
145
|
+
# @api private
|
146
|
+
def install_options
|
147
|
+
project = /\s*-P (\w+)\s*/.match(config[:chef_omnibus_install_options])
|
148
|
+
{
|
149
|
+
:omnibus_url => config[:chef_omnibus_url],
|
150
|
+
:project => project.nil? ? nil : project[1],
|
151
|
+
:install_flags => config[:chef_omnibus_install_options]
|
152
|
+
}.tap do |opts|
|
153
|
+
opts[:root] = config[:chef_omnibus_root] if config.key? :chef_omnibus_root
|
154
|
+
opts[:http_proxy] = config[:http_proxy] if config.key? :http_proxy
|
155
|
+
opts[:https_proxy] = config[:https_proxy] if config.key? :https_proxy
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
153
159
|
# @return [String] an absolute path to a Berksfile, relative to the
|
154
160
|
# kitchen root
|
155
161
|
# @api private
|
@@ -251,43 +257,6 @@ module Kitchen
|
|
251
257
|
].join("\n")
|
252
258
|
end
|
253
259
|
|
254
|
-
# Generates the install command variables for Bourne shell-based
|
255
|
-
# platforms.
|
256
|
-
#
|
257
|
-
# @param version [String] version string
|
258
|
-
# @return [String] shell variable lines
|
259
|
-
# @api private
|
260
|
-
def install_command_vars_for_bourne(version)
|
261
|
-
install_flags = %w[latest true].include?(version) ? "" : "-v #{CGI.escape(version)}"
|
262
|
-
if config[:chef_omnibus_install_options]
|
263
|
-
install_flags << " " << config[:chef_omnibus_install_options]
|
264
|
-
end
|
265
|
-
|
266
|
-
[
|
267
|
-
shell_var("chef_omnibus_root", config[:chef_omnibus_root]),
|
268
|
-
shell_var("chef_omnibus_url", config[:chef_omnibus_url]),
|
269
|
-
shell_var("install_flags", install_flags.strip),
|
270
|
-
shell_var("pretty_version", pretty_version(version)),
|
271
|
-
shell_var("sudo_sh", sudo("sh")),
|
272
|
-
shell_var("version", version)
|
273
|
-
].join("\n")
|
274
|
-
end
|
275
|
-
|
276
|
-
# Generates the install command variables for PowerShell-based platforms.
|
277
|
-
#
|
278
|
-
# @param version [String] version string
|
279
|
-
# @return [String] shell variable lines
|
280
|
-
# @api private
|
281
|
-
def install_command_vars_for_powershell(version)
|
282
|
-
[
|
283
|
-
shell_var("chef_metadata_url", config[:chef_metadata_url]),
|
284
|
-
shell_var("chef_omnibus_root", config[:chef_omnibus_root]),
|
285
|
-
shell_var("msi", "$env:TEMP\\chef-#{version}.msi"),
|
286
|
-
shell_var("pretty_version", pretty_version(version)),
|
287
|
-
shell_var("version", version)
|
288
|
-
].join("\n")
|
289
|
-
end
|
290
|
-
|
291
260
|
# Load cookbook dependency resolver code, if required.
|
292
261
|
#
|
293
262
|
# (see Base#load_needed_dependencies!)
|
@@ -302,31 +271,6 @@ module Kitchen
|
|
302
271
|
end
|
303
272
|
end
|
304
273
|
|
305
|
-
# @return the correct Chef Omnitruck API metadata endpoint, based on
|
306
|
-
# project type which could live in
|
307
|
-
# `config[:chef_omnibus_install_options]`
|
308
|
-
# @api private
|
309
|
-
def metadata_project_from_options
|
310
|
-
match = /\s*-P (\w+)\s*/.match(config[:chef_omnibus_install_options])
|
311
|
-
|
312
|
-
if match.nil? || match[1].downcase == "chef"
|
313
|
-
"metadata"
|
314
|
-
else
|
315
|
-
"metadata-#{match[1].downcase}"
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
# @return [String] a pretty/helpful representation of a Chef Omnibus
|
320
|
-
# package version
|
321
|
-
# @api private
|
322
|
-
def pretty_version(version)
|
323
|
-
case version
|
324
|
-
when "true" then "install only if missing"
|
325
|
-
when "latest" then "always install latest version"
|
326
|
-
else version
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
274
|
# @return [String] a powershell command to reload the `PATH` environment
|
331
275
|
# variable, only to be used to support old Omnibus Chef packages that
|
332
276
|
# require `PATH` to find the `ruby.exe` binary
|
@@ -46,7 +46,7 @@ module Kitchen
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# (see Base#run_command)
|
49
|
-
def run_command
|
49
|
+
def run_command # rubocop:disable Metrics/AbcSize
|
50
50
|
level = config[:log_level] == :info ? :auto : config[:log_level]
|
51
51
|
|
52
52
|
cmd = sudo(config[:chef_solo_path]).dup.
|
@@ -60,10 +60,12 @@ module Kitchen
|
|
60
60
|
]
|
61
61
|
args << "--logfile #{config[:log_file]}" if config[:log_file]
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
prefix_command(
|
64
|
+
wrap_shell_code(
|
65
|
+
[cmd, *args].join(" ").
|
66
|
+
tap { |str| str.insert(0, reload_ps1_path) if windows_os? }
|
66
67
|
)
|
68
|
+
)
|
67
69
|
end
|
68
70
|
|
69
71
|
private
|
@@ -66,16 +66,18 @@ module Kitchen
|
|
66
66
|
shell_var("gem", sudo(gem_bin))
|
67
67
|
].join("\n").concat("\n")
|
68
68
|
|
69
|
-
shell_code_from_file(vars, "chef_zero_prepare_command_legacy")
|
69
|
+
prefix_command(shell_code_from_file(vars, "chef_zero_prepare_command_legacy"))
|
70
70
|
end
|
71
71
|
|
72
72
|
# (see Base#run_command)
|
73
73
|
def run_command
|
74
74
|
cmd = modern? ? local_mode_command : shim_command
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
prefix_command(
|
77
|
+
wrap_shell_code(
|
78
|
+
[cmd, *chef_client_args].join(" ").
|
79
|
+
tap { |str| str.insert(0, reload_ps1_path) if windows_os? }
|
80
|
+
)
|
79
81
|
)
|
80
82
|
end
|
81
83
|
|
@@ -111,7 +113,7 @@ module Kitchen
|
|
111
113
|
# @return [Array<String>] an array of command line arguments
|
112
114
|
# @api private
|
113
115
|
def chef_client_args
|
114
|
-
level = config[:log_level] == :info ? :
|
116
|
+
level = config[:log_level] == :info ? :warn : config[:log_level]
|
115
117
|
args = [
|
116
118
|
"--config #{remote_path_join(config[:root_path], "client.rb")}",
|
117
119
|
"--log_level #{level}",
|
@@ -87,6 +87,10 @@ module Kitchen
|
|
87
87
|
def execute(command)
|
88
88
|
return if command.nil?
|
89
89
|
logger.debug("[WinRM] #{self} (#{command})")
|
90
|
+
|
91
|
+
if command.length > MAX_COMMAND_SIZE
|
92
|
+
command = run_from_file_command(command)
|
93
|
+
end
|
90
94
|
exit_code, stderr = execute_with_exit_code(command)
|
91
95
|
|
92
96
|
if logger.debug? && exit_code == 0
|
@@ -134,6 +138,11 @@ module Kitchen
|
|
134
138
|
|
135
139
|
PING_COMMAND = "Write-Host '[WinRM] Established\n'".freeze
|
136
140
|
|
141
|
+
# Maximum string to send to the transport to execute. WinRM has an 8000 character
|
142
|
+
# command line limit. The original command string is coverted to a base 64 encoded
|
143
|
+
# UTF-16 string which will double the string size.
|
144
|
+
MAX_COMMAND_SIZE = 3000
|
145
|
+
|
137
146
|
RESCUE_EXCEPTIONS_ON_ESTABLISH = lambda do
|
138
147
|
[
|
139
148
|
Errno::EACCES, Errno::EADDRINUSE, Errno::ECONNREFUSED,
|
@@ -375,11 +384,36 @@ module Kitchen
|
|
375
384
|
def to_s
|
376
385
|
"#{winrm_transport}::#{endpoint}<#{options.inspect}>"
|
377
386
|
end
|
387
|
+
|
388
|
+
# takes a long (greater than 3000 characters) command and saves it to a
|
389
|
+
# file and uploads it to the test instance.
|
390
|
+
#
|
391
|
+
# @param command [String] a long command to be saved and uploaded
|
392
|
+
# @return [String] a command that executes the uploaded script
|
393
|
+
# @api private
|
394
|
+
def run_from_file_command(command)
|
395
|
+
temp_dir = Dir.mktmpdir("kitchen-long-script")
|
396
|
+
begin
|
397
|
+
script_name = "#{instance_name}-long_script.ps1"
|
398
|
+
script_path = File.join(temp_dir, script_name)
|
399
|
+
|
400
|
+
File.open(script_path, "wb") do |file|
|
401
|
+
file.write(command)
|
402
|
+
end
|
403
|
+
|
404
|
+
target_path = File.join("$env:TEMP", "kitchen")
|
405
|
+
upload(script_path, target_path)
|
406
|
+
|
407
|
+
%{& "#{File.join(target_path, script_name)}"}
|
408
|
+
ensure
|
409
|
+
FileUtils.rmtree(temp_dir)
|
410
|
+
end
|
411
|
+
end
|
378
412
|
end
|
379
413
|
|
380
414
|
private
|
381
415
|
|
382
|
-
WINRM_TRANSPORT_SPEC_VERSION = "~> 1.0".freeze
|
416
|
+
WINRM_TRANSPORT_SPEC_VERSION = ["~> 1.0", ">= 1.0.3"].freeze
|
383
417
|
|
384
418
|
# Builds the hash of options needed by the Connection object on
|
385
419
|
# construction.
|
@@ -429,7 +463,7 @@ module Kitchen
|
|
429
463
|
spec_version = WINRM_TRANSPORT_SPEC_VERSION.dup
|
430
464
|
logger.debug("Winrm Transport requested," \
|
431
465
|
" loading WinRM::Transport gem (#{spec_version})")
|
432
|
-
gem "winrm-transport", spec_version
|
466
|
+
gem "winrm-transport", *spec_version
|
433
467
|
first_load = require "winrm/transport/version"
|
434
468
|
load_winrm_transport!
|
435
469
|
|
@@ -33,8 +33,8 @@ module Kitchen
|
|
33
33
|
include Logging
|
34
34
|
|
35
35
|
default_config :http_proxy, nil
|
36
|
-
|
37
36
|
default_config :https_proxy, nil
|
37
|
+
default_config :ftp_proxy, nil
|
38
38
|
|
39
39
|
default_config :root_path do |verifier|
|
40
40
|
verifier.windows_os? ? "$env:TEMP\\verifier" : "/tmp/verifier"
|
@@ -44,10 +44,14 @@ module Kitchen
|
|
44
44
|
verifier.windows_os? ? nil : true
|
45
45
|
end
|
46
46
|
|
47
|
+
default_config :chef_omnibus_root, "/opt/chef"
|
48
|
+
|
47
49
|
default_config :sudo_command do |verifier|
|
48
50
|
verifier.windows_os? ? nil : "sudo -E"
|
49
51
|
end
|
50
52
|
|
53
|
+
default_config :command_prefix, nil
|
54
|
+
|
51
55
|
default_config(:suite_name) { |busser| busser.instance.suite.name }
|
52
56
|
|
53
57
|
# Creates a new Verifier object using the provided configuration data
|
@@ -213,6 +217,19 @@ module Kitchen
|
|
213
217
|
def sudo(script)
|
214
218
|
config[:sudo] ? "#{config[:sudo_command]} #{script}" : script
|
215
219
|
end
|
220
|
+
|
221
|
+
# Conditionally prefixes a command with a command prefix.
|
222
|
+
# This should generally be done after a command has been
|
223
|
+
# conditionally prefixed by #sudo as certain platforms, such as
|
224
|
+
# Cisco Nexus, require all commands to be run with a prefix to
|
225
|
+
# obtain outbound network access.
|
226
|
+
#
|
227
|
+
# @param command [String] command to be prefixed
|
228
|
+
# @return [String] the command, conditionally prefixed with the configured prefix
|
229
|
+
# @api private
|
230
|
+
def prefix_command(script)
|
231
|
+
config[:command_prefix] ? "#{config[:command_prefix]} #{script}" : script
|
232
|
+
end
|
216
233
|
end
|
217
234
|
end
|
218
235
|
end
|
@@ -46,7 +46,7 @@ module Kitchen
|
|
46
46
|
if verifier.windows_os?
|
47
47
|
"$env:systemdrive\\opscode\\chef\\embedded\\bin"
|
48
48
|
else
|
49
|
-
|
49
|
+
verifier.remote_path_join(%W[#{verifier[:chef_omnibus_root]} embedded bin])
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -76,7 +76,7 @@ module Kitchen
|
|
76
76
|
cmd = sudo(config[:busser_bin]).dup.
|
77
77
|
tap { |str| str.insert(0, "& ") if powershell_shell? }
|
78
78
|
|
79
|
-
wrap_shell_code(Util.outdent!(<<-CMD))
|
79
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
80
80
|
#{busser_env}
|
81
81
|
|
82
82
|
#{cmd} suite cleanup
|
@@ -89,7 +89,7 @@ module Kitchen
|
|
89
89
|
|
90
90
|
vars = install_command_vars
|
91
91
|
|
92
|
-
shell_code_from_file(vars, "busser_install_command")
|
92
|
+
prefix_command(shell_code_from_file(vars, "busser_install_command"))
|
93
93
|
end
|
94
94
|
|
95
95
|
# (see Base#run_command)
|
@@ -99,7 +99,7 @@ module Kitchen
|
|
99
99
|
cmd = sudo(config[:busser_bin]).dup.
|
100
100
|
tap { |str| str.insert(0, "& ") if powershell_shell? }
|
101
101
|
|
102
|
-
wrap_shell_code(Util.outdent!(<<-CMD))
|
102
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
103
103
|
#{busser_env}
|
104
104
|
|
105
105
|
#{cmd} test
|
@@ -173,9 +173,16 @@ module Kitchen
|
|
173
173
|
gem, version = config[:version].split("@")
|
174
174
|
gem, version = "busser", gem if gem =~ /^\d+\.\d+\.\d+/
|
175
175
|
|
176
|
+
root = config[:root_path]
|
177
|
+
gem_bin = remote_path_join(root, "bin")
|
178
|
+
|
179
|
+
# We don't want the gems to be installed in the home directory,
|
180
|
+
# this will force the bindir and the gem install location both
|
181
|
+
# to be under /tmp/verifier
|
176
182
|
args = gem
|
177
183
|
args += " --version #{version}" if version
|
178
|
-
args += " --no-rdoc --no-ri"
|
184
|
+
args += " --no-rdoc --no-ri --no-format-executable -n #{gem_bin}"
|
185
|
+
args += " --no-user-install"
|
179
186
|
args
|
180
187
|
end
|
181
188
|
|