diff options
author | Phil Dibowitz <phild@fb.com> | 2015-06-24 04:56:40 -0700 |
---|---|---|
committer | Phil Dibowitz <phild@fb.com> | 2015-06-24 04:57:40 -0700 |
commit | 27efdab791d59d239007f1dea9cbd4a75c27dfda (patch) | |
tree | e4ad18836280b138f40a6898d35719d4999066a1 | |
parent | 132eef525ccf62bbd639e89d9e44094d0e13a2bc (diff) | |
download | ohai-27efdab791d59d239007f1dea9cbd4a75c27dfda.tar.gz |
Port new filesystem2 plugin to darwin.
This is just a port of #559 to Darwin. See that PR for the details.
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 3 | ||||
-rw-r--r-- | lib/ohai/plugins/darwin/filesystem2.rb | 103 | ||||
-rw-r--r-- | spec/unit/plugins/darwin/filesystem2_spec.rb | 96 |
4 files changed, 202 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ac7e68c6..96c6acd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased * [**Phil Dibowitz**](https://github.com/jymzh): - Provide a new and improved filesystem plugin for Linux (filesystem2), to + Provide a new and improved filesystem plugin for Linux & Mac (filesystem2), to support CentOS7, multiple virtual filesystes, etc. * [**Jonathan Amiez**](https://github.com/josqu4red): Linux filesystems plugin report wrong fs-type for logical volumes diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 137685d6..70008289 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -27,7 +27,8 @@ populate the old system (role & system) with LXC if there are no other virtualiz ### Filesystem2 -There is a new plugin for filesystems in Linux. It solves several problems: +There is a new plugin for filesystems in Linux & Darwin. It solves several +problems: * Can handle multiple virtual FSes with the same "device" (eg, 'none') * Can handle a device mounted multiple places * Is resilient to mtab being a symlink to /proc/mounts diff --git a/lib/ohai/plugins/darwin/filesystem2.rb b/lib/ohai/plugins/darwin/filesystem2.rb new file mode 100644 index 00000000..040e8c4d --- /dev/null +++ b/lib/ohai/plugins/darwin/filesystem2.rb @@ -0,0 +1,103 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +Ohai.plugin(:Filesystem2) do + provides "filesystem2" + + def generate_device_view(fs) + view = {} + fs.each_value do |entry| + view[entry[:device]] = Mash.new unless view[entry[:device]] + entry.each do |key, val| + next if ['device', 'mount'].include?(key) + view[entry[:device]][key] = val + end + if entry[:mount] + view[entry[:device]][:mounts] = [] unless view[entry[:device]][:mounts] + view[entry[:device]][:mounts] << entry[:mount] + end + end + view + end + + def generate_mountpoint_view(fs) + view = {} + fs.each_value do |entry| + next unless entry[:mount] + view[entry[:mount]] = Mash.new unless view[entry[:mount]] + entry.each do |key, val| + next if key == 'mount' + view[entry[:mount]][key] = val + end + end + view + end + + collect_data(:darwin) do + fs = Mash.new + + + block_size = 0 + # on new versions of OSX, -i is default, on old versions it's not, so + # specifying it gets consistent output + so = shell_out("df -i") + so.stdout.each_line do |line| + case line + when /^Filesystem\s+(\d+)-/ + block_size = $1.to_i + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(.+)$/ + key = "#{$1},#{$9}" + fs[key] = Mash.new + fs[key][:block_size] = block_size + fs[key][:device] = $1 + fs[key][:kb_size] = ($2.to_i / (1024 / block_size)).to_s + fs[key][:kb_used] = ($3.to_i / (1024 / block_size)).to_s + fs[key][:kb_available] = ($4.to_i / (1024 / block_size)).to_s + fs[key][:percent_used] = $5 + fs[key][:inodes_used] = $6 + fs[key][:inodes_available] = $7 + fs[key][:total_inodes] = ($6.to_i + $7.to_i).to_s + fs[key][:inodes_percent_used] = $8 + fs[key][:mount] = $9 + end + end + + so = shell_out("mount") + so.stdout.lines do |line| + if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ + key = "#{$1},#{$2}" + fs[key] = Mash.new unless fs.has_key?(key) + fs[key][:mount] = $2 + fs[key][:fs_type] = $3 + fs[key][:mount_options] = $4.split(/,\s*/) + end + end + + by_pair = fs + by_device = generate_device_view(fs) + by_mountpoint = generate_mountpoint_view(fs) + + fs2 = Mash.new + fs2['by_device'] = by_device + fs2['by_mountpoint'] = by_mountpoint + fs2['by_pair'] = by_pair + + filesystem2 fs2 + end +end diff --git a/spec/unit/plugins/darwin/filesystem2_spec.rb b/spec/unit/plugins/darwin/filesystem2_spec.rb new file mode 100644 index 00000000..85e44de1 --- /dev/null +++ b/spec/unit/plugins/darwin/filesystem2_spec.rb @@ -0,0 +1,96 @@ +# +# Author:: Phil Dibowitz (<phil@ipom.com>) +# Copyright:: Copyright (c) 2015 Facebook, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper.rb') + +describe Ohai::System, "darwin filesystem2 plugin" do + before(:each) do + @plugin = get_plugin("darwin/filesystem2") + allow(@plugin).to receive(:collect_os).and_return(:darwin) + + allow(@plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, "", "")) + allow(@plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, "", "")) + end + + describe "when gathering filesystem usage data from df" do + before(:each) do + @stdout = <<-DF +Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on +/dev/disk0s2 488555536 313696448 174347088 65% 39276054 21793386 64% / +devfs 385 385 0 100% 666 0 100% /dev +map /etc/auto.direct 0 0 0 100% 0 0 100% /mnt/vol +map -hosts 0 0 0 100% 0 0 100% /net +map -static 0 0 0 100% 0 0 100% /mobile_symbol +deweyfs@osxfuse0 0 0 0 100% 0 0 100% /mnt/dewey +DF + allow(@plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, @stdout, "")) + end + + it "should run df -i" do + expect(@plugin).to receive(:shell_out).ordered.with("df -i").and_return(mock_shell_out(0, @stdout, "")) + @plugin.run + end + + it "should set size to value from df -i" do + @plugin.run + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:kb_size]).to eq("244277768") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:kb_used]).to eq("156848224") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:kb_available]).to eq("87173544") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:percent_used]).to eq("65%") + end + + it "should set device and mount to value from df -i" do + @plugin.run + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:mount]).to eq("/") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:device]).to eq("/dev/disk0s2") + end + + it "should set inode info to value from df -i" do + @plugin.run + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:total_inodes]).to eq("61069440") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:inodes_used]).to eq("39276054") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:inodes_available]).to eq("21793386") + end + end + + describe "when gathering mounted filesystem data from mount" do + before(:each) do + @stdout = <<-MOUNT +/dev/disk0s2 on / (hfs, local, journaled) +devfs on /dev (devfs, local, nobrowse) +map /etc/auto.direct on /mnt/vol (autofs, automounted, nobrowse) +map -hosts on /net (autofs, nosuid, automounted, nobrowse) +map -static on /mobile_symbol (autofs, automounted, nobrowse) +deweyfs@osxfuse0 on /mnt/dewey (osxfusefs, synchronous, nobrowse) +MOUNT + allow(@plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) + end + + it "should run mount" do + expect(@plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) + @plugin.run + end + + it "should set values from mount" do + @plugin.run + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:mount]).to eq("/") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:fs_type]).to eq("hfs") + expect(@plugin[:filesystem2]["by_pair"]["/dev/disk0s2,/"][:mount_options]).to eq([ "local", "journaled" ]) + end + end +end |