Skip to content

Commit

Permalink
[filesystem] Convert windows to filesystem2
Browse files Browse the repository at this point in the history
[based on top of chef#1266 - will rebase after that is merged]

Windows doesn't follow quite the same paradigms as Unix, but there's
enough in common that we can still map most things.

The tests don't pass here, yet, and I'm not quite sure why. In some test
logical_properties is returning an array but I don't see how that's
possible. :/

Signed-off-by: Phil Dibowitz <[email protected]>
  • Loading branch information
jaymzh committed Oct 10, 2018
1 parent 8a82f74 commit 0e01a28
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 152 deletions.
154 changes: 154 additions & 0 deletions lib/ohai/plugins/filesystem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -589,4 +589,158 @@ def collect_old_version(shell_outs)
filesystem generate_deprecated_view(fs)
filesystem2 fs_data
end

collect_data(:windows) do
require "wmi-lite/wmi"

# Volume encryption or decryption status
#
# @see https://docs.microsoft.com/en-us/windows/desktop/SecProv/getconversionstatus-win32-encryptablevolume#parameters
#
CONVERSION_STATUS = %w{FullyDecrypted FullyEncrypted EncryptionInProgress
DecryptionInProgress EncryptionPaused DecryptionPaused}.freeze

# Returns a Mash loaded with logical details
#
# Uses Win32_LogicalDisk and logical_properties to return encryption details of volumes.
#
# Returns an empty Mash in case of any WMI exception.
#
# @see https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-logicaldisk
#
# @return [Mash]
#
def logical_info
wmi = WmiLite::Wmi.new("Root\\CIMV2")

# Note: we should really be parsing Win32_Volume and Win32_Mapped drive.
disks = wmi.instances_of("Win32_LogicalDisk")
logical_properties(disks)
rescue WmiLite::WmiException
Ohai::Log.debug("Unable to access Win32_LogicalDisk. Skipping logical details")
Mash.new
end

# Returns a Mash loaded with encryption details
#
# Uses Win32_EncryptableVolume and encryption_properties to return encryption details of volumes.
#
# Returns an empty Mash in case of any WMI exception.
#
# @note We are fetching Encryption Status only as of now
#
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx
#
# @return [Mash]
#
def encryptable_info
wmi = WmiLite::Wmi.new("Root\\CIMV2\\Security\\MicrosoftVolumeEncryption")
disks = wmi.instances_of("Win32_EncryptableVolume")
encryption_properties(disks)
rescue WmiLite::WmiException
Ohai::Log.debug("Unable to access Win32_EncryptableVolume. Skipping encryptable details")
Mash.new
end

# Refines and calculates logical properties out of given instances
#
# @param [WmiLite::Wmi::Instance] disks
#
# @return [Mash] Each drive containing following properties:
#
# * :kb_size (Integer)
# * :kb_available (Integer)
# * :kb_used (Integer)
# * :percent_used (Integer)
# * :mount (String)
# * :fs_type (String)
# * :volume_name (String)
#
def logical_properties(disks)
properties = Mash.new
disks.each do |disk|
property = Mash.new
# In windows the closet thing we have to a device is the volumename
# and the "mountpoint" is the drive letter...
device = disk["volumename"].to_s.downcase
mount = disk["deviceid"]
property[:kb_size] = disk["size"].to_i / 1000
property[:kb_available] = disk["freespace"].to_i / 1000
property[:kb_used] = property[:kb_size] - property[:kb_available]
property[:percent_used] = (property[:kb_size] == 0 ? 0 : (property[:kb_used] * 100 / property[:kb_size]))
property[:mount] = mount
property[:fs_type] = disk["filesystem"].to_s.downcase
property[:volume_name] = device
property[:device] = device

key = "#{device},#{mount}"
properties[key] = property
end
properties
end

# Refines and calculates encryption properties out of given instances
#
# @param [WmiLite::Wmi::Instance] disks
#
# @return [Mash] Each drive containing following properties:
#
# * :encryption_status (String)
#
def encryption_properties(disks)
properties = Mash.new
puts "PHILD: EP disks: #{disks}"
disks.each do |disk|
mount = disk["driveletter"]
property = Mash.new
property[:encryption_status] = disk["conversionstatus"] ? CONVERSION_STATUS[disk["conversionstatus"]] : ""
properties[mount] = property
end
properties
end

# Merges all the various properties of filesystems
#
# @param [Mash] logical_info
# Mash by pair
#
# @param [Mash] encryption
# Mashe by mountpoint (driveletter)
#
# @return [Mash]
#
def merge_info(logical, encryption)
fs = logical.dup

puts "PHILD: l: #{logical}"
puts "PHILD: e: #{encryption}"
logical.each do |key, info|
mount = info['mount']
if encryption[info['mount']]
einfo = encryption[info['mount']]
puts "PHILD: Got einfo #{einfo} for #{info['mount']}"
einfo.each do |k, v|
fs[key][k] ||= v
end
end
end
fs
end

fs = merge_info(logical_info, encryptable_info)

by_pair = fs
by_device = generate_device_view(fs)
by_mountpoint = generate_mountpoint_view(fs)

fs_data = Mash.new
fs_data["by_device"] = by_device
fs_data["by_mountpoint"] = by_mountpoint
fs_data["by_pair"] = by_pair

# Set the filesystem data - Windows didn't do the conversion when everyone
# else did, so 15 will have both be the new API and 16 will drop the old API
filesystem generate_deprecated_view(fs)
filesystem2 fs_data
end
end
147 changes: 0 additions & 147 deletions lib/ohai/plugins/windows/filesystem.rb

This file was deleted.

10 changes: 5 additions & 5 deletions spec/unit/plugins/windows/filesystem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
require "wmi-lite/wmi"

describe Ohai::System, "Windows Filesystem Plugin", :windows_only do
let(:plugin) { get_plugin("windows/filesystem") }
let(:plugin) { get_plugin("filesystem") }

let(:success) { true }

Expand Down Expand Up @@ -195,12 +195,12 @@

describe "#merge_info" do
let(:info1) do
{ "drive1" => { "x" => 10, "y" => "test1" },
"drive2" => { "x" => 20, "z" => "test2" } }
{ "drive1,C:" => { "x" => 10, "y" => "test1", "mount" => "C:" },
"drive2,D:" => { "x" => 20, "z" => "test2", "mount" => "D:" } }
end
let(:info2) do
{ "drive1" => { "k" => 10, "l" => "test1" },
"drive2" => { "l" => 20, "m" => "test2" } }
{ "C:" => { "k" => 10, "l" => "test1" },
"D:" => { "l" => 20, "m" => "test2" } }
end
let(:info3) { { "drive1" => { "o" => 10, "p" => "test1" } } }
let(:info4) { { "drive2" => { "q" => 10, "r" => "test1" } } }
Expand Down

0 comments on commit 0e01a28

Please sign in to comment.