From 657cd7126e6d01f883c2e038dae449aea30db5d0 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Fri, 14 Oct 2022 17:35:56 +0200 Subject: [PATCH] Determine root_home without shelling out This uses Ruby's Etc library to determine the root home. This avoids shelling out and writing multiple implementations. --- lib/facter/root_home.rb | 48 +++------------------- spec/unit/facter/root_home_spec.rb | 66 +++++------------------------- 2 files changed, 15 insertions(+), 99 deletions(-) diff --git a/lib/facter/root_home.rb b/lib/facter/root_home.rb index b8d8f5ddc..0e1764254 100644 --- a/lib/facter/root_home.rb +++ b/lib/facter/root_home.rb @@ -1,49 +1,11 @@ # frozen_string_literal: true -# root_home.rb -module Facter::Util::RootHome - # @summary - # A facter fact to determine the root home directory. - # This varies on PE supported platforms and may be - # reconfigured by the end user. - class << self - # determines the root home directory - def returnt_root_home - root_ent = Facter::Core::Execution.execute('getent passwd root') - # The home directory is the sixth element in the passwd entry - # If the platform doesn't have getent, root_ent will be nil and we should - # return it straight away. - root_ent && root_ent.split(':')[5] - end - end -end - -Facter.add(:root_home) do - setcode { Facter::Util::RootHome.returnt_root_home } -end - -Facter.add(:root_home) do - confine kernel: :darwin - setcode do - str = Facter::Core::Execution.execute('dscacheutil -q user -a name root') - hash = {} - str.split("\n").each do |pair| - key, value = pair.split(%r{:}) - hash[key] = value - end - hash['dir'].strip - end -end - Facter.add(:root_home) do - confine kernel: :aix - root_home = nil setcode do - str = Facter::Core::Execution.execute('lsuser -c -a home root') - str&.split("\n")&.each do |line| - next if %r{^#}.match?(line) - root_home = line.split(%r{:})[1] - end - root_home + require 'etc' + rescue LoadError + # Unavailable on platforms like Windows + else + Etc.getpwnam('root').dir end end diff --git a/spec/unit/facter/root_home_spec.rb b/spec/unit/facter/root_home_spec.rb index 14555fe3e..4b9648d6c 100644 --- a/spec/unit/facter/root_home_spec.rb +++ b/spec/unit/facter/root_home_spec.rb @@ -2,66 +2,20 @@ require 'spec_helper' require 'facter/root_home' -describe 'Root Home Specs' do - describe Facter::Util::RootHome do - context 'when solaris' do - let(:root_ent) { 'root:x:0:0:Super-User:/:/sbin/sh' } - let(:expected_root_home) { '/' } - it 'returns /' do - expect(Facter::Core::Execution).to receive(:execute).with('getent passwd root').and_return(root_ent) - expect(described_class.returnt_root_home).to eq(expected_root_home) - end - end - context 'when linux' do - let(:root_ent) { 'root:x:0:0:root:/root:/bin/bash' } - let(:expected_root_home) { '/root' } +describe 'root_home', type: :fact do + subject { Facter.fact(:root_home) } - it 'returns /root' do - expect(Facter::Core::Execution).to receive(:execute).with('getent passwd root').and_return(root_ent) - expect(described_class.returnt_root_home).to eq(expected_root_home) - end - end - context 'when windows' do - it 'is nil on windows' do - expect(Facter::Core::Execution).to receive(:execute).with('getent passwd root').and_return(nil) - expect(described_class.returnt_root_home).to be_nil - end - end - end - - describe 'root_home', type: :fact do - before(:each) { Facter.clear } - after(:each) { Facter.clear } - - context 'when macosx' do - before(:each) do - allow(Facter.fact(:kernel)).to receive(:value).and_return('Darwin') - allow(Facter.fact(:osfamily)).to receive(:value).and_return('Darwin') - end - let(:expected_root_home) { '/var/root' } + before(:each) { Facter.clear } + after(:each) { Facter.clear } - sample_dscacheutil = File.read(fixtures('dscacheutil', 'root')) - - it 'returns /var/root' do - allow(Facter::Core::Execution).to receive(:execute).with('dscacheutil -q user -a name root').and_return(sample_dscacheutil) - expect(Facter.fact(:root_home).value).to eq(expected_root_home) - end - end - - context 'when aix' do - before(:each) do - allow(Facter.fact(:kernel)).to receive(:value).and_return('AIX') - allow(Facter.fact(:osfamily)).to receive(:value).and_return('AIX') - end - let(:expected_root_home) { '/root' } + context 'when Windows', if: Facter.value(:kernel) == 'Windows' do + it { expect(subject.value).to be(nil) } + end - sample_lsuser = File.read(fixtures('lsuser', 'root')) + context 'when non-Windows', if: Facter.value(:kernel) != 'Windows' do + let(:expected) { Facter.value(:kernel) == 'Darwin' ? '/var/root' : '/root' } - it 'returns /root' do - allow(Facter::Core::Execution).to receive(:execute).with('lsuser -c -a home root').and_return(sample_lsuser) - expect(Facter.fact(:root_home).value).to eq(expected_root_home) - end - end + it { expect(subject.value).to eq(expected) } end end