Class: MIQExtract
- Inherits:
-
Object
- Object
- MIQExtract
- Defined in:
- lib/metadata/MIQExtract/MIQExtract.rb
Instance Attribute Summary collapse
-
#systemFs ⇒ Object
readonly
Returns the value of attribute systemFs.
-
#systemFsMsg ⇒ Object
readonly
Returns the value of attribute systemFsMsg.
-
#vm ⇒ Object
readonly
Returns the value of attribute vm.
Instance Method Summary collapse
- #categories ⇒ Object
- #close ⇒ Object
- #extract(category, &blk) ⇒ Object
- #getAccounts(c) ⇒ Object
- #getBaseConfigName ⇒ Object
- #getEventLogs(_c) ⇒ Object
- #getProfileData(&blk) ⇒ Object
- #getServices(c) ⇒ Object
- #getSoftware(c) ⇒ Object
- #getSystem(c) ⇒ Object
- #getVMConfig(_c) ⇒ Object
-
#initialize(filename, ost = nil) ⇒ MIQExtract
constructor
TODO: Always pass in MiqVm.
- #scanMD5deep ⇒ Object
- #split_registry(path) ⇒ Object
- #xml_doc_node(category) ⇒ Object
Constructor Details
#initialize(filename, ost = nil) ⇒ MIQExtract
TODO: Always pass in MiqVm
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 24 def initialize(filename, ost = nil) # TODO: Always pass in MiqVm ost ||= OpenStruct.new @ost = ost @dataDir = ost.config.try(:dataDir) ost.scanData = {} if ost.scanData.nil? @xml_class = ost.xml_class.nil? ? XmlHash::Document : ost.xml_class # TODO: Should all be subclasses of MiqVm. # Going forward, we should only pass in an MiqVm - so the "else" will be removed. if filename.respond_to?(:rootTrees) @externalMount = true @target = filename @configFile = filename.respond_to?(:vmConfigFile) ? @target.vmConfigFile : nil $log.info "MIQExtract using config file: [#{@configFile}] settings: [#{ManageIQ::Password.sanitize_string(ost.scanData.inspect)}]" else @externalMount = false @configFile = filename.gsub(/^"/, "").gsub(/"$/, "") $log.info "MIQExtract using config file: [#{@configFile}] settings: [#{ManageIQ::Password.sanitize_string(ost.scanData.inspect)}]" ost.openParent = true if ost.scanData.fetch_path('snapshot', 'use_existing') == true ost.force = false if ost.scanData.fetch_path('snapshot', 'forceFleeceDefault') == false ost.snapshotDescription = ost.scanData.fetch_path('snapshot', 'description') if ost.scanData.fetch_path('snapshot', 'description') ost.snapshot_create_free_space = ost.scanData.fetch_path('snapshot', 'create_free_percent') || 100 ost.snapshot_remove_free_space = ost.scanData.fetch_path('snapshot', 'remove_free_percent') || 100 @target = MiqVm.new(@configFile, ost) end # Set the system fs handle begin st = Time.now $log.info "Loading disk files for VM [#{@configFile}]" @systemFs = @target.rootTrees[0] if @systemFs.nil? raise MiqException::MiqVmMountError, "No root filesystem found." if @target.diskInitErrors.empty? err_msg = '' @target.diskInitErrors.each do |disk, err| err = "#{err} - #{disk}" unless err.include?(disk) err_msg += "#{err}\n" end raise err_msg.chomp end @systemFsMsg = "OS:[#{@systemFs.guestOS}] found on VM [#{@configFile}]. Loaded in [#{Time.now - st}] seconds" $log.info @systemFsMsg rescue => err @systemFsMsg = "Unable to mount filesystem. Reason:[#{err}]" $log.error "#{@systemFsMsg} for VM [#{@configFile}]" log_level = err.kind_of?(MiqException::Error) ? :debug : :error err.backtrace.each { |bt| $log.send(log_level, "MIQExtract.new #{bt}") } close end # Load Scan Profiles @scanProfiles = VmScanProfiles.new(ost.scanData['vmScanProfiles'], VmScanProfiles::SCAN_ITEM_CATEGORIES => ost.category, :xml_class => @xml_class) end |
Instance Attribute Details
#systemFs ⇒ Object (readonly)
Returns the value of attribute systemFs.
22 23 24 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 22 def systemFs @systemFs end |
#systemFsMsg ⇒ Object (readonly)
Returns the value of attribute systemFsMsg.
22 23 24 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 22 def systemFsMsg @systemFsMsg end |
#vm ⇒ Object (readonly)
Returns the value of attribute vm.
22 23 24 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 22 def vm @vm end |
Instance Method Details
#categories ⇒ Object
82 83 84 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 82 def categories @scanProfiles.get_categories end |
#close ⇒ Object
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 277 def close return if @externalMount # Call Unmount command if drive was succesfully mounted unless @target.nil? $log.debug "Unmounting..." begin @target.unmount $log.debug "Unmounting complete" rescue => err $log.error "Error during disk unmounting for VM:[#{@configFile}]" $log.debug err.backtrace.join("\n") ensure @ost.miqVim.disconnect if @ost.miqVim unmount_storage(@mount) unless @mount.blank? (:reset) end end end |
#extract(category, &blk) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 127 def extract(category, &blk) xml = nil Array.wrap(category.presence).each do |c| c = c.downcase xml = case c when "accounts" then getAccounts(c) when "services" then getServices(c) when "software" then getSoftware(c) when "system" then getSystem(c) when "ntevents" then getEventLogs(c) when "vmconfig" then getVMConfig(c) # vmEvents are added to the blackbox externally, not extracted from the vm disks. when "vmevents" then return nil when "profiles" then getProfileData(&blk) else $log.warn "Warning: Category not processed [#{c}]" nil end # Write XML to data directory for debugging # File.open(File.join(@dataDir, "scan_#{c}.xml"),"w") {|f| xml.write(f,0)} if xml rescue nil end rescue => err $log.error "MIQExtract.extract #{err}" log_level = err.kind_of?(MiqException::Error) ? :debug : :error err.backtrace.each { |bt| $log.send(log_level, "MIQExtract.extract #{bt}") } raise err ensure return xml end |
#getAccounts(c) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 194 def getAccounts(c) return if @systemFs.nil? doc, node = xml_doc_node(:accounts) # doc.root.attributes["xsi:schemaLocation"] += " accounts.xsd" case @systemFs.guestOS when "Windows" MiqWin32::Accounts.new(c, @systemFs).to_xml(node) when "Linux" MiqLinux::Users.new(@systemFs).to_xml(node) end doc end |
#getBaseConfigName ⇒ Object
273 274 275 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 273 def getBaseConfigName File.join(File.dirname(@configFile), File.basename(@configFile, ".*")) end |
#getEventLogs(_c) ⇒ Object
259 260 261 262 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 259 def getEventLogs(_c) ntevent = Win32EventLog.new(@systemFs) ntevent.readAllLogs(Win32EventLog::SYSTEM_LOGS) end |
#getProfileData(&blk) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 91 def getProfileData(&blk) # First check for registry keys if @systemFs.guestOS == "Windows" reg_filters = @scanProfiles.get_registry_filters if reg_filters st = Time.now $log.info "Scanning [Profile-Registry] information." yield({:msg => 'Scanning Profile-Registry'}) if block_given? filters = [] Array.wrap(reg_filters[:HKCU]).each { |f| filters << {:key => split_registry(f['key']).join('/'), :depth => f['depth']} } @scanProfiles.parse_data(@target, RemoteRegistry.new(@systemFs, @xml_class).loadCurrentUser(filters)) unless filters.empty? filters = {} reg_filters[:HKLM].each do |f| hive, path = split_registry(f["key"]) filters[hive.downcase] = [] if filters[hive.downcase].nil? filters[hive.downcase] << path end unless reg_filters[:HKLM].nil? filters.each_pair do |k, v| regHnd = RemoteRegistry.new(@systemFs, @xml_class) xml = regHnd.loadHive(k, v) @scanProfiles.parse_data(@target, xml) end unless filters.empty? $log.info "Scanning [Profile-Registry] information ran for [#{Time.now - st}] seconds." end end # Pass in the MiqVm handle to do file parsing @scanProfiles.parse_data(@target, nil, &blk) @scanProfiles.to_xml end |
#getServices(c) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 210 def getServices(c) return if @systemFs.nil? doc, node = xml_doc_node(:services) # doc.root.attributes["xsi:schemaLocation"] += " services.xsd" case @systemFs.guestOS when "Windows" MiqWin32::Services.new(c, @systemFs).to_xml(node) when "Linux" MiqLinux::Systemd.new(@systemFs).toXml(node) if MiqLinux::Systemd.detected?(@systemFs) MiqLinux::InitProcs.new(@systemFs).toXml(node) end doc end |
#getSoftware(c) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 243 def getSoftware(c) return if @systemFs.nil? doc, node = xml_doc_node(:software) # doc.root.attributes["xsi:schemaLocation"] += " software.xsd" case @systemFs.guestOS when "Windows" MiqWin32::Software.new(c, @systemFs).to_xml(node) when "Linux" MiqLinux::Packages.new(@systemFs).toXml(node) end doc end |
#getSystem(c) ⇒ Object
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 227 def getSystem(c) return if @systemFs.nil? doc, node = xml_doc_node(:system) # doc.root.attributes["xsi:schemaLocation"] += " system.xsd" case @systemFs.guestOS when "Windows" MiqWin32::System.new(c, @systemFs).to_xml(node) when "Linux" MiqLinux::OSInfo.new(@systemFs).toXml(node) end doc end |
#getVMConfig(_c) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 158 def getVMConfig(_c) # Get VM config in XML format config_xml = @target.vmConfig.toXML(true, @target) begin # Log snapshot data for diagnostic purposes config_xml.find_each("//vm/snapshots") do |s| formattedXml = "" s.write(formattedXml, 0) # Dump the formated snapshot xml section formattedXml.split("\n").each { |l| $log.debug l } # Log the high level snapshot details $log.info "Snapshot overview: Count:[#{s.attributes['numsnapshots']}] Current:[#{s.attributes['current']}]" # Log each child snapshot element s.find_each("child::snapshot") { |ss| $log.info "Snapshot details: id:[#{ss.attributes['uid']}] Name:[#{ss.attributes['displayname']}]" } end rescue # => e # $log.error e end if config_xml.class != @xml_class config_xml = @xml_class.load(config_xml.to_s) end config_xml end |
#scanMD5deep ⇒ Object
264 265 266 267 268 269 270 271 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 264 def scanMD5deep # Produce file system XML with MD5 info $log.debug "Starting Filesystem scan" # scanPath = "c:/program files" scanPath = "c:/program files/Java/jdk1.5.0_12/jre/lib" md5 = MD5deep.new(@systemFs, 'versioninfo' => true, 'imports' => true) md5.scan(scanPath, scanPath) end |
#split_registry(path) ⇒ Object
86 87 88 89 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 86 def split_registry(path) y = path.tr("\\", "/").split("/") return y[0].downcase, y[1..-1].join("/") end |
#xml_doc_node(category) ⇒ Object
188 189 190 191 192 |
# File 'lib/metadata/MIQExtract/MIQExtract.rb', line 188 def xml_doc_node(category) doc = @xml_class.createDoc(:miq) node = doc.root.add_element(category) return doc, node end |