manageiq-smartstate 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13e6b5bd4822beefd6217f39e5320bb0a94c56f6
4
- data.tar.gz: a21c41c5a954b611d05856fbba6c77d2191d4cd6
3
+ metadata.gz: 440961abf4d2b73adb7b0f459afa62e1d367eb82
4
+ data.tar.gz: e41b5ed2da90f269b303fcb1a5b56df012f32088
5
5
  SHA512:
6
- metadata.gz: 2a38067166253a50a581ba44f6bd77c1151d4aa2d1977a8610788aa2f28d071663f00420c797cfbf965466b50d273edeb4dc97db7dcb84fbae54142a8d836061
7
- data.tar.gz: e5034f8bc6024e748b9f3a54523815ee3c67efa671312c7f3feb9af2253142c1156768816f87a30ed902c6ee7e61022dd2f4225cbef8be0da89bfcf08b555d01
6
+ metadata.gz: a457a91e0cda2e54b9b352512062999f12fd0a049cb055692e608520820fbe22e3189b91299edefcabf5d95bccc623662ce946fd333e1dc68659b4b5f1340497
7
+ data.tar.gz: 8187dbd78395beab1cb7ba6533cb7cbf36d9abc7391cd4333e8a2956bf31b394f7b87b022d2647dd8e9b2a66c121438247cf9b937115536eb2ee1234e2477acb
@@ -0,0 +1,52 @@
1
+ ---
2
+ exclude_paths:
3
+ - ".git/"
4
+ - "**.xml"
5
+ - "**.yaml"
6
+ - "**.yml"
7
+ - "lib/metadata/linux/test/Packages"
8
+ - "lib/metadata/linux/test/tc_LinuxUtils.rb"
9
+ - "locale/"
10
+ - "spec/"
11
+ - "test/"
12
+ - "tools/"
13
+ - "tmp/"
14
+ engines:
15
+ brakeman:
16
+ # very slow :sad_panda:
17
+ enabled: false
18
+ bundler-audit:
19
+ # requires Gemfile.lock
20
+ enabled: false
21
+ csslint:
22
+ enabled: false
23
+ duplication:
24
+ enabled: true
25
+ config:
26
+ languages:
27
+ ruby:
28
+ mass_threshold: 25
29
+ javascript:
30
+ eslint:
31
+ enabled: false
32
+ channel: "eslint-3"
33
+ fixme:
34
+ # let's enable later
35
+ enabled: false
36
+ markdownlint:
37
+ # let's enable later
38
+ enabled: false
39
+ rubocop:
40
+ enabled: true
41
+ config: '.rubocop_cc.yml'
42
+ prepare:
43
+ fetch:
44
+ - url: "https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml"
45
+ path: ".rubocop_base.yml"
46
+ - url: "https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_cc_base.yml"
47
+ path: ".rubocop_cc_base.yml"
48
+ ratings:
49
+ paths:
50
+ - Gemfile.lock
51
+ - "**.rake"
52
+ - "**.rb"
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  /coverage/
6
6
  /doc/
7
7
  /pkg/
8
+ /.rubocop-*
8
9
  /spec/reports/
9
10
  /tmp/
10
11
 
@@ -0,0 +1,4 @@
1
+ inherit_from:
2
+ - https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml
3
+ # put all local rubocop config into .rubocop_local.yml as it will be loaded by .rubocop_cc.yml as well
4
+ - .rubocop_local.yml
@@ -0,0 +1,5 @@
1
+ inherit_from:
2
+ # this is downloaded by .codeclimate.yml
3
+ - .rubocop_base.yml
4
+ - .rubocop_cc_base.yml
5
+ - .rubocop_local.yml
@@ -0,0 +1,8 @@
1
+ #
2
+ # Overrides
3
+ #
4
+ GlobalVars:
5
+ AllowedVariables:
6
+ # Loggers
7
+ - $log
8
+ - $vim_log
@@ -1,11 +1,14 @@
1
1
  require 'MiqVm/MiqVm'
2
2
  require 'disk/modules/AzureBlobDisk'
3
+ require 'disk/modules/AzureManagedDisk'
3
4
  require 'disk/modules/miq_disk_cache'
4
5
 
5
6
  class MiqAzureVm < MiqVm
6
7
  def initialize(azure_handle, args)
7
- @azure_handle = azure_handle
8
- @uri = nil
8
+ @azure_handle = azure_handle
9
+ @uri = nil
10
+ @snap_name = nil
11
+ @resource_group = args[:resource_group]
9
12
 
