facter 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of facter might be problematic. Click here for more details.

Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +14 -0
  3. data/ext/project_data.yaml +9 -6
  4. data/lib/facter/core/execution/base.rb +3 -3
  5. data/lib/facter/core/suitable.rb +1 -5
  6. data/lib/facter/dhcp_servers.rb +39 -0
  7. data/lib/facter/ec2.rb +33 -26
  8. data/lib/facter/ec2/rest.rb +130 -0
  9. data/lib/facter/fqdn.rb +2 -0
  10. data/lib/facter/gce.rb +16 -0
  11. data/lib/facter/gce/metadata.rb +87 -0
  12. data/lib/facter/kernelmajversion.rb +8 -0
  13. data/lib/facter/kernelrelease.rb +8 -0
  14. data/lib/facter/memory.rb +21 -15
  15. data/lib/facter/netmask.rb +1 -1
  16. data/lib/facter/operatingsystem.rb +20 -0
  17. data/lib/facter/operatingsystemmajrelease.rb +2 -1
  18. data/lib/facter/operatingsystemrelease.rb +19 -0
  19. data/lib/facter/osfamily.rb +3 -1
  20. data/lib/facter/partitions.rb +35 -0
  21. data/lib/facter/physicalprocessorcount.rb +9 -0
  22. data/lib/facter/processor.rb +25 -25
  23. data/lib/facter/util/config.rb +3 -1
  24. data/lib/facter/util/dhcp_servers.rb +43 -0
  25. data/lib/facter/util/ec2.rb +5 -0
  26. data/lib/facter/util/formatter.rb +2 -1
  27. data/lib/facter/util/ip.rb +1 -1
  28. data/lib/facter/util/loader.rb +10 -1
  29. data/lib/facter/util/manufacturer.rb +15 -16
  30. data/lib/facter/util/memory.rb +12 -12
  31. data/lib/facter/util/netmask.rb +1 -1
  32. data/lib/facter/util/operatingsystem.rb +21 -0
  33. data/lib/facter/util/partitions.rb +41 -0
  34. data/lib/facter/util/partitions/linux.rb +65 -0
  35. data/lib/facter/util/posix.rb +16 -0
  36. data/lib/facter/util/processor.rb +8 -10
  37. data/lib/facter/util/resolution.rb +4 -0
  38. data/lib/facter/util/values.rb +29 -0
  39. data/lib/facter/util/virtual.rb +32 -3
  40. data/lib/facter/util/windows_root.rb +2 -32
  41. data/lib/facter/version.rb +1 -1
  42. data/lib/facter/virtual.rb +53 -12
  43. data/spec/fixtures/ifconfig/openbsd_bridge_rules +11 -0
  44. data/spec/fixtures/unit/dhcp_servers/nmcli_devices +4 -0
  45. data/spec/fixtures/unit/dhcp_servers/nmcli_devices_disconnected +4 -0
  46. data/spec/fixtures/unit/dhcp_servers/nmcli_eth0_dhcp +36 -0
  47. data/spec/fixtures/unit/dhcp_servers/nmcli_eth0_static +24 -0
  48. data/spec/fixtures/unit/dhcp_servers/nmcli_wlan0_dhcp +49 -0
  49. data/spec/fixtures/unit/dhcp_servers/nmcli_wlan0_static +37 -0
  50. data/spec/fixtures/unit/dhcp_servers/route +3 -0
  51. data/spec/fixtures/unit/dhcp_servers/route_nogw +1 -0
  52. data/spec/fixtures/unit/ec2/rest/meta-data/root +20 -0
  53. data/spec/fixtures/unit/gce/metadata/metadata.json +69 -0
  54. data/spec/fixtures/unit/kernelrelease/openbsd-5.3 +2 -0
  55. data/spec/fixtures/unit/kernelrelease/openbsd-5.3-current +3 -0
  56. data/spec/fixtures/unit/memory/aix-svmon +9 -0
  57. data/spec/fixtures/unit/memory/aix-swap_l +2 -0
  58. data/spec/fixtures/unit/memory/darwin-swapinfo-multiple +3 -0
  59. data/spec/fixtures/unit/memory/darwin-swapinfo-single +2 -0
  60. data/spec/fixtures/unit/memory/darwin-vm_stat +13 -0
  61. data/spec/fixtures/unit/memory/dragonfly-vmstat +3 -0
  62. data/spec/fixtures/unit/memory/freebsd-vmstat +3 -0
  63. data/spec/fixtures/unit/memory/linux-proc_meminfo +10 -0
  64. data/spec/fixtures/unit/memory/openbsd-vmstat +3 -0
  65. data/spec/fixtures/unit/memory/smartos_zone_swap_l-single +2 -0
  66. data/spec/fixtures/unit/memory/solaris-prtconf +4 -0
  67. data/spec/fixtures/unit/memory/solaris-swap_l-multiple +3 -0
  68. data/spec/fixtures/unit/memory/solaris-swap_l-single +2 -0
  69. data/spec/fixtures/unit/memory/solaris-vmstat +3 -0
  70. data/spec/fixtures/unit/netmask/ifconfig_aix_7.txt +3 -0
  71. data/spec/fixtures/unit/util/dhcp_servers/route +3 -0
  72. data/spec/fixtures/unit/util/dhcp_servers/route_nogw +1 -0
  73. data/spec/fixtures/unit/util/manufacturer/smartos_smbios +533 -0
  74. data/spec/fixtures/unit/util/operatingsystem/cumuluslinux.txt +8 -0
  75. data/spec/fixtures/unit/util/operatingsystem/redhat-7.txt +12 -0
  76. data/spec/fixtures/unit/util/operatingsystem/sabayon.txt +7 -0
  77. data/spec/fixtures/unit/util/operatingsystem/wheezy.txt +9 -0
  78. data/spec/fixtures/unit/util/partitions/partitions/mount +9 -0
  79. data/spec/fixtures/virtual/proc_1_cgroup/in_a_container +9 -0
  80. data/spec/fixtures/virtual/proc_1_cgroup/in_a_docker_container +8 -0
  81. data/spec/fixtures/virtual/proc_1_cgroup/not_in_a_container +9 -0
  82. data/spec/spec_helper.rb +1 -1
  83. data/spec/unit/core/execution/base_spec.rb +3 -5
  84. data/spec/unit/core/execution/posix_spec.rb +2 -2
  85. data/spec/unit/core/suitable_spec.rb +10 -0
  86. data/spec/unit/dhcp_servers_spec.rb +152 -0
  87. data/spec/unit/ec2/rest_spec.rb +145 -0
  88. data/spec/unit/ec2_spec.rb +87 -147
  89. data/spec/unit/fqdn_spec.rb +16 -0
  90. data/spec/unit/gce/metadata_spec.rb +49 -0
  91. data/spec/unit/gce_spec.rb +34 -0
  92. data/spec/unit/interfaces_spec.rb +9 -9
  93. data/spec/unit/kernelmajversion_spec.rb +14 -9
  94. data/spec/unit/kernelrelease_spec.rb +16 -0
  95. data/spec/unit/macaddress_spec.rb +12 -0
  96. data/spec/unit/memory_spec.rb +53 -122
  97. data/spec/unit/netmask_spec.rb +11 -0
  98. data/spec/unit/operatingsystem_spec.rb +19 -0
  99. data/spec/unit/operatingsystemmajrelease_spec.rb +1 -1
  100. data/spec/unit/operatingsystemrelease_spec.rb +8 -0
  101. data/spec/unit/osfamily_spec.rb +62 -0
  102. data/spec/unit/partitions_spec.rb +48 -0
  103. data/spec/unit/physicalprocessorcount_spec.rb +9 -0
  104. data/spec/unit/processor_spec.rb +15 -7
  105. data/spec/unit/util/config_spec.rb +13 -0
  106. data/spec/unit/util/dhcp_servers_spec.rb +63 -0
  107. data/spec/unit/util/ec2_spec.rb +4 -0
  108. data/spec/unit/util/formatter_spec.rb +50 -0
  109. data/spec/unit/util/loader_spec.rb +4 -4
  110. data/spec/unit/util/macosx_spec.rb +3 -2
  111. data/spec/unit/util/manufacturer_spec.rb +44 -0
  112. data/spec/unit/util/operatingsystem_spec.rb +92 -0
  113. data/spec/unit/util/partitions/partitions_spec.rb +67 -0
  114. data/spec/unit/util/partitions_spec.rb +19 -0
  115. data/spec/unit/util/posix_spec.rb +11 -0
  116. data/spec/unit/util/values_spec.rb +40 -0
  117. data/spec/unit/util/virtual_spec.rb +72 -2
  118. data/spec/unit/virtual_spec.rb +67 -18
  119. metadata +116 -4
  120. data/spec/fixtures/unit/util/loader/nosuchfact.rb +0 -1
@@ -23,10 +23,11 @@ module Facter
23
23
  # name and separated by "=>"
24
24
  if hash.length == 1
25
25
  if value = hash.values.first
26
- output = value
26
+ output = value.is_a?(String) ? value : value.inspect
27
27
  end
28
28
  else
29
29
  hash.sort_by { |(name, value)| name }.each do |name,value|
30
+ value = value.is_a?(String) ? value : value.inspect
30
31
  output << "#{name} => #{value}\n"
31
32
  end
32
33
  end
@@ -9,7 +9,7 @@ module Facter::Util::IP
9
9
  :ipaddress6 => /inet6 (?:addr: )?((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
10
10
  :macaddress => /(?:ether|HWaddr)\s+((\w{1,2}:){5,}\w{1,2})/,
11
11
  :netmask => /(?:Mask:|netmask )([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
12
- :mtu => /MTU:(\d+)/
12
+ :mtu => /MTU:?\s*(\d+)/i
13
13
  },
14
14
  :bsd => {
15
15
  :aliases => [:openbsd, :netbsd, :freebsd, :darwin, :"gnu/kfreebsd", :dragonfly],
@@ -112,7 +112,7 @@ class Facter::Util::Loader
112
112
  begin
113
113
  # Store the file path so we don't try to reload it
114
114
  @loaded << file
115
- Kernel.load(file)
115
+ kernel_load(file)
116
116
  rescue ScriptError => detail
117
117
  # Don't store the path if the file can't be loaded
118
118
  # in case it's loadable later on.
@@ -121,6 +121,15 @@ class Facter::Util::Loader
121
121
  end
122
122
  end
123
123
 
124
+ # Load and execute the Ruby program specified in the file. This exists
125
+ # for testing purposes.
126
+ #
127
+ # @api private
128
+ # @return [Boolean]
129
+ def kernel_load(file)
130
+ Kernel.load(file)
131
+ end
132
+
124
133
  # Load facts from the environment. If no name is provided,
125
134
  # all will be loaded.
126
135
  def load_env(fact = nil)
@@ -1,30 +1,29 @@
1
1
  # mamufacturer.rb
2
2
  # Support methods for manufacturer specific facts
3
3
 
4
- module Facter::Manufacturer
4
+ require 'facter/util/posix'
5
5
 
6
+ module Facter::Manufacturer
6
7
  def self.get_dmi_table()
7
8
  case Facter.value(:kernel)
8
9
  when 'Linux', 'GNU/kFreeBSD'
9
- return nil unless FileTest.exists?("/usr/sbin/dmidecode")
10
-
11
- output=%x{/usr/sbin/dmidecode 2>/dev/null}
10
+ cmd = '/usr/sbin/dmidecode'
12
11
  when 'FreeBSD'
13
- return nil unless FileTest.exists?("/usr/local/sbin/dmidecode")
14
-
15
- output=%x{/usr/local/sbin/dmidecode 2>/dev/null}
12
+ cmd = '/usr/local/sbin/dmidecode'
16
13
  when 'NetBSD', 'DragonFly'
17
- return nil unless FileTest.exists?("/usr/pkg/sbin/dmidecode")
18
-
19
- output=%x{/usr/pkg/sbin/dmidecode 2>/dev/null}
14
+ cmd = '/usr/pkg/sbin/dmidecode'
20
15
  when 'SunOS'
21
- return nil unless FileTest.exists?("/usr/sbin/smbios")
16
+ cmd = '/usr/sbin/smbios'
17
+ end
18
+
19
+ if cmd and (output = Facter::Core::Execution.exec("#{cmd} 2>/dev/null"))
20
+
21
+ if output.respond_to?(:force_encoding)
22
+ output.force_encoding(Encoding::ASCII_8BIT)
23
+ end
22
24
 
23
- output=%x{/usr/sbin/smbios 2>/dev/null}
24
- else
25
- output=nil
25
+ return output
26
26
  end
27
- return output
28
27
  end
29
28
 
30
29
  def self.dmi_find_system_info(name)
@@ -54,7 +53,7 @@ module Facter::Manufacturer
54
53
  name.each do |sysctlkey,facterkey|
55
54
  Facter.add(facterkey) do
56
55
  confine :kernel => [:openbsd, :darwin]
57
- setcode "sysctl -n #{sysctlkey} 2>/dev/null"
56
+ setcode { Facter::Util::POSIX.sysctl(sysctlkey) }
58
57
  end
59
58
  end
60
59
  end
@@ -2,6 +2,8 @@
2
2
  ## Support module for memory related facts
3
3
  ##
4
4
 
5
+ require 'facter/util/posix'
6
+
5
7
  module Facter::Memory
6
8
  def self.meminfo_number(tag)
7
9
  memsize = ""
@@ -111,14 +113,10 @@ module Facter::Memory
111
113
 
112
114
  def self.mem_size_info(kernel = Facter.value(:kernel))
113
115
  case kernel
114
- when /OpenBSD/i
115
- Facter::Core::Execution.exec("sysctl hw.physmem | cut -d'=' -f2")
116
- when /FreeBSD/i
117
- Facter::Core::Execution.exec("sysctl -n hw.physmem")
116
+ when /Dragonfly/i, /FreeBSD/i, /OpenBSD/i
117
+ Facter::Util::POSIX.sysctl("hw.physmem")
118
118
  when /Darwin/i
119
- Facter::Core::Execution.exec("sysctl -n hw.memsize")
120
- when /Dragonfly/i
121
- Facter::Core::Execution.exec("sysctl -n hw.physmem")
119
+ Facter::Util::POSIX.sysctl("hw.memsize")
122
120
  when /AIX/i
123
121
  if Facter::Core::Execution.exec("/usr/bin/svmon -O unit=KB") =~ /^memory\s+(\d+)\s+/
124
122
  $1
@@ -156,7 +154,7 @@ module Facter::Memory
156
154
  when /FreeBSD/i
157
155
  Facter::Core::Execution.exec('swapinfo -k')
158
156
  when /Darwin/i
159
- Facter::Core::Execution.exec('sysctl vm.swapusage')
157
+ Facter::Util::POSIX.sysctl('vm.swapusage')
160
158
  when /SunOS/i
161
159
  Facter::Core::Execution.exec('/usr/sbin/swap -l 2>/dev/null')
162
160
  end
@@ -189,8 +187,8 @@ module Facter::Memory
189
187
  0
190
188
  end
191
189
  when /OpenBSD/i
192
- if line =~ /^total: (\d+)k bytes allocated = \d+k used, (\d+)k available$/
193
- (is_size) ? $1.to_i : $2.to_i
190
+ if line =~ /^total: (\d+) (\d+)-blocks allocated, (\d+) used, (\d+) available$/
191
+ (is_size) ? ($1.to_i * $2.to_i) : ($4.to_i * $2.to_i)
194
192
  else
195
193
  0
196
194
  end
@@ -207,7 +205,7 @@ module Facter::Memory
207
205
  0
208
206
  end
209
207
  when /SunOS/i
210
- if line =~ /^\/\S+\s.*\s+(\d+)\s+(\d+)$/
208
+ if line =~ /^\S+\s.*\s+(\d+)\s+(\d+)$/
211
209
  (is_size) ? $1.to_i : $2.to_i
212
210
  else
213
211
  0
@@ -217,8 +215,10 @@ module Facter::Memory
217
215
 
218
216
  def self.scale_swap_value(value, kernel)
219
217
  case kernel
220
- when /OpenBSD/i, /FreeBSD/i
218
+ when /FreeBSD/i
221
219
  value.to_f / 1024.0
220
+ when /OpenBSD/i
221
+ value.to_f / 1024.0 / 1024.0
222
222
  when /SunOS/i
223
223
  value.to_f / 2 / 1024.0
224
224
  else
@@ -17,7 +17,7 @@ module Facter::NetMask
17
17
  :regex => %r{\s+ inet \s #{Facter.value(:ipaddress)} \s netmask \s (\w{8})}x,
18
18
  :munge => Proc.new { |mask| mask.scan(/../).collect do |byte| byte.to_i(16) end.join('.') }
19
19
  }
20
- when 'FreeBSD','NetBSD','OpenBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly'
20
+ when 'FreeBSD','NetBSD','OpenBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly', 'AIX'
21
21
  ops = {
22
22
  :ifconfig_opts => ['-a'],
23
23
  :regex => %r{\s+ inet \s #{Facter.value(:ipaddress)} \s netmask \s 0x(\w{8})}x,
@@ -0,0 +1,21 @@
1
+ module Facter
2
+ module Util
3
+ module Operatingsystem
4
+
5
+ # @see http://www.freedesktop.org/software/systemd/man/os-release.html
6
+ def self.os_release(file = '/etc/os-release')
7
+ values = {}
8
+
9
+ if File.readable?(file)
10
+ File.readlines(file).each do |line|
11
+ if (match = line.match(/^(\w+)=["']?(.+?)["']?$/))
12
+ values[match[1]] = match[2]
13
+ end
14
+ end
15
+ end
16
+
17
+ values
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'facter/util/partitions/linux'
2
+
3
+ module Facter::Util::Partitions
4
+ IMPLEMENTATIONS = {
5
+ 'Linux' => Linux
6
+ }
7
+
8
+ module NoImplementation
9
+ def self.list
10
+ []
11
+ end
12
+ end
13
+
14
+ def self.implementation
15
+ IMPLEMENTATIONS[Facter.fact(:kernel).value] || NoImplementation
16
+ end
17
+
18
+ def self.list
19
+ implementation.list
20
+ end
21
+
22
+ def self.uuid(partition)
23
+ implementation.uuid(partition)
24
+ end
25
+
26
+ def self.size(partition)
27
+ implementation.size(partition)
28
+ end
29
+
30
+ def self.mount(partition)
31
+ implementation.mount(partition)
32
+ end
33
+
34
+ def self.filesystem(partition)
35
+ implementation.filesystem(partition)
36
+ end
37
+
38
+ def self.available?
39
+ !self.list.empty?
40
+ end
41
+ end
@@ -0,0 +1,65 @@
1
+ module Facter::Util::Partitions
2
+ module Linux
3
+ # Only Linux 2.6+ kernels support sysfs which is required to easily get device details
4
+ SYSFS_BLOCK_DIRECTORY = '/sys/block/'
5
+ DEVDISK_BY_UUID_DIRECTORY = '/dev/disk/by-uuid/'
6
+
7
+ def self.list
8
+ if File.exist?(SYSFS_BLOCK_DIRECTORY)
9
+ devices = Dir.entries(SYSFS_BLOCK_DIRECTORY).select { |d| File.exist?( SYSFS_BLOCK_DIRECTORY + d + "/device" ) }
10
+
11
+ if devices.empty?
12
+ []
13
+ else
14
+ devices.collect do |device|
15
+ Dir.glob( SYSFS_BLOCK_DIRECTORY + device + "/#{device}*" ).collect do |d|
16
+ File.basename(d)
17
+ end
18
+ end.flatten
19
+ end
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def self.uuid(partition)
26
+ uuid = nil
27
+ if File.exist?(DEVDISK_BY_UUID_DIRECTORY)
28
+ Dir.entries(DEVDISK_BY_UUID_DIRECTORY).each do |file|
29
+ qualified_file = File.join(DEVDISK_BY_UUID_DIRECTORY, file)
30
+
31
+ #A uuid is 16 octets long (RFC4122) which is 32hex chars + 4 '-'s
32
+ next unless file.length == 36
33
+ next unless File.symlink?(qualified_file)
34
+ next unless File.readlink(qualified_file).match(%r[(?:\.\./\.\./|/dev/)#{partition}$])
35
+
36
+ uuid = file
37
+ end
38
+ end
39
+ uuid
40
+ end
41
+
42
+ def self.size(partition)
43
+ read_size(partition)
44
+ end
45
+
46
+ def self.mount(partition)
47
+ if Facter::Core::Execution.which('mount')
48
+ Facter::Core::Execution.exec('mount').scan(/\/dev\/#{partition}\son\s(\S+)/).flatten.first
49
+ end
50
+ end
51
+
52
+ def self.filesystem(partition)
53
+ if Facter::Core::Execution.which('blkid')
54
+ Facter::Core::Execution.exec("blkid #{File.join('/dev', partition)}").scan(/TYPE="(.+)"/).flatten.first
55
+ end
56
+ end
57
+
58
+ private
59
+ def self.read_size(partition)
60
+ if device = partition.match(/(\D+)/)[1] and File.readable?(File.join(SYSFS_BLOCK_DIRECTORY, device, partition, 'size'))
61
+ File.read(File.join(SYSFS_BLOCK_DIRECTORY, device, partition, 'size')).chomp
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,16 @@
1
+ module Facter
2
+ module Util
3
+ module POSIX
4
+ # Provides a consistent way of invoking sysctl(8) across POSIX platforms
5
+ #
6
+ # @param mib [String] the sysctl(8) MIB name
7
+ #
8
+ # @api private
9
+ def sysctl(mib)
10
+ Facter::Util::Resolution.exec("sysctl -n #{mib} 2>/dev/null")
11
+ end
12
+
13
+ module_function :sysctl
14
+ end
15
+ end
16
+ end
@@ -271,16 +271,14 @@ module Processor
271
271
  def self.enum_kstat
272
272
  processor_num = -1
273
273
  processor_list = []
274
- Thread::exclusive do
275
- kstat = Facter::Core::Execution.exec('/usr/bin/kstat cpu_info')
276
- if kstat
277
- kstat.each_line do |l|
278
- if l =~ /cpu_info(\d+)/
279
- processor_num = $1.to_i
280
- elsif l =~ /brand\s+(.*)\s*$/
281
- processor_list[processor_num] = $1 unless processor_num == -1
282
- processor_num = -1
283
- end
274
+ kstat = Facter::Core::Execution.exec('/usr/bin/kstat cpu_info')
275
+ if kstat
276
+ kstat.each_line do |l|
277
+ if l =~ /cpu_info(\d+)/
278
+ processor_num = $1.to_i
279
+ elsif l =~ /brand\s+(.*)\s*$/
280
+ processor_list[processor_num] = $1 unless processor_num == -1
281
+ processor_num = -1
284
282
  end
285
283
  end
286
284
  end
@@ -62,6 +62,10 @@ class Facter::Util::Resolution
62
62
  @weight = nil
63
63
  end
64
64
 
65
+ def resolution_type
66
+ :simple
67
+ end
68
+
65
69
  # Evaluate the given block in the context of this resolution. If a block has
66
70
  # already been evaluated emit a warning to that effect.
67
71
  #
@@ -1,3 +1,4 @@
1
+
1
2
  module Facter
2
3
  module Util
3
4
  # A util module for facter containing helper methods
@@ -75,6 +76,34 @@ module Facter
75
76
  value = value.downcase if value.is_a?(String)
76
77
  value
77
78
  end
79
+
80
+ # Flatten the given data structure to something that's suitable to return
81
+ # as flat facts.
82
+ #
83
+ # @param path [String] The fact path to be prefixed to the given value.
84
+ # @param structure [Object] The data structure to flatten. Nested hashes
85
+ # will be recursively flattened, everything else will be returned as-is.
86
+ #
87
+ # @return [Hash] The given data structure prefixed with the given path
88
+ def flatten_structure(path, structure)
89
+ results = {}
90
+
91
+ if structure.is_a? Hash
92
+ structure.each_pair do |name, value|
93
+ new_path = "#{path}_#{name}".gsub(/\-|\//, '_')
94
+ results.merge! flatten_structure(new_path, value)
95
+ end
96
+ elsif structure.is_a? Array
97
+ structure.each_with_index do |value, index|
98
+ new_path = "#{path}_#{index}"
99
+ results.merge! flatten_structure(new_path, value)
100
+ end
101
+ else
102
+ results[path] = structure
103
+ end
104
+
105
+ results
106
+ end
78
107
  end
79
108
  end
80
109
  end
@@ -1,4 +1,6 @@
1
+ require 'facter/util/posix'
1
2
  require 'facter/util/file_read'
3
+ require 'pathname'
2
4
 
3
5
  module Facter::Util::Virtual
4
6
  ##
@@ -92,7 +94,7 @@ module Facter::Util::Virtual
92
94
  txt = if FileTest.exists?("/proc/cpuinfo")
93
95
  File.read("/proc/cpuinfo")
94
96
  elsif ["FreeBSD", "OpenBSD"].include? Facter.value(:kernel)
95
- Facter::Core::Execution.exec("/sbin/sysctl -n hw.model")
97
+ Facter::Util::POSIX.sysctl("hw.model")
96
98
  end
97
99
  (txt =~ /QEMU Virtual CPU/) ? true : false
98
100
  end
@@ -118,6 +120,10 @@ module Facter::Util::Virtual
118
120
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /oVirt Node/ rescue false
119
121
  end
120
122
 
123
+ def self.gce?
124
+ File.read("/sys/devices/virtual/dmi/id/product_name") =~ /Google/ rescue false
125
+ end
126
+
121
127
  def self.jail?
122
128
  path = case Facter.value(:kernel)
123
129
  when "FreeBSD" then "/sbin"
@@ -130,6 +136,29 @@ module Facter::Util::Virtual
130
136
  Facter::Core::Execution.exec("/usr/bin/getconf MACHINE_MODEL").chomp =~ /Virtual Machine/
131
137
  end
132
138
 
139
+ ##
140
+ # lxc? returns true if the process is running inside of a linux container.
141
+ # Implementation derived from
142
+ # http://stackoverflow.com/questions/20010199/determining-if-a-process-runs-inside-lxc-docker
143
+ def self.lxc?
144
+ path = Pathname.new('/proc/1/cgroup')
145
+ return false unless path.readable?
146
+ in_lxc = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/lxc/' }
147
+ return true if in_lxc
148
+ return false
149
+ end
150
+
151
+ ##
152
+ # docker? returns true if the process is running inside of a docker container.
153
+ # Implementation derived from observation of a boot2docker system
154
+ def self.docker?
155
+ path = Pathname.new('/proc/1/cgroup')
156
+ return false unless path.readable?
157
+ in_docker = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/docker/' }
158
+ return true if in_docker
159
+ return false
160
+ end
161
+
133
162
  def self.zlinux?
134
163
  "zlinux"
135
164
  end
@@ -142,9 +171,9 @@ module Facter::Util::Virtual
142
171
  #
143
172
  # @api public
144
173
  #
145
- # @return [String] or nil if the path does not exist
174
+ # @return [String] or nil if the path does not exist or is unreadable
146
175
  def self.read_sysfs_dmi_entries(path="/sys/firmware/dmi/entries/1-0/raw")
147
- if File.exists?(path)
176
+ if File.readable?(path)
148
177
  Facter::Util::FileRead.read_binary(path)
149
178
  end
150
179
  end