manageiq-smartstate 0.3.5 → 0.3.10

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: 00a7fd279564b332f1a1d404da7cd92cd41d9827
4
- data.tar.gz: 4e458d0d28103d49b69edc730c38bf3ca1fe9a01
3
+ metadata.gz: 8d279efbb6413424193473e6d2139818d1afb189
4
+ data.tar.gz: 732bdf1ffae2c46876c93a3cc66b56fcb9478b4e
5
5
  SHA512:
6
- metadata.gz: 11c5b3bed6d746d0631bed97dc25fff334c845446b33553c467913c2cd404d1dc1ba26cc4ee7118de535ce08592d6ff143102d9d036106af8426ea0a2c538825
7
- data.tar.gz: 3b6392fed96603ef12de4214a004bf9a36c5cda4e40064452d43c6e8bc1841bbc22f359f6bf9aed6e97e62600bc1c5afa6849931fdd035e59c04bddc1381c3f7
6
+ metadata.gz: 8617444550ba063368dba0d683a7bddfac1e861bc52ffb866e16206b5f57239d76502a850a73aef07fe0bd94f2e2a94f34d7dba307acb665f2dc3ddfd03f0012
7
+ data.tar.gz: 7f3967e4f1fec3c427e22a371849f3ba2c0e05e94c4899eba1fbc70a00cba98bec315fe8a8788f29b6ed1188b9e0b26f3ecfaa8d0b6630eb13f8d72f4c3224b7
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in manageiq-smartstate.gemspec
4
4
  gemspec
5
5
 
6
- gem "manageiq-gems-pending", :git => "https://github.com/ManageIQ/manageiq-gems-pending.git", :branch => "master"
6
+ gem "manageiq-gems-pending", :git => "https://github.com/ManageIQ/manageiq-gems-pending.git", :branch => "ivanchuk"
7
7
 
8
8
  # Modified gems for vmware_web_service. Setting sources here since they are git references
9
9
  gem "handsoap", "~>0.2.5", :require => false, :git => "https://github.com/ManageIQ/handsoap.git", :tag => "v0.2.5-5"
@@ -42,7 +42,7 @@ class MiqRhevmVm < MiqVm
42
42
  disks = @rhevm.collect_vm_disks(@rhevmVm)
43
43
  disks.each_with_index do |disk, idx|
44
44
  $log.debug "MiqRhevmVm#getCfg: disk = #{disk.inspect}"
45
- storage_domain = disk.storage_domains.first
45
+ storage_domain = disk.storage_domains&.first
46
46
  if storage_domain.nil?
47
47
  $log.info("Disk <#{disk.name}> is skipped due to unassigned storage domain")
48
48
  next
@@ -309,23 +309,27 @@ module LinuxMount
309
309
  #
310
310
  components.each do |c|
311
311
  ncp = File.join(cp, c)
312
- #
313
- # Each file system know how to check for,
314
- # and read its own links.
315
- #
316
- fs, lp = getFsPathBase(ncp)
317
- if fs.fileSymLink?(lp)
318
- sl = getSymLink(fs, lp)
319
- if sl[0, 1] == '/'
320
- cp = sl
321
- else
322
- cp = File.join(cp, sl)
323
- end
312
+ cp = follow_all_symlinks(ncp)
313
+ end
314
+ cp
315
+ end
316
+
317
+ def follow_all_symlinks(link_ptr)
318
+ #
319
+ # Each filesystem knows how to check for,
320
+ # and read its own links.
321
+ #
322
+ no_more_links = false
323
+ until no_more_links
324
+ filesys, tmp_link_ptr = getFsPathBase(link_ptr)
325
+ if filesys.fileSymLink?(tmp_link_ptr)
326
+ symlink = getSymLink(filesys, tmp_link_ptr)
327
+ link_ptr = symlink[0, 1] == '/' ? symlink : File.join(File.dirname(link_ptr), symlink)
324
328
  else
325
- cp = ncp
329
+ no_more_links = true
326
330
  end
327
331
  end
328
- (cp)
332
+ link_ptr
329
333
  end
330
334
 
331
335
  def getSymLink(fs, p)
@@ -282,7 +282,7 @@ module NTFS
282
282
 
283
283
  @runSpec.each_slice(2) do |lcn, len|
284
284
  total_clusters += len
285
- next unless total_clusters > start_vcn
285
+ next unless lcn && len && total_clusters > start_vcn
286
286
 
287
287
  start = lcn + (vcn - (total_clusters - len))
288
288
  count = len - (start - lcn)
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module Smartstate
3
- VERSION = "0.3.5".freeze
3
+ VERSION = "0.3.10".freeze
4
4
  end
5
5
  end
@@ -498,7 +498,7 @@ class VmConfig
498
498
  end
499
499
 
500
500
  def rhevm_disk_file_entry(disk)
501
- storage_id = disk.storage_domains.first&.id
501
+ storage_id = disk.storage_domains&.first&.id
502
502
  disk_id = disk.image_id || disk.id
503
503
  full_path = storage_id && File.join('/dev', storage_id, disk_id)
504
504
  {:path => full_path, :name => disk_id, :size => disk.actual_size.to_i}
@@ -550,7 +550,7 @@ class VmConfig
550
550
  elsif miqvm.rhevmVm
551
551
  disks = miqvm.rhevm.collect_vm_disks(miqvm.rhevmVm)
552
552
  disks.each do |disk|
553
- storage_id = disk.storage_domains.first&.id
553
+ storage_id = disk.storage_domains&.first&.id
554
554
  disk_id = disk.image_id || disk.id
555
555
  full_path = storage_id && File.join('/dev', storage_id, disk_id)
556
556
  d = {:path => full_path, :name => disk.name.to_s, :size => disk.actual_size.to_i}
@@ -0,0 +1,133 @@
1
+ module FindClassMethods
2
+ # Return directory entries matching specified glob pattern
3
+ #
4
+ # @param glob_pattern [String] pattern to match
5
+ # @param flags [Integer] file match flags
6
+ # @yield block invoked with each match if specified
7
+ #
8
+ # @see VfsRealFile.fnmatch
9
+ # @see FindClassMethods#dir_and_glob which does most of the work regarding globbing
10
+ # @see FindClassMethods#find which retrieves stats information & dir entries for found files
11
+ #
12
+ def self.glob(glob_pattern, filesys, flags = 0)
13
+ @fs = filesys
14
+ return [] unless (glob = dir_and_glob(glob_pattern))
15
+
16
+ ra = []
17
+ find(@search_path, glob_depth(glob)) do |p|
18
+ if (p = check_file(p, glob, flags))
19
+ block_given? ? yield(p) : ra << p
20
+ end
21
+ end
22
+ ra.sort_by(&:downcase)
23
+ end
24
+
25
+ #
26
+ # Determine if the file returned from "find" will be used or skipped.
27
+ #
28
+ def self.check_file(file, glob, flags)
29
+ return nil if file == @search_path
30
+
31
+ if @search_path == File::SEPARATOR
32
+ file.sub!(File::SEPARATOR, "")
33
+ else
34
+ file.sub!("#{@search_path}#{File::SEPARATOR}", "")
35
+ end
36
+
37
+ return nil if file == "" || !File.fnmatch(glob, file, flags)
38
+
39
+ @specified_path ? File.join(@specified_path, file) : file
40
+ end
41
+
42
+ #
43
+ # Modified version of Find.find:
44
+ # - Accepts only a single path.
45
+ # - Can be restricted by depth - optimization for glob searches.
46
+ #
47
+ # @param path [String] starting directory of the find
48
+ # @param max_depth [Integer] max number of levels to decend befroelookup
49
+ # @yield files found
50
+ #
51
+ def self.find(path, max_depth = nil)
52
+ block_given? || (return enum_for(__method__, path, max_depth))
53
+
54
+ depths = [0]
55
+ paths = [path.dup]
56
+
57
+ while (file = paths.shift)
58
+ depth = depths.shift
59
+ yield file.dup.taint
60
+ next if max_depth && depth + 1 > max_depth
61
+
62
+ get_dir_entries(file).each do |f|
63
+ f = File.join(file, f)
64
+ paths.unshift f.untaint
65
+ depths.unshift depth + 1
66
+ end
67
+ end
68
+ end
69
+
70
+ def self.get_dir_entries(directory)
71
+ return [] unless @fs.fileExists?(directory) && @fs.fileDirectory?(directory)
72
+
73
+ files = @fs.dirEntries(directory)
74
+ files -= [".", ".."]
75
+ files.sort!
76
+ files.reverse_each
77
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
78
+ $log.info "find: while-loop @fs.dirEntries #{directory} returned an error"
79
+ []
80
+ end
81
+
82
+ GLOB_CHARS = '*?[{'.freeze
83
+ def self.glob_str?(str)
84
+ str.gsub(/\\./, "X").count(GLOB_CHARS) != 0
85
+ end
86
+
87
+ # Returns files matching glob pattern
88
+ #
89
+ # @api private
90
+ # @param glob_pattern [String,Regex] pattern to search for
91
+ # @return [String] paths to files found
92
+ #
93
+ def self.dir_and_glob(glob_pattern)
94
+ stripped_path = glob_pattern.sub(/^[a-zA-Z]:/, "")
95
+ glob_path = Pathname.new(stripped_path)
96
+ @search_path = File::SEPARATOR
97
+ @specified_path = File::SEPARATOR
98
+
99
+ unless glob_path.absolute?
100
+ @search_path = Dir.getwd
101
+ @specified_path = nil
102
+ end
103
+
104
+ components = path_components(glob_path)
105
+ @search_path = File.expand_path(@search_path, "/")
106
+ @fs.fileExists?(@search_path) ? File.join(components) : nil
107
+ end
108
+
109
+ def self.path_components(glob_path, search_path = @search_path)
110
+ components = glob_path.each_filename.to_a
111
+ while (comp = components.shift)
112
+ if glob_str?(comp)
113
+ components.unshift(comp)
114
+ break
115
+ end
116
+ @search_path = File.join(search_path, comp)
117
+ @specified_path = @specified_path ? File.join(@specified_path, comp) : comp
118
+ end
119
+ components
120
+ end
121
+
122
+ # Return max levels which glob pattern may resolve to
123
+ #
124
+ # @api private
125
+ # @param glob_pattern [String,Regex] pattern to search for
126
+ # @return [Integer] max levels which pattern may match
127
+ def self.glob_depth(glob_pattern)
128
+ path_components = Pathname(glob_pattern).each_filename.to_a
129
+ return nil if path_components.include?('**')
130
+
131
+ path_components.length
132
+ end
133
+ end
@@ -1,6 +1,7 @@
1
1
  require 'time'
2
2
  require 'metadata/util/win32/peheader'
3
3
  require 'metadata/util/win32/versioninfo'
4
+ require 'metadata/util/find_class_methods'
4
5
  require 'util/miq-xml'
5
6
  require 'ostruct'
6
7
  require 'util/miq-encode'
@@ -54,29 +55,35 @@ class MD5deep
54
55
  def scan_glob(filename)
55
56
  filename.tr!("\\", "/")
56
57
  startDir = File.dirname(filename)
57
- globPattern = File.basename(filename)
58
58
  @xml.root.add_attribute("base_path", startDir)
59
- @fs.chdir(startDir)
59
+ path_prefix = startDir[0, 2]
60
+ @drive_letter = path_prefix.match?(/^\w\:/) ? path_prefix : ""
60
61
 
61
62
  # First check if we are passed a fully qualifed file name
62
63
  if @fs.fileExists?(filename)
63
- isDir?(filename) ? process_dir_as_file(startDir, globPattern, @xml.root) : processFile(startDir, globPattern, @xml.root)
64
+ base_file = File.basename(filename)
65
+ isDir?(filename) ? process_dir_as_file(startDir, base_file, @xml.root) : processFile(startDir, base_file, @xml.root)
64
66
  else
65
67
  # If the file is not found then process the data as a glob pattern.
66
- @fs.dirGlob(globPattern) do |f|
67
- # $log.info "Glob file found: [#{f}]"
68
- # Passing "startDir" as the first parameter is a work-around for issues
69
- # when scanning Win VMs from Linux where the path returned from dirGlob
70
- # do not include the drive letter.
71
- # Below is the original line
72
- # processFile(File.dirname(f), File.basename(f), @xml.root)
73
- processFile(startDir, File.basename(f), @xml.root)
74
- end
68
+ process_each_glob_file(filename)
75
69
  end
76
70
  @xml
77
71
  end
78
72
 
73
+ def process_each_glob_file(file_name)
74
+ FindClassMethods.glob(file_name, @fs) do |f|
75
+ # Passing "startDir" as the first parameter is a work-around for issues
76
+ # when scanning Win VMs from Linux where the path returned from dirGlob
77
+ # do not include the drive letter.
78
+ processFile(File.dirname(f), File.basename(f), @xml.root)
79
+ end
80
+ rescue => err
81
+ $log.error "process_each_glob_file: Exception #{err} rescued"
82
+ $log.debug err.backtrace.join("\n")
83
+ end
84
+
79
85
  def read_fs(path, xmlNode)
86
+ @drive_letter = @drive_letter.nil? ? "" : @drive_letter
80
87
  if @fs
81
88
  @fs.dirForeach(path) { |x| processFile(path, x, xmlNode) }
82
89
  @fs.dirForeach(path) { |x| processDir(path, x, xmlNode) }
@@ -91,7 +98,7 @@ class MD5deep
91
98
 
92
99
  def processDir(path, x, xmlNode)
93
100
  if x != "." && x != ".."
94
- currFile = File.join(path, x)
101
+ currFile = File.join(@drive_letter, path, x)
95
102
 
96
103
  begin
97
104
  if File.directory?(currFile)
@@ -110,7 +117,7 @@ class MD5deep
110
117
 
111
118
  def process_dir_as_file(path, x, xml_node)
112
119
  if x != "." && x != ".."
113
- curr_dir = File.join(path, x)
120
+ curr_dir = File.join(@drive_letter, path, x)
114
121
  if isDir?(curr_dir)
115
122
  xml_file_node = xml_node.add_element("file", "name" => x, "fqname" => curr_dir)
116
123
  stat_hash = {}
@@ -122,7 +129,7 @@ class MD5deep
122
129
 
123
130
  def processFile(path, x, xmlNode)
124
131
  if (@opts.exclude.include?(x) == false) && x[0..0] != "$"
125
- currFile = File.join(path, x)
132
+ currFile = File.join(@drive_letter, path, x)
126
133
 
127
134
  begin
128
135
  # unless File.directory?(currFile) then
@@ -150,13 +157,14 @@ class MD5deep
150
157
  fh.close if fh.kind_of?(File) && !fh.closed?
151
158
  end
152
159
  end
160
+ $log.debug "processFile: finished @xml is #{@xml}"
153
161
  end
154
162
 
155
163
  def process_pe_header(pe_hdr, xml_file_node)
156
164
  xml_file_node.add_element("versioninfo", pe_hdr.versioninfo) if @opts.versioninfo && pe_hdr.versioninfo.present?
157
165
  xml_file_node.add_element("libraries", "imports" => pe_hdr.getImportList) if @opts.imports && pe_hdr.imports.present?
158
166
  rescue TypeError => err
159
- $log.info "processFile: TypeError handling PEheader; skipping PEheader info"
167
+ $log.info "process_pe_header: TypeError handling PEheader; skipping PEheader info"
160
168
  $log.debug err.backtrace.join("\n")
161
169
  end
162
170
 
@@ -218,10 +226,15 @@ class MD5deep
218
226
  # Create hash for requested digests
219
227
  digest = create_digest_hash
220
228
 
221
- fileName.seek(0, IO::SEEK_SET)
222
- # Loop over each digest and add the file contents
223
- while buf = fileName.read(10240000)
224
- digest.each_pair { |_k, v| v << buf }
229
+ begin
230
+ fileName.seek(0, IO::SEEK_SET)
231
+ # Loop over each digest and add the file contents
232
+ while (buf = fileName.read(10_240_000))
233
+ digest.each_pair { |_k, v| v << buf }
234
+ end
235
+ rescue => err
236
+ $log.error "Error #{err} reading file to calculate digest"
237
+ $log.debug err.backtrace.join("\n")
225
238
  end
226
239
  end
227
240
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-smartstate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-19 00:00:00.000000000 Z
11
+ date: 2020-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: azure-armrest
@@ -525,6 +525,7 @@ files:
525
525
  - lib/metadata/linux/MiqConaryPackages.rb
526
526
  - lib/metadata/linux/MiqRpmPackages.rb
527
527
  - lib/metadata/util/event_log_filter.rb
528
+ - lib/metadata/util/find_class_methods.rb
528
529
  - lib/metadata/util/md5deep.rb
529
530
  - lib/metadata/util/win32/Win32Accounts.rb
530
531
  - lib/metadata/util/win32/Win32EventLog.rb