10
13
  raise ArgumentError, "MiqAzureVm: missing required arg :name" unless (@name = args[:name])
11
14
 
@@ -13,7 +16,18 @@ class MiqAzureVm < MiqVm
13
16
  @uri = args[:image_uri]
14
17
  elsif args[:resource_group] && args[:name]
15
18
  vm_obj = vm_svc.get(@name, args[:resource_group])
16
- @uri = vm_obj.properties.storage_profile.os_disk.vhd.uri
19
+ os_disk = vm_obj.properties.storage_profile.os_disk
20
+ if vm_obj.managed_disk?
21
+ #
22
+ # Use the EVM SNAPSHOT Added by the Provider
23
+ #
24
+ @snap_name = os_disk.name + "__EVM__SSA__SNAPSHOT"
25
+ else
26
+ #
27
+ # Non-Managed Disk Snapshot handling will be added here by a separate PR.
28
+ #
29
+ @uri = os_disk.vhd.uri
30
+ end
17
31
  else
18
32
  raise ArgumentError, "MiqAzureVm: missing required args: :image_uri or :resource_group"
19
33
  end
@@ -24,13 +38,14 @@ class MiqAzureVm < MiqVm
24
38
  def getCfg
25
39
  cfg_hash = {}
26
40
  cfg_hash['displayname'] = @name
41
+ file_name = @uri ? @uri : @snap_name
27
42
 
28
- $log.debug "MiqAzureVm#getCfg: disk = #{@uri}"
43
+ $log.debug("MiqAzureVm#getCfg: disk = #{file_name}")
29
44
 
30
45
  tag = "scsi0:0"
31
46
  cfg_hash["#{tag}.present"] = "true"
32
47
  cfg_hash["#{tag}.devicetype"] = "disk"
33
- cfg_hash["#{tag}.filename"] = @uri
48
+ cfg_hash["#{tag}.filename"] = file_name
34
49
 
35
50
  cfg_hash
36
51
  end
@@ -38,30 +53,23 @@ class MiqAzureVm < MiqVm
38
53
  def openDisks(diskFiles)
39
54
  p_volumes = []
40
55
 
41
- $log.debug "openDisks: no disk files supplied." unless diskFiles
56
+ $log.debug("openDisks: #{diskFiles.size} disk files supplied.")
42
57
 
43
58
  #
44
59
  # Build a list of the VM's physical volumes.
45
60
  #
46
61
  diskFiles.each do |dtag, df|
47
62
  $log.debug "openDisks: processing disk file (#{dtag}): #{df}"
48
- dInfo = OpenStruct.new
49
-
50
- dInfo.fileName = df
51
- dInfo.hardwareId = dtag
52
- disk_format = @vmConfig.getHash["#{dtag}.format"]
53
- dInfo.format = disk_format unless disk_format.blank?
54
-
55
- mode = @vmConfig.getHash["#{dtag}.mode"]
56
-
57
- dInfo.hardwareId = dtag
58
- dInfo.rawDisk = true
63
+ d_info = open_disks_info(dtag, df)
59
64
 
60
65
  begin
61
- d = MiqDiskCache.new(AzureBlobDisk.new(sa_svc, @uri, dInfo), 100, 128)
66
+ if @uri
67
+ d = MiqDiskCache.new(AzureBlobDisk.new(sa_svc, @uri, d_info), 100, 128)
68
+ else
69
+ d = MiqDiskCache.new(AzureManagedDisk.new(snap_svc, @snap_name, d_info), 100, 128)
70
+ end
62
71
  rescue => err
63
- $log.error "Couldn't open disk file: #{df}"
64
- $log.error err.to_s
72
+ $log.error("#{err}: Couldn't open disk file: #{df}")
65
73
  $log.debug err.backtrace.join("\n")
66
74
  @diskInitErrors[df] = err.to_s
67
75
  next
@@ -86,6 +94,17 @@ class MiqAzureVm < MiqVm
86
94
  p_volumes
87
95
  end # def openDisks
88
96
 
97
+ def open_disks_info(disk_tag, disk_file)
98
+ disk_info = OpenStruct.new
99
+ disk_info.fileName = disk_file
100
+ disk_info.hardwareId = disk_tag
101
+ disk_format = @vmConfig.getHash["#{disk_tag}.format"]
102
+ disk_info.format = disk_format unless disk_format.blank?
103
+ disk_info.rawDisk = true
104
+ disk_info.resource_group = @resource_group
105
+ disk_info
106
+ end
107
+
89
108
  def vm_svc
