diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2020-01-31 13:54:10 -0800 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2020-01-31 13:54:10 -0800 |
commit | 9ce4eb455526074cc88f398a8397e5d2a62443fa (patch) | |
tree | 2e4b38b643411065340068b2b6b8d34f69f46719 /chef-utils | |
parent | 3023717497cb5540190c1977d578599437325330 (diff) | |
download | chef-9ce4eb455526074cc88f398a8397e5d2a62443fa.tar.gz |
Add chef-sugar virtualization helpers
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
Diffstat (limited to 'chef-utils')
-rw-r--r-- | chef-utils/README.md | 12 | ||||
-rw-r--r-- | chef-utils/lib/chef-utils.rb | 4 | ||||
-rw-r--r-- | chef-utils/lib/chef-utils/dsl/virtualization.rb | 159 | ||||
-rw-r--r-- | chef-utils/spec/spec_helper.rb | 8 | ||||
-rw-r--r-- | chef-utils/spec/unit/dsl/virtualization_spec.rb | 68 |
5 files changed, 247 insertions, 4 deletions
diff --git a/chef-utils/README.md b/chef-utils/README.md index 8116f84c5e..ce62afa64a 100644 --- a/chef-utils/README.md +++ b/chef-utils/README.md @@ -133,6 +133,18 @@ Architecture Helpers allow you to determine the processor architecture of your n * `digital_ocean?` - if the node is running in digital ocean * `softlayer?` - if the node is running in softlayer +### Virtualization Helpers + +* `kvm?` - if the node is a kvm guest +* `lxc?` - if the node is an lxc guest +* `parallels?`- if the node is a parallels guest +* `vbox?` - if the node is a virtualbox guest +* `vmware?` - if the node is a vmware guest +* `openvz?` - if the node is an openvz guest +* `virtual?` - if any of the above are true (guest of any detected virtualization system) +* `physical?` - strictly the logical opposite of `virtual?` +* `vagrant?` - attempts to identify the node as a vagrant guest (this check may be error prone) + ### Train Helpers **EXPERIMENTAL**: APIs may have breaking changes any time without warning diff --git a/chef-utils/lib/chef-utils.rb b/chef-utils/lib/chef-utils.rb index d52c866de5..39c74d3f68 100644 --- a/chef-utils/lib/chef-utils.rb +++ b/chef-utils/lib/chef-utils.rb @@ -24,11 +24,12 @@ require_relative "chef-utils/dsl/platform" require_relative "chef-utils/dsl/platform_family" require_relative "chef-utils/dsl/service" require_relative "chef-utils/dsl/train_helpers" +require_relative "chef-utils/dsl/virtualization" require_relative "chef-utils/dsl/which" require_relative "chef-utils/dsl/windows" require_relative "chef-utils/mash" -# This is the Chef Infra Client DSL, not everytihng needs to go in here +# This is the Chef Infra Client DSL, not everything needs to go in here module ChefUtils include ChefUtils::DSL::Architecture include ChefUtils::DSL::Cloud @@ -38,6 +39,7 @@ module ChefUtils include ChefUtils::DSL::Platform include ChefUtils::DSL::PlatformFamily include ChefUtils::DSL::TrainHelpers + include ChefUtils::DSL::Virtualization include ChefUtils::DSL::Which include ChefUtils::DSL::Windows # ChefUtils::DSL::Service is deliberately excluded diff --git a/chef-utils/lib/chef-utils/dsl/virtualization.rb b/chef-utils/lib/chef-utils/dsl/virtualization.rb new file mode 100644 index 0000000000..eb324bd946 --- /dev/null +++ b/chef-utils/lib/chef-utils/dsl/virtualization.rb @@ -0,0 +1,159 @@ +# +# Copyright:: Copyright 2018-2020, Chef Software 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_relative "../internal" + +module ChefUtils + module DSL + module Virtualization + include Internal + + # Determine if the current node is running under KVM. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def kvm?(node = __getnode) + node.dig("virtualization", "system") == "kvm" + end + + # Determine if the current node is running in a linux container. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def lxc?(node = __getnode) + node.dig("virtualization", "system") == "lxc" + end + + # + # Determine if the current node is running under Parallels Desktop. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # true if the machine is currently running under Parallels Desktop, false + # otherwise + # + def parallels?(node = __getnode) + node.dig("virtualization", "system") == "parallels" + end + + # Determine if the current node is running under VirtualBox. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def vbox?(node = __getnode) + node.dig("virtualization", "system") == "vbox" + end + + alias_method :virtualbox?, :vbox? + + # + # Determine if the current node is running under VMware. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def vmware?(node = __getnode) + node.dig("virtualization", "system") == "vmware" + end + + # Determine if the current node is running under openvz. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def openvz?(node = __getnode) + node.dig("virtualization", "system") == "openvz" + end + + # Determine if the current node is running under any virutalization environment + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def virtual?(node = __getnode) + openvz?(node) || vmware?(node) || virtualbox?(node) || parallels?(node) || lxc?(node) || kvm?(node) + end + + # Determine if the current node is NOT running under any virutalization environment + # + # @param [Chef::Node] node + # + # @return [Boolean] + # + def physical?(node = __getnode) + !virtual?(node) + end + + # Determine if the current node is running in vagrant mode. + # + # Note that this API is equivalent to just looking for the vagrant user or the + # vagrantup.com domain in the hostname, which is the best API we have. + # + # @param [Chef::Node] node + # + # @return [Boolean] + # true if the machine is currently running vagrant, false + # otherwise + # + def vagrant?(node = __getnode) + vagrant_key?(node) || vagrant_domain?(node) || vagrant_user?(node) + end + + private + + # Check if the +vagrant+ key exists on the +node+ object. This key is no + # longer populated by vagrant, but it is kept around for legacy purposes. + # + # @param (see vagrant?) + # @return (see vagrant?) + # + def vagrant_key?(node = __getnode) + node.key?("vagrant") + end + + # Check if "vagrantup.com" is included in the node's domain. + # + # @param (see vagrant?) + # @return (see vagrant?) + # + def vagrant_domain?(node = __getnode) + node.key?("domain") && !node["domain"].nil? && node["domain"].include?("vagrantup.com") + end + + # Check if the system contains a +vagrant+ user. + # + # @param (see vagrant?) + # @return (see vagrant?) + # + def vagrant_user?(node = __getnode) + !!(Etc.getpwnam("vagrant") rescue nil) + end + + extend self + end + end +end diff --git a/chef-utils/spec/spec_helper.rb b/chef-utils/spec/spec_helper.rb index 4d9b5518d1..a44377336e 100644 --- a/chef-utils/spec/spec_helper.rb +++ b/chef-utils/spec/spec_helper.rb @@ -10,17 +10,19 @@ HELPER_MODULES = [ ChefUtils::DSL::Platform, ChefUtils::DSL::PlatformFamily, ChefUtils::DSL::Service, + ChefUtils::DSL::Virtualization, ChefUtils::DSL::Which, ChefUtils::DSL::Windows, ].freeze ARCH_HELPERS = (ChefUtils::DSL::Architecture.methods - Module.methods).freeze +CLOUD_HELPERS = (ChefUtils::DSL::Cloud.methods - Module.methods).freeze +INTROSPECTION_HELPERS = (ChefUtils::DSL::Introspection.methods - Module.methods).freeze OS_HELPERS = (ChefUtils::DSL::OS.methods - Module.methods).freeze -PLATFORM_HELPERS = (ChefUtils::DSL::Platform.methods - Module.methods).freeze PLATFORM_FAMILY_HELPERS = (ChefUtils::DSL::PlatformFamily.methods - Module.methods).freeze -INTROSPECTION_HELPERS = (ChefUtils::DSL::Introspection.methods - Module.methods).freeze +PLATFORM_HELPERS = (ChefUtils::DSL::Platform.methods - Module.methods).freeze +VIRTUALIZATION_HELPERS = (ChefUtils::DSL::Virtualization.methods - Module.methods).freeze WINDOWS_HELPERS = (ChefUtils::DSL::Windows.methods - Module.methods).freeze -CLOUD_HELPERS = (ChefUtils::DSL::Cloud.methods - Module.methods).freeze # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| diff --git a/chef-utils/spec/unit/dsl/virtualization_spec.rb b/chef-utils/spec/unit/dsl/virtualization_spec.rb new file mode 100644 index 0000000000..52b3eb65d1 --- /dev/null +++ b/chef-utils/spec/unit/dsl/virtualization_spec.rb @@ -0,0 +1,68 @@ +# +# Copyright:: Copyright 2018-2020, Chef Software 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 "spec_helper" +require "fauxhai" + +def virtualization_reports_true_for(*args, node:) + args.each do |method| + it "reports true for #{method}" do + expect(described_class.send(method, node)).to be true + end + end + (VIRTUALIZATION_HELPERS - args).each do |method| + it "reports false for #{method}" do + expect(described_class.send(method, node)).to be false + end + end +end + +RSpec.describe ChefUtils::DSL::Virtualization do + ( HELPER_MODULES - [ described_class ] ).each do |klass| + it "does not have methods that collide with #{klass}" do + expect((klass.methods - Module.methods) & VIRTUALIZATION_HELPERS).to be_empty + end + end + + VIRTUALIZATION_HELPERS.each do |helper| + it "has the #{helper} in the ChefUtils module" do + expect(ChefUtils).to respond_to(helper) + end + end + + context "on kvm" do + virtualization_reports_true_for(:virtual?, :kvm?, node: { "virtualization" => { "system" => "kvm" } }) + end + context "on lxc" do + virtualization_reports_true_for(:virtual?, :lxc?, node: { "virtualization" => { "system" => "lxc" } }) + end + context "on parallels" do + virtualization_reports_true_for(:virtual?, :parallels?, node: { "virtualization" => { "system" => "parallels" } }) + end + context "on virtualbox" do + virtualization_reports_true_for(:virtual?, :virtualbox?, :vbox?, node: { "virtualization" => { "system" => "vbox" } }) + end + context "on vmware" do + virtualization_reports_true_for(:virtual?, :vmware?, node: { "virtualization" => { "system" => "vmware" } }) + end + context "on openvz" do + virtualization_reports_true_for(:virtual?, :openvz?, node: { "virtualization" => { "system" => "openvz" } }) + end + context "on anything else" do + virtualization_reports_true_for(:physical?, node: {} ) + end +end |