Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

OHAI-551 #287

Closed
wants to merge 8 commits into from

4 participants

@atomic-penguin

Add LXC guest hint, and unit test to virtualization.

atomic-penguin added some commits
@atomic-penguin atomic-penguin OHAI-551
Add LXC guest hint, and unit test to virtualization.
84eb297
@atomic-penguin atomic-penguin OHAI-551
Add LXC notes, and full-content cgroup unit tests for LXC.

Change /proc/1/cgroup to /proc/self/cgroup, more consistent
with kernel documentation
[here](https://www.kernel.org/doc/Documentation/cgroups/).

Full-content examples of cgroups in OHAI-551 ticket
[here](https://tickets.opscode.com/browse/OHAI-551?focusedCommentId=47513&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-47513).
0e12854
@atomic-penguin atomic-penguin Add coverage for arbitrarily named cgroups
* Not all platforms may call a cgroup /lxc.
* For example, in the kernel documentation, 'Charlie' is used as an arbitrary cgroup name.
b860e8a
@atomic-penguin atomic-penguin Add lxc host support
* Added regex anchors (^|$) for specificity.
* lxc hosts should match pattern: '<digit>:<subsystem:/' in /proc/self/cgroup
65bd309
@atomic-penguin atomic-penguin Change \w+ to .+, since cgroup names could include dashes d725727
@glensc

container id is not hexadecimal, it's just Docker using hexadecimal LXC names, for pure LXC it's the lxc name:

inside container:

# cat /proc/self/cgroup 
8:perf_event:/lxc/white
7:memory:/lxc/white
6:freezer:/lxc/white
5:devices:/lxc/white
4:cpuset:/lxc/white
3:cpuacct:/lxc/white
2:cpu:/lxc/white
1:blkio:/lxc/white

in the host:

# lxc-ls --fancy
NAME    STATE    IPV4                        IPV6  
-------------------------------------------------
dragon  STOPPED  -                           -     
sshd    STOPPED  -                           -     
test    STOPPED  -                           -     
white   RUNNING  192.168.2.7  -     

Thanks, I saw this on the OHAI-551 ticket, and updated accordingly.

atomic-penguin added some commits
@atomic-penguin atomic-penguin Check specifically for /lxc/ cgroup
* If cgroup is named lxc, with a container name (hex/alpha/digit/dashes), then its an lxc guest.
* If cgroup is named arbitrarily, then its not necessarily an lxc guest.
* If cgroup capabilities exist, and the cgroup is root (/), then its an lxc host.
2dd71b0
@atomic-penguin atomic-penguin OHAI-551
* Add /docker/ LXC guest coverage for docker-0.9.0-master
02d1a30
@glensc

if that regexp is supposed to match this line:
4:cpuacct,cpu:/docker/9c2adaa4c391ec0d3bf994

then perhaps use non-greedy option instead (knowing that separator is :):
%r{^\d+:[^:]+:/(lxc|docker)/.+$}

as you could otherwise match FP: 4:cpuacct,cpu:/whatever/whatever/docker/foo

It doesn't match the '4:cpuacct,cpu:/whatever/whatever/docker/foo' string. Because the ':/(lxc|docker)/' match is non-greedy. The matched pattern would have to be ':/lxc/' or ':/docker/'

':/(lxc|docker)/' !~ ':/whatever/'

Although you're option would be slightly less greedy, by excluding the literal : from the prior field set. I don't think that is a bad idea, will change it.

but .+ is greedy

Right, and I'm not arguing otherwise. I agree with your suggestion, and applied the change to the OHAI-551 branch.

@atomic-penguin atomic-penguin Use less greedy inverse set match.
Rather than using a greedy wildcard like so:

* `%r{^\d+:.+:/(lxc|docker)/.+$}`

Use a less greedy inverse set, which excludes literal colon:

* `%r{^\d+:[^:]+:/(lxc|docker)/.+$}`

Discussion, 02d1a30#diff-725858488c1235840f3a62b4eb7a575fR149
aa188d6
@atomic-penguin

Closing, merged. Trivial change for docker-0.9.0-master support in #307

@adamedx
Owner

If the following pr gets merged, that should fix this, correct? (chef#307)

Yes, I just rebased against master with the two additional commits

Owner

Thanks, rebase appreciated, we'll do a little validation and then merge.

@spheromak

@atomic-penguin @adamedx This regex wont work on boot2docker/dvm vm running containers with ohai 7.0.4

Privileged output:

[kitchen@851ec609c2a4 ~]$ /opt/chef/embedded/bin/irb
irb(main):001:0> File.read("/proc/self/cgroup") =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$}
=> nil
irb(main):002:0> ^D
[kitchen@851ec609c2a4 ~]$ cat /proc/self/cgroup
9:blkio:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/
4:cpu,cpuacct:/
3:cpuset:/
2:name=systemd:/system.slice/docker-851ec609c2a4e6b9c407ae8f44331f90c33366f161667cd81bcfdd8b233691f0.scope

Unprivileged:


[kitchen@93b2c18cd379 ~]$ /opt/chef/embedded/bin/irb
irb(main):001:0>  File.read("/proc/self/cgroup") =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$}
=> nil
irb(main):002:0> ^D
[kitchen@93b2c18cd379 ~]$ cat /proc/self/cgroup
9:blkio:/
8:net_cls:/
7:freezer:/
6:devices:/system.slice/docker-93b2c18cd37904d1e93bc5d77f3fcdc2417da7e822f577266559dd7320fd01ef.scope
5:memory:/
4:cpu,cpuacct:/
3:cpuset:/
2:name=systemd:/system.slice/docker-93b2c18cd37904d1e93bc5d77f3fcdc2417da7e822f577266559dd7320fd01ef.scope
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 8, 2014
  1. @atomic-penguin

    OHAI-551

    atomic-penguin authored
    Add LXC guest hint, and unit test to virtualization.
Commits on Mar 1, 2014
  1. @atomic-penguin

    OHAI-551

    atomic-penguin authored
    Add LXC notes, and full-content cgroup unit tests for LXC.
    
    Change /proc/1/cgroup to /proc/self/cgroup, more consistent
    with kernel documentation
    [here](https://www.kernel.org/doc/Documentation/cgroups/).
    
    Full-content examples of cgroups in OHAI-551 ticket
    [here](https://tickets.opscode.com/browse/OHAI-551?focusedCommentId=47513&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-47513).
Commits on Mar 6, 2014
  1. @atomic-penguin

    Add coverage for arbitrarily named cgroups

    atomic-penguin authored
    * Not all platforms may call a cgroup /lxc.
    * For example, in the kernel documentation, 'Charlie' is used as an arbitrary cgroup name.
  2. @atomic-penguin

    Add lxc host support

    atomic-penguin authored
    * Added regex anchors (^|$) for specificity.
    * lxc hosts should match pattern: '<digit>:<subsystem:/' in /proc/self/cgroup
  3. @atomic-penguin
  4. @atomic-penguin

    Check specifically for /lxc/ cgroup

    atomic-penguin authored
    * If cgroup is named lxc, with a container name (hex/alpha/digit/dashes), then its an lxc guest.
    * If cgroup is named arbitrarily, then its not necessarily an lxc guest.
    * If cgroup capabilities exist, and the cgroup is root (/), then its an lxc host.
Commits on Mar 25, 2014
  1. @atomic-penguin

    OHAI-551

    atomic-penguin authored
    * Add /docker/ LXC guest coverage for docker-0.9.0-master
Commits on Mar 26, 2014
  1. @atomic-penguin

    Use less greedy inverse set match.

    atomic-penguin authored
    Rather than using a greedy wildcard like so:
    
    * `%r{^\d+:.+:/(lxc|docker)/.+$}`
    
    Use a less greedy inverse set, which excludes literal colon:
    
    * `%r{^\d+:[^:]+:/(lxc|docker)/.+$}`
    
    Discussion, 02d1a30#diff-725858488c1235840f3a62b4eb7a575fR149
This page is out of date. Refresh to see the latest.
View
28 lib/ohai/plugins/linux/virtualization.rb
@@ -126,5 +126,33 @@
end
end
end
+
+ # Detect LXC/Docker
+ #
+ # /proc/self/cgroup will look like this inside a docker container:
+ # <index #>:<subsystem>:/lxc/<hexadecimal container id>
+ #
+ # /proc/self/cgroup could have a name including alpha/digit/dashes
+ # <index #>:<subsystem>:/lxc/<named container id>
+ #
+ # /proc/self/cgroup could have a non-lxc cgroup name indicating other uses
+ # of cgroups. This is probably not LXC/Docker.
+ # <index #>:<subsystem>:/Charlie
+ #
+ # A host which supports cgroups, and has capacity to host lxc containers,
+ # will show the subsystems and root (/) namespace.
+ # <index #>:<subsystem>:/
+ #
+ # Full notes, https://tickets.opscode.com/browse/OHAI-551
+ # Kernel docs, https://www.kernel.org/doc/Documentation/cgroups
+ if File.exists?("/proc/self/cgroup")
+ if File.read("/proc/self/cgroup") =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$}
+ virtualization[:system] = "lxc"
+ virtualization[:role] = "guest"
+ elsif File.read("/proc/self/cgroup") =~ %r{\d:[^:]+:/$}
+ virtualization[:system] = "lxc"
+ virtualization[:role] = "host"
+ end
+ end
end
end
View
100 spec/unit/plugins/linux/virtualization_spec.rb
@@ -32,6 +32,7 @@
File.stub(:exists?).with("/proc/self/status").and_return(false)
File.stub(:exists?).with("/proc/bc/0").and_return(false)
File.stub(:exists?).with("/proc/vz").and_return(false)
+ File.stub(:exists?).with("/proc/self/cgroup").and_return(false)
end
describe "when we are checking for xen" do
@@ -262,6 +263,105 @@
end
end
+ describe "when we are checking for lxc" do
+ it "should set lxc guest if /proc/self/cgroup exist and there are /lxc/<hexadecimal> mounts" do
+ self_cgroup=<<-CGROUP
+8:blkio:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+7:net_cls:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+6:freezer:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+5:devices:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+4:memory:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+3:cpuacct:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+2:cpu:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc
+1:cpuset:/
+CGROUP
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(true)
+ File.stub(:read).with("/proc/self/cgroup").and_return(self_cgroup)
+ @plugin.run
+ @plugin[:virtualization][:system].should == "lxc"
+ @plugin[:virtualization][:role].should == "guest"
+ end
+
+ it "should set lxc guest if /proc/self/cgroup exist and there are /lxc/<name> mounts" do
+ self_cgroup=<<-CGROUP
+8:blkio:/lxc/vanilla
+7:net_cls:/lxc/vanilla
+6:freezer:/lxc/vanilla
+5:devices:/lxc/vanilla
+4:memory:/lxc/vanilla
+3:cpuacct:/lxc/vanilla
+2:cpu:/lxc/vanilla
+1:cpuset:/lxc/vanilla
+CGROUP
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(true)
+ File.stub(:read).with("/proc/self/cgroup").and_return(self_cgroup)
+ @plugin.run
+ @plugin[:virtualization][:system].should == "lxc"
+ @plugin[:virtualization][:role].should == "guest"
+ end
+
+ it "should set lxc guest if /proc/self/cgroup exist and there are /docker/<name> mounts" do
+ self_cgroup=<<-CGROUP
+11:hugetlb:/
+10:perf_event:/
+9:blkio:/
+8:net_cls:/
+7:freezer:/
+6:devices:/
+5:memory:/
+4:cpuacct,cpu:/docker/9c2adaa4c391ec0d3bf994fbd91ff30c3d317694d179e5b1dc7e1e4c8ed56b61
+3:cpuset:/
+2:name=systemd:/system.slice/docker.service
+CGROUP
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(true)
+ File.stub(:read).with("/proc/self/cgroup").and_return(self_cgroup)
+ @plugin.run
+ @plugin[:virtualization][:system].should == "lxc"
+ @plugin[:virtualization][:role].should == "guest"
+ end
+
+ it "should set not set anything if /proc/self/cgroup exist and the cgroup is named arbitrarily, it isn't necessarily lxc." do
+ self_cgroup=<<-CGROUP
+8:blkio:/Charlie
+7:net_cls:/Charlie
+6:freezer:/Charlie
+5:devices:/Charlie
+4:memory:/Charlie
+3:cpuacct:/Charlie
+2:cpu:/Charlie
+1:cpuset:/Charlie
+CGROUP
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(true)
+ File.stub(:read).with("/proc/self/cgroup").and_return(self_cgroup)
+ @plugin.run
+ @plugin[:virtualization].should == {}
+ end
+
+ it "should set lxc host if /proc/self/cgroup only has / mounts" do
+ self_cgroup=<<-CGROUP
+8:blkio:/
+7:net_cls:/
+6:freezer:/
+5:devices:/
+4:memory:/
+3:cpuacct:/
+2:cpu:/
+1:cpuset:/
+CGROUP
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(true)
+ File.stub(:read).with("/proc/self/cgroup").and_return(self_cgroup)
+ @plugin.run
+ @plugin[:virtualization][:system].should == "lxc"
+ @plugin[:virtualization][:role].should == "host"
+ end
+
+ it "should not set virtualization if /proc/self/cgroup isn't there" do
+ File.should_receive(:exists?).with("/proc/self/cgroup").and_return(false)
+ @plugin.run
+ @plugin[:virtualization].should == {}
+ end
+ end
+
it "should not set virtualization if no tests match" do
@plugin.run
@plugin[:virtualization].should == {}
Something went wrong with that request. Please try again.