90
109
  @vm_svc ||= Azure::Armrest::VirtualMachineService.new(@azure_handle)
91
110
  end
@@ -93,4 +112,8 @@ class MiqAzureVm < MiqVm
93
112
  def sa_svc
94
113
  @sa_svc ||= Azure::Armrest::StorageAccountService.new(@azure_handle)
95
114
  end
115
+
116
+ def snap_svc
117
+ @snap_svc ||= Azure::Armrest::Storage::SnapshotService.new(@azure_handle)
118
+ end
96
119
  end
@@ -11,20 +11,23 @@ module MiqOpenStackCommon
11
11
  send("disk_format_glance_#{image_service.version}", snapshot_image_id)
12
12
  end
13
13
 
14
- def get_image_file_glance_v2(image_id)
15
- log_prefix = "#{self.class.name}##{__method__}"
14
+ def get_image_metadata_snapshot_id(image)
15
+ image.metadata.each do |m|
16
+ next if m.key != "block_device_mapping"
17
+ return m.value[0]['snapshot_id']
18
+ end
19
+ end
16
20
 
17
- image = image_service.images.get(image_id)
18
- raise "Image #{image_id} not found" unless image
19
- $log.debug "#{log_prefix}: image = #{image.class.name}"
21
+ def download_image_data_glance_v2(image)
22
+ log_prefix = "#{self.class.name}##{__method__}"
20
23
 
24
+ image_id = image.id
21
25
  iname = image.name
22
26
  isize = image.size.to_i
23
27
  $log.debug "#{log_prefix}: iname = #{iname}"
24
28
  $log.debug "#{log_prefix}: isize = #{isize}"
25
29
 
26
30
  raise "Image: #{iname} (#{image_id}) is empty" unless isize > 0
27
-
28
31
  tot = 0
29
32
  tf = MiqTempfile.new(iname, :encoding => 'ascii-8bit')
30
33
  $log.debug "#{log_prefix}: saving image to #{tf.path}"
@@ -50,6 +53,57 @@ module MiqOpenStackCommon
50
53
  end
51
54
  tf
52
55
  end
56
+
57
+ def create_image_from_snapshot(snapshot_id, disk_format)
58
+ snapshot = volume_service.snapshots.get(snapshot_id)
59
+ volume_options = {
60
+ :name => "Temp Volume from #{snapshot.name}",
61
+ :size => snapshot.size,
62
+ :snapshot_id => snapshot_id
63
+ }
64
+ volume = volume_service.volumes.new(volume_options)
65
+ volume.save
66
+ begin
67
+ while volume.status != 'available'
68
+ sleep(10)
69
+ volume = volume_service.volumes.get(volume.id)
70
+ end
71
+ response = volume_service.action(volume.id, 'os-volume_upload_image' => {
72
+ :image_name => "Temp Image from #{snapshot.name}",
73
+ :disk_format => disk_format})
74
+ image_id = response.body["os-volume_upload_image"]["image_id"]
75
+ while image_service.images.get(image_id).status.downcase != 'active'
76
+ sleep(10)
77
+ end
78
+ return image_service.images.get(image_id)
79
+ ensure
80
+ volume.destroy
81
+ end
82
+ end
83
+
84
+ def get_image_file_glance_v2(image_id)
85
+ log_prefix = "#{self.class.name}##{__method__}"
86
+
87
+ image = image_service.images.get(image_id)
88
+ raise "Image #{image_id} not found" unless image
89
+ $log.debug "#{log_prefix}: image = #{image.class.name}"
90
+
91
+ if image.size.to_i == 0
92
+ # try getting image from metadata; oddly the image metadata is only available if
93
+ # image is queried through compute service
94
+ unless (snapshot_id = get_image_metadata_snapshot_id(compute_service.images.get(image_id))).nil?
95
+ temp_image = create_image_from_snapshot(snapshot_id, image.disk_format)
96
+ begin
97
+ tf = download_image_data_glance_v2(temp_image)
98
+ ensure
99
+ temp_image.destroy
100
+ end
101
+ end
102
+ else
103
+ tf = download_image_data_glance_v2(image)
104
+ end
105
+ tf
106
+ end
53
107
 
54
108
  def get_image_file_glance_v1(image_id)
55
109
  log_prefix = "#{self.class.name}##{__method__}"
@@ -28,6 +28,10 @@ class MiqOpenStackInstance
28
28
  @image_service ||= @openstack_handle.detect_image_service
29
29
  end
