manageiq-smartstate 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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