From 92a533ac2ec5860dde504e4c6af0778cef37026a Mon Sep 17 00:00:00 2001 From: Davide Cavalca Date: Thu, 3 Mar 2016 10:22:26 -0800 Subject: [PATCH 1/4] add plugin to detect user sessions using loginctl --- lib/ohai/plugins/linux/sessions.rb | 55 +++++++++++++ spec/unit/plugins/linux/sessions_spec.rb | 98 ++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 lib/ohai/plugins/linux/sessions.rb create mode 100644 spec/unit/plugins/linux/sessions_spec.rb diff --git a/lib/ohai/plugins/linux/sessions.rb b/lib/ohai/plugins/linux/sessions.rb new file mode 100644 index 000000000..3f72a0116 --- /dev/null +++ b/lib/ohai/plugins/linux/sessions.rb @@ -0,0 +1,55 @@ +# +# Author:: Davide Cavalca +# Copyright:: Copyright (c) 2016 Facebook +# 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 "ohai/util/file_helper" + +include Ohai::Util::FileHelper + +Ohai.plugin(:Sessions) do + provides "sessions/by_session", "sessions/by_user" + + collect_data(:linux) do + sessions Mash.new unless sessions + + loginctl_path = which("loginctl") + if loginctl_path + cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " + + "list-sessions" + loginctl = shell_out(cmd) + + sessions[:by_session] = Mash.new unless sessions[:by_session] + sessions[:by_user] = Mash.new unless sessions[:by_user] + + loginctl.stdout.split("\n").each do |line| + session, uid, user, seat = line.split + s = { + "session" => session, + "uid" => uid, + "user" => user, + "seat" => seat, + } + sessions[:by_session][session] = s + if sessions[:by_user][user] + sessions[:by_user][user] << s + else + sessions[:by_user][user] = [s] + end + end + end + end +end diff --git a/spec/unit/plugins/linux/sessions_spec.rb b/spec/unit/plugins/linux/sessions_spec.rb new file mode 100644 index 000000000..c35015e0f --- /dev/null +++ b/spec/unit/plugins/linux/sessions_spec.rb @@ -0,0 +1,98 @@ +# +# Author:: Davide Cavalca +# Copyright:: Copyright (c) 2016 Facebook +# 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 File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper.rb") + +describe Ohai::System, "Linux sessions plugin" do + let(:plugin) { get_plugin("linux/sessions") } + + before(:each) do + allow(plugin).to receive(:collect_os).and_return(:linux) + end + + it "should populate sessions if loginctl is found" do + loginctl_out = <<-LOGINCTL_OUT + c1 118 Debian-gdm seat0 + 318 0 root + 46 0 root + 306 1000 joe +LOGINCTL_OUT + allow(plugin).to receive(:which).with("loginctl").and_return("/bin/loginctl") + allow(plugin).to receive(:shell_out).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) + plugin.run + expect(plugin[:sessions].to_hash).to eq({ + "by_session" => { + "c1" => { + "session" => "c1", + "uid" => "118", + "user" => "Debian-gdm", + "seat" => "seat0", + }, + "318" => { + "session" => "318", + "uid" => "0", + "user" => "root", + "seat" => nil, + }, + "46" => { + "session" => "46", + "uid" => "0", + "user" => "root", + "seat" => nil, + }, + "306" => { + "session" => "306", + "uid" => "1000", + "user" => "joe", + "seat" => nil, + } + }, + "by_user" => { + "Debian-gdm" => [{ + "session" => "c1", + "uid" => "118", + "user" => "Debian-gdm", + "seat" => "seat0", + }], + "root" => [{ + "session" => "318", + "uid" => "0", + "user" => "root", + "seat" => nil + }, { + "session" => "46", + "uid" => "0", + "user" => "root", + "seat" => nil, + }], + "joe" => [{ + "session" => "306", + "uid" => "1000", + "user" => "joe", + "seat" => nil, + }], + }, + }) + end + + it "should not populate sessions if loginctl is not found" do + allow(plugin).to receive(:which).with("loginctl").and_return(false) + plugin.run + expect(plugin[:sessions]).to eq({}) + end +end From 13c86a5fc571bc45ca37c889e77d6dc970596ee5 Mon Sep 17 00:00:00 2001 From: Davide Cavalca Date: Mon, 7 Mar 2016 12:02:52 -0800 Subject: [PATCH 2/4] do not create mash until after the shellout --- lib/ohai/plugins/linux/sessions.rb | 3 +-- spec/unit/plugins/linux/sessions_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ohai/plugins/linux/sessions.rb b/lib/ohai/plugins/linux/sessions.rb index 3f72a0116..f2f33bba8 100644 --- a/lib/ohai/plugins/linux/sessions.rb +++ b/lib/ohai/plugins/linux/sessions.rb @@ -24,14 +24,13 @@ provides "sessions/by_session", "sessions/by_user" collect_data(:linux) do - sessions Mash.new unless sessions - loginctl_path = which("loginctl") if loginctl_path cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " + "list-sessions" loginctl = shell_out(cmd) + sessions Mash.new unless sessions sessions[:by_session] = Mash.new unless sessions[:by_session] sessions[:by_user] = Mash.new unless sessions[:by_user] diff --git a/spec/unit/plugins/linux/sessions_spec.rb b/spec/unit/plugins/linux/sessions_spec.rb index c35015e0f..32936670a 100644 --- a/spec/unit/plugins/linux/sessions_spec.rb +++ b/spec/unit/plugins/linux/sessions_spec.rb @@ -93,6 +93,6 @@ it "should not populate sessions if loginctl is not found" do allow(plugin).to receive(:which).with("loginctl").and_return(false) plugin.run - expect(plugin[:sessions]).to eq({}) + expect(plugin[:sessions]).to be(nil) end end From f5f0e2985f021997d4cdedc683cd77635032e578 Mon Sep 17 00:00:00 2001 From: Davide Cavalca Date: Tue, 8 Mar 2016 10:28:33 -0800 Subject: [PATCH 3/4] use shell_out! --- lib/ohai/plugins/linux/sessions.rb | 3 ++- spec/unit/plugins/linux/sessions_spec.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ohai/plugins/linux/sessions.rb b/lib/ohai/plugins/linux/sessions.rb index f2f33bba8..bd1364c81 100644 --- a/lib/ohai/plugins/linux/sessions.rb +++ b/lib/ohai/plugins/linux/sessions.rb @@ -25,10 +25,11 @@ collect_data(:linux) do loginctl_path = which("loginctl") + if loginctl_path cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " + "list-sessions" - loginctl = shell_out(cmd) + loginctl = shell_out!(cmd) sessions Mash.new unless sessions sessions[:by_session] = Mash.new unless sessions[:by_session] diff --git a/spec/unit/plugins/linux/sessions_spec.rb b/spec/unit/plugins/linux/sessions_spec.rb index 32936670a..1e1ab2c1f 100644 --- a/spec/unit/plugins/linux/sessions_spec.rb +++ b/spec/unit/plugins/linux/sessions_spec.rb @@ -33,7 +33,7 @@ 306 1000 joe LOGINCTL_OUT allow(plugin).to receive(:which).with("loginctl").and_return("/bin/loginctl") - allow(plugin).to receive(:shell_out).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) + allow(plugin).to receive(:shell_out!).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) plugin.run expect(plugin[:sessions].to_hash).to eq({ "by_session" => { From 6c02c7798d05e0e3fd9cfab6254149684b0206ea Mon Sep 17 00:00:00 2001 From: Davide Cavalca Date: Tue, 8 Mar 2016 11:57:59 -0800 Subject: [PATCH 4/4] Revert "use shell_out!" This reverts commit f5f0e2985f021997d4cdedc683cd77635032e578. --- lib/ohai/plugins/linux/sessions.rb | 3 +-- spec/unit/plugins/linux/sessions_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ohai/plugins/linux/sessions.rb b/lib/ohai/plugins/linux/sessions.rb index bd1364c81..f2f33bba8 100644 --- a/lib/ohai/plugins/linux/sessions.rb +++ b/lib/ohai/plugins/linux/sessions.rb @@ -25,11 +25,10 @@ collect_data(:linux) do loginctl_path = which("loginctl") - if loginctl_path cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " + "list-sessions" - loginctl = shell_out!(cmd) + loginctl = shell_out(cmd) sessions Mash.new unless sessions sessions[:by_session] = Mash.new unless sessions[:by_session] diff --git a/spec/unit/plugins/linux/sessions_spec.rb b/spec/unit/plugins/linux/sessions_spec.rb index 1e1ab2c1f..32936670a 100644 --- a/spec/unit/plugins/linux/sessions_spec.rb +++ b/spec/unit/plugins/linux/sessions_spec.rb @@ -33,7 +33,7 @@ 306 1000 joe LOGINCTL_OUT allow(plugin).to receive(:which).with("loginctl").and_return("/bin/loginctl") - allow(plugin).to receive(:shell_out!).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) + allow(plugin).to receive(:shell_out).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) plugin.run expect(plugin[:sessions].to_hash).to eq({ "by_session" => {