30
30
 
31
+ def volume_service
32
+ @volume_service ||= @openstack_handle.detect_volume_service
33
+ end
34
+
31
35
  def instance
32
36
  @instance ||= compute_service.servers.get(@instance_id)
33
37
  end
@@ -1,7 +1,9 @@
1
+ require "disk/modules/AzureDiskCommon"
1
2
  require_relative "../MiqDisk"
2
3
  require 'ostruct'
3
4
 
4
5
  module AzureBlobDisk
6
+ include AzureDiskCommon
5
7
  # The maximum read length that supports MD5 return.
6
8
  MAX_READ_LEN = 1024 * 1024 * 4
7
9
 
@@ -16,50 +18,19 @@ module AzureBlobDisk
16
18
 
17
19
  def d_init
18
20
  @diskType = "azure-blob"
19
- @blockSize = 512
21
+ @blockSize = AzureDiskCommon::SECTOR_LENGTH
20
22
  @blob_uri = @dInfo.blob_uri
21
23
  @storage_acct_svc = @dInfo.storage_acct_svc
22
-
23
- uri_info = @storage_acct_svc.parse_uri(@blob_uri)
24
- @container = uri_info[:container]
25
- @blob = uri_info[:blob]
26
- @acct_name = uri_info[:account_name]
27
- @snapshot = uri_info[:snapshot]
28
-
29
- @storage_acct = @storage_acct_svc.accounts_by_name[@acct_name]
30
- raise "AzureBlob: Storage account #{@acct_name} not found." unless @storage_acct
31
-
32
- $log.debug "AzureBlobDisk: open(#{@blob_uri})"
33
- @t0 = Time.now.to_i
34
- @reads = 0
35
- @bytes = 0
36
- @split_reads = 0
24
+ d_init_common(@dInfo)
37
25
  end
38
26
 
39
27
  def d_close
40
- return nil unless $log.debug?
41
- t1 = Time.now.to_i
42
- $log.debug "AzureBlobDisk: close(#{@blob_uri})"
43
- $log.debug "AzureBlobDisk: (#{@blob_uri}) time: #{t1 - @t0}"
44
- $log.debug "AzureBlobDisk: (#{@blob_uri}) reads: #{@reads}, split_reads: #{@split_reads}"
45
- $log.debug "AzureBlobDisk: (#{@blob_uri}) bytes: #{@bytes}"
46
- nil
28
+ d_close_common
47
29
  end
48
30
 
49
31
  def d_read(pos, len)
50
32
  $log.debug "AzureBlobDisk#d_read(#{pos}, #{len})"
51
- return blob_read(pos, len) unless len > MAX_READ_LEN
52
-
53
- @split_reads += 1
54
- ret = ""
55
- blocks, rem = len.divmod(MAX_READ_LEN)
56
-
57
- blocks.times do
58
- ret << blob_read(pos, MAX_READ_LEN)
59
- end
60
- ret << blob_read(pos, rem) if rem > 0
61
-
62
- ret
33
+ d_read_common(pos, len)
63
34
  end
64
35
 
65
36
  def d_size
@@ -69,33 +40,4 @@ module AzureBlobDisk
69
40
  def d_write(_pos, _buf, _len)
70
41
  raise "Write operation not supported."
71
42
  end
72
-
73
- private
74
-
75
- def blob_read(start_byte, length)
76
- $log.debug "AzureBlobDisk#blob_read(#{start_byte}, #{length})"
77
- options = {
78
- :start_byte => start_byte,
79
- :length => length
80
- }
81
- options[:date] = @snapshot if @snapshot
82
-
83
- ret = @storage_acct.get_blob_raw(@container, @blob, key, options)
84
-
85
- @reads += 1
86
- @bytes += ret.body.length
87
-
88
- ret.body
89
- end
90
-
91
- def blob_properties
92
- @blob_properties ||= begin
93
- options = @snapshot ? {:date => @snapshot} : {}
94
- @storage_acct.blob_properties(@container, @blob, key, options)
95
- end
96
- end
97
-
98
- def key
99
- @key ||= @storage_acct_svc.list_account_keys(@storage_acct.name, @storage_acct.resource_group).fetch('key1')
100
- end
101
43
  end
