ohai 8.11.1 → 8.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ohai/loader.rb +7 -1
- data/lib/ohai/mixin/dmi_decode.rb +3 -3
- data/lib/ohai/mixin/gce_metadata.rb +16 -8
- data/lib/ohai/plugins/bsd/virtualization.rb +47 -2
- data/lib/ohai/plugins/linux/sessions.rb +54 -0
- data/lib/ohai/plugins/linux/virtualization.rb +27 -15
- data/lib/ohai/plugins/solaris2/virtualization.rb +20 -21
- data/lib/ohai/plugins/virtualization.rb +5 -12
- data/lib/ohai/util/file_helper.rb +5 -1
- data/lib/ohai/version.rb +1 -1
- data/spec/unit/plugins/bsd/virtualization_spec.rb +54 -2
- data/spec/unit/plugins/gce_spec.rb +8 -7
- data/spec/unit/plugins/linux/sessions_spec.rb +98 -0
- data/spec/unit/plugins/linux/virtualization_spec.rb +28 -3
- data/spec/unit/plugins/solaris2/virtualization_spec.rb +10 -8
- data/spec/unit/util/file_helper_spec.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8f9860cc79310cfd97f6ede9093b0eb6f76b088
|
4
|
+
data.tar.gz: 5c992abbc0cb9f4d189dfd904e5dfd52d3a6d343
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 608a4e76cd1ec82e2b45e0d76cd0a39ff15dbc9034b341132917109a10e92336c8139d00841c02eb1a1da24fe33bed73296590b34bbb4f90458fccd6c0fc9742
|
7
|
+
data.tar.gz: 6b7ac1da8c6dc7ddc6e5bcd81e049128201191f612cbbd0230790a930455944438ef2c96b356ab9ceb199a7b49ca74979cc02071299751ae4313ae70f974a354
|
data/lib/ohai/loader.rb
CHANGED
@@ -39,7 +39,13 @@ module Ohai
|
|
39
39
|
|
40
40
|
# Finds all the *.rb files under the configured paths in :plugin_path
|
41
41
|
def self.find_all_in(plugin_dir)
|
42
|
-
|
42
|
+
# escape_glob_dir does not exist in 12.7 or below
|
43
|
+
if ChefConfig::PathHelper.respond_to?(:escape_glob_dir)
|
44
|
+
escaped = ChefConfig::PathHelper.escape_glob_dir(plugin_dir)
|
45
|
+
else
|
46
|
+
escaped = ChefConfig::PathHelper.escape_glob(plugin_dir)
|
47
|
+
end
|
48
|
+
Dir[File.join(escaped, "**", "*.rb")].map do |file|
|
43
49
|
new(file, plugin_dir)
|
44
50
|
end
|
45
51
|
end
|
@@ -21,7 +21,7 @@ module ::Ohai::Mixin::DmiDecode
|
|
21
21
|
dmi_data.each_line do |line|
|
22
22
|
case line
|
23
23
|
when /Manufacturer: Microsoft/
|
24
|
-
if dmi_data =~ /Product
|
24
|
+
if dmi_data =~ /Product.*: Virtual Machine/
|
25
25
|
if dmi_data =~ /Version: (7.0|Hyper-V)/
|
26
26
|
return "hyperv"
|
27
27
|
elsif dmi_data =~ /Version: (VS2005R2|6.0)/
|
@@ -34,9 +34,9 @@ module ::Ohai::Mixin::DmiDecode
|
|
34
34
|
return "vmware"
|
35
35
|
when /Manufacturer: Xen/
|
36
36
|
return "xen"
|
37
|
-
when /Product
|
37
|
+
when /Product.*: VirtualBox/
|
38
38
|
return "vbox"
|
39
|
-
when /Product
|
39
|
+
when /Product.*: OpenStack/
|
40
40
|
return "openstack"
|
41
41
|
when /Manufacturer: QEMU|Product Name: (KVM|RHEV)/
|
42
42
|
return "kvm"
|
@@ -23,11 +23,17 @@ module Ohai
|
|
23
23
|
|
24
24
|
# Trailing dot to host is added to avoid DNS search path
|
25
25
|
GCE_METADATA_ADDR = "metadata.google.internal." unless defined?(GCE_METADATA_ADDR)
|
26
|
-
GCE_METADATA_URL = "/computeMetadata/
|
26
|
+
GCE_METADATA_URL = "/computeMetadata/v1/?recursive=true" unless defined?(GCE_METADATA_URL)
|
27
27
|
|
28
28
|
def can_metadata_connect?(addr, port, timeout = 2)
|
29
29
|
t = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
|
30
|
-
|
30
|
+
begin
|
31
|
+
saddr = Socket.pack_sockaddr_in(port, addr)
|
32
|
+
rescue SocketError => e # occurs when non-GCE systems try to resolve metadata.google.internal
|
33
|
+
Ohai::Log.debug("gce mixin: can_metadata_connect? failed setting up socket: #{e}")
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
|
31
37
|
connected = false
|
32
38
|
|
33
39
|
begin
|
@@ -47,24 +53,26 @@ module Ohai
|
|
47
53
|
end
|
48
54
|
rescue SystemCallError
|
49
55
|
end
|
50
|
-
Ohai::Log.debug("can_metadata_connect? == #{connected}")
|
56
|
+
Ohai::Log.debug("gce mixin: can_metadata_connect? == #{connected}")
|
51
57
|
connected
|
52
58
|
end
|
53
59
|
|
54
|
-
|
55
|
-
|
60
|
+
# fetch the meta content with a timeout and the required header
|
61
|
+
def http_get(uri)
|
62
|
+
conn = Net::HTTP.start(GCE_METADATA_ADDR)
|
63
|
+
conn.read_timeout = 6
|
64
|
+
conn.get(uri, initheader = { "Metadata-Flavor" => "Google" })
|
56
65
|
end
|
57
66
|
|
58
67
|
def fetch_metadata(id = "")
|
59
|
-
|
60
|
-
response = http_client.get(uri)
|
68
|
+
response = http_get("#{GCE_METADATA_URL}/#{id}")
|
61
69
|
return nil unless response.code == "200"
|
62
70
|
|
63
71
|
if json?(response.body)
|
64
72
|
data = StringIO.new(response.body)
|
65
73
|
parser = FFI_Yajl::Parser.new
|
66
74
|
parser.parse(data)
|
67
|
-
elsif has_trailing_slash?(id)
|
75
|
+
elsif has_trailing_slash?(id) || (id == "")
|
68
76
|
temp = {}
|
69
77
|
response.body.split("\n").each do |sub_attr|
|
70
78
|
temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}#{sub_attr}")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Bryan McLellan (btm@loftninjas.org)
|
3
3
|
# Copyright:: Copyright (c) 2009 Bryan McLellan
|
4
|
+
# Copyright:: Copyright (c) 2015-2016 Chef Software, Inc.
|
4
5
|
# License:: Apache License, Version 2.0
|
5
6
|
#
|
6
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -34,13 +35,18 @@ Ohai.plugin(:Virtualization) do
|
|
34
35
|
virtualization[:system] = "jail"
|
35
36
|
virtualization[:role] = "guest"
|
36
37
|
virtualization[:systems][:jail] = "guest"
|
38
|
+
Ohai::Log.debug("Virtualization plugin: Guest running in FreeBSD jail detected")
|
37
39
|
end
|
38
40
|
|
39
|
-
|
41
|
+
# run jls to get a list of running jails
|
42
|
+
# -n: name=value 1 line per jail format
|
43
|
+
# -d: list the dying jails as well as active jails
|
44
|
+
so = shell_out("jls -nd")
|
40
45
|
if (so.stdout || "").lines.count >= 1
|
41
46
|
virtualization[:system] = "jail"
|
42
47
|
virtualization[:role] = "host"
|
43
48
|
virtualization[:systems][:jail] = "host"
|
49
|
+
Ohai::Log.debug("Virtualization plugin: Host running FreeBSD jails detected")
|
44
50
|
end
|
45
51
|
|
46
52
|
# detect from modules
|
@@ -51,20 +57,58 @@ Ohai.plugin(:Virtualization) do
|
|
51
57
|
virtualization[:system] = "vbox"
|
52
58
|
virtualization[:role] = "host"
|
53
59
|
virtualization[:systems][:vbox] = "host"
|
60
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on VirtualBox detected")
|
54
61
|
when /vboxguest/
|
55
62
|
virtualization[:system] = "vbox"
|
56
63
|
virtualization[:role] = "guest"
|
57
64
|
virtualization[:systems][:vbox] = "guest"
|
65
|
+
Ohai::Log.debug("Virtualization plugin: Host running VirtualBox detected")
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
61
|
-
# Detect
|
69
|
+
# Detect bhyve by presence of /dev/vmm
|
70
|
+
if File.exist?("/dev/vmm")
|
71
|
+
virtualization[:system] = "bhyve"
|
72
|
+
virtualization[:role] = "host"
|
73
|
+
virtualization[:systems][:bhyve] = "host"
|
74
|
+
Ohai::Log.debug("Virtualization plugin: Host running bhyve detected")
|
75
|
+
end
|
76
|
+
|
77
|
+
# Detect KVM/QEMU paravirt guests from cpu, report as KVM
|
62
78
|
# hw.model: QEMU Virtual CPU version 0.9.1
|
63
79
|
so = shell_out("sysctl -n hw.model")
|
64
80
|
if so.stdout.split($/)[0] =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/
|
65
81
|
virtualization[:system] = "kvm"
|
66
82
|
virtualization[:role] = "guest"
|
67
83
|
virtualization[:systems][:kvm] = "guest"
|
84
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on KVM detected")
|
85
|
+
end
|
86
|
+
|
87
|
+
# gather hypervisor of guests from sysctl kern.vm_guest
|
88
|
+
# there are a limited number of hypervisors detected here, BUT it doesn't
|
89
|
+
# require dmidecode to be installed and dmidecode isn't in freebsd out of the box
|
90
|
+
so = shell_out("sysctl -n kern.vm_guest")
|
91
|
+
case so.stdout
|
92
|
+
when /vmware/
|
93
|
+
virtualization[:system] = "vmware"
|
94
|
+
virtualization[:role] = "guest"
|
95
|
+
virtualization[:systems][:vmware] = "guest"
|
96
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on VMware detected")
|
97
|
+
when /hv/
|
98
|
+
virtualization[:system] = "hyperv"
|
99
|
+
virtualization[:role] = "guest"
|
100
|
+
virtualization[:systems][:hyperv] = "guest"
|
101
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on Hyper-V detected")
|
102
|
+
when /xen/
|
103
|
+
virtualization[:system] = "xen"
|
104
|
+
virtualization[:role] = "guest"
|
105
|
+
virtualization[:systems][:xen] = "guest"
|
106
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on Xen detected")
|
107
|
+
when /bhyve/
|
108
|
+
virtualization[:system] = "bhyve"
|
109
|
+
virtualization[:role] = "guest"
|
110
|
+
virtualization[:systems][:bhyve] = "guest"
|
111
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on bhyve detected")
|
68
112
|
end
|
69
113
|
|
70
114
|
# parse dmidecode to discover various virtualization guests
|
@@ -74,6 +118,7 @@ Ohai.plugin(:Virtualization) do
|
|
74
118
|
virtualization[:system] = guest
|
75
119
|
virtualization[:role] = "guest"
|
76
120
|
virtualization[:systems][guest.to_sym] = "guest"
|
121
|
+
Ohai::Log.debug("Virtualization plugin: Guest running on #{guest} detected")
|
77
122
|
end
|
78
123
|
end
|
79
124
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Davide Cavalca <dcavalca@fb.com>
|
3
|
+
# Copyright:: Copyright (c) 2016 Facebook
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require "ohai/util/file_helper"
|
20
|
+
|
21
|
+
include Ohai::Util::FileHelper
|
22
|
+
|
23
|
+
Ohai.plugin(:Sessions) do
|
24
|
+
provides "sessions/by_session", "sessions/by_user"
|
25
|
+
|
26
|
+
collect_data(:linux) do
|
27
|
+
loginctl_path = which("loginctl")
|
28
|
+
if loginctl_path
|
29
|
+
cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " +
|
30
|
+
"list-sessions"
|
31
|
+
loginctl = shell_out(cmd)
|
32
|
+
|
33
|
+
sessions Mash.new unless sessions
|
34
|
+
sessions[:by_session] = Mash.new unless sessions[:by_session]
|
35
|
+
sessions[:by_user] = Mash.new unless sessions[:by_user]
|
36
|
+
|
37
|
+
loginctl.stdout.split("\n").each do |line|
|
38
|
+
session, uid, user, seat = line.split
|
39
|
+
s = {
|
40
|
+
"session" => session,
|
41
|
+
"uid" => uid,
|
42
|
+
"user" => user,
|
43
|
+
"seat" => seat,
|
44
|
+
}
|
45
|
+
sessions[:by_session][session] = s
|
46
|
+
if sessions[:by_user][user]
|
47
|
+
sessions[:by_user][user] << s
|
48
|
+
else
|
49
|
+
sessions[:by_user][user] = [s]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -33,13 +33,14 @@ Ohai.plugin(:Virtualization) do
|
|
33
33
|
which("docker")
|
34
34
|
end
|
35
35
|
|
36
|
+
def nova_exists?
|
37
|
+
which("nova")
|
38
|
+
end
|
39
|
+
|
36
40
|
collect_data(:linux) do
|
37
41
|
virtualization Mash.new unless virtualization
|
38
42
|
virtualization[:systems] = Mash.new unless virtualization[:systems]
|
39
43
|
|
40
|
-
# if it is possible to detect paravirt vs hardware virt, it should be put in
|
41
|
-
# virtualization[:mechanism]
|
42
|
-
|
43
44
|
## Xen
|
44
45
|
# /proc/xen is an empty dir for EL6 + Linode Guests + Paravirt EC2 instances
|
45
46
|
if File.exist?("/proc/xen")
|
@@ -60,18 +61,13 @@ Ohai.plugin(:Virtualization) do
|
|
60
61
|
# Xen Notes:
|
61
62
|
# - cpuid of guests, if we could get it, would also be a clue
|
62
63
|
# - may be able to determine if under paravirt from /dev/xen/evtchn (See OHAI-253)
|
63
|
-
# - EL6 guests carry a 'hypervisor' cpu flag
|
64
64
|
# - Additional edge cases likely should not change the above assumptions
|
65
65
|
# but rather be additive - btm
|
66
66
|
|
67
|
-
# Detect from kernel module
|
67
|
+
# Detect Virtualbox from kernel module
|
68
68
|
if File.exist?("/proc/modules")
|
69
69
|
modules = File.read("/proc/modules")
|
70
|
-
if modules =~ /^
|
71
|
-
virtualization[:system] = "kvm"
|
72
|
-
virtualization[:role] = "host"
|
73
|
-
virtualization[:systems][:kvm] = "host"
|
74
|
-
elsif modules =~ /^vboxdrv/
|
70
|
+
if modules =~ /^vboxdrv/
|
75
71
|
virtualization[:system] = "vbox"
|
76
72
|
virtualization[:role] = "host"
|
77
73
|
virtualization[:systems][:vbox] = "host"
|
@@ -82,11 +78,14 @@ Ohai.plugin(:Virtualization) do
|
|
82
78
|
end
|
83
79
|
end
|
84
80
|
|
85
|
-
#
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
81
|
+
# if nova binary is present we're on an openstack host
|
82
|
+
if nova_exists?
|
83
|
+
virtualization[:system] = "openstack"
|
84
|
+
virtualization[:role] = "host"
|
85
|
+
virtualization[:systems][:openstack] = "host"
|
86
|
+
end
|
87
|
+
|
88
|
+
# Detect paravirt KVM/QEMU from cpuinfo, report as KVM
|
90
89
|
if File.exist?("/proc/cpuinfo")
|
91
90
|
if File.read("/proc/cpuinfo") =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/
|
92
91
|
virtualization[:system] = "kvm"
|
@@ -95,6 +94,19 @@ Ohai.plugin(:Virtualization) do
|
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
97
|
+
# Detect KVM systems via /sys
|
98
|
+
# guests will have the hypervisor cpu feature that hosts don't have
|
99
|
+
if File.exist?("/sys/devices/virtual/misc/kvm")
|
100
|
+
virtualization[:system] = "kvm"
|
101
|
+
if File.read("/proc/cpuinfo") =~ /hypervisor/
|
102
|
+
virtualization[:role] = "guest"
|
103
|
+
virtualization[:systems][:kvm] = "guest"
|
104
|
+
else
|
105
|
+
virtualization[:role] = "host"
|
106
|
+
virtualization[:systems][:kvm] = "host"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
98
110
|
# Detect OpenVZ / Virtuozzo.
|
99
111
|
# http://wiki.openvz.org/BC_proc_entries
|
100
112
|
if File.exist?("/proc/bc/0")
|
@@ -18,6 +18,9 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
+
require "ohai/mixin/dmi_decode"
|
22
|
+
include Ohai::Mixin::DmiDecode
|
23
|
+
|
21
24
|
Ohai.plugin(:Virtualization) do
|
22
25
|
provides "virtualization"
|
23
26
|
|
@@ -29,34 +32,28 @@ Ohai.plugin(:Virtualization) do
|
|
29
32
|
|
30
33
|
collect_data(:solaris2) do
|
31
34
|
virtualization Mash.new
|
35
|
+
virtualization[:systems] = Mash.new
|
32
36
|
|
33
|
-
# Detect KVM/QEMU from cpuinfo, report as KVM
|
37
|
+
# Detect paravirt KVM/QEMU from cpuinfo, report as KVM
|
34
38
|
psrinfo_path = Ohai.abs_path( "/usr/sbin/psrinfo" )
|
35
|
-
if File.
|
39
|
+
if File.exist?(psrinfo_path)
|
36
40
|
so = shell_out("#{psrinfo_path} -pv")
|
37
|
-
if so.stdout =~ /QEMU Virtual CPU/
|
41
|
+
if so.stdout =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/
|
38
42
|
virtualization[:system] = "kvm"
|
39
43
|
virtualization[:role] = "guest"
|
44
|
+
virtualization[:systems][:kvm] = "guest"
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
when /Manufacturer: VMware/
|
54
|
-
if so.stdout =~ /Product: VMware Virtual Platform/
|
55
|
-
virtualization[:system] = "vmware"
|
56
|
-
virtualization[:role] = "guest"
|
57
|
-
end
|
58
|
-
else
|
59
|
-
nil
|
48
|
+
# Pass smbios information to the dmi_decode mixin to
|
49
|
+
# identify possible virtualization systems
|
50
|
+
smbios_path = Ohai.abs_path("/usr/sbin/smbios")
|
51
|
+
if File.exist?(smbios_path)
|
52
|
+
guest = guest_from_dmi(shell_out(smbios_path).stdout)
|
53
|
+
if guest
|
54
|
+
virtualization[:system] = guest
|
55
|
+
virtualization[:role] = "guest"
|
56
|
+
virtualization[:systems][guest.to_sym] = "guest"
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
@@ -77,15 +74,17 @@ Ohai.plugin(:Virtualization) do
|
|
77
74
|
|
78
75
|
if zones.length == 1
|
79
76
|
first_zone = zones.keys[0]
|
80
|
-
unless
|
77
|
+
unless first_zone == "global"
|
81
78
|
virtualization[:system] = "zone"
|
82
79
|
virtualization[:role] = "guest"
|
80
|
+
virtualization[:systems][:zone] = "guest"
|
83
81
|
virtualization[:guest_uuid] = zones[first_zone]["uuid"]
|
84
82
|
virtualization[:guest_id] = collect_solaris_guestid
|
85
83
|
end
|
86
84
|
elsif zones.length > 1
|
87
85
|
virtualization[:system] = "zone"
|
88
86
|
virtualization[:role] = "host"
|
87
|
+
virtualization[:systems][:zone] = "host"
|
89
88
|
virtualization[:guests] = zones
|
90
89
|
end
|
91
90
|
end
|
@@ -16,6 +16,9 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
+
# Note: despite the name this is really a libvirt plugin.
|
20
|
+
# perhaps we'd be better off renaming it? -tsmith
|
21
|
+
|
19
22
|
Ohai.plugin(:VirtualizationInfo) do
|
20
23
|
%w{ uri capabilities nodeinfo domains networks storage }.each do |info|
|
21
24
|
provides "virtualization/#{info}"
|
@@ -24,8 +27,7 @@ Ohai.plugin(:VirtualizationInfo) do
|
|
24
27
|
collect_data do
|
25
28
|
unless virtualization.nil? || !(virtualization[:role].eql?("host"))
|
26
29
|
begin
|
27
|
-
require "libvirt"
|
28
|
-
require "hpricot"
|
30
|
+
require "libvirt" # this is the ruby-libvirt gem not the libvirt gem
|
29
31
|
|
30
32
|
emu = (virtualization[:system].eql?("kvm") ? "qemu" : virtualization[:system])
|
31
33
|
virtualization[:libvirt_version] = Libvirt.version(emu)[0].to_s
|
@@ -34,8 +36,6 @@ Ohai.plugin(:VirtualizationInfo) do
|
|
34
36
|
|
35
37
|
virtualization[:uri] = virtconn.uri
|
36
38
|
virtualization[:capabilities] = Mash.new
|
37
|
-
virtualization[:capabilities][:xml_desc] = (virtconn.capabilities.split("\n").collect { |line| line.strip }).join
|
38
|
-
#xdoc = Hpricot virtualization[:capabilities][:xml_desc]
|
39
39
|
|
40
40
|
virtualization[:nodeinfo] = Mash.new
|
41
41
|
ni = virtconn.node_get_info
|
@@ -46,10 +46,8 @@ Ohai.plugin(:VirtualizationInfo) do
|
|
46
46
|
dv = virtconn.lookup_domain_by_id d
|
47
47
|
virtualization[:domains][dv.name] = Mash.new
|
48
48
|
virtualization[:domains][dv.name][:id] = d
|
49
|
-
virtualization[:domains][dv.name][:xml_desc] = (dv.xml_desc.split("\n").collect { |line| line.strip }).join
|
50
49
|
%w{os_type uuid}.each { |a| virtualization[:domains][dv.name][a] = dv.send(a) }
|
51
50
|
%w{cpu_time max_mem memory nr_virt_cpu state}.each { |a| virtualization[:domains][dv.name][a] = dv.info.send(a) }
|
52
|
-
#xdoc = Hpricot virtualization[:domains][dv.name][:xml_desc]
|
53
51
|
|
54
52
|
end
|
55
53
|
|
@@ -57,20 +55,15 @@ Ohai.plugin(:VirtualizationInfo) do
|
|
57
55
|
virtconn.list_networks.each do |n|
|
58
56
|
nv = virtconn.lookup_network_by_name n
|
59
57
|
virtualization[:networks][n] = Mash.new
|
60
|
-
virtualization[:networks][n][:xml_desc] = (nv.xml_desc.split("\n").collect { |line| line.strip }).join
|
61
58
|
%w{bridge_name uuid}.each { |a| virtualization[:networks][n][a] = nv.send(a) }
|
62
|
-
#xdoc = Hpricot virtualization[:networks][n][:xml_desc]
|
63
|
-
|
64
59
|
end
|
65
60
|
|
66
61
|
virtualization[:storage] = Mash.new
|
67
62
|
virtconn.list_storage_pools.each do |pool|
|
68
63
|
sp = virtconn.lookup_storage_pool_by_name pool
|
69
64
|
virtualization[:storage][pool] = Mash.new
|
70
|
-
virtualization[:storage][pool][:xml_desc] = (sp.xml_desc.split("\n").collect { |line| line.strip }).join
|
71
65
|
%w{autostart uuid}.each { |a| virtualization[:storage][pool][a] = sp.send(a) }
|
72
66
|
%w{allocation available capacity state}.each { |a| virtualization[:storage][pool][a] = sp.info.send(a) }
|
73
|
-
#xdoc = Hpricot virtualization[:storage][pool][:xml_desc]
|
74
67
|
|
75
68
|
virtualization[:storage][pool][:volumes] = Mash.new
|
76
69
|
sp.list_volumes.each do |v|
|
@@ -83,7 +76,7 @@ Ohai.plugin(:VirtualizationInfo) do
|
|
83
76
|
|
84
77
|
virtconn.close
|
85
78
|
rescue LoadError => e
|
86
|
-
Ohai::Log.debug("Can't load gem: #{e}.
|
79
|
+
Ohai::Log.debug("Can't load gem: #{e}. VirtualizationInfo plugin cannot continue.")
|
87
80
|
end
|
88
81
|
end
|
89
82
|
end
|
@@ -25,8 +25,12 @@ module Ohai
|
|
25
25
|
paths = ENV["PATH"].split(File::PATH_SEPARATOR) + [ "/bin", "/usr/bin", "/sbin", "/usr/sbin" ]
|
26
26
|
paths.each do |path|
|
27
27
|
filename = File.join(path, cmd)
|
28
|
-
|
28
|
+
if File.executable?(filename)
|
29
|
+
Ohai::Log.debug("#{self.name} plugin: found #{cmd} at #{filename}")
|
30
|
+
return filename
|
31
|
+
end
|
29
32
|
end
|
33
|
+
Ohai::Log.debug("#{self.name} plugin: did not find #{cmd}")
|
30
34
|
false
|
31
35
|
end
|
32
36
|
end
|
data/lib/ohai/version.rb
CHANGED
@@ -24,8 +24,30 @@ describe Ohai::System, "BSD virtualization plugin" do
|
|
24
24
|
allow(@plugin).to receive(:collect_os).and_return(:freebsd)
|
25
25
|
allow(@plugin).to receive(:shell_out).with("sysctl -n security.jail.jailed").and_return(mock_shell_out(0, "0", ""))
|
26
26
|
allow(@plugin).to receive(:shell_out).with("#{ Ohai.abs_path( "/sbin/kldstat" )}").and_return(mock_shell_out(0, "", ""))
|
27
|
-
allow(@plugin).to receive(:shell_out).with("jls -
|
27
|
+
allow(@plugin).to receive(:shell_out).with("jls -nd").and_return(mock_shell_out(0, "", ""))
|
28
28
|
allow(@plugin).to receive(:shell_out).with("sysctl -n hw.model").and_return(mock_shell_out(0, "", ""))
|
29
|
+
allow(@plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "", ""))
|
30
|
+
allow(File).to receive(:exist?).and_return false
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when on a bhyve host" do
|
34
|
+
it "detects we are a host" do
|
35
|
+
allow(File).to receive(:exist?).with("/dev/vmm").and_return true
|
36
|
+
@plugin.run
|
37
|
+
expect(@plugin[:virtualization][:system]).to eq("bhyve")
|
38
|
+
expect(@plugin[:virtualization][:role]).to eq("host")
|
39
|
+
expect(@plugin[:virtualization][:systems][:bhyve]).to eq("host")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when on a bhyve guest" do
|
44
|
+
it "detects we are a guest" do
|
45
|
+
allow(@plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "bhyve", ""))
|
46
|
+
@plugin.run
|
47
|
+
expect(@plugin[:virtualization][:system]).to eq("bhyve")
|
48
|
+
expect(@plugin[:virtualization][:role]).to eq("guest")
|
49
|
+
expect(@plugin[:virtualization][:systems][:bhyve]).to eq("guest")
|
50
|
+
end
|
29
51
|
end
|
30
52
|
|
31
53
|
context "jails" do
|
@@ -40,7 +62,7 @@ describe Ohai::System, "BSD virtualization plugin" do
|
|
40
62
|
it "detects we are hosting jails" do
|
41
63
|
# from http://www.freebsd.org/doc/handbook/jails-application.html
|
42
64
|
@jails = "JID IP Address Hostname Path\n 3 192.168.3.17 ns.example.org /home/j/ns\n 2 192.168.3.18 mail.example.org /home/j/mail\n 1 62.123.43.14 www.example.org /home/j/www"
|
43
|
-
allow(@plugin).to receive(:shell_out).with("jls -
|
65
|
+
allow(@plugin).to receive(:shell_out).with("jls -nd").and_return(mock_shell_out(0, @jails, ""))
|
44
66
|
@plugin.run
|
45
67
|
expect(@plugin[:virtualization][:system]).to eq("jail")
|
46
68
|
expect(@plugin[:virtualization][:role]).to eq("host")
|
@@ -95,4 +117,34 @@ OUT
|
|
95
117
|
end
|
96
118
|
end
|
97
119
|
end
|
120
|
+
|
121
|
+
context "when on a xen guest" do
|
122
|
+
it "detects we are a guest" do
|
123
|
+
allow(@plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "xen", ""))
|
124
|
+
@plugin.run
|
125
|
+
expect(@plugin[:virtualization][:system]).to eq("xen")
|
126
|
+
expect(@plugin[:virtualization][:role]).to eq("guest")
|
127
|
+
expect(@plugin[:virtualization][:systems][:xen]).to eq("guest")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when on a vmware guest" do
|
132
|
+
it "detects we are a guest" do
|
133
|
+
allow(@plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "vmware", ""))
|
134
|
+
@plugin.run
|
135
|
+
expect(@plugin[:virtualization][:system]).to eq("vmware")
|
136
|
+
expect(@plugin[:virtualization][:role]).to eq("guest")
|
137
|
+
expect(@plugin[:virtualization][:systems][:vmware]).to eq("guest")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when on a hyper-v guest" do
|
142
|
+
it "detects we are a guest" do
|
143
|
+
allow(@plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "hv", ""))
|
144
|
+
@plugin.run
|
145
|
+
expect(@plugin[:virtualization][:system]).to eq("hyperv")
|
146
|
+
expect(@plugin[:virtualization][:role]).to eq("guest")
|
147
|
+
expect(@plugin[:virtualization][:systems][:hyperv]).to eq("guest")
|
148
|
+
end
|
149
|
+
end
|
98
150
|
end
|
@@ -25,15 +25,20 @@ describe Ohai::System, "plugin gce" do
|
|
25
25
|
|
26
26
|
shared_examples_for "!gce" do
|
27
27
|
it "should NOT attempt to fetch the gce metadata" do
|
28
|
-
expect(@plugin).not_to receive(:
|
28
|
+
expect(@plugin).not_to receive(:http_get)
|
29
|
+
@plugin.run
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should NOT set gce attributes" do
|
33
|
+
expect(@plugin[:gce]).to be_nil
|
29
34
|
@plugin.run
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
33
38
|
shared_examples_for "gce" do
|
34
39
|
before(:each) do
|
35
|
-
@
|
36
|
-
allow(@plugin).to receive(:
|
40
|
+
@http_get = double("Net::HTTP client")
|
41
|
+
allow(@plugin).to receive(:http_get).and_return(double("Net::HTTP Response", :body => '{"instance":{"hostname":"test-host"}}', :code => "200"))
|
37
42
|
allow(IO).to receive(:select).and_return([[], [1], []])
|
38
43
|
t = double("connection")
|
39
44
|
allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS)
|
@@ -42,10 +47,6 @@ describe Ohai::System, "plugin gce" do
|
|
42
47
|
end
|
43
48
|
|
44
49
|
it "should recursively fetch and properly parse json metadata" do
|
45
|
-
expect(@http_client).to receive(:get).
|
46
|
-
with("/computeMetadata/v1beta1/?recursive=true/").
|
47
|
-
and_return(double("Net::HTTP Response", :body => '{"instance":{"hostname":"test-host"}}', :code => "200"))
|
48
|
-
|
49
50
|
@plugin.run
|
50
51
|
|
51
52
|
expect(@plugin[:gce]).not_to be_nil
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Davide Cavalca <dcavalca@fb.com>
|
3
|
+
# Copyright:: Copyright (c) 2016 Facebook
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper.rb")
|
20
|
+
|
21
|
+
describe Ohai::System, "Linux sessions plugin" do
|
22
|
+
let(:plugin) { get_plugin("linux/sessions") }
|
23
|
+
|
24
|
+
before(:each) do
|
25
|
+
allow(plugin).to receive(:collect_os).and_return(:linux)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should populate sessions if loginctl is found" do
|
29
|
+
loginctl_out = <<-LOGINCTL_OUT
|
30
|
+
c1 118 Debian-gdm seat0
|
31
|
+
318 0 root
|
32
|
+
46 0 root
|
33
|
+
306 1000 joe
|
34
|
+
LOGINCTL_OUT
|
35
|
+
allow(plugin).to receive(:which).with("loginctl").and_return("/bin/loginctl")
|
36
|
+
allow(plugin).to receive(:shell_out).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, ""))
|
37
|
+
plugin.run
|
38
|
+
expect(plugin[:sessions].to_hash).to eq({
|
39
|
+
"by_session" => {
|
40
|
+
"c1" => {
|
41
|
+
"session" => "c1",
|
42
|
+
"uid" => "118",
|
43
|
+
"user" => "Debian-gdm",
|
44
|
+
"seat" => "seat0",
|
45
|
+
},
|
46
|
+
"318" => {
|
47
|
+
"session" => "318",
|
48
|
+
"uid" => "0",
|
49
|
+
"user" => "root",
|
50
|
+
"seat" => nil,
|
51
|
+
},
|
52
|
+
"46" => {
|
53
|
+
"session" => "46",
|
54
|
+
"uid" => "0",
|
55
|
+
"user" => "root",
|
56
|
+
"seat" => nil,
|
57
|
+
},
|
58
|
+
"306" => {
|
59
|
+
"session" => "306",
|
60
|
+
"uid" => "1000",
|
61
|
+
"user" => "joe",
|
62
|
+
"seat" => nil,
|
63
|
+
}
|
64
|
+
},
|
65
|
+
"by_user" => {
|
66
|
+
"Debian-gdm" => [{
|
67
|
+
"session" => "c1",
|
68
|
+
"uid" => "118",
|
69
|
+
"user" => "Debian-gdm",
|
70
|
+
"seat" => "seat0",
|
71
|
+
}],
|
72
|
+
"root" => [{
|
73
|
+
"session" => "318",
|
74
|
+
"uid" => "0",
|
75
|
+
"user" => "root",
|
76
|
+
"seat" => nil
|
77
|
+
}, {
|
78
|
+
"session" => "46",
|
79
|
+
"uid" => "0",
|
80
|
+
"user" => "root",
|
81
|
+
"seat" => nil,
|
82
|
+
}],
|
83
|
+
"joe" => [{
|
84
|
+
"session" => "306",
|
85
|
+
"uid" => "1000",
|
86
|
+
"user" => "joe",
|
87
|
+
"seat" => nil,
|
88
|
+
}],
|
89
|
+
},
|
90
|
+
})
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should not populate sessions if loginctl is not found" do
|
94
|
+
allow(plugin).to receive(:which).with("loginctl").and_return(false)
|
95
|
+
plugin.run
|
96
|
+
expect(plugin[:sessions]).to be(nil)
|
97
|
+
end
|
98
|
+
end
|
@@ -37,6 +37,12 @@ describe Ohai::System, "Linux virtualization platform" do
|
|
37
37
|
allow(File).to receive(:exist?).with("/.dockerenv").and_return(false)
|
38
38
|
allow(File).to receive(:exist?).with("/.dockerinit").and_return(false)
|
39
39
|
allow(File).to receive(:exist?).with("/proc/bus/pci/devices").and_return(false)
|
40
|
+
allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(false)
|
41
|
+
|
42
|
+
# default the which wrappers to nil
|
43
|
+
allow(plugin).to receive(:lxc_version_exists?).and_return(false)
|
44
|
+
allow(plugin).to receive(:docker_exists?).and_return(false)
|
45
|
+
allow(plugin).to receive(:nova_exists?).and_return(false)
|
40
46
|
end
|
41
47
|
|
42
48
|
describe "when we are checking for xen" do
|
@@ -76,10 +82,29 @@ describe Ohai::System, "Linux virtualization platform" do
|
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
85
|
+
describe "when we are checking for openstack" do
|
86
|
+
it "sets openstack host if nova binary exists" do
|
87
|
+
allow(plugin).to receive(:nova_exists?).and_return("/usr/bin/nova")
|
88
|
+
plugin.run
|
89
|
+
expect(plugin[:virtualization][:system]).to eq("openstack")
|
90
|
+
expect(plugin[:virtualization][:role]).to eq("host")
|
91
|
+
expect(plugin[:virtualization][:systems][:openstack]).to eq("host")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
79
95
|
describe "when we are checking for kvm" do
|
80
|
-
it "sets kvm
|
81
|
-
|
82
|
-
allow(File).to receive(:read).with("/proc/
|
96
|
+
it "sets kvm guest if /sys/devices/virtual/misc/kvm exists & hypervisor cpu feature is present" do
|
97
|
+
allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(true)
|
98
|
+
allow(File).to receive(:read).with("/proc/cpuinfo").and_return("fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon rep_good nopl pni vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt hypervisor lahf_lm vnmi ept tsc_adjust")
|
99
|
+
plugin.run
|
100
|
+
expect(plugin[:virtualization][:system]).to eq("kvm")
|
101
|
+
expect(plugin[:virtualization][:role]).to eq("guest")
|
102
|
+
expect(plugin[:virtualization][:systems][:kvm]).to eq("guest")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "sets kvm host if /sys/devices/virtual/misc/kvm exists & hypervisor cpu feature is not present" do
|
106
|
+
allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(true)
|
107
|
+
allow(File).to receive(:read).with("/proc/cpuinfo").and_return("fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 popcnt lahf_lm ida dtherm tpr_shadow vnmi flexpriority ept vpid")
|
83
108
|
plugin.run
|
84
109
|
expect(plugin[:virtualization][:system]).to eq("kvm")
|
85
110
|
expect(plugin[:virtualization][:role]).to eq("host")
|
@@ -30,16 +30,16 @@ PSRINFO_PV
|
|
30
30
|
allow(@plugin).to receive(:collect_os).and_return(:solaris2)
|
31
31
|
|
32
32
|
# default to all requested Files not existing
|
33
|
-
allow(File).to receive(:
|
34
|
-
allow(File).to receive(:
|
35
|
-
allow(File).to receive(:
|
33
|
+
allow(File).to receive(:exist?).with("/usr/sbin/psrinfo").and_return(false)
|
34
|
+
allow(File).to receive(:exist?).with("/usr/sbin/smbios").and_return(false)
|
35
|
+
allow(File).to receive(:exist?).with("/usr/sbin/zoneadm").and_return(false)
|
36
36
|
allow(@plugin).to receive(:shell_out).with("/usr/sbin/smbios").and_return(mock_shell_out(0, "", ""))
|
37
37
|
allow(@plugin).to receive(:shell_out).with("#{ Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv").and_return(mock_shell_out(0, "", ""))
|
38
38
|
end
|
39
39
|
|
40
40
|
describe "when we are checking for kvm" do
|
41
41
|
before(:each) do
|
42
|
-
expect(File).to receive(:
|
42
|
+
expect(File).to receive(:exist?).with("/usr/sbin/psrinfo").and_return(true)
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should run psrinfo -pv" do
|
@@ -52,18 +52,19 @@ PSRINFO_PV
|
|
52
52
|
@plugin.run
|
53
53
|
expect(@plugin[:virtualization][:system]).to eq("kvm")
|
54
54
|
expect(@plugin[:virtualization][:role]).to eq("guest")
|
55
|
+
expect(@plugin[:virtualization][:systems][:kvm]).to eq("guest")
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should not set virtualization if kvm isn't there" do
|
58
59
|
expect(@plugin).to receive(:shell_out).with("#{ Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv").and_return(mock_shell_out(0, @psrinfo_pv, ""))
|
59
60
|
@plugin.run
|
60
|
-
expect(@plugin[:virtualization]).to eq({})
|
61
|
+
expect(@plugin[:virtualization][:systems]).to eq({})
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
65
|
describe "when we are parsing smbios" do
|
65
66
|
before(:each) do
|
66
|
-
expect(File).to receive(:
|
67
|
+
expect(File).to receive(:exist?).with("/usr/sbin/smbios").and_return(true)
|
67
68
|
end
|
68
69
|
|
69
70
|
it "should run smbios" do
|
@@ -107,17 +108,18 @@ VMWARE
|
|
107
108
|
@plugin.run
|
108
109
|
expect(@plugin[:virtualization][:system]).to eq("vmware")
|
109
110
|
expect(@plugin[:virtualization][:role]).to eq("guest")
|
111
|
+
expect(@plugin[:virtualization][:systems][:vmware]).to eq("guest")
|
110
112
|
end
|
111
113
|
|
112
114
|
it "should run smbios and not set virtualization if nothing is detected" do
|
113
115
|
expect(@plugin).to receive(:shell_out).with("/usr/sbin/smbios")
|
114
116
|
@plugin.run
|
115
|
-
expect(@plugin[:virtualization]).to eq({})
|
117
|
+
expect(@plugin[:virtualization][:systems]).to eq({})
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
119
121
|
it "should not set virtualization if no tests match" do
|
120
122
|
@plugin.run
|
121
|
-
expect(@plugin[:virtualization]).to eq({})
|
123
|
+
expect(@plugin[:virtualization][:systems]).to eq({})
|
122
124
|
end
|
123
125
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ohai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.
|
4
|
+
version: 8.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
@@ -367,6 +367,7 @@ files:
|
|
367
367
|
- lib/ohai/plugins/linux/memory.rb
|
368
368
|
- lib/ohai/plugins/linux/network.rb
|
369
369
|
- lib/ohai/plugins/linux/platform.rb
|
370
|
+
- lib/ohai/plugins/linux/sessions.rb
|
370
371
|
- lib/ohai/plugins/linux/virtualization.rb
|
371
372
|
- lib/ohai/plugins/lua.rb
|
372
373
|
- lib/ohai/plugins/mono.rb
|
@@ -540,6 +541,7 @@ files:
|
|
540
541
|
- spec/unit/plugins/linux/memory_spec.rb
|
541
542
|
- spec/unit/plugins/linux/network_spec.rb
|
542
543
|
- spec/unit/plugins/linux/platform_spec.rb
|
544
|
+
- spec/unit/plugins/linux/sessions_spec.rb
|
543
545
|
- spec/unit/plugins/linux/uptime_spec.rb
|
544
546
|
- spec/unit/plugins/linux/virtualization_spec.rb
|
545
547
|
- spec/unit/plugins/lua_spec.rb
|