diff options
author | Tim Smith <tsmith@chef.io> | 2018-01-10 12:11:30 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-10 12:11:30 -0800 |
commit | 39f241b21926e7dfa07193e89a6880f1a7f5b3c0 (patch) | |
tree | ca30907d6d09761d3a0bcd30eaace32a467552d8 | |
parent | eb6d7c600273d75eeaa63afaf976b511f181f560 (diff) | |
parent | fc5c21a2d578aa557af4e823320c89b022517e1a (diff) | |
download | ohai-39f241b21926e7dfa07193e89a6880f1a7f5b3c0.tar.gz |
Merge pull request #1111 from chef/fix_ec2
Backport support for new EC2 instance types
-rw-r--r-- | lib/ohai/plugins/ec2.rb | 93 | ||||
-rw-r--r-- | spec/unit/plugins/ec2_spec.rb | 74 |
2 files changed, 124 insertions, 43 deletions
diff --git a/lib/ohai/plugins/ec2.rb b/lib/ohai/plugins/ec2.rb index 4d647fb2..454642d4 100644 --- a/lib/ohai/plugins/ec2.rb +++ b/lib/ohai/plugins/ec2.rb @@ -21,65 +21,94 @@ # How we detect EC2 from easiest to hardest & least reliable # 1. Ohai ec2 hint exists. This always works # 2. Xen hypervisor UUID starts with 'ec2'. This catches Linux HVM & paravirt instances -# 3. DMI data mentions amazon. This catches HVM instances in a VPC +# 3. DMI bios version data mentions amazon. This catches HVM instances in a VPC on the Xen based hypervisor +# 3. DMI bios vendor data mentions amazon. This catches HVM instances in a VPC on the non-Xen based hypervisor # 4. Kernel data mentioned Amazon. This catches Windows HVM & paravirt instances -require "ohai/mixin/ec2_metadata" -require "base64" - Ohai.plugin(:EC2) do + require "ohai/mixin/ec2_metadata" + require "base64" + include Ohai::Mixin::Ec2Metadata provides "ec2" - depends "dmi" - depends "kernel" + # look for amazon string in dmi vendor bios data within the sys tree. + # this works even if the system lacks dmidecode use by the Dmi plugin + # this gets us detection of new Xen-less HVM instances that are within a VPC + # @return [Boolean] do we have Amazon DMI data? + def has_ec2_amazon_dmi? + # detect a version of '4.2.amazon' + if file_val_if_exists("/sys/class/dmi/id/bios_vendor") =~ /Amazon/ + Ohai::Log.debug("Plugin EC2: has_ec2_amazon_dmi? == true") + true + else + Ohai::Log.debug("Plugin EC2: has_ec2_amazon_dmi? == false") + false + end + end - # look for amazon string in dmi bios data + # look for amazon string in dmi bios version data within the sys tree. + # this works even if the system lacks dmidecode use by the Dmi plugin # this gets us detection of HVM instances that are within a VPC - def has_ec2_dmi? + # @return [Boolean] do we have Amazon DMI data? + def has_ec2_xen_dmi? # detect a version of '4.2.amazon' - if get_attribute(:dmi, :bios, :all_records, 0, :Version) =~ /amazon/ - Ohai::Log.debug("Plugin EC2: has_ec2_dmi? == true") - return true + if file_val_if_exists("/sys/class/dmi/id/bios_version") =~ /amazon/ + Ohai::Log.debug("Plugin EC2: has_ec2_xen_dmi? == true") + true else - Ohai::Log.debug("Plugin EC2: has_ec2_dmi? == false") - return false + Ohai::Log.debug("Plugin EC2: has_ec2_xen_dmi? == false") + false end end - # looks for a xen UUID that starts with ec2 - # this gets us detection of Linux HVM and Paravirt hosts + # looks for a xen UUID that starts with ec2 from within the Linux sys tree + # @return [Boolean] do we have a Xen UUID or not? def has_ec2_xen_uuid? - if ::File.exist?("/sys/hypervisor/uuid") - if ::File.read("/sys/hypervisor/uuid") =~ /^ec2/ - Ohai::Log.debug("Plugin EC2: has_ec2_xen_uuid? == true") - return true - end + if file_val_if_exists("/sys/hypervisor/uuid") =~ /^ec2/ + Ohai::Log.debug("Plugin EC2: has_ec2_xen_uuid? == true") + return true end Ohai::Log.debug("Plugin EC2: has_ec2_xen_uuid? == false") - return false + false end - # looks for the Amazon.com Organization in Windows Kernel data - # this gets us detection of Windows systems - def has_amazon_org? - # detect an Organization of 'Amazon.com' - if get_attribute(:kernel, :os_info, :organization) =~ /Amazon/ - Ohai::Log.debug("Plugin EC2: has_amazon_org? == true") - return true + # looks at the identifying number WMI value to see if it starts with ec2. + # this is actually the same value we're looking at in has_ec2_xen_uuid? on + # linux hosts + # @return [Boolean] do we have a Xen Identifying Number or not? + def has_ec2_identifying_number? + if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + require "wmi-lite/wmi" + wmi = WmiLite::Wmi.new + if wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"] =~ /^ec2/ + Ohai::Log.debug("Plugin EC2: has_ec2_identifying_number? == true") + return true + end else - Ohai::Log.debug("Plugin EC2: has_amazon_org? == false") - return false + Ohai::Log.debug("Plugin EC2: has_ec2_identifying_number? == false") + false + end + end + + # return the contents of a file if the file exists + # @param path[String] abs path to the file + # @return [String] contents of the file if it exists + def file_val_if_exists(path) + if ::File.exist?(path) + ::File.read(path) end end + # a single check that combines all the various detection methods for EC2 + # @return [Boolean] Does the system appear to be on EC2 def looks_like_ec2? return true if hint?("ec2") # Even if it looks like EC2 try to connect first - if has_ec2_xen_uuid? || has_ec2_dmi? || has_amazon_org? - return true if can_metadata_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) + if has_ec2_xen_uuid? || has_ec2_amazon_dmi? || has_ec2_xen_dmi? || has_ec2_identifying_number? + return true if can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) end end diff --git a/spec/unit/plugins/ec2_spec.rb b/spec/unit/plugins/ec2_spec.rb index ef35cee8..f9c62150 100644 --- a/spec/unit/plugins/ec2_spec.rb +++ b/spec/unit/plugins/ec2_spec.rb @@ -17,20 +17,22 @@ # limitations under the License. # -require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper.rb") +require_relative "../../spec_helper.rb" require "open-uri" require "base64" describe Ohai::System, "plugin ec2" do + let(:plugin) { get_plugin("ec2") } + before(:each) do allow(plugin).to receive(:hint?).with("ec2").and_return(false) allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(false) + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(false) + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(false) end shared_examples_for "!ec2" do - let(:plugin) { get_plugin("ec2") } - it "DOESN'T attempt to fetch the ec2 metadata or set ec2 attribute" do expect(plugin).not_to receive(:http_client) expect(plugin[:ec2]).to be_nil @@ -39,8 +41,6 @@ describe Ohai::System, "plugin ec2" do end shared_examples_for "ec2" do - let(:plugin) { get_plugin("ec2") } - before(:each) do @http_client = double("Net::HTTP client") allow(plugin).to receive(:http_client).and_return(@http_client) @@ -334,19 +334,39 @@ describe Ohai::System, "plugin ec2" do end end # shared examples for ec2 - describe "with ec2 dmi data" do + describe "with amazon dmi bios version data" do it_behaves_like "ec2" before(:each) do - plugin[:dmi] = { :bios => { :all_records => [ { :Version => "4.2.amazon" } ] } } + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(true) + allow(File).to receive(:read).with("/sys/class/dmi/id/bios_version").and_return("4.2.amazon\n") end end - describe "with amazon kernel data" do + describe "with non-amazon dmi bios version data" do + it_behaves_like "!ec2" + + before(:each) do + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(true) + allow(File).to receive(:read).with("/sys/class/dmi/id/bios_version").and_return("1.0\n") + end + end + + describe "with amazon dmi bios vendor data" do it_behaves_like "ec2" before(:each) do - plugin[:kernel] = { :os_info => { :organization => "Amazon.com" } } + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(true) + allow(File).to receive(:read).with("/sys/class/dmi/id/bios_vendor").and_return("Amazon EC2\n") + end + end + + describe "with non-amazon dmi bios vendor data" do + it_behaves_like "!ec2" + + before(:each) do + allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(true) + allow(File).to receive(:read).with("/sys/class/dmi/id/bios_vendor").and_return("Xen\n") end end @@ -355,7 +375,7 @@ describe Ohai::System, "plugin ec2" do before(:each) do allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(true) - allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("ec2a0561-e4d6-8e15-d9c8-2e0e03adcde8") + allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("ec2a0561-e4d6-8e15-d9c8-2e0e03adcde8\n") end end @@ -364,7 +384,39 @@ describe Ohai::System, "plugin ec2" do before(:each) do allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(true) - allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("123a0561-e4d6-8e15-d9c8-2e0e03adcde8") + allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("123a0561-e4d6-8e15-d9c8-2e0e03adcde8\n") + end + end + + describe "with EC2 Identifying Number", :windows_only do + it_behaves_like "ec2" + + before do + allow_any_instance_of(WmiLite::Wmi).to receive(:first_of).and_return( + { "caption" => "Computer System Product", + "description" => "Computer System Product", + "identifyingnumber" => "ec2a355a-91cd-5fe8-bbfc-cc891d0bf9d6", + "name" => "HVM domU", + "skunumber" => nil, + "uuid" => "5A352AEC-CD91-E85F-BBFC-CC891D0BF9D6", + "vendor" => "Xen", + "version" => "4.2.amazon" }) + end + end + + describe "without EC2 Identifying Number", :windows_only do + it_behaves_like "!ec2" + + before do + allow_any_instance_of(WmiLite::Wmi).to receive(:first_of).and_return( + { "caption" => "Computer System Product", + "description" => "Computer System Product", + "identifyingnumber" => "1234", + "name" => "HVM domU", + "skunumber" => nil, + "uuid" => "5A352AEC-CD91-E85F-BBFC-CC891D0BF9D6", + "vendor" => "Xen", + "version" => "1.2.3" }) end end |