@@ -0,0 +1,99 @@
1
+ require_relative '../MiqDisk'
2
+ require 'ostruct'
3
+
4
+ module AzureDiskCommon
5
+ # The maximum read length that supports MD5 return.
6
+ MAX_READ_LEN = 1024 * 1024 * 4
7
+ SECTOR_LENGTH = 512
8
+
9
+ def d_init_common(d_info)
10
+ @blockSize = SECTOR_LENGTH
11
+ if d_info.blob_uri
12
+ d_init_blob_disk(d_info)
13
+ else
14
+ d_init_managed_disk(d_info)
15
+ end
16
+ $log.debug("#{@class}: open(#{@disk_path})")
17
+ @t0 = Time.now.to_i
18
+ @reads = 0
19
+ @bytes = 0
20
+ @split_reads = 0
21
+ end
22
+
23
+ def d_init_blob_disk(d_info)
24
+ @blob_uri = d_info.blob_uri
25
+ @storage_acct_svc = d_info.storage_acct_svc
26
+ @my_class = "AzureBlobDisk"
27
+ uri_info = @storage_acct_svc.parse_uri(@blob_uri)
28
+ @container = uri_info[:container]
29
+ @blob = uri_info[:blob]
30
+ @acct_name = uri_info[:account_name]
31
+ @snapshot = uri_info[:snapshot]
32
+ @storage_acct = @storage_acct_svc.accounts_by_name[@acct_name]
33
+ @disk_path = @blob_uri
34
+ raise "AzureBlob: Storage account #{@acct_name} not found." unless @storage_acct
35
+ end
36
+
37
+ def d_init_managed_disk(d_info)
38
+ @disk_name = d_info.disk_name
39
+ @storage_disk_svc = d_info.storage_disk_svc
40
+ @resource_group = d_info.resource_group
41
+ @my_class = "AzureManagedDisk"
42
+ @disk_path = @disk_name
43
+ end
44
+
45
+ def d_close_common
46
+ return nil unless $log.debug?
47
+ t1 = Time.now.to_i
48
+ $log.debug("#{@my_class}: close(#{@disk_path})")
49
+ $log.debug("#{@my_class}: (#{@disk_path}) time: #{t1 - @t0}")
50
+ $log.debug("#{@my_class}: (#{@disk_path}) reads: #{@reads}, split_reads: #{@split_reads}")
51
+ $log.debug("#{@my_class}: (#{@disk_path}) bytes: #{@bytes}")
52
+ nil
53
+ end
54
+
55
+ def d_read_common(pos, len)
56
+ return blob_read(pos, len) unless len > MAX_READ_LEN
57
+
58
+ @split_reads += 1
59
+ ret = ""
60
+ blocks, rem = len.divmod(MAX_READ_LEN)
61
+
62
+ blocks.times do
63
+ ret << blob_read(pos, MAX_READ_LEN)
64
+ end
65
+ ret << blob_read(pos, rem) if rem > 0
66
+
67
+ ret
68
+ end
69
+
70
+ def blob_properties
71
+ @blob_properties ||= begin
72
+ options = @snapshot ? {:date => @snapshot} : {}
73
+ @storage_acct.blob_properties(@container, @blob, key, options)
74
+ end
75
+ end
76
+
77
+ def blob_read(start_byte, length)
78
+ $log.debug("#{@my_class}#blob_read(#{start_byte}, #{length})")
79
+ options = {
80
+ :start_byte => start_byte,
81
+ :length => length
82
+ }
83
+ if @storage_acct
84
+ options[:date] = @snapshot if @snapshot
85
+ ret = @storage_acct.get_blob_raw(@container, @blob, key, options)
86
+ else
87
+ ret = @storage_disk_svc.get_blob_raw(@disk_name, @resource_group, options)
88
+ end
89
+
90
+ @reads += 1
91
+ @bytes += ret.body.length
92
+
93
+ ret.body
94
+ end
95
+
96
+ def key
97
+ @key ||= @storage_acct_svc.list_account_keys(@storage_acct.name, @storage_acct.resource_group).fetch('key1')
98
+ end
99
+ end
@@ -0,0 +1,55 @@
1
+ require "disk/modules/AzureDiskCommon"
2
+ require_relative "../MiqDisk"
3
+ require 'ostruct'
4
+
5
+ module AzureManagedDisk
6
+ include AzureDiskCommon
7
+ def self.new(svc, disk_name, dInfo = nil)
8
+ d_info = dInfo || OpenStruct.new
9
+ d_info.storage_disk_svc = svc
10
+ d_info.disk_name = disk_name
11
+ d_info.fileName = disk_name
12
+
13
+ MiqDisk.new(self, d_info, 0)
14
+ end
15
+
16
+ def d_init
17
+ @diskType = "azure-managed"
18
+ @blockSize = SECTOR_LENGTH
19
+ @disk_name = @dInfo.disk_name
20
+ @storage_disk_svc = @dInfo.storage_disk_svc
21
+ @resource_group = @dInfo.resource_group
22
+ d_init_common(@dInfo)
23
+ end
24
+
25
+ def d_close
26
+ d_close_common
27
+ end
28
+
29
+ def d_read(pos, len)
30
+ $log.debug("AzureManagedDisk#d_read(#{pos}, #{len})")
31
+ d_read_common(pos, len)
32
+ end
33
+
34
+ def d_size
35
+ @d_size ||= blob_headers[:content_range].split("/")[1].to_i
36
+ end
37
+
38
+ def d_write(_pos, _buf, _len)
39
+ raise "Write operation not supported."
40
+ end
41
+
42
+ private
43
+
44
+ def blob_headers
45
+ $log.debug("AzureManagedDisk#blob_headers")
46
+ @blob_headers ||= begin
47
+ options = {
48
+ :start_byte => 0,
49
+ :length => 1
50
+ }
51
+ data = @storage_disk_svc.get_blob_raw(@disk_name, @resource_group, options)
52
+ data.headers
53
+ end
54
+ end
55
+ end
@@ -6,15 +6,11 @@ if Sys::Platform::IMPL == :linux
6
6
  require 'linux_block_device'
7
7
  require 'disk/modules/RawBlockIO'
8
8
  end
9
- elsif Sys::Platform::OS == :windows
10
- require 'disk/modules/MiqLargeFileWin32'
11
9
  end
12
10
 
13
11
  module MiqLargeFile
14
12
  def self.open(file_name, flags)
15
13
  case Sys::Platform::OS
16
- when :windows
17
- return(MiqLargeFileWin32.new(file_name, flags))
18
14
  when :unix
19
15
  if Sys::Platform::IMPL == :linux
20
16
  return(RawBlockIO.new(file_name, flags)) if MiqLargeFileStat.new(file_name).blockdev?
@@ -26,17 +22,10 @@ module MiqLargeFile
26
22
  end
27
23
 
28
24
  def self.size(file_name)
29
- case Sys::Platform::OS
30
- when :windows
31
- # The win32/file require is needed to support +2GB file sizes
32
- require 'win32/file'
33
- File.size(file_name)
34
- else
35
- f = open(file_name, "r")
36
- s = f.size
37
- f.close
38
- return s
39
- end
25
+ f = open(file_name, "r")
26
+ s = f.size
27
+ f.close
28
+ s
40
29
  end
41
30
 
42
31
  # For camcorder interposition.
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module Smartstate
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3".freeze
4
4
  end
5
5
  end
@@ -158,8 +158,7 @@ class VmConfig
158
158
  end
159
159
 
160
160
  def set_vmconfig_path(config_path)
161
- ds, _dir, _name = split_filename(config_path)
162
- @configFile = ds.nil? ? File.normalize(config_path) : config_path
161
+ @configFile = normalize_vmconfig_file(config_path)
163
162
  @configPath = File.dirname(@configFile)
164
163
  end
165
164
 
@@ -255,6 +254,13 @@ class VmConfig
255
254
 
256
255
  private
257
256
 
257
+ def normalize_vmconfig_file(config_file)
258
+ ds, _dir, _name = split_filename(config_file)
259
+ return config_file unless ds.nil?
260
+
261
+ File.expand_path(config_file.tr('\\', '/'))
262
+ end
263
+
258
264
  def diskKey?(key)
259
265
  key =~ /^ide\d+:\d+\.filename$/ || key =~ /^scsi\d+:\d+\.filename$/
260
266
  end
@@ -446,7 +452,7 @@ class VmConfig
446
452
  @files = []
447
453
  if @direct_file_access
448
454
  Dir.glob(File.join(@configPath, "/*.*")) do |f|
449
- s = File.sizeEx(f) rescue 0
455
+ s = File.size(f) rescue 0
450
456
  @files << {:path => f, :name => File.basename(f), :size => s, :mtime => File.mtime(f)}
451
457
  end
452
458
  else
@@ -13,7 +13,6 @@ require 'metadata/util/win32/peheader'
13
13
  require 'metadata/util/win32/remote-registry'
14
14
 
15
15
  # Dev needs this.
16
- require 'Win32API' if Sys::Platform::OS == :windows
17
16
  require 'metadata/util/win32/system_path_win'
18
17
 
19
18
  require 'digest/md5'
@@ -149,7 +148,7 @@ class Win32EventLog
149
148
 
150
149
  # If an MiqFS instance was not passed, then the OS has to be (or emulate) Win32.
151
150
  # If an MiqFS instance *was* passed, then if the guest OS is not Windows then getSystemRoot will throw.
152
- raise "#{self.class}::initialize: Platform is not Windows and file system is not MiqFS: cannot continue" if Sys::Platform::OS != :windows and !vmMiqFs.class.to_s.include?('Miq')
151
+ raise "#{self.class}::initialize: Filesystem is not MiqFS: cannot continue" if !vmMiqFs.class.to_s.include?('Miq')
153
152
 
154
153
  # Get a file system instance if we don't already have one.
155
154
  @fs = vmMiqFs
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
+ spec.add_dependency "azure-armrest"
24
+ spec.add_dependency "binary_struct", "~> 2.1"
23
25
  spec.add_dependency "iniparse"
24
26
  spec.add_dependency "linux_block_device", "~>0.2.1"
25
27
  spec.add_dependency "memory_buffer", ">=0.1.0"
@@ -33,6 +35,7 @@ Gem::Specification.new do |spec|
33
35
  spec.add_development_dependency "vcr", "~>3.0.2"
34
36
  spec.add_development_dependency "webmock", "~>2.3.1"
35
37
  spec.add_development_dependency "simplecov"
38
+ spec.add_development_dependency "rubocop"
36
39
  spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
37
40
 
38
41
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-smartstate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-02 00:00:00.000000000 Z
11
+ date: 2017-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: azure-armrest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: binary_struct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: iniparse
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +206,20 @@ dependencies:
178
206
  - - ">="
179
207
  - !ruby/object:Gem::Version
180
208
  version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rubocop
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
181
223
  - !ruby/object:Gem::Dependency
182
224
  name: codeclimate-test-reporter
183
225
  requirement: !ruby/object:Gem::Requirement
@@ -198,9 +240,13 @@ executables: []
198
240
  extensions: []
199
241
  extra_rdoc_files: []
200
242
  files:
243
+ - ".codeclimate.yml"
201
244
  - ".gitignore"
202
245
  - ".rspec"
203
246
  - ".rspec_ci"
247
+ - ".rubocop.yml"
248
+ - ".rubocop_cc.yml"
249
+ - ".rubocop_local.yml"
204
250
  - ".travis.yml"
205
251
  - Gemfile
206
252
  - LICENSE.txt
@@ -271,6 +317,8 @@ files:
271
317
  - lib/disk/camcorder_test.rb
272
318
  - lib/disk/dos_mbr.img
273
319
  - lib/disk/modules/AzureBlobDisk.rb
320
+ - lib/disk/modules/AzureDiskCommon.rb
321
+ - lib/disk/modules/AzureManagedDisk.rb
274
322
  - lib/disk/modules/LocalDevMod.rb
275
323
  - lib/disk/modules/LocalDevProbe.rb
276
324
  - lib/disk/modules/MSCommon.rb
@@ -279,7 +327,6 @@ files:
279
327
  - lib/disk/modules/MSVSDynamicDisk.rb
280
328
  - lib/disk/modules/MSVSFixedDisk.rb
281
329
  - lib/disk/modules/MiqLargeFile.rb
282
- - lib/disk/modules/MiqLargeFileWin32.rb
283
330
  - lib/disk/modules/QcowDisk.rb
284
331
  - lib/disk/modules/QcowDiskProbe.rb
285
332
  - lib/disk/modules/RawBlockIO.rb
@@ -521,7 +568,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
521
568
  version: '0'
522
569
  requirements: []
523
570
  rubyforge_project:
524
- rubygems_version: 2.6.11
571
+ rubygems_version: 2.6.12
525
572
  signing_key:
526
573
  specification_version: 4
527
574
  summary: ManageIQ SmartState Analysis
@@ -1,107 +0,0 @@
1
- require 'memory_buffer'
2
- require 'Win32API'
3
-
4
- class MiqLargeFileWin32
5
- # Access specifiers.
6
- GENERIC_READ = 0x80000000
7
- GENERIC_WRITE = 0x40000000
8
-
9
- # Share specifiers.
10
- FILE_SHARE_READ = 0x00000001
11
- FILE_SHARE_WRITE = 0x00000002
12
-
13
- # Creation disposition specifiers.
14
- OPEN_EXISTING = 3
15
-
16
- # Seek origin.
17
- FILE_BEGIN = 0
18
- FILE_CURRENT = 1
19
- FILE_END = 2
20
-
21
- # Misc.
22
- INVALID_HANDLE_VALUE = -1
23
-
24
- # API.
25
- @@createFile = Win32API.new('kernel32', 'CreateFileA', 'PLLLLLL', 'L')
26
- @@setFilePointerEx = Win32API.new('kernel32', 'SetFilePointerEx', 'LLLPL', 'L')
27
- @@readFile = Win32API.new('kernel32', 'ReadFile', 'LPLPL', 'L')
28
- @@writeFile = Win32API.new('kernel32', 'WriteFile', 'LPLPL', 'L')
29
- @@closeHandle = Win32API.new('kernel32', 'CloseHandle', 'L', 'L')
30
- @@getFileSize = Win32API.new('kernel32', 'GetFileSizeEx', 'LP', 'L')
31
- @@getLastError = Win32API.new('kernel32', 'GetLastError', nil, 'L')
32
-
33
- # Default constructor.
34
- def initialize(file, access = "r")
35
- accessOptions = 0
36
- accessOptions |= GENERIC_READ if access.include?("r")
37
- accessOptions |= GENERIC_WRITE if access.include?("+")
38
- @hFile = @@createFile.call(file, accessOptions, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
39
- raise "Couldn't open file #{file}" if @hFile == INVALID_HANDLE_VALUE
40
- $log.debug("MiqLargeFile<#{object_id}> Opening #{file}, handle 0x#{'%08x' % @hFile}") if $log
41
- end
42
-
43
- # Alternative initialization.
44
- def self.open(file, access = "r")
45
- initialize(file, access)
46
- end
47
-
48
- def size
49
- siz = MemoryBuffer.create_quad
50
- err = @@getFileSize.call(@hFile, siz)
51
- siz.unpack('Q')[0]
52
- end
53
-
54
- def seek(offset, whence)
55
- method = case whence
56
- when IO::SEEK_SET then FILE_BEGIN
57
- when IO::SEEK_CUR then FILE_CURRENT
58
- when IO::SEEK_END then FILE_END
59
- else raise "Invalid seek method: #{whence}"
60
- end
61
- offHi, offLo = offset.divmod(4294967296) # 2 ** 32
62
- new_pos = MemoryBuffer.create_quad
63
- res = @@setFilePointerEx.call(@hFile, offLo, offHi, new_pos, method)
64
- if res == 0
65
- last_error = @@getLastError.call
66
- raise "SetFilePointerEx failed - Offset:[#{offset}] method:[#{whence}] Handle:[0x#{'%08x' % @hFile}] GetLastErrorNum:[#{last_error}]"
67
- end
68
- new_pos = new_pos.unpack('Q')[0]
69
- new_pos
70
- end
71
-
72
- def read(bytes)
73
- # puts "#{getFilePos}, #{bytes}" if $track_pos
74
- buf = MemoryBuffer.create(bytes)
75
- bytesRead = MemoryBuffer.create_long
76
- res = @@readFile.call(@hFile, buf, bytes, bytesRead, 0)
77
- bytesRead = bytesRead.unpack('L')[0]
78
- if bytesRead == 0 && bytes != 0 || res == 0
79
- last_error = @@getLastError.call
80
- raise "Read from disk file failed - result:[#{res}] bytesRead:[#{bytesRead}] expected:[#{bytes}] file pointer:[#{getFilePos}] file size:[#{size}] Handle:[0x#{'%08x' % @hFile}] GetLastErrorNum:[#{last_error}]."
81
- end
82
- buf = buf[0...bytesRead] if bytesRead != bytes
83
- buf
84
- end
85
-
86
- def write(buf, len)
87
- # NOTE: len must be a double word.
88
- bytesWritten = MemoryBuffer.create_long
89
- res = @@writeFile.call(@hFile, buf, len, bytesWritten, 0)
90
- raise "WriteFile failed" if res == 0
91
- bytesWritten = bytesWritten.unpack('L')[0]
92
- raise "Not all data written" if bytesWritten != len
93
- bytesWritten
94
- end
95
-
96
- def close
97
- $log.debug("MiqLargeFile<#{object_id}> Closing handle 0x#{'%08x' % @hFile}") if $log
98
- h = @hFile
99
- res = @@closeHandle.call(@hFile)
100
- @hFile = INVALID_HANDLE_VALUE if res != 0
101
- return res, h
102
- end
103
-
104
- def getFilePos
105
- seek(0, IO::SEEK_CUR)
106
- end
107
- end