diff --git a/lib/linux_admin.rb b/lib/linux_admin.rb index 99e8607..de3c9e0 100644 --- a/lib/linux_admin.rb +++ b/lib/linux_admin.rb @@ -5,7 +5,6 @@ require 'linux_admin/common' require 'linux_admin/exceptions' -require 'linux_admin/package' require 'linux_admin/rpm' require 'linux_admin/deb' require 'linux_admin/version' diff --git a/lib/linux_admin/common.rb b/lib/linux_admin/common.rb index a194b42..fcbeb03 100644 --- a/lib/linux_admin/common.rb +++ b/lib/linux_admin/common.rb @@ -3,7 +3,7 @@ class LinuxAdmin module Common def cmd(cmd) - Distros::Distro.local.class::COMMANDS[cmd] + Distros.local.command(cmd) end def run(cmd, options = {}) diff --git a/lib/linux_admin/deb.rb b/lib/linux_admin/deb.rb index 8bf7639..1e50f15 100644 --- a/lib/linux_admin/deb.rb +++ b/lib/linux_admin/deb.rb @@ -4,7 +4,7 @@ # Licensed under the MIT License class LinuxAdmin - class Deb < Package + class Deb APT_CACHE_CMD = '/usr/bin/apt-cache' def self.from_line(apt_cache_line, in_description=false) @@ -34,6 +34,5 @@ def self.from_string(apt_cache_string) def self.info(pkg) self.from_string(run!(APT_CACHE_CMD, :params => ["show", pkg]).output) end - end end diff --git a/lib/linux_admin/distro.rb b/lib/linux_admin/distro.rb index 39fef36..31fba7b 100644 --- a/lib/linux_admin/distro.rb +++ b/lib/linux_admin/distro.rb @@ -8,135 +8,60 @@ class LinuxAdmin module Distros def self.generic - @generic ||= Generic.new - end - - def self.redhat - @redhat ||= RedHat.new + @generic ||= Distro.new(:generic) end def self.rhel - @rhel ||= RHEL.new + @rhel ||= Distro.new(:rhel, '/etc/redhat-release', ['red hat', 'centos'], LinuxAdmin::Rpm) end def self.fedora - @fedora ||= Fedora.new + @fedora ||= Distro.new(:fedora, "/etc/fedora-release", ['Fedora'], LinuxAdmin::Rpm) end def self.ubuntu - @ubuntu ||= Ubuntu.new + @ubuntu ||= Distro.new(:ubuntu, nil, ['ubuntu'], LinuxAdmin::Deb) end def self.all - @distros ||= [generic, redhat, ubuntu] + @distros ||= [rhel, fedora, ubuntu, generic] end def self.local - Distro.local + @local ||= begin + Distros.all.detect(&:detected?) || Distros.generic + end end class Distro - RELEASE_FILE = '' - ETC_ISSUE_KEYWORDS = [] - - def self.etc_issue_keywords - self::ETC_ISSUE_KEYWORDS + attr_accessor :release_file, :etc_issue_keywords, :info_class + + def initialize(id, release_file = nil, etc_issue_keywords = [], info_class = nil) + @id = id + @path = %w(/sbin /bin /usr/bin /usr/sbin) + @release_file = release_file + @etc_issue_keywords = etc_issue_keywords + @info_class = info_class end - def self.release_file - self::RELEASE_FILE - end - - def self.local - # this can be cleaned up.. - @local ||= begin - result = nil - Distros.constants.each do |cdistro| - distro_method = cdistro.to_s.downcase.to_sym - distro = Distros.const_get(cdistro) - next unless distro < Distro - result = Distros.send(distro_method) if distro.detected? - end - result || Distros.generic - end - end - - def self.detected? + def detected? detected_by_etc_issue? || detected_by_etc_release? end - def self.detected_by_etc_issue? - etc_issue_keywords.any? { |k| EtcIssue.instance.to_s.include?(k) } + def detected_by_etc_issue? + etc_issue_keywords && etc_issue_keywords.any? { |k| EtcIssue.instance.include?(k) } end - def self.detected_by_etc_release? - File.exists?(release_file) + def detected_by_etc_release? + release_file && File.exists?(release_file) end - end - - class Generic < Distro - COMMANDS = {} - def initialize - @id = :generic + def command(name) + @path.collect { |dir| "#{dir}/#{name}" }.detect { |cmd| File.exists?(cmd) } end - end - - class RedHat < Distro - COMMANDS = {:service => '/sbin/service', - :chkconfig => '/sbin/chkconfig', - :parted => '/sbin/parted', - :mount => '/bin/mount', - :umount => '/bin/umount', - :shutdown => '/sbin/shutdown', - :mke2fs => '/sbin/mke2fs', - :fdisk => '/sbin/fdisk', - :dd => '/bin/dd', - :vgdisplay => '/sbin/vgdisplay', - :pvdisplay => '/sbin/pvdisplay', - :lvdisplay => '/sbin/lvdisplay', - :lvextend => '/sbin/lvextend', - :vgextend => '/sbin/vgextend', - :lvcreate => '/sbin/lvcreate', - :pvcreate => '/sbin/pvcreate', - :vgcreate => '/sbin/vgcreate'} - - def initialize - @id = :redhat - end - end - - class RHEL < RedHat - RELEASE_FILE = "/etc/redhat-release" - ETC_ISSUE_KEYWORDS = ['red hat', 'Red Hat', 'centos', 'CentOS'] - - COMMANDS = COMMANDS.merge( - :rpm => '/bin/rpm' - ) - def initialize - @id = :rhel - end - end - - class Fedora < RedHat - RELEASE_FILE = "/etc/fedora-release" - ETC_ISSUE_KEYWORDS = ['Fedora'] - - COMMANDS = COMMANDS.merge( - :rpm => '/usr/bin/rpm' - ) - def initialize - @id = :fedora - end - end - - class Ubuntu < Distro - ETC_ISSUE_KEYWORDS = ['ubuntu'] - - COMMANDS = {} - def initialize - @id = :ubuntu + def info(pkg) + info_class ? info_class.info(pkg) : nil end end end diff --git a/lib/linux_admin/etc_issue.rb b/lib/linux_admin/etc_issue.rb index 33c184d..2de69ea 100644 --- a/lib/linux_admin/etc_issue.rb +++ b/lib/linux_admin/etc_issue.rb @@ -11,18 +11,16 @@ class EtcIssue PATH = '/etc/issue' - def initialize - refresh + def include?(osname) + data.downcase.include?(osname.to_s.downcase) end - def to_s - @data.to_s + def data + @data ||= File.exists?(PATH) ? File.read(PATH) : "" end - private - def refresh - @data = File.exists?(PATH) ? File.read(PATH) : "" + @data = nil end end end diff --git a/lib/linux_admin/package.rb b/lib/linux_admin/package.rb deleted file mode 100644 index 364591c..0000000 --- a/lib/linux_admin/package.rb +++ /dev/null @@ -1,18 +0,0 @@ -# LinuxAdmin Abstract Package Representation -# -# Copyright (C) 2013 Red Hat Inc. -# Licensed under the MIT License - -class LinuxAdmin - class Package < LinuxAdmin - def self.info(pkg) - if Distros::Distro.local == Distros.redhat - return Rpm.info(pkg) - elsif Distros::Distro.local == Distros.ubuntu - return Deb.info(pkg) - end - - nil - end - end -end diff --git a/lib/linux_admin/rpm.rb b/lib/linux_admin/rpm.rb index db5506e..6d10301 100644 --- a/lib/linux_admin/rpm.rb +++ b/lib/linux_admin/rpm.rb @@ -1,7 +1,7 @@ class LinuxAdmin - class Rpm < Package + class Rpm def self.rpm_cmd - Distros::Distro.local.class::COMMANDS[:rpm] + Distros.local.command(:rpm) end def self.list_installed diff --git a/spec/common_spec.rb b/spec/common_spec.rb index 941940c..5e9e4fc 100644 --- a/spec/common_spec.rb +++ b/spec/common_spec.rb @@ -1,24 +1,11 @@ require 'spec_helper' describe LinuxAdmin::Common do - before do - class TestClass - extend LinuxAdmin::Common - end - end - - after do - Object.send(:remove_const, :TestClass) - end - - subject { TestClass } + subject { Class.new { include LinuxAdmin::Common }.new } context "#cmd" do it "looks up local command from id" do - d = double(LinuxAdmin::Distros::Distro) - d.class::COMMANDS = {:sh => '/bin/sh'} - LinuxAdmin::Distros::Distro.should_receive(:local).and_return(d) - subject.cmd(:sh).should == '/bin/sh' + expect(subject.cmd(:dd)).to match(/bin\/dd/) end end diff --git a/spec/distro_spec.rb b/spec/distro_spec.rb index 77b0e96..2364fa4 100644 --- a/spec/distro_spec.rb +++ b/spec/distro_spec.rb @@ -1,7 +1,12 @@ require 'spec_helper' describe LinuxAdmin::Distros::Distro do + let(:subject) { LinuxAdmin::Distros.local } describe "#local" do + before do + LinuxAdmin::Distros.unstub(:local) + end + [['ubuntu', :ubuntu], ['Fedora', :fedora], ['red hat', :rhel], @@ -9,45 +14,66 @@ ['centos', :rhel]].each do |i, d| context "/etc/issue contains '#{i}'" do before(:each) do - LinuxAdmin::EtcIssue.instance.should_receive(:to_s).at_least(:once).and_return(i) - File.should_receive(:exists?).at_least(:once).and_return(false) + etc_issue_contains(i) + exists("/etc/fedora-release" => false, "/etc/redhat-release" => false) end it "returns Distros.#{d}" do distro = LinuxAdmin::Distros.send(d) - described_class.local.should == distro + expect(subject).to eq(distro) end end end context "/etc/issue did not match" do before(:each) do - LinuxAdmin::EtcIssue.instance.should_receive(:to_s).at_least(:once).and_return('') + etc_issue_contains('') end context "/etc/redhat-release exists" do it "returns Distros.rhel" do - File.should_receive(:exists?).with('/etc/redhat-release').and_return(true) - LinuxAdmin::Distros::Fedora.should_receive(:detected?).and_return(false) - File.should_receive(:exists?).at_least(:once).and_call_original - described_class.local.should == LinuxAdmin::Distros.rhel + exists("/etc/fedora-release" => false, "/etc/redhat-release" => true) + expect(subject).to eq(LinuxAdmin::Distros.rhel) end end context "/etc/fedora-release exists" do it "returns Distros.fedora" do - File.should_receive(:exists?).with('/etc/redhat-release').and_return(false) - File.should_receive(:exists?).with('/etc/fedora-release').and_return(true) - File.should_receive(:exists?).at_least(:once).and_call_original - described_class.local.should == LinuxAdmin::Distros.fedora + exists("/etc/fedora-release" => true, "/etc/redhat-release" => false) + expect(subject).to eq(LinuxAdmin::Distros.fedora) end end end it "returns Distros.generic" do - LinuxAdmin::EtcIssue.instance.should_receive(:to_s).at_least(:once).and_return('') - File.should_receive(:exists?).at_least(:once).and_return(false) - described_class.local.should == LinuxAdmin::Distros.generic + etc_issue_contains('') + exists("/etc/fedora-release" => false, "/etc/redhat-release" => false) + expect(subject).to eq(LinuxAdmin::Distros.generic) + end + end + + describe "#info" do + it "dispatches to redhat lookup mechanism" do + stub_distro(LinuxAdmin::Distros.rhel) + expect(LinuxAdmin::Rpm).to receive(:info).with('ruby') + LinuxAdmin::Distros.local.info 'ruby' + end + + it "dispatches to ubuntu lookup mechanism" do + stub_distro(LinuxAdmin::Distros.ubuntu) + expect(LinuxAdmin::Deb).to receive(:info).with('ruby') + LinuxAdmin::Distros.local.info 'ruby' + end + + it "dispatches to ubuntu lookup mechanism" do + stub_distro(LinuxAdmin::Distros.generic) + expect { LinuxAdmin::Distros.local.info 'ruby' }.not_to raise_error end end + + private + + def exists(files) + files.each_pair { |file, value| allow(File).to receive(:exists?).with(file).and_return(value) } + end end diff --git a/spec/etc_issue_spec.rb b/spec/etc_issue_spec.rb new file mode 100644 index 0000000..bc911d4 --- /dev/null +++ b/spec/etc_issue_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' +require 'stringio' + +describe LinuxAdmin::EtcIssue do + subject { described_class.instance } + before do + # Reset the singleton so subsequent tests get a new instance + subject.refresh + end + + it "should not find the phrase when the file is missing" do + expect(File).to receive(:exists?).with('/etc/issue').at_least(:once).and_return(false) + expect(subject).not_to include("phrase") + end + + it "should not find phrase when the file is empty" do + etc_issue_contains("") + expect(subject).not_to include("phrase") + end + + it "should not find phrase when the file has a different phrase" do + etc_issue_contains("something\nelse") + expect(subject).not_to include("phrase") + end + + it "should find phrase in same case" do + etc_issue_contains("phrase") + expect(subject).to include("phrase") + end + + it "should find upper phrase in file" do + etc_issue_contains("PHRASE\nother") + expect(subject).to include("phrase") + end + + it "should find phrase when searching with upper" do + etc_issue_contains("other\nphrase") + expect(subject).to include("PHRASE") + end +end diff --git a/spec/logical_volume_spec.rb b/spec/logical_volume_spec.rb index 4f07360..a039e56 100644 --- a/spec/logical_volume_spec.rb +++ b/spec/logical_volume_spec.rb @@ -2,8 +2,6 @@ describe LinuxAdmin::LogicalVolume do before(:each) do - LinuxAdmin::Distros::Distro.stub(:local => LinuxAdmin::Distros::Test.new) - @logical_volumes = < LinuxAdmin::Distros::Test.new) - @physical_volumes = < distro) +end def data_file_path(to) File.expand_path(to, File.join(File.dirname(__FILE__), "data")) @@ -47,10 +59,3 @@ def sample_output(to) def clear_caches LinuxAdmin::RegistrationSystem.instance_variable_set(:@registration_type, nil) end - -class LinuxAdmin - module Distros - # simply alias test distro to redhat distro for time being - Distros::Test = Distros::RedHat - end -end diff --git a/spec/volume_group_spec.rb b/spec/volume_group_spec.rb index c68d425..c25ecbf 100644 --- a/spec/volume_group_spec.rb +++ b/spec/volume_group_spec.rb @@ -2,8 +2,6 @@ describe LinuxAdmin::VolumeGroup do before(:each) do - LinuxAdmin::Distros::Distro.stub(:local => LinuxAdmin::Distros::Test.new) - @groups = <