manageiq-smartstate 0.8.1 → 0.9.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +31 -0
  3. data/.rspec +0 -1
  4. data/.whitesource +3 -0
  5. data/Gemfile +1 -1
  6. data/README.md +1 -2
  7. data/lib/MiqVm/MiqRhevmVm.rb +1 -0
  8. data/lib/MiqVm/MiqVm.rb +0 -7
  9. data/lib/blackbox/VmBlackBox.rb +1 -0
  10. data/lib/db/MiqBdb/MiqBdb.rb +1 -0
  11. data/lib/db/MiqBdb/MiqBdbBtree.rb +1 -0
  12. data/lib/db/MiqBdb/MiqBdbHash.rb +1 -0
  13. data/lib/db/MiqBdb/MiqBdbPage.rb +1 -0
  14. data/lib/disk/DiskProbe.rb +2 -1
  15. data/lib/disk/modules/MiqLargeFile.rb +1 -0
  16. data/lib/fs/ntfs/attrib_file_name.rb +1 -0
  17. data/lib/fs/ntfs/attrib_standard_information.rb +1 -0
  18. data/lib/manageiq/smartstate/version.rb +1 -1
  19. data/lib/metadata/MIQExtract/MIQExtract.rb +1 -0
  20. data/lib/metadata/ScanProfile/ScanProfilesBase.rb +1 -0
  21. data/lib/metadata/VmConfig/GetNativeCfg.rb +1 -0
  22. data/lib/metadata/VmConfig/VmConfig.rb +1 -0
  23. data/lib/metadata/VmConfig/ovfConfig.rb +1 -0
  24. data/lib/metadata/VmConfig/vmcConfig.rb +1 -0
  25. data/lib/metadata/VmConfig/xmlConfig.rb +1 -6
  26. data/lib/metadata/linux/LinuxInitProcs.rb +1 -0
  27. data/lib/metadata/linux/LinuxOSInfo.rb +1 -0
  28. data/lib/metadata/linux/LinuxPackages.rb +1 -0
  29. data/lib/metadata/linux/LinuxSystemd.rb +1 -0
  30. data/lib/metadata/linux/LinuxUsers.rb +1 -0
  31. data/lib/metadata/linux/MiqConaryPackages.rb +1 -0
  32. data/lib/metadata/linux/MiqRpmPackages.rb +1 -0
  33. data/lib/metadata/util/md5deep.rb +1 -0
  34. data/lib/metadata/util/win32/Win32Accounts.rb +1 -0
  35. data/lib/metadata/util/win32/Win32EventLog.rb +1 -0
  36. data/lib/metadata/util/win32/Win32Services.rb +1 -0
  37. data/lib/metadata/util/win32/Win32Software.rb +1 -0
  38. data/lib/metadata/util/win32/Win32System.rb +1 -0
  39. data/lib/metadata/util/win32/fleece_hives.rb +1 -0
  40. data/lib/metadata/util/win32/ms-registry.rb +1 -0
  41. data/lib/metadata/util/win32/remote-registry.rb +1 -0
  42. data/manageiq-smartstate.gemspec +4 -5
  43. metadata +7 -32
  44. data/.travis.yml +0 -15
  45. data/lib/MiqVm/miq_scvmm_vm.rb +0 -39
  46. data/lib/Scvmm/miq_hyperv_disk.rb +0 -274
  47. data/lib/Scvmm/miq_scvmm_parse_powershell.rb +0 -75
  48. data/lib/Scvmm/miq_scvmm_vm_ssa_info.rb +0 -135
  49. data/lib/disk/modules/MSCommon.rb +0 -354
  50. data/lib/disk/modules/MSVSDiffDisk.rb +0 -85
  51. data/lib/disk/modules/MSVSDiskProbe.rb +0 -61
  52. data/lib/disk/modules/MSVSDynamicDisk.rb +0 -36
  53. data/lib/disk/modules/MSVSFixedDisk.rb +0 -39
  54. data/lib/disk/modules/VhdxDisk.rb +0 -629
  55. data/lib/disk/modules/VhdxDiskProbe.rb +0 -46
  56. data/lib/metadata/VmConfig/xmlMsHyperVConfig.rb +0 -41
@@ -1,274 +0,0 @@
1
- # encoding: US-ASCII
2
-
3
- require 'util/miq_winrm'
4
- require 'util/miq-exception'
5
- require 'Scvmm/miq_scvmm_parse_powershell'
6
- require 'base64'
7
- require 'securerandom'
8
- require 'memory_buffer'
9
-
10
- require 'rufus/lru'
11
-
12
- class MiqHyperVDisk
13
- MIN_SECTORS_TO_CACHE = 64
14
- DEF_BLOCK_CACHE_SIZE = 1200
15
- DEBUG_CACHE_STATS = false
16
- BREAD_RETRIES = 3
17
- OPEN_ERRORS = %w( Exception\ calling At\ line: ).freeze
18
-
19
- attr_reader :hostname, :virtual_disk, :file_offset, :file_size, :parser, :vm_name, :temp_snapshot_name
20
-
21
- def initialize(hyperv_host, user, pass, port = nil, network = false)
22
- @hostname = hyperv_host
23
- @winrm = MiqWinRM.new
24
- port ||= 5985
25
- @winrm.connect(:port => port, :user => user, :password => pass, :hostname => @hostname)
26
- @parser = MiqScvmmParsePowershell.new
27
- @block_size = 4096
28
- @file_size = 0
29
- @block_cache = LruHash.new(DEF_BLOCK_CACHE_SIZE)
30
- @cache_hits = Hash.new(0)
31
- @cache_misses = Hash.new(0)
32
- @network = network
33
- @total_read_execution_time = @total_copy_from_remote_time = 0
34
- end
35
-
36
- def open(vm_disk)
37
- @virtual_disk = vm_disk
38
- @file_offset = 0
39
-
40
- unless @network
41
- open_script = <<-OPEN_EOL
42
- $file_stream = [System.IO.File]::Open("#{@virtual_disk}", "Open", "Read", "Read")
43
- $file_stream.seek(0, 0)
44
- OPEN_EOL
45
- @winrm.run_powershell_script(open_script)
46
- end
47
-
48
- stat_script = <<-STAT_EOL
49
- (Get-Item "#{@virtual_disk}").length
50
- STAT_EOL
51
- file_size, stderr = @parser.parse_single_powershell_value(run_correct_powershell(stat_script))
52
-
53
- if @network && stderr.include?("RegisterTaskDefinition")
54
- raise MiqException::MiqInvalidCredentialsError, "Unable to obtain virtual disk size for #{vm_disk}. Check Hyper-V Host Domain Credentials."
55
- end
56
- OPEN_ERRORS.each { |error| raise "Unable to obtain virtual disk size for #{vm_disk}" if stderr.include?(error) }
57
- @file_size = file_size.to_i
58
- @end_byte_addr = @file_size - 1
59
- @size_in_blocks, rem = @file_size.divmod(@block_size)
60
- @size_in_blocks += 1 if rem > 0
61
- @lba_end = @size_in_blocks - 1
62
- end
63
-
64
- def size
65
- @file_size
66
- end
67
-
68
- def close
69
- hit_or_miss if DEBUG_CACHE_STATS
70
- @file_offset = 0
71
- unless @network
72
- close_script = <<-CLOSE_EOL
73
- $file_stream.Close()
74
- CLOSE_EOL
75
- run_correct_powershell(close_script)
76
- end
77
- @winrm.close
78
- @winrm = nil
79
- end
80
-
81
- def hit_or_miss
82
- $log.debug "\nmiq_hyperv_disk cache hits:"
83
- @cache_hits.keys.sort.each do |block|
84
- $log.debug "block #{block} - #{@cache_hits[block]}"
85
- end
86
- $log.debug "\nmiq_hyperv_disk cache misses:"
87
- @cache_misses.keys.sort.each do |block|
88
- $log.debug "block #{block} - #{@cache_misses[block]}"
89
- end
90
- $log.debug "Total time spent copying reads from remote system is #{@total_copy_from_remote_time}"
91
- $log.debug "Total time spent transferring and decoding reads on local system is #{@total_read_execution_time - @total_copy_from_remote_time}"
92
- $log.debug "Total time spent processing remote reads is #{@total_read_execution_time}"
93
- end
94
-
95
- def seek(offset, whence = IO::SEEK_SET)
96
- $log.debug "miq_hyperv_disk.seek(#{offset})"
97
- case whence
98
- when IO::SEEK_CUR
99
- @file_offset += offset
100
- when IO::SEEK_END
101
- @file_offset = @end_byte_addr + offset
102
- when IO::SEEK_SET
103
- @file_offset = offset
104
- end
105
- @file_offset
106
- end
107
-
108
- def read(size)
109
- $log.debug "miq_hyperv_disk.read(#{size})"
110
- return nil if @file_offset >= @file_size
111
- size = @file_size - @file_offset if (@file_offset + size) > @file_size
112
-
113
- start_sector, start_offset = @file_offset.divmod(@block_size)
114
- end_sector = (@file_offset + size - 1) / @block_size
115
- number_sectors = end_sector - start_sector + 1
116
-
117
- @file_offset += size
118
- bread_cached(start_sector, number_sectors)[start_offset, size]
119
- end
120
-
121
- def bread_cached(start_sector, number_sectors)
122
- $log.debug "miq_hyperv_disk.bread_cached(#{start_sector}, #{number_sectors})"
123
- @block_cache.keys.each do |block_range|
124
- sector_offset = start_sector - block_range.first
125
- buffer_offset = sector_offset * @block_size
126
- if block_range.include?(start_sector) && block_range.include?(start_sector + number_sectors - 1)
127
- length = number_sectors * @block_size
128
- @cache_hits[start_sector] += 1
129
- return @block_cache[block_range][buffer_offset, length]
130
- elsif block_range.include?(start_sector)
131
- # This range overlaps the start of our requested read, but more data is required at the end of the request
132
- sectors_in_range = block_range.last - start_sector
133
- length = sectors_in_range * @block_size
134
- remaining_blocks = number_sectors - sectors_in_range
135
- @cache_hits[start_sector] += 1
136
- # The "+" operator is required rather than "<<" so as not to modify the @block_cache object.
137
- return @block_cache[block_range][buffer_offset, length] + bread_cached(block_range.last + 1, remaining_blocks)
138
- elsif block_range.include?(start_sector + number_sectors - 1)
139
- # This range overlaps the end of our requested read, but more data is required at the start of the request
140
- sectors_in_range = (start_sector + number_sectors) - block_range.first
141
- length = sectors_in_range * @block_size
142
- remaining_blocks = number_sectors - sectors_in_range
143
- @cache_hits[start_sector] += 1
144
- # The "<<" operator is valid and more efficient here
145
- return bread_cached(start_sector, remaining_blocks) << @block_cache[block_range][0, length]
146
- elsif block_range.first > start_sector && block_range.last < start_sector + number_sectors
147
- # This range overlaps our requested read but more data is required both before and after the range
148
- sectors_in_range = block_range.last - block_range.first + 1
149
- sectors_pre_range = block_range.first - start_sector
150
- sectors_post_range = number_sectors - sectors_in_range - sectors_pre_range
151
- # Note the mixed use of operators below.
152
- # The first "<<" operator is valid and more efficient while the second "+" operator
153
- # is required instead so as not to modify the in-place @block_cache object.
154
- return bread_cached(start_sector, sectors_pre_range) <<
155
- @block_cache[block_range] +
156
- bread_cached(block_range.last + 1, sectors_post_range)
157
- end
158
- end
159
- block_range = entry_range(start_sector, number_sectors)
160
- @block_cache[block_range] = bread(block_range.first, block_range.last - block_range.first + 1)
161
- @cache_misses[start_sector] += 1
162
-
163
- sector_offset = start_sector - block_range.first
164
- buffer_offset = sector_offset * @block_size
165
- length = number_sectors * @block_size
166
-
167
- @block_cache[block_range][buffer_offset, length]
168
- end
169
-
170
- def bread(start_sector, number_sectors)
171
- log_header = "MIQ(#{self.class.name}.#{__method__}:"
172
- $log.debug "#{log_header} (#{start_sector}, #{number_sectors})"
173
- return nil if start_sector > @lba_end
174
- number_sectors = @size_in_blocks - start_sector if (start_sector + number_sectors) > @size_in_blocks
175
- expected_bytes = number_sectors * @block_size
176
- read_script = if @network
177
-
178
- <<-READ_NETWORK_EOL
179
- $file_stream = [System.IO.File]::Open("#{@virtual_disk}", "Open", "Read", "Read")
180
- $bufsize = #{number_sectors * @block_size}
181
- $buffer = New-Object System.Byte[] $bufsize
182
- $encodedbuflen = $bufsize * 4 / 3
183
- if (($encodedbuflen % 4) -ne 0)
184
- {
185
- $encodedbuflen += 4 - ($encodedbuflen % 4)
186
- }
187
- $encodedarray = New-Object Char[] $encodedbuflen
188
- $file_stream.seek(#{start_sector * @block_size}, 0)
189
- $file_stream.read($buffer, 0, #{expected_bytes})
190
- [System.Convert]::ToBase64CharArray($buffer, 0, $bufsize, $encodedarray, 0)
191
- [string]::join("", $encodedarray)
192
- $file_stream.Close()
193
- READ_NETWORK_EOL
194
- else
195
-
196
- <<-READ_EOL
197
- if ($bufsize -ne #{number_sectors * @block_size})
198
- {
199
- $bufsize = #{number_sectors * @block_size}
200
- $buffer = New-Object System.Byte[] $bufsize
201
- $encodedbuflen = $bufsize * 4 / 3
202
- if (($encodedbuflen % 4) -ne 0)
203
- {
204
- $encodedbuflen += 4 - ($encodedbuflen % 4)
205
- }
206
- $encodedarray = New-Object Char[] $encodedbuflen
207
- }
208
- $file_stream.seek(#{start_sector * @block_size}, 0)
209
- $file_stream.read($buffer, 0, #{expected_bytes})
210
- [System.Convert]::ToBase64CharArray($buffer, 0, $bufsize, $encodedarray, 0)
211
- [string]::join("", $encodedarray)
212
- READ_EOL
213
- end
214
-
215
- i = 0
216
- (0...BREAD_RETRIES).each do
217
- t1 = Time.now.getlocal
218
- encoded_data = @parser.output_to_attribute(run_correct_powershell(read_script))
219
- if encoded_data.empty?
220
- $log.debug "#{log_header} no encoded data returned on attempt #{i}"
221
- i += 1
222
- continue
223
- end
224
- t2 = Time.now.getlocal
225
- decoded_data = Base64.decode64(encoded_data)
226
- @total_copy_from_remote_time += t2 - t1
227
- @total_read_execution_time += Time.now.getlocal - t1
228
- decoded_size = decoded_data.size
229
- return decoded_data if expected_bytes == decoded_size
230
- $log.debug "#{log_header} expected #{expected_bytes} bytes - got #{decoded_size} on attempt #{i}"
231
- i += 1
232
- end
233
- raise "#{log_header} expected #{expected_bytes} bytes - got #{decoded_size}"
234
- end
235
-
236
- def snap(vm_name)
237
- @vm_name = vm_name
238
- @temp_snapshot_name = vm_name + SecureRandom.hex
239
- snap_script = <<-SNAP_EOL
240
- Checkpoint-VM -Name #{@vm_name} -SnapshotName #{@temp_snapshot_name}
241
- SNAP_EOL
242
- @vm_name = vm_name
243
- @temp_snapshot_name = vm_name + SecureRandom.hex
244
- @winrm.run_powershell_script(snap_script)
245
- end
246
-
247
- def delete_snap
248
- delete_snap_script = <<-DELETE_SNAP_EOL
249
- Remove-VMSnapShot -VMName #{@vm_name} -Name #{@temp_snapshot_name}
250
- DELETE_SNAP_EOL
251
- @winrm.run_powershell_script(delete_snap_script)
252
- end
253
-
254
- private
255
-
256
- def run_correct_powershell(script)
257
- return @winrm.run_elevated_powershell_script(script) if @network
258
- @winrm.run_powershell_script(script)
259
- end
260
-
261
- def entry_range(start_sector, number_sectors)
262
- # Cache entries are *multiples* of MIN_SECTORS_TO_CACHE * @blocksize in length,
263
- # aligned to MIN_SECTORS_TO_CACHE * @blocksize byte boundaries.
264
- # real_start_block is the aligned cache block based on the start_sector, and
265
- # real_start_sector is the disk sector for that cache block.
266
- real_start_block = start_sector / MIN_SECTORS_TO_CACHE
267
- real_end_block = (start_sector + number_sectors) / MIN_SECTORS_TO_CACHE
268
- number_cache_blocks = real_end_block - real_start_block + 1
269
- sectors_to_read = number_cache_blocks * MIN_SECTORS_TO_CACHE
270
- real_start_sector = real_start_block * MIN_SECTORS_TO_CACHE
271
- end_sector = real_start_sector + sectors_to_read - 1
272
- Range.new(real_start_sector, end_sector)
273
- end
274
- end
@@ -1,75 +0,0 @@
1
- class MiqScvmmParsePowershell
2
- def output_to_attribute(winrm_output)
3
- attribute, stderr = stdout_stderr(winrm_output)
4
- if stderr =~ /Exception/ || stderr =~ /At line:/
5
- raise "Error running PowerShell command.\n #{stderr}"
6
- end
7
- $log.debug "MiqScvmmParsePowershell: STDERR is \"#{stderr}\"" unless stderr.nil? || $log.nil?
8
- attribute.split("\r\n").last
9
- end
10
-
11
- #
12
- # This method handles one or more lines of exactly one attribute.
13
- #
14
- def parse_single_attribute_values(output)
15
- parse_attribute_values(output)
16
- end
17
-
18
- def parse_multiple_attribute_values(output)
19
- parse_attribute_values(output, true)
20
- end
21
-
22
- #
23
- # This method handles one or more lines of one or more attributes.
24
- #
25
- def parse_attribute_values(output, multiple = nil)
26
- stdout, stderr = parse_powershell_value(output)
27
- lines = stdout.split("\r\n")
28
- dashes = nil
29
- attributes = []
30
- attribute_names = []
31
- lines.each do |line|
32
- next if line.nil? || line == ""
33
- if line =~ /^-+/
34
- dashes = true
35
- next
36
- end
37
- if dashes.nil?
38
- attribute_names = line.split(" ")
39
- next
40
- end
41
- line_parts = multiple.nil? ? [line.rstrip] : line.split(" ")
42
- raise "Incorrect number of PowerShell Output Attributes Found" if line_parts.size != attribute_names.size
43
- i = 0
44
- line_hash = {}
45
- attribute_names.each do |attribute|
46
- line_hash[attribute] = line_parts[i]
47
- i += 1
48
- end
49
- attributes << line_hash
50
- end
51
- return attributes, stderr
52
- end
53
-
54
- def parse_single_powershell_value(output)
55
- stdout, stderr = parse_powershell_value(output)
56
- return stdout.split("\r\n").first, stderr
57
- end
58
-
59
- def parse_powershell_value(output)
60
- stdout, stderr = stdout_stderr(output)
61
- $log.debug "MiqScvmmParsePowershell: STDOUT is \"#{stdout}\"" unless stdout.nil? || $log.nil?
62
- $log.debug "MiqScvmmParsePowershell: STDERR is \"#{stderr}\"" unless stderr.nil? || $log.nil?
63
- return stdout, stderr
64
- end
65
-
66
- private
67
-
68
- def stdout_stderr(output)
69
- stdout = ""
70
- stderr = ""
71
- stdout << output.stdout unless output.stdout.nil?
72
- stderr << output.stderr unless output.stderr.nil?
73
- return stdout, stderr
74
- end
75
- end
@@ -1,135 +0,0 @@
1
- # encoding: US-ASCII
2
-
3
- require 'util/miq_winrm'
4
- require 'Scvmm/miq_scvmm_parse_powershell'
5
-
6
- class MiqScvmmVmSSAInfo
7
- attr_reader :vhds, :hostname, :checkpoints, :vhd_type
8
- def initialize(provider, user, pass, port = nil)
9
- @checkpoints = []
10
- @vhds = []
11
- @hostname = nil
12
- @vhd_type = nil
13
- @winrm = MiqWinRM.new
14
- winrmport = port.nil? ? 5985 : port
15
- options = {:port => winrmport, :user => user, :password => pass, :hostname => provider}
16
- @elevated = nil
17
-
18
- @winrm.connect(options)
19
- @parser = MiqScvmmParsePowershell.new
20
- end
21
-
22
- def close
23
- @winrm.close
24
- end
25
-
26
- # Note the following method returns *all* hard disks and some common attributes from the Hyper-V host
27
- def vm_all_harddisks(vm_name, snapshot = nil, check_snapshot = TRUE)
28
- vhds = vm_get_disks(vm_name, snapshot, check_snapshot)
29
- properties = vm_get_properties(vm_name)
30
- raise "Error getting VHD(s) and Attributes for #{vm_name}" if vhds.size != properties.size
31
- raise "No Virtual Hard Disk found for VM #{vm_name}" unless vhds.any?
32
-
33
- i = 0
34
- new_vhds = []
35
- $log.debug "vm_all_harddisks: #{vhds.size} vhds found:\n"
36
- vhds.each do |vhd|
37
- vhd.merge!(properties[i])
38
- new_vhds << vhd
39
- i += 1
40
- end
41
- new_vhds
42
- end
43
-
44
- def vm_get_checkpoint(vm_name, snapshot)
45
- get_checkpoint_script = <<-GETCHECKPOINT_EOL
46
- Get-VMSnapShot -ComputerName localhost -VMName "#{vm_name}" -Name "#{snapshot}"| \
47
- Select-Object -ExpandProperty Name
48
- GETCHECKPOINT_EOL
49
-
50
- checkpoint, stderr = @parser.parse_single_powershell_value(@winrm.run_powershell_script(get_checkpoint_script))
51
- if stderr =~ /Unable to find a snapshot/
52
- return nil
53
- else
54
- raise "Error finding Snapshot for #{vm_name}: #{stderr}" unless stderr.empty?
55
- end
56
- checkpoint
57
- end
58
-
59
- def vm_create_evm_checkpoint(vm_name, snapshot = nil)
60
- snapshot = vm_name + "__EVM_SNAPSHOT" if snapshot.nil?
61
- raise "Checkpoint for VM #{vm_name} Already Exists" unless vm_get_checkpoint(vm_name, snapshot).nil?
62
-
63
- checkpoint_script = <<-CHECKPOINT_EOL
64
- Checkpoint-VM -ComputerName localhost -Name "#{vm_name}" -SnapshotName "#{snapshot}"
65
- CHECKPOINT_EOL
66
-
67
- _stdout, stderr = @parser.parse_single_powershell_value(@winrm.run_powershell_script(checkpoint_script))
68
- unless stderr.empty?
69
- @elevated = true
70
- _stdout, stderr = @parser.parse_single_powershell_value(@winrm.run_elevated_powershell_script(checkpoint_script))
71
- end
72
- raise "Unable to create Snapshot for #{vm_name}: #{stderr}" unless stderr.empty?
73
- snapshot
74
- end
75
-
76
- def vm_remove_evm_checkpoint(vm_name, snapshot = nil)
77
- snapshot = vm_name + "__EVM_SNAPSHOT" if snapshot.nil?
78
- rm_checkpt_script = <<-RM_CHECKPOINT_EOL
79
- Remove-VMSnapshot -ComputerName localhost -VMName "#{vm_name}" -Name "#{snapshot}"
80
- RM_CHECKPOINT_EOL
81
-
82
- if @elevated
83
- _stdout, stderr = @parser.parse_single_powershell_value(@winrm.run_elevated_powershell_script(rm_checkpt_script))
84
- else
85
- _stdout, stderr = @parser.parse_single_powershell_value(@winrm.run_powershell_script(rm_checkpt_script))
86
- end
87
- raise "Unable to remove Snapshot for #{vm_name}: #{stderr}" unless stderr.empty?
88
- end
89
-
90
- def get_drivetype(vhd_path)
91
- return "Network" if vhd_path[0, 2] == '\\\\'
92
- raise "Invalid Drive Letter for Hard Drive #{vhd_path}" unless vhd_path[1, 1] == ":"
93
- drive_letter = vhd_path[0, 1]
94
-
95
- drivetype_script = <<-DRIVETYPE_EOL
96
- ([System.IO.DriveInfo]("#{drive_letter}")).DriveType
97
- DRIVETYPE_EOL
98
- drive_type, stderr = @parser.parse_single_powershell_value(@winrm.run_powershell_script(drivetype_script))
99
- raise "Unable to get drive letter for disk #{vhd_path}: #{stderr}" unless stderr.empty? || drive_type.nil?
100
- drive_type
101
- end
102
-
103
- private
104
-
105
- def vm_get_properties(vm_name)
106
- properties_script = <<-PROPERTIES_EOL
107
- Get-VMHardDiskDrive -VMName "#{vm_name}" | \
108
- Format-Table -Property ControllerType,ControllerNumber,ControllerLocation -Autosize
109
- PROPERTIES_EOL
110
-
111
- properties, stderr = @parser.parse_multiple_attribute_values(@winrm.run_powershell_script(properties_script))
112
- raise "Error getting VHD(s) and Attributes for #{vm_name}: #{stderr}" unless stderr.empty?
113
- properties
114
- end
115
-
116
- def vm_get_disks(vm_name, snapshot, check_snapshot)
117
- if check_snapshot.nil?
118
- vhd_script = <<-VHD_EOL
119
- Get-VMHardDiskDrive -VMName "#{vm_name}" | \
120
- Format-Table -Property Path | out-string -Width 200
121
- VHD_EOL
122
- else
123
- snapshot = vm_name + "__EVM_SNAPSHOT" if snapshot.nil?
124
- raise "Checkpoint #{snapshot} for VM #{vm_name} missing" if vm_get_checkpoint(vm_name, snapshot).nil?
125
- vhd_script = <<-SNAP_EOL
126
- Get-VMSnapShot -VMName "#{vm_name}" -Name "#{snapshot}" | Get-VMHardDiskDrive | \
127
- Format-Table -Property Path | out-string -Width 200
128
- SNAP_EOL
129
- end
130
-
131
- vhds, stderr = @parser.parse_single_attribute_values(@winrm.run_powershell_script(vhd_script))
132
- raise "Unable to obtain VHD Name(s) for #{vm_name}: #{stderr}" unless stderr.empty?
133
- vhds
134
- end
135
- end