right_agent 0.10.8 → 0.10.9
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.
- data/lib/right_agent/pid_file.rb +1 -1
- data/lib/right_agent/platform/windows.rb +85 -11
- data/right_agent.gemspec +2 -2
- data/spec/platform/windows_volume_manager_spec.rb +65 -0
- metadata +22 -20
data/lib/right_agent/pid_file.rb
CHANGED
@@ -114,7 +114,7 @@ module RightScale
|
|
114
114
|
if exists?
|
115
115
|
open(@pid_file,'r') { |f| content[:pid] = f.read.to_i }
|
116
116
|
open(@cookie_file,'r') do |f|
|
117
|
-
command_options = YAML.load(f.read) rescue {}
|
117
|
+
command_options = (YAML.load(f.read) rescue {}) || {}
|
118
118
|
content.merge!(command_options)
|
119
119
|
end if File.exists?(@cookie_file)
|
120
120
|
end
|
@@ -468,8 +468,6 @@ EOF
|
|
468
468
|
# partition has actually been formatted.
|
469
469
|
raise ArgumentError.new("Invalid index = #{disk_index}") unless disk_index >= 0
|
470
470
|
raise ArgumentError.new("Invalid device = #{device}") unless is_attachable_volume_path?(device)
|
471
|
-
online_command = if @os_info.major < 6; "online noerr"; else; "online disk noerr"; end
|
472
|
-
clear_readonly_command = if @os_info.major < 6; ""; else; "attribute disk clear readonly noerr"; end
|
473
471
|
|
474
472
|
# note that Windows 2003 server version of diskpart doesn't support
|
475
473
|
# format so that has to be done separately.
|
@@ -478,8 +476,8 @@ EOF
|
|
478
476
|
rescan
|
479
477
|
list disk
|
480
478
|
select disk #{disk_index}
|
481
|
-
#{
|
482
|
-
#{
|
479
|
+
#{get_clear_readonly_command('disk')}
|
480
|
+
#{get_online_disk_command}
|
483
481
|
clean
|
484
482
|
create partition primary
|
485
483
|
#{get_assign_command_for_device(device)}
|
@@ -506,6 +504,8 @@ EOF
|
|
506
504
|
#
|
507
505
|
# === Parameters
|
508
506
|
# disk_index(int):: zero-based disk index
|
507
|
+
# options(Hash):: A hash of options which allows different behavior while onlining a drive. Possible options are;
|
508
|
+
# :idempotent(Bool) - Checks the current disk statuses before attempting to online the disk. If the drive is already online, it bails out making this method idempotent.
|
509
509
|
#
|
510
510
|
# === Return
|
511
511
|
# always true
|
@@ -514,22 +514,55 @@ EOF
|
|
514
514
|
# ArgumentError:: on invalid parameters
|
515
515
|
# VolumeError:: on failure to online disk
|
516
516
|
# ParserError:: on failure to parse volume list
|
517
|
-
def online_disk(disk_index)
|
517
|
+
def online_disk(disk_index, options={})
|
518
518
|
raise ArgumentError.new("Invalid disk_index = #{disk_index}") unless disk_index >= 0
|
519
|
-
|
520
|
-
|
519
|
+
# Set some defaults for backward compatibility, allow user specified options to override defaults
|
520
|
+
options = {:idempotent => false}.merge(options)
|
521
521
|
script = <<EOF
|
522
522
|
rescan
|
523
523
|
list disk
|
524
524
|
select disk #{disk_index}
|
525
|
-
#{
|
526
|
-
#{
|
525
|
+
#{get_clear_readonly_command('disk')}
|
526
|
+
#{get_online_disk_command}
|
527
527
|
EOF
|
528
|
+
|
529
|
+
if(options[:idempotent])
|
530
|
+
disk = disks(:index => disk_index)
|
531
|
+
return true if disk && disk[:status] == "Online"
|
532
|
+
end
|
533
|
+
|
528
534
|
exit_code, output_text = run_script(script)
|
529
535
|
raise VolumeError.new("Failed to online disk #{disk_index}: exit code = #{exit_code}\n#{script}\n#{output_text}") if exit_code != 0
|
530
536
|
true
|
531
537
|
end
|
532
538
|
|
539
|
+
# Brings the disk given by index offline
|
540
|
+
#
|
541
|
+
# === Parameters
|
542
|
+
# disk_index(int):: zero-based disk index
|
543
|
+
#
|
544
|
+
# === Return
|
545
|
+
# always true
|
546
|
+
#
|
547
|
+
# === Raise
|
548
|
+
# ArgumentError:: on invalid parameters
|
549
|
+
# VolumeError:: on failure to online disk
|
550
|
+
# ParserError:: on failure to parse volume list
|
551
|
+
def offline_disk(disk_index)
|
552
|
+
raise ArgumentError.new("Invalid disk_index = #{disk_index}") unless disk_index >= 0
|
553
|
+
# Set some defaults for backward compatibility, allow user specified options to override defaults
|
554
|
+
script = <<EOF
|
555
|
+
rescan
|
556
|
+
list disk
|
557
|
+
select disk #{disk_index}
|
558
|
+
offline disk noerr
|
559
|
+
EOF
|
560
|
+
|
561
|
+
exit_code, output_text = run_script(script)
|
562
|
+
raise VolumeError.new("Failed to offline disk #{disk_index}: exit code = #{exit_code}\n#{script}\n#{output_text}") if exit_code != 0
|
563
|
+
true
|
564
|
+
end
|
565
|
+
|
533
566
|
# Assigns the given device name to the volume given by index and clears
|
534
567
|
# the readonly attribute, if necessary. The device must not currently be
|
535
568
|
# in use.
|
@@ -537,6 +570,10 @@ EOF
|
|
537
570
|
# === Parameters
|
538
571
|
# volume_device_or_index(int):: old device or zero-based volume index (from volumes list, etc.) to select for assignment.
|
539
572
|
# device(String):: disk letter or mount path specified for the volume to create
|
573
|
+
# options(Hash):: A hash of options which allows different behavior while assigning a device. Possible options are:
|
574
|
+
# :clear_readonly(Bool) - Set to true by default, since the previous implementation of this method always cleared readonly
|
575
|
+
# :remove_all(Bool) - Removes all previously assigned devices and paths, essentially a big RESET button for volume assignment
|
576
|
+
# :idempotent(Bool) - Checks the current device assignments before assigning the device according to the specified parameters. If the device is already assigned, it bails out making this method idempotent.
|
540
577
|
#
|
541
578
|
# === Return
|
542
579
|
# always true
|
@@ -545,7 +582,10 @@ EOF
|
|
545
582
|
# ArgumentError:: on invalid parameters
|
546
583
|
# VolumeError:: on failure to assign device name
|
547
584
|
# ParserError:: on failure to parse volume list
|
548
|
-
def assign_device(volume_device_or_index, device)
|
585
|
+
def assign_device(volume_device_or_index, device, options={})
|
586
|
+
# Set some defaults for backward compatibility, allow user specified options to override defaults
|
587
|
+
options = {:clear_readonly => true, :idempotent => false}.merge(options)
|
588
|
+
|
549
589
|
if device.match(@assignable_path_regex) && @os_info.major < 6
|
550
590
|
raise ArgumentError.new("Mount path assignment is not supported in this version of windows")
|
551
591
|
end
|
@@ -556,11 +596,26 @@ EOF
|
|
556
596
|
raise ArgumentError.new("Invalid volume_device_or_index = #{volume_device_or_index}") unless volume_selector_match
|
557
597
|
volume_selector = volume_selector_match[1]
|
558
598
|
raise ArgumentError.new("Invalid device = #{device}") unless is_attachable_volume_path?(device)
|
599
|
+
if(options[:idempotent])
|
600
|
+
# Device already assigned?
|
601
|
+
vols = volumes
|
602
|
+
already_assigned = vols.select do |k,v|
|
603
|
+
# The volume is specified by it's index and is already mounted to the specified device/path
|
604
|
+
(k == :index && v == volume_device_or_index && vols[:device] == device) ||
|
605
|
+
# The volume is specified by it's current device/path assignment and is already mounted to the specified device/path
|
606
|
+
(k == :device && v == volume_device_or_index)
|
607
|
+
end
|
608
|
+
|
609
|
+
return true if already_assigned.length > 0
|
610
|
+
end
|
611
|
+
# Validation ends here, and real stuff starts to happen
|
612
|
+
|
559
613
|
script = <<EOF
|
560
614
|
rescan
|
561
615
|
list volume
|
562
616
|
select volume "#{volume_selector}"
|
563
|
-
|
617
|
+
#{get_clear_readonly_command('volume') if options[:clear_readonly]}
|
618
|
+
#{"remove all noerr" if options[:remove_all]}
|
564
619
|
#{get_assign_command_for_device(device)}
|
565
620
|
EOF
|
566
621
|
|
@@ -858,6 +913,25 @@ EOF
|
|
858
913
|
end
|
859
914
|
end
|
860
915
|
|
916
|
+
# Returns the correct 'online disk' diskpart command based on the OS version
|
917
|
+
#
|
918
|
+
# === Return
|
919
|
+
# result(String):: Either "online noerr" or "online disk noerr" depending upon the OS version
|
920
|
+
def get_online_disk_command()
|
921
|
+
if @os_info.major < 6; "online noerr" else; "online disk noerr" end
|
922
|
+
end
|
923
|
+
|
924
|
+
# Returns the correct 'attribute disk clear readonly' diskpart command based on the OS version
|
925
|
+
#
|
926
|
+
# === Parameters
|
927
|
+
# object_type(String):: One of "disk" or "volume" to clear read only for
|
928
|
+
#
|
929
|
+
# === Return
|
930
|
+
# result(String):: Either a blank string or "attribute #{object_type} clear readonly noerr" depending upon the OS version
|
931
|
+
def get_clear_readonly_command(object_type)
|
932
|
+
if @os_info.major < 6; "" else; "attribute #{object_type} clear readonly noerr" end
|
933
|
+
end
|
934
|
+
|
861
935
|
end # VolumeManager
|
862
936
|
|
863
937
|
# Provides utilities for formatting executable shell commands, etc.
|
data/right_agent.gemspec
CHANGED
@@ -24,8 +24,8 @@ require 'rubygems'
|
|
24
24
|
|
25
25
|
Gem::Specification.new do |spec|
|
26
26
|
spec.name = 'right_agent'
|
27
|
-
spec.version = '0.10.
|
28
|
-
spec.date = '2012-
|
27
|
+
spec.version = '0.10.9'
|
28
|
+
spec.date = '2012-06-18'
|
29
29
|
spec.authors = ['Lee Kirchhoff', 'Raphael Simon', 'Tony Spataro']
|
30
30
|
spec.email = 'lee@rightscale.com'
|
31
31
|
spec.homepage = 'https://github.com/rightscale/right_agent'
|
@@ -139,6 +139,7 @@ rescan
|
|
139
139
|
list volume
|
140
140
|
select volume "0"
|
141
141
|
attribute volume clear readonly noerr
|
142
|
+
|
142
143
|
assign letter=S
|
143
144
|
EOF
|
144
145
|
|
@@ -160,6 +161,7 @@ rescan
|
|
160
161
|
list volume
|
161
162
|
select volume "0"
|
162
163
|
attribute volume clear readonly noerr
|
164
|
+
|
163
165
|
assign mount="C:\\Program Files\\RightScale\\Mount\\Softlayer"
|
164
166
|
EOF
|
165
167
|
|
@@ -187,6 +189,51 @@ EOF
|
|
187
189
|
lambda{@platform.volume_manager.assign_device(0, "C:\\Somepath")}.should raise_error(RightScale::Platform::VolumeManager::ArgumentError)
|
188
190
|
@platform.volume_manager.set_osinfo(old_osinfo)
|
189
191
|
end
|
192
|
+
|
193
|
+
it 'does not assign the device if the device is already assigned' do
|
194
|
+
script = <<EOF
|
195
|
+
rescan
|
196
|
+
list volume
|
197
|
+
select volume "0"
|
198
|
+
attribute volume clear readonly noerr
|
199
|
+
|
200
|
+
assign mount="C:\\Program Files\\RightScale\\Mount\\Softlayer"
|
201
|
+
EOF
|
202
|
+
|
203
|
+
flexmock(@platform.volume_manager).should_receive(:run_script).with(script).once.and_return([0, ''])
|
204
|
+
|
205
|
+
@platform.volume_manager.assign_device('0', "C:\\Program Files\\RightScale\\Mount\\Softlayer")
|
206
|
+
flexmock(@platform.volume_manager).should_receive(:volumes).once.and_return({:index => '0', :device => "C:\\Program Files\\RightScale\\Mount\\Softlayer"})
|
207
|
+
@platform.volume_manager.assign_device('0', "C:\\Program Files\\RightScale\\Mount\\Softlayer", :idempotent => true)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'does not clear readonly flag if :clear_readonly option is set to false' do
|
211
|
+
script = <<EOF
|
212
|
+
rescan
|
213
|
+
list volume
|
214
|
+
select volume "0"
|
215
|
+
|
216
|
+
|
217
|
+
assign mount="C:\\Program Files\\RightScale\\Mount\\Softlayer"
|
218
|
+
EOF
|
219
|
+
|
220
|
+
flexmock(@platform.volume_manager).should_receive(:run_script).with(script).once.and_return([0, ''])
|
221
|
+
@platform.volume_manager.assign_device('0', "C:\\Program Files\\RightScale\\Mount\\Softlayer", {:clear_readonly => false})
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'removes all previous assignments if :remove_all option is set to true' do
|
225
|
+
script = <<EOF
|
226
|
+
rescan
|
227
|
+
list volume
|
228
|
+
select volume "0"
|
229
|
+
attribute volume clear readonly noerr
|
230
|
+
remove all noerr
|
231
|
+
assign mount="C:\\Program Files\\RightScale\\Mount\\Softlayer"
|
232
|
+
EOF
|
233
|
+
|
234
|
+
flexmock(@platform.volume_manager).should_receive(:run_script).with(script).once.and_return([0, ''])
|
235
|
+
@platform.volume_manager.assign_device('0', "C:\\Program Files\\RightScale\\Mount\\Softlayer", :remove_all => true)
|
236
|
+
end
|
190
237
|
end
|
191
238
|
|
192
239
|
context :format_disk do
|
@@ -248,6 +295,24 @@ EOF
|
|
248
295
|
end
|
249
296
|
|
250
297
|
end
|
298
|
+
|
299
|
+
context :online_disk do
|
300
|
+
it 'does not online the disk if the disk is already online' do
|
301
|
+
script = <<EOF
|
302
|
+
rescan
|
303
|
+
list disk
|
304
|
+
select disk 0
|
305
|
+
attribute disk clear readonly noerr
|
306
|
+
online disk noerr
|
307
|
+
EOF
|
308
|
+
|
309
|
+
flexmock(@platform.volume_manager).should_receive(:run_script).with(script).once.and_return([0, ''])
|
310
|
+
|
311
|
+
@platform.volume_manager.online_disk(0)
|
312
|
+
flexmock(@platform.volume_manager).should_receive(:disks).once.and_return({:index => 0, :status => "Online"})
|
313
|
+
@platform.volume_manager.online_disk(0, :idempotent => true)
|
314
|
+
end
|
315
|
+
end
|
251
316
|
end
|
252
317
|
end
|
253
318
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 37
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 10
|
9
|
-
-
|
10
|
-
version: 0.10.
|
9
|
+
- 9
|
10
|
+
version: 0.10.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Lee Kirchhoff
|
@@ -17,10 +17,10 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2012-
|
20
|
+
date: 2012-06-18 00:00:00 -07:00
|
21
|
+
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
23
|
-
name: right_support
|
24
24
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
@@ -31,11 +31,11 @@ dependencies:
|
|
31
31
|
- 1
|
32
32
|
- 3
|
33
33
|
version: "1.3"
|
34
|
-
type: :runtime
|
35
34
|
requirement: *id001
|
35
|
+
name: right_support
|
36
36
|
prerelease: false
|
37
|
+
type: :runtime
|
37
38
|
- !ruby/object:Gem::Dependency
|
38
|
-
name: right_amqp
|
39
39
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
@@ -46,11 +46,11 @@ dependencies:
|
|
46
46
|
- 0
|
47
47
|
- 3
|
48
48
|
version: "0.3"
|
49
|
-
type: :runtime
|
50
49
|
requirement: *id002
|
50
|
+
name: right_amqp
|
51
51
|
prerelease: false
|
52
|
+
type: :runtime
|
52
53
|
- !ruby/object:Gem::Dependency
|
53
|
-
name: json
|
54
54
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
55
|
none: false
|
56
56
|
requirements:
|
@@ -61,11 +61,11 @@ dependencies:
|
|
61
61
|
- 1
|
62
62
|
- 4
|
63
63
|
version: "1.4"
|
64
|
-
type: :runtime
|
65
64
|
requirement: *id003
|
65
|
+
name: json
|
66
66
|
prerelease: false
|
67
|
+
type: :runtime
|
67
68
|
- !ruby/object:Gem::Dependency
|
68
|
-
name: eventmachine
|
69
69
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
71
71
|
requirements:
|
@@ -77,11 +77,11 @@ dependencies:
|
|
77
77
|
- 12
|
78
78
|
- 10
|
79
79
|
version: 0.12.10
|
80
|
-
type: :runtime
|
81
80
|
requirement: *id004
|
81
|
+
name: eventmachine
|
82
82
|
prerelease: false
|
83
|
+
type: :runtime
|
83
84
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: right_popen
|
85
85
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
@@ -93,11 +93,11 @@ dependencies:
|
|
93
93
|
- 0
|
94
94
|
- 11
|
95
95
|
version: 1.0.11
|
96
|
-
type: :runtime
|
97
96
|
requirement: *id005
|
97
|
+
name: right_popen
|
98
98
|
prerelease: false
|
99
|
+
type: :runtime
|
99
100
|
- !ruby/object:Gem::Dependency
|
100
|
-
name: msgpack
|
101
101
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
102
102
|
none: false
|
103
103
|
requirements:
|
@@ -109,11 +109,11 @@ dependencies:
|
|
109
109
|
- 4
|
110
110
|
- 4
|
111
111
|
version: 0.4.4
|
112
|
-
type: :runtime
|
113
112
|
requirement: *id006
|
113
|
+
name: msgpack
|
114
114
|
prerelease: false
|
115
|
+
type: :runtime
|
115
116
|
- !ruby/object:Gem::Dependency
|
116
|
-
name: net-ssh
|
117
117
|
version_requirements: &id007 !ruby/object:Gem::Requirement
|
118
118
|
none: false
|
119
119
|
requirements:
|
@@ -124,9 +124,10 @@ dependencies:
|
|
124
124
|
- 2
|
125
125
|
- 0
|
126
126
|
version: "2.0"
|
127
|
-
type: :runtime
|
128
127
|
requirement: *id007
|
128
|
+
name: net-ssh
|
129
129
|
prerelease: false
|
130
|
+
type: :runtime
|
130
131
|
description: |
|
131
132
|
RightAgent provides a foundation for running an agent on a server to interface
|
132
133
|
in a secure fashion with other agents in the RightScale system. A RightAgent
|
@@ -290,6 +291,7 @@ files:
|
|
290
291
|
- spec/spec.win32.opts
|
291
292
|
- spec/spec_helper.rb
|
292
293
|
- spec/tracer_spec.rb
|
294
|
+
has_rdoc: true
|
293
295
|
homepage: https://github.com/rightscale/right_agent
|
294
296
|
licenses: []
|
295
297
|
|
@@ -324,7 +326,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
324
326
|
requirements: []
|
325
327
|
|
326
328
|
rubyforge_project:
|
327
|
-
rubygems_version: 1.
|
329
|
+
rubygems_version: 1.3.7
|
328
330
|
signing_key:
|
329
331
|
specification_version: 3
|
330
332
|
summary: Agent for interfacing server with RightScale system
|