rspec-system 2.5.1 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +24 -0
- data/README.md +66 -71
- data/lib/rspec-system.rb +0 -1
- data/lib/rspec-system/helper.rb +2 -5
- data/lib/rspec-system/helpers.rb +1 -1
- data/lib/rspec-system/helpers/rcp.rb +2 -5
- data/lib/rspec-system/helpers/shell.rb +1 -1
- data/lib/rspec-system/node.rb +1 -3
- data/lib/rspec-system/node_set.rb +12 -4
- data/lib/rspec-system/node_set/base.rb +132 -7
- data/lib/rspec-system/node_set/{vagrant.rb → vagrant_base.rb} +63 -82
- data/lib/rspec-system/node_set/vagrant_virtualbox.rb +41 -0
- data/lib/rspec-system/node_set/vagrant_vmware_fusion.rb +43 -0
- data/lib/rspec-system/node_set/vsphere.rb +35 -95
- data/lib/rspec-system/spec_helper.rb +50 -11
- data/resources/prefabs.yml +26 -116
- data/rspec-system.gemspec +4 -4
- data/spec/spec_helper_system.rb +0 -1
- data/spec/system/base_spec.rb +8 -2
- metadata +16 -31
- data/lib/rspec-system/internal_helpers.rb +0 -101
@@ -5,13 +5,22 @@ require 'net/scp'
|
|
5
5
|
require 'rspec-system/node_set/base'
|
6
6
|
|
7
7
|
module RSpecSystem
|
8
|
-
#
|
9
|
-
class NodeSet::
|
8
|
+
# An abstract NodeSet implementation for Vagrant.
|
9
|
+
class NodeSet::VagrantBase < RSpecSystem::NodeSet::Base
|
10
10
|
include RSpecSystem::Log
|
11
11
|
include RSpecSystem::Util
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
# @!group Abstract Methods
|
14
|
+
|
15
|
+
# The vagrant specific provider name
|
16
|
+
#
|
17
|
+
# @return [String] name of the provider as used by `vagrant --provider`
|
18
|
+
# @abstract override to return the name of the vagrant provider
|
19
|
+
def vagrant_provider_name
|
20
|
+
raise RuntimeError, "Unimplemented method #vagrant_provider_name"
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!group Common Methods
|
15
24
|
|
16
25
|
# Creates a new instance of RSpecSystem::NodeSet::Vagrant
|
17
26
|
#
|
@@ -21,30 +30,49 @@ module RSpecSystem
|
|
21
30
|
# @param options [Hash] options Hash
|
22
31
|
def initialize(setname, config, custom_prefabs_path, options)
|
23
32
|
super
|
24
|
-
@vagrant_path = File.expand_path(File.join(RSpec.configuration.
|
33
|
+
@vagrant_path = File.expand_path(File.join(RSpec.configuration.rs_tmp, 'vagrant_projects', setname))
|
25
34
|
|
26
|
-
RSpec.configuration.
|
35
|
+
RSpec.configuration.rs_storage[:nodes] ||= {}
|
27
36
|
end
|
28
37
|
|
29
|
-
#
|
38
|
+
# Launch the nodes
|
30
39
|
#
|
31
40
|
# @return [void]
|
32
|
-
def
|
41
|
+
def launch
|
33
42
|
create_vagrantfile()
|
34
43
|
|
35
44
|
teardown()
|
36
45
|
|
37
|
-
|
38
|
-
|
46
|
+
nodes.each do |k,v|
|
47
|
+
RSpec.configuration.rs_storage[:nodes][k] ||= {}
|
48
|
+
output << bold(color("localhost$", :green)) << " vagrant up #{k}\n"
|
49
|
+
vagrant("up #{k} --provider=#{vagrant_provider_name}")
|
50
|
+
end
|
51
|
+
|
52
|
+
nil
|
53
|
+
end
|
39
54
|
|
40
|
-
|
55
|
+
# Connect to the nodes
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
def connect
|
41
59
|
nodes.each do |k,v|
|
42
|
-
|
43
|
-
|
60
|
+
RSpec.configuration.rs_storage[:nodes][k] ||= {}
|
61
|
+
|
62
|
+
chan = ssh_connect(:host => k, :user => 'vagrant', :net_ssh_options => {
|
63
|
+
:config => ssh_config
|
64
|
+
})
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
|
66
|
+
# Copy the authorized keys from vagrant user to root then reconnect
|
67
|
+
cmd = 'mkdir /root/.ssh ; cp /home/vagrant/.ssh/authorized_keys /root/.ssh'
|
68
|
+
|
69
|
+
output << bold(color("#{k}$ ", :green)) << cmd << "\n"
|
70
|
+
ssh_exec!(chan, "cd /tmp && sudo sh -c #{shellescape(cmd)}")
|
71
|
+
|
72
|
+
chan = ssh_connect(:host => k, :user => 'root', :net_ssh_options => {
|
73
|
+
:config => ssh_config
|
74
|
+
})
|
75
|
+
RSpec.configuration.rs_storage[:nodes][k][:ssh] = chan
|
48
76
|
end
|
49
77
|
|
50
78
|
nil
|
@@ -55,7 +83,7 @@ module RSpecSystem
|
|
55
83
|
# @return [void]
|
56
84
|
def teardown
|
57
85
|
nodes.each do |k,v|
|
58
|
-
storage = RSpec.configuration.
|
86
|
+
storage = RSpec.configuration.rs_storage[:nodes][k]
|
59
87
|
|
60
88
|
next if storage.nil?
|
61
89
|
|
@@ -67,49 +95,8 @@ module RSpecSystem
|
|
67
95
|
output << bold(color("localhost$", :green)) << " vagrant destroy --force\n"
|
68
96
|
vagrant("destroy --force")
|
69
97
|
end
|
70
|
-
nil
|
71
|
-
end
|
72
98
|
|
73
|
-
|
74
|
-
#
|
75
|
-
# @param opts [Hash] options
|
76
|
-
# @return [Hash] a hash containing :exit_code, :stdout and :stderr
|
77
|
-
def run(opts)
|
78
|
-
dest = opts[:n].name
|
79
|
-
cmd = opts[:c]
|
80
|
-
|
81
|
-
ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
|
82
|
-
ssh_exec!(ssh, "cd /tmp && sudo sh -c #{shellescape(cmd)}")
|
83
|
-
end
|
84
|
-
|
85
|
-
# Transfer files to a host in the NodeSet.
|
86
|
-
#
|
87
|
-
# @param opts [Hash] options
|
88
|
-
# @return [Boolean] returns true if command succeeded, false otherwise
|
89
|
-
# @todo This is damn ugly, because we ssh in as vagrant, we copy to a temp
|
90
|
-
# path then move it later. Its slow and brittle and we need a better
|
91
|
-
# solution. Its also very Linux-centrix in its use of temp dirs.
|
92
|
-
def rcp(opts)
|
93
|
-
dest = opts[:d].name
|
94
|
-
source = opts[:sp]
|
95
|
-
dest_path = opts[:dp]
|
96
|
-
|
97
|
-
# Grab a remote path for temp transfer
|
98
|
-
tmpdest = tmppath
|
99
|
-
|
100
|
-
# Do the copy and print out results for debugging
|
101
|
-
cmd = "scp -r '#{source}' #{dest}:#{tmpdest}"
|
102
|
-
output << bold(color("localhost$", :green)) << " #{cmd}\n"
|
103
|
-
ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
|
104
|
-
ssh.scp.upload! source.to_s, tmpdest.to_s, :recursive => true
|
105
|
-
|
106
|
-
# Now we move the file into their final destination
|
107
|
-
result = shell(:n => opts[:d], :c => "mv #{tmpdest} #{dest_path}")
|
108
|
-
if result[:exit_code] == 0
|
109
|
-
return true
|
110
|
-
else
|
111
|
-
return false
|
112
|
-
end
|
99
|
+
nil
|
113
100
|
end
|
114
101
|
|
115
102
|
# Create the Vagrantfile for the NodeSet.
|
@@ -121,7 +108,7 @@ module RSpecSystem
|
|
121
108
|
File.open(File.expand_path(File.join(@vagrant_path, "Vagrantfile")), 'w') do |f|
|
122
109
|
f.write('Vagrant.configure("2") do |c|' + "\n")
|
123
110
|
nodes.each do |k,v|
|
124
|
-
ps = v.provider_specifics[
|
111
|
+
ps = v.provider_specifics[provider_type]
|
125
112
|
default_options = { 'mac' => randmac }
|
126
113
|
options = default_options.merge(v.options || {})
|
127
114
|
|
@@ -130,8 +117,8 @@ module RSpecSystem
|
|
130
117
|
node_config << " v.vm.box = '#{ps['box']}'\n"
|
131
118
|
node_config << " v.vm.box_url = '#{ps['box_url']}'\n" unless ps['box_url'].nil?
|
132
119
|
node_config << customize_vm(k,options)
|
133
|
-
node_config << " v.vm.provider '
|
134
|
-
node_config <<
|
120
|
+
node_config << " v.vm.provider '#{vagrant_provider_name}' do |prov, override|\n"
|
121
|
+
node_config << customize_provider(k,options)
|
135
122
|
node_config << " end\n"
|
136
123
|
node_config << " end\n"
|
137
124
|
|
@@ -142,26 +129,15 @@ module RSpecSystem
|
|
142
129
|
nil
|
143
130
|
end
|
144
131
|
|
145
|
-
#
|
146
|
-
#
|
132
|
+
# Add provider specific customization to the Vagrantfile
|
133
|
+
#
|
147
134
|
# @api private
|
148
135
|
# @param name [String] name of the node
|
149
136
|
# @param options [Hash] customization options
|
150
|
-
# @return [String] a series of
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
next if VALID_VM_OPTIONS.include?(key)
|
155
|
-
case key
|
156
|
-
when 'cpus','memory'
|
157
|
-
custom_config << " vbox.customize ['modifyvm', :id, '--#{key}','#{value}']\n"
|
158
|
-
when 'mac'
|
159
|
-
custom_config << " vbox.customize ['modifyvm', :id, '--macaddress1','#{value}']\n"
|
160
|
-
else
|
161
|
-
log.warn("Skipped invalid custom option for node #{name}: #{key}=#{value}")
|
162
|
-
end
|
163
|
-
end
|
164
|
-
custom_config
|
137
|
+
# @return [String] a series of prov.customize lines
|
138
|
+
# @abstract Overridet ot provide your own customizations
|
139
|
+
def customize_provider(name,options)
|
140
|
+
''
|
165
141
|
end
|
166
142
|
|
167
143
|
# Adds VM customization to the Vagrantfile
|
@@ -207,9 +183,6 @@ module RSpecSystem
|
|
207
183
|
#
|
208
184
|
# @api private
|
209
185
|
# @param args [String] args to vagrant
|
210
|
-
# @todo This seems a little too specific these days, might want to
|
211
|
-
# generalize. It doesn't use systemu, because we want to see the output
|
212
|
-
# immediately, but still - maybe we can make systemu do that.
|
213
186
|
def vagrant(args)
|
214
187
|
Dir.chdir(@vagrant_path) do
|
215
188
|
system("vagrant #{args}")
|
@@ -217,5 +190,13 @@ module RSpecSystem
|
|
217
190
|
nil
|
218
191
|
end
|
219
192
|
|
193
|
+
# Returns a list of options that apply to all types of vagrant providers
|
194
|
+
#
|
195
|
+
# @return [Array<String>] Array of options
|
196
|
+
# @api private
|
197
|
+
def global_vagrant_options
|
198
|
+
['ip']
|
199
|
+
end
|
200
|
+
|
220
201
|
end
|
221
202
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'systemu'
|
3
|
+
require 'net/ssh'
|
4
|
+
require 'net/scp'
|
5
|
+
require 'rspec-system/node_set/vagrant_base'
|
6
|
+
|
7
|
+
module RSpecSystem
|
8
|
+
# A NodeSet implementation for Vagrant.
|
9
|
+
class NodeSet::VagrantVirtualbox < NodeSet::VagrantBase
|
10
|
+
PROVIDER_TYPE = 'vagrant_virtualbox'
|
11
|
+
|
12
|
+
# Name of provider
|
13
|
+
#
|
14
|
+
# @return [String] name of the provider as used by `vagrant --provider`
|
15
|
+
def vagrant_provider_name
|
16
|
+
'virtualbox'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds virtualbox customization to the Vagrantfile
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @param name [String] name of the node
|
23
|
+
# @param options [Hash] customization options
|
24
|
+
# @return [String] a series of vbox.customize lines
|
25
|
+
def customize_provider(name,options)
|
26
|
+
custom_config = ""
|
27
|
+
options.each_pair do |key,value|
|
28
|
+
next if global_vagrant_options.include?(key)
|
29
|
+
case key
|
30
|
+
when 'cpus','memory'
|
31
|
+
custom_config << " prov.customize ['modifyvm', :id, '--#{key}','#{value}']\n"
|
32
|
+
when 'mac'
|
33
|
+
custom_config << " prov.customize ['modifyvm', :id, '--macaddress1','#{value}']\n"
|
34
|
+
else
|
35
|
+
log.warn("Skipped invalid custom option for node #{name}: #{key}=#{value}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
custom_config
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'systemu'
|
3
|
+
require 'net/ssh'
|
4
|
+
require 'net/scp'
|
5
|
+
require 'rspec-system/node_set/vagrant_base'
|
6
|
+
|
7
|
+
module RSpecSystem
|
8
|
+
# A NodeSet implementation for Vagrant using the vmware_fusion provider
|
9
|
+
class NodeSet::VagrantVmwareFusion < NodeSet::VagrantBase
|
10
|
+
PROVIDER_TYPE = 'vagrant_vmware_fusion'
|
11
|
+
|
12
|
+
# Name of provider
|
13
|
+
#
|
14
|
+
# @return [String] name of the provider as used by `vagrant --provider`
|
15
|
+
def vagrant_provider_name
|
16
|
+
'vmware_fusion'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds virtualbox customization to the Vagrantfile
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @param name [String] name of the node
|
23
|
+
# @param options [Hash] customization options
|
24
|
+
# @return [String] a series of vbox.customize lines
|
25
|
+
def customize_provider(name,options)
|
26
|
+
custom_config = ""
|
27
|
+
options.each_pair do |key,value|
|
28
|
+
next if global_vagrant_options.include?(key)
|
29
|
+
case key
|
30
|
+
when 'cpus'
|
31
|
+
custom_config << " prov.vmx['numvcpus'] = '#{value}'\n"
|
32
|
+
when 'memory'
|
33
|
+
custom_config << " prov.vmx['memsize'] = '#{value}'\n"
|
34
|
+
when 'mac'
|
35
|
+
custom_config << " prov.vmx['ethernet0.generatedAddress'] = '#{value}'\n"
|
36
|
+
else
|
37
|
+
log.warn("Skipped invalid custom option for node #{name}: #{key}=#{value}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
custom_config
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -10,7 +10,7 @@ module RSpecSystem
|
|
10
10
|
class NodeSet::Vsphere < RSpecSystem::NodeSet::Base
|
11
11
|
include RSpecSystem::Log
|
12
12
|
|
13
|
-
|
13
|
+
PROVIDER_TYPE = 'vsphere'
|
14
14
|
|
15
15
|
attr_reader :vmconf
|
16
16
|
|
@@ -26,8 +26,7 @@ module RSpecSystem
|
|
26
26
|
# Valid supported ENV variables
|
27
27
|
options = [:host, :user, :pass, :dest_dir, :template_dir, :rpool,
|
28
28
|
:cluster, :ssh_keys, :datacenter, :node_timeout, :node_tries,
|
29
|
-
:node_sleep, :
|
30
|
-
:connect_tries]
|
29
|
+
:node_sleep, :connect_timeout, :connect_tries]
|
31
30
|
|
32
31
|
# Devise defaults, use fog configuration from file system if it exists
|
33
32
|
defaults = load_fog_config()
|
@@ -35,9 +34,6 @@ module RSpecSystem
|
|
35
34
|
:node_timeout => 1200,
|
36
35
|
:node_tries => 10,
|
37
36
|
:node_sleep => 30 + rand(60),
|
38
|
-
:ssh_timeout => 60,
|
39
|
-
:ssh_tries => 10,
|
40
|
-
:ssh_sleep => 4,
|
41
37
|
:connect_timeout => 60,
|
42
38
|
:connect_tries => 10,
|
43
39
|
})
|
@@ -45,8 +41,8 @@ module RSpecSystem
|
|
45
41
|
# Traverse the ENV variables and load them into our config automatically
|
46
42
|
@vmconf = defaults
|
47
43
|
ENV.each do |k,v|
|
48
|
-
next unless k =~/^
|
49
|
-
var = k.sub(/^
|
44
|
+
next unless k =~/^RS(PEC)?_VSPHERE_/
|
45
|
+
var = k.sub(/^RS(PEC)?_VSPHERE_/, '').downcase.to_sym
|
50
46
|
unless options.include?(var)
|
51
47
|
log.info("Ignoring unknown environment variable #{k}")
|
52
48
|
next
|
@@ -55,7 +51,7 @@ module RSpecSystem
|
|
55
51
|
end
|
56
52
|
|
57
53
|
# Initialize node storage if not already
|
58
|
-
RSpec.configuration.
|
54
|
+
RSpec.configuration.rs_storage[:nodes] ||= {}
|
59
55
|
end
|
60
56
|
|
61
57
|
# Retrieves fog configuration if it exists
|
@@ -82,7 +78,7 @@ module RSpecSystem
|
|
82
78
|
# The connection handling automatically retries upon failure.
|
83
79
|
#
|
84
80
|
# @api private
|
85
|
-
def
|
81
|
+
def with_vsphere_connection(&block)
|
86
82
|
vim = nil
|
87
83
|
dc = nil
|
88
84
|
|
@@ -122,11 +118,11 @@ module RSpecSystem
|
|
122
118
|
|
123
119
|
# @!group NodeSet Methods
|
124
120
|
|
125
|
-
#
|
121
|
+
# Launch the nodes
|
126
122
|
#
|
127
123
|
# @return [void]
|
128
|
-
def
|
129
|
-
|
124
|
+
def launch
|
125
|
+
with_vsphere_connection do |dc|
|
130
126
|
# Traverse folders to find target folder for new vm's and template
|
131
127
|
# folders. Automatically create the destination folder if it doesn't
|
132
128
|
# exist.
|
@@ -148,10 +144,7 @@ module RSpecSystem
|
|
148
144
|
|
149
145
|
log.info "Launching VSphere instances one by one"
|
150
146
|
nodes.each do |k,v|
|
151
|
-
|
152
|
-
# Node launching step
|
153
|
-
#####################
|
154
|
-
RSpec.configuration.rspec_storage[:nodes][k] ||= {}
|
147
|
+
RSpec.configuration.rs_storage[:nodes][k] ||= {}
|
155
148
|
|
156
149
|
# Obtain the template name to use
|
157
150
|
ps = v.provider_specifics['vsphere']
|
@@ -165,7 +158,7 @@ module RSpecSystem
|
|
165
158
|
|
166
159
|
# Create a random name for the new VM
|
167
160
|
vm_name = "rspec-system-#{k}-#{random_string(10)}"
|
168
|
-
RSpec.configuration.
|
161
|
+
RSpec.configuration.rs_storage[:nodes][k][:vm] = vm_name
|
169
162
|
|
170
163
|
log.info "Launching VSphere instance #{k} with template #{vmconf[:template_dir]}/#{template} as #{vmconf[:dest_dir]}/#{vm_name}"
|
171
164
|
|
@@ -201,7 +194,7 @@ module RSpecSystem
|
|
201
194
|
time3 = Time.now
|
202
195
|
log.info "#{k}> Time in seconds waiting for IP: #{time3 - time2}"
|
203
196
|
end
|
204
|
-
RSpec.configuration.
|
197
|
+
RSpec.configuration.rs_storage[:nodes][k][:ipaddress] = ipaddress
|
205
198
|
rescue Timeout::Error, SystemCallError => e
|
206
199
|
tries += 1
|
207
200
|
log.error("VM launch attempt #{tries} failed with: " + e.message)
|
@@ -227,47 +220,31 @@ module RSpecSystem
|
|
227
220
|
raise e
|
228
221
|
end
|
229
222
|
end
|
223
|
+
|
230
224
|
time2 = Time.now
|
231
225
|
log.info "#{k}> Took #{time2 - start_time} seconds to boot instance"
|
226
|
+
end
|
227
|
+
end
|
232
228
|
|
233
|
-
|
234
|
-
|
235
|
-
#####################
|
236
|
-
tries = 0
|
237
|
-
begin
|
238
|
-
timeout(vmconf[:ssh_timeout]) do
|
239
|
-
output << bold(color("localhost$", :green)) << " ssh #{k}\n"
|
240
|
-
chan = Net::SSH.start(ipaddress, 'root', {
|
241
|
-
:keys => vmconf[:ssh_keys].split(":"),
|
242
|
-
})
|
229
|
+
nil
|
230
|
+
end
|
243
231
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
######################
|
262
|
-
# Do initial box setup
|
263
|
-
######################
|
264
|
-
hosts = <<-EOS
|
265
|
-
127.0.0.1 localhost localhost.localdomain
|
266
|
-
#{ipaddress} #{k}
|
267
|
-
EOS
|
268
|
-
shell(:n => k, :c => "echo '#{hosts}' > /etc/hosts")
|
269
|
-
shell(:n => k, :c => "hostname #{k}")
|
270
|
-
end
|
232
|
+
# Connect to the nodes
|
233
|
+
#
|
234
|
+
# @return [void]
|
235
|
+
def connect
|
236
|
+
nodes.each do |k,v|
|
237
|
+
rs_storage = RSpec.configuration.rs_storage[:nodes][k]
|
238
|
+
raise RuntimeError, "No internal storage for node #{k}" if rs_storage.nil?
|
239
|
+
|
240
|
+
ipaddress = rs_storage[:ipaddress]
|
241
|
+
raise RuntimeError, "No ipaddress provided from launch phase for node #{k}" if ipaddress.nil?
|
242
|
+
|
243
|
+
chan = ssh_connect(:host => k, :user => 'root', :net_ssh_options => {
|
244
|
+
:keys => vmconf[:ssh_keys].split(":"),
|
245
|
+
:host_name => ipaddress,
|
246
|
+
})
|
247
|
+
RSpec.configuration.rs_storage[:nodes][k][:ssh] = chan
|
271
248
|
end
|
272
249
|
|
273
250
|
nil
|
@@ -277,9 +254,9 @@ module RSpecSystem
|
|
277
254
|
#
|
278
255
|
# @return [void]
|
279
256
|
def teardown
|
280
|
-
|
257
|
+
with_vsphere_connection do |dc|
|
281
258
|
nodes.each do |k,v|
|
282
|
-
storage = RSpec.configuration.
|
259
|
+
storage = RSpec.configuration.rs_storage[:nodes][k]
|
283
260
|
|
284
261
|
if storage.nil?
|
285
262
|
log.info "No entry for node #{k}, no teardown necessary"
|
@@ -325,42 +302,5 @@ module RSpecSystem
|
|
325
302
|
nil
|
326
303
|
end
|
327
304
|
|
328
|
-
# Run a command on a host in the NodeSet.
|
329
|
-
#
|
330
|
-
# @param opts [Hash] options
|
331
|
-
# @return [Hash] a hash containing :exit_code, :stdout and :stderr
|
332
|
-
def run(opts)
|
333
|
-
dest = opts[:n].name
|
334
|
-
cmd = opts[:c]
|
335
|
-
|
336
|
-
ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
|
337
|
-
ssh_exec!(ssh, cmd)
|
338
|
-
end
|
339
|
-
|
340
|
-
# Transfer files to a host in the NodeSet.
|
341
|
-
#
|
342
|
-
# @param opts [Hash] options
|
343
|
-
# @return [Boolean] returns true if command succeeded, false otherwise
|
344
|
-
# @todo This is damn ugly, because we ssh in as vagrant, we copy to a temp
|
345
|
-
# path then move it later. Its slow and brittle and we need a better
|
346
|
-
# solution. Its also very Linux-centrix in its use of temp dirs.
|
347
|
-
def rcp(opts)
|
348
|
-
dest = opts[:d].name
|
349
|
-
source = opts[:sp]
|
350
|
-
dest_path = opts[:dp]
|
351
|
-
|
352
|
-
# Do the copy and print out results for debugging
|
353
|
-
ssh = RSpec.configuration.rspec_storage[:nodes][dest][:ssh]
|
354
|
-
|
355
|
-
begin
|
356
|
-
ssh.scp.upload! source.to_s, dest_path.to_s, :recursive => true
|
357
|
-
rescue => e
|
358
|
-
log.error("Error with scp of file #{source} to #{dest}:#{dest_path}")
|
359
|
-
raise e
|
360
|
-
end
|
361
|
-
|
362
|
-
true
|
363
|
-
end
|
364
|
-
|
365
305
|
end
|
366
306
|
end
|