rspec-system 2.5.1 → 2.6.0
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 +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
|