diff --git a/lib/ohai/plugins/linux/sessions.rb b/lib/ohai/plugins/linux/sessions.rb new file mode 100644 index 000000000..f2f33bba8 --- /dev/null +++ b/lib/ohai/plugins/linux/sessions.rb @@ -0,0 +1,54 @@ +# +# 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 + 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] + + 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..32936670a --- /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 be(nil) + end +end