manageiq-smartstate 0.3.5 → 0.3.6

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: 00a7fd279564b332f1a1d404da7cd92cd41d9827
4
- data.tar.gz: 4e458d0d28103d49b69edc730c38bf3ca1fe9a01
3
+ metadata.gz: 329da11c20c2a1ea5a2089d9d8b50fbd4c2f5b4a
4
+ data.tar.gz: 8f29a1c35119e098e0b1a8e8421adc773545aa67
5
5
  SHA512:
6
- metadata.gz: 11c5b3bed6d746d0631bed97dc25fff334c845446b33553c467913c2cd404d1dc1ba26cc4ee7118de535ce08592d6ff143102d9d036106af8426ea0a2c538825
7
- data.tar.gz: 3b6392fed96603ef12de4214a004bf9a36c5cda4e40064452d43c6e8bc1841bbc22f359f6bf9aed6e97e62600bc1c5afa6849931fdd035e59c04bddc1381c3f7
6
+ metadata.gz: 1117fc552c4ef5931f86e7e612a395f98339cfe8ae49737f1c0f9a3515be3682011f574b4bd6144e849e0deeae4cebab63863ecefee6974cfeba7256964cc929
7
+ data.tar.gz: 73f022ff2c9a8bbfa940837f0b3aa3a54000b719024150d6774485189248cd15a9feacb880bd31934b3b77dc1fe46d4dae1fe81f88eef5f143b96f014af32dd6
@@ -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, link_ptr = getFsPathBase(link_ptr)
325
+ if filesys.fileSymLink?(link_ptr)
326
+ symlink = getSymLink(filesys, linkptr)
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)
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  module Smartstate
3
- VERSION = "0.3.5".freeze
3
+ VERSION = "0.3.6".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,132 @@
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
+ p = check_file(p, glob, flags)
19
+ p && block_given? ? yield(p) : ra << p
20
+ end
21
+ ra.sort_by(&:downcase)
22
+ end
23
+
24
+ #
25
+ # Determine if the file returned from "find" will be used or skipped.
26
+ #
27
+ def self.check_file(file, glob, flags)
28
+ return nil if file == @search_path
29
+
30
+ if @search_path == File::SEPARATOR
31
+ file.sub!(File::SEPARATOR, "")
32
+ else
33
+ file.sub!("#{@search_path}#{File::SEPARATOR}", "")
34
+ end
35
+
36
+ return nil if file == "" || !File.fnmatch(glob, file, flags)
37
+
38
+ @specified_path ? File.join(@specified_path, file) : file
39
+ end
40
+
41
+ #
42
+ # Modified version of Find.find:
43
+ # - Accepts only a single path.
44
+ # - Can be restricted by depth - optimization for glob searches.
45
+ #
46
+ # @param path [String] starting directory of the find
47
+ # @param max_depth [Integer] max number of levels to decend befroelookup
48
+ # @yield files found
49
+ #
50
+ def self.find(path, max_depth = nil)
51
+ block_given? || (return enum_for(__method__, path, max_depth))
52
+
53
+ depths = [0]
54
+ paths = [path.dup]
55
+
56
+ while (file = paths.shift)
57
+ depth = depths.shift
58
+ yield file.dup.taint
59
+ next if max_depth && depth + 1 > max_depth
60
+
61
+ get_dir_entries(file).each do |f|
62
+ f = File.join(file, f)
63
+ paths.unshift f.untaint
64
+ depths.unshift depth + 1
65
+ end
66
+ end
67
+ end
68
+
69
+ def self.get_dir_entries(directory)
70
+ return [] unless @fs.fileExists?(directory) && @fs.fileDirectory?(directory)
71
+
72
+ files = @fs.dirEntries(directory)
73
+ files.difference([".", ".."])
74
+ files.sort!
75
+ files.reverse_each
76
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
77
+ $log.info "find: while-loop @fs.dirEntries #{directory} returned an error"
78
+ []
79
+ end
80
+
81
+ GLOB_CHARS = '*?[{'.freeze
82
+ def self.glob_str?(str)
83
+ str.gsub(/\\./, "X").count(GLOB_CHARS) != 0
84
+ end
85
+
86
+ # Returns files matching glob pattern
87
+ #
88
+ # @api private
89
+ # @param glob_pattern [String,Regex] pattern to search for
90
+ # @return [String] paths to files found
91
+ #
92
+ def self.dir_and_glob(glob_pattern)
93
+ stripped_path = glob_pattern.sub(/^[a-zA-Z]:/, "")
94
+ glob_path = Pathname.new(stripped_path)
95
+ @search_path = File::SEPARATOR
96
+ @specified_path = File::SEPARATOR
97
+
98
+ unless glob_path.absolute?
99
+ @search_path = Dir.getwd
100
+ @specified_path = nil
101
+ end
102
+
103
+ components = path_components(glob_path)
104
+ @search_path = File.expand_path(@search_path, "/")
105
+ @fs.fileExists?(@search_path) ? File.join(components) : nil
106
+ end
107
+
108
+ def self.path_components(glob_path, search_path = @search_path)
109
+ components = glob_path.each_filename.to_a
110
+ while (comp = components.shift)
111
+ if glob_str?(comp)
112
+ components.unshift(comp)
113
+ break
114
+ end
115
+ @search_path = File.join(search_path, comp)
116
+ @specified_path = @specified_path ? File.join(@specified_path, comp) : comp
117
+ end
118
+ components
119
+ end
120
+
121
+ # Return max levels which glob pattern may resolve to
122
+ #
123
+ # @api private
124
+ # @param glob_pattern [String,Regex] pattern to search for
125
+ # @return [Integer] max levels which pattern may match
126
+ def self.glob_depth(glob_pattern)
127
+ path_components = Pathname(glob_pattern).each_filename.to_a
128
+ return nil if path_components.include?('**')
129
+
130
+ path_components.length
131
+ end
132
+ 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.info "scan_glob: 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
 
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.6
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-03-30 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