Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/linux_admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion lib/linux_admin/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {})
Expand Down
3 changes: 1 addition & 2 deletions lib/linux_admin/deb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
125 changes: 25 additions & 100 deletions lib/linux_admin/distro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 5 additions & 7 deletions lib/linux_admin/etc_issue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 0 additions & 18 deletions lib/linux_admin/package.rb

This file was deleted.

4 changes: 2 additions & 2 deletions lib/linux_admin/rpm.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
17 changes: 2 additions & 15 deletions spec/common_spec.rb
Original file line number Diff line number Diff line change
@@ -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

Expand Down
56 changes: 41 additions & 15 deletions spec/distro_spec.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,79 @@
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],
['CentOS', :rhel],
['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
Loading