diff options
| author | Rein Henrichs <reinh@reinh.com> | 2010-08-02 17:28:45 -0700 |
|---|---|---|
| committer | Rein Henrichs <reinh@reinh.com> | 2010-08-03 14:59:29 -0700 |
| commit | a2bcacdc54fc9e9446bd5b084e70d60aaaeeebd2 (patch) | |
| tree | 45cb11ad615785f496cadb2b057a0a2c743a75e0 /lib | |
| parent | 1bd2ca29d8fd7d11e75096ceeeb704fe887cad31 (diff) | |
| download | facter-a2bcacdc54fc9e9446bd5b084e70d60aaaeeebd2.tar.gz facter-a2bcacdc54fc9e9446bd5b084e70d60aaaeeebd2.tar.xz facter-a2bcacdc54fc9e9446bd5b084e70d60aaaeeebd2.zip | |
[#2330] Uptime should not make redundant system calls
Rewrite of uptime facts and supporting utility methods. Works on unix,
BSD, windows. No longer makes redundant system calls.
Uses Facter::Util::Uptime utility methods:
* Implemented uptime_seconds_unix using /proc/uptime or who -b on unix,
sysctl on BSD.
Added unit tests for the behaviors of get_uptime_seconds_unix: read
from proc/uptime, read uptime from "sysctl -b kern.boottime", read
uptime from "who -b", and return nil if nothing else works.
* Implemented uptime_seconds_win using the Win32 API.
Facts implemented:
* uptime_{seconds,hours,days}
Returns the respective integer value.
* uptime
Returns human readable uptime statistic that preserves original
behavior.
Examples:
3 days
1 day
5:08 hours
0:35 hours
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/facter/uptime.rb | 31 | ||||
| -rw-r--r-- | lib/facter/uptime_days.rb | 7 | ||||
| -rw-r--r-- | lib/facter/uptime_hours.rb | 7 | ||||
| -rw-r--r-- | lib/facter/uptime_seconds.rb | 10 | ||||
| -rw-r--r-- | lib/facter/util/uptime.rb | 66 |
5 files changed, 84 insertions, 37 deletions
diff --git a/lib/facter/uptime.rb b/lib/facter/uptime.rb index 3a3bc86..56a959b 100644 --- a/lib/facter/uptime.rb +++ b/lib/facter/uptime.rb @@ -1,20 +1,23 @@ require 'facter/util/uptime' Facter.add(:uptime) do - confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE SLES Debian Ubuntu Gentoo AIX} - setcode do - Facter::Util::Uptime.get_uptime_simple - end -end + setcode do + seconds = Facter.fact(:uptime_seconds).value -if FileTest.exists?("/proc/uptime") - uptime = Facter::Util::Uptime.get_uptime + unless seconds + "unknown" + else + days = seconds / (60 * 60 * 24) + hours = seconds / (60 * 60) % 24 + minutes = seconds / 60 % 60 - %w{days hours seconds}.each do |label| - Facter.add("uptime_" + label) do - setcode do - Facter::Util::Uptime.get_uptime_period(uptime, label) - end - end - end + case days + when 0 then "#{hours}:#{"%02d" % minutes} hours" + when 1 then '1 day' + else "#{days} days" + end + end + + end end + diff --git a/lib/facter/uptime_days.rb b/lib/facter/uptime_days.rb new file mode 100644 index 0000000..add305c --- /dev/null +++ b/lib/facter/uptime_days.rb @@ -0,0 +1,7 @@ +Facter.add(:uptime_days) do + setcode do + hours = Facter.value(:uptime_hours) + hours && hours / 24 # hours in day + end +end + diff --git a/lib/facter/uptime_hours.rb b/lib/facter/uptime_hours.rb new file mode 100644 index 0000000..ce691d2 --- /dev/null +++ b/lib/facter/uptime_hours.rb @@ -0,0 +1,7 @@ +Facter.add(:uptime_hours) do + setcode do + seconds = Facter.value(:uptime_seconds) + seconds && seconds / (60 * 60) # seconds in hour + end +end + diff --git a/lib/facter/uptime_seconds.rb b/lib/facter/uptime_seconds.rb new file mode 100644 index 0000000..14bb573 --- /dev/null +++ b/lib/facter/uptime_seconds.rb @@ -0,0 +1,10 @@ +require 'facter/util/uptime' + +Facter.add(:uptime_seconds) do + setcode { Facter::Util::Uptime.get_uptime_seconds_unix } +end + +Facter.add(:uptime_seconds) do + confine :kernel => :windows + setcode { Facter::Util::Uptime.get_uptime_seconds_win } +end diff --git a/lib/facter/util/uptime.rb b/lib/facter/util/uptime.rb index c1e339b..f8a17db 100644 --- a/lib/facter/util/uptime.rb +++ b/lib/facter/util/uptime.rb @@ -1,32 +1,52 @@ +require 'time' + # A module to gather uptime facts # module Facter::Util::Uptime - def self.get_uptime_simple - time = Facter::Util::Resolution.exec('uptime') - if time =~ /up\s*(\d+\s\w+)/ - $1 - elsif time =~ /up\s*(\d+:\d+)/ - $1 + " hours" - else - "unknown" + def self.get_uptime_seconds_unix + uptime_proc_uptime or uptime_sysctl or uptime_who_dash_b + end + + def self.get_uptime_seconds_win + require 'Win32API' + getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L') + compute_uptime(Time.at(getTickCount.call() / 1000.0)) + end + + private + + def self.uptime_proc_uptime + if File.exists? uptime_file + r = File.read uptime_file + r.split(" ").first.to_i + end + end + + def self.uptime_sysctl + if (output = `#{uptime_sysctl_cmd}`) and $?.success? + compute_uptime(Time.at(output.unpack('L').first)) + end + end + + def self.uptime_who_dash_b + if (output = `#{uptime_who_cmd}`) and $?.success? + compute_uptime(Time.parse(output)) end end - def self.get_uptime - r = IO.popen("/bin/cat /proc/uptime") - uptime, idletime = r.readline.split(" ") - r.close - uptime_seconds = uptime.to_i + def self.compute_uptime(time) + (Time.now - time).to_i + end + + def self.uptime_file + "/proc/uptime" + end + + def self.uptime_sysctl_cmd + 'sysctl -b kern.boottime 2>/dev/null' end - def self.get_uptime_period(seconds, label) - case label - when 'days' - value = seconds / 86400 - when 'hours' - value = seconds / 3600 - when 'seconds' - seconds - end + def self.uptime_who_cmd + 'who -b 2>/dev/null' end -end +end |
