[Pkg-puppet-devel] [facter] 78/180: Add docker detection to virtual and is_virtual facts

Stig Sandbeck Mathisen ssm at debian.org
Mon Jun 30 15:06:33 UTC 2014


This is an automated email from the git hooks/post-receive script.

ssm pushed a commit to branch master
in repository facter.

commit 071cdf6d0ad84eb15c54365a02f97143e03062a5
Author: Jeff McCune <jeff at puppetlabs.com>
Date:   Mon May 5 11:44:23 2014 -0700

    Add docker detection to virtual and is_virtual facts
    
    Without this patch facter is not detecting the Docker virtual
    environment.  This is a problem because docker containers are a
    lightweight virtualization approach and as such should be flagged.
    
    This patch addresses the problem by specifically looking for the docker
    specific substring in the progress group hierarchy of the init process.
    This is very similar, but distinct, from the LXC detection.
    
    Docker builds upon generic Linux containers and customizes the detection
    to indicate a docker specific environment.  This patch detects the
    docker specific environment.
---
 lib/facter/util/virtual.rb                         | 15 +++++++++--
 lib/facter/virtual.rb                              | 11 ++++++++
 .../virtual/proc_1_cgroup/in_a_docker_container    |  8 ++++++
 spec/unit/util/virtual_spec.rb                     | 30 ++++++++++++++++++++++
 spec/unit/virtual_spec.rb                          | 18 +++++++++++++
 5 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/lib/facter/util/virtual.rb b/lib/facter/util/virtual.rb
index 8d22595..fa10674 100644
--- a/lib/facter/util/virtual.rb
+++ b/lib/facter/util/virtual.rb
@@ -138,8 +138,19 @@ module Facter::Util::Virtual
   def self.lxc?
     path = Pathname.new('/proc/1/cgroup')
     return false unless path.readable?
-    lxc_hierarchies = path.readlines.map {|l| l.split(":")[2].to_s.start_with? '/lxc/' }
-    return true if lxc_hierarchies.include?(true)
+    in_lxc = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/lxc/' }
+    return true if in_lxc
+    return false
+  end
+
+  ##
+  # docker? returns true if the process is running inside of a docker container.
+  # Implementation derived from observation of a boot2docker system
+  def self.docker?
+    path = Pathname.new('/proc/1/cgroup')
+    return false unless path.readable?
+    in_docker = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/docker/' }
+    return true if in_docker
     return false
   end
 
diff --git a/lib/facter/virtual.rb b/lib/facter/virtual.rb
index 9f195ea..907da82 100644
--- a/lib/facter/virtual.rb
+++ b/lib/facter/virtual.rb
@@ -265,6 +265,17 @@ Facter.add("virtual") do
   end
 end
 
+##
+# virtual fact specific to docker containers.
+Facter.add("virtual") do
+  has_weight 750
+  confine :kernel => "Linux"
+
+  setcode do
+    "docker" if Facter::Util::Virtual.docker?
+  end
+end
+
 # Fact: is_virtual
 #
 # Purpose: returning true or false for if a machine is virtualised or not.
diff --git a/spec/fixtures/virtual/proc_1_cgroup/in_a_docker_container b/spec/fixtures/virtual/proc_1_cgroup/in_a_docker_container
new file mode 100644
index 0000000..a34d4ea
--- /dev/null
+++ b/spec/fixtures/virtual/proc_1_cgroup/in_a_docker_container
@@ -0,0 +1,8 @@
+9:perf_event:/
+8:blkio:/
+7:freezer:/
+6:devices:/docker/0e3c605ac1470c776c34a8eff362a0c816bcaac78559a43955173bd786281b7f
+5:memory:/
+4:cpuacct:/
+3:cpu:/docker/0e3c605ac1470c776c34a8eff362a0c816bcaac78559a43955173bd786281b7f
+2:cpuset:/
diff --git a/spec/unit/util/virtual_spec.rb b/spec/unit/util/virtual_spec.rb
index e9ef651..2fe57f2 100755
--- a/spec/unit/util/virtual_spec.rb
+++ b/spec/unit/util/virtual_spec.rb
@@ -321,4 +321,34 @@ describe Facter::Util::Virtual do
       end
     end
   end
+
+  describe '.docker?' do
+    subject do
+      Facter::Util::Virtual.docker?
+    end
+
+    fixture_path = fixtures('virtual', 'proc_1_cgroup')
+
+    context '/proc/1/cgroup has at least one hierarchy rooted in /docker/' do
+      before :each do
+        fakepath = Pathname.new(File.join(fixture_path, 'in_a_docker_container'))
+        Pathname.stubs(:new).with('/proc/1/cgroup').returns(fakepath)
+      end
+
+      it 'is true' do
+        subject.should be_true
+      end
+    end
+
+    context '/proc/1/cgroup has no hierarchies rooted in /docker/' do
+      before :each do
+        fakepath = Pathname.new(File.join(fixture_path, 'not_in_a_container'))
+        Pathname.stubs(:new).with('/proc/1/cgroup').returns(fakepath)
+      end
+
+      it 'is false' do
+        subject.should be_false
+      end
+    end
+  end
 end
diff --git a/spec/unit/virtual_spec.rb b/spec/unit/virtual_spec.rb
index 16f08d6..cb18c53 100755
--- a/spec/unit/virtual_spec.rb
+++ b/spec/unit/virtual_spec.rb
@@ -6,6 +6,7 @@ require 'facter/util/macosx'
 
 describe "Virtual fact" do
   before(:each) do
+    Facter::Util::Virtual.stubs(:docker?).returns(false)
     Facter::Util::Virtual.stubs(:lxc?).returns(false)
     Facter::Util::Virtual.stubs(:zone?).returns(false)
     Facter::Util::Virtual.stubs(:openvz?).returns(false)
@@ -182,6 +183,17 @@ describe "Virtual fact" do
       end
     end
 
+    context "In a Docker Container (docker)" do
+      before :each do
+        Facter.fact(:kernel).stubs(:value).returns("Linux")
+      end
+
+      it 'is "docker" when Facter::Util::Virtual.docker? is true' do
+        Facter::Util::Virtual.stubs(:docker?).returns(true)
+        Facter.fact(:virtual).value.should == 'docker'
+      end
+    end
+
     context "In Google Compute Engine" do
       before :each do
         Facter.fact(:kernel).stubs(:value).returns("Linux")
@@ -485,4 +497,10 @@ describe "is_virtual fact" do
     Facter.fact(:virtual).stubs(:value).returns("lxc")
     Facter.fact(:is_virtual).value.should == "true"
   end
+
+  it "should be true when running in docker" do
+    Facter.fact(:kernel).stubs(:value).returns("Linux")
+    Facter.fact(:virtual).stubs(:value).returns("docker")
+    Facter.fact(:is_virtual).value.should == "true"
+  end
 end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git



More information about the Pkg-puppet-devel mailing list