-
Notifications
You must be signed in to change notification settings - Fork 30
Small fixes to RPM module #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,35 +3,9 @@ | |
# Copyright (C) 2013 Red Hat Inc. | ||
# Licensed under the MIT License | ||
|
||
class LinuxAdmin | ||
class Distro < LinuxAdmin | ||
attr_accessor :id | ||
|
||
def initialize(id) | ||
@id = id | ||
end | ||
|
||
def self.local | ||
@local ||= begin | ||
if File.exists?('/etc/issue') | ||
issue = File.read('/etc/issue') | ||
if issue.include?('ubuntu') | ||
return Distros.ubuntu | ||
elsif ['fedora', 'red hat', 'centos'].any? { |d| issue.downcase.include?(d) } | ||
return Distros.redhat | ||
end | ||
|
||
elsif File.exists?('/etc/redhat-release') || | ||
File.exists?('/etc/fedora-release') | ||
return Distros.redhat | ||
end | ||
|
||
Distros.generic | ||
end | ||
end | ||
|
||
end | ||
require 'linux_admin/etc_issue' | ||
|
||
class LinuxAdmin | ||
module Distros | ||
def self.generic | ||
@generic ||= Generic.new | ||
|
@@ -41,6 +15,14 @@ def self.redhat | |
@redhat ||= RedHat.new | ||
end | ||
|
||
def self.rhel | ||
@rhel ||= RHEL.new | ||
end | ||
|
||
def self.fedora | ||
@fedora ||= Fedora.new | ||
end | ||
|
||
def self.ubuntu | ||
@ubuntu ||= Ubuntu.new | ||
end | ||
|
@@ -49,6 +31,49 @@ def self.all | |
@distros ||= [generic, redhat, ubuntu] | ||
end | ||
|
||
def self.local | ||
Distro.local | ||
end | ||
|
||
class Distro | ||
RELEASE_FILE = '' | ||
ETC_ISSUE_KEYWORDS = [] | ||
|
||
def self.etc_issue_keywords | ||
self::ETC_ISSUE_KEYWORDS | ||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With possible mixins and stuff in the sub-classes, I'm afraid this method could get extra constants you may not be aware of. Can we use |
||
next unless distro < Distro | ||
result = Distros.send(distro_method) if distro.detected? | ||
end | ||
result || Distros.generic | ||
end | ||
end | ||
|
||
def self.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) } | ||
end | ||
|
||
def self.detected_by_etc_release? | ||
File.exists?(release_file) | ||
end | ||
end | ||
|
||
class Generic < Distro | ||
COMMANDS = {} | ||
|
||
|
@@ -81,7 +106,33 @@ def initialize | |
end | ||
end | ||
|
||
class RHEL < RedHat | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As we add/expand these classes, we'll want to split them out into their own files. |
||
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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# LinuxAdmin /etc/issue Representation | ||
# | ||
# Copyright (C) 2014 Red Hat Inc. | ||
# Licensed under the MIT License | ||
|
||
require 'singleton' | ||
|
||
class LinuxAdmin | ||
class EtcIssue | ||
include Singleton | ||
|
||
PATH = '/etc/issue' | ||
|
||
def initialize | ||
refresh | ||
end | ||
|
||
def to_s | ||
@data.to_s | ||
end | ||
|
||
private | ||
|
||
def refresh | ||
@data = File.exists?(PATH) ? File.read(PATH) : "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is a singleton-based class, then is it possible for this to get out of sync? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Fryguy Yes, but this is the OS version file so there's a very high likelihood that you'll need to reboot your linux box when this file changes. |
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
class LinuxAdmin | ||
class Rpm < Package | ||
RPM_CMD = '/usr/bin/rpm' | ||
def self.rpm_cmd | ||
Distros::Distro.local.class::COMMANDS[:rpm] | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be handled through the Distro::COMMANDS? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we have the Distro's, I would suggest using them. Also, Fedora and RHEL should be listed as different distro's. |
||
|
||
def self.list_installed | ||
out = run!("rpm -qa --qf \"%{NAME} %{VERSION}-%{RELEASE}\n\"").output | ||
out = run!("#{rpm_cmd} -qa --qf \"%{NAME} %{VERSION}-%{RELEASE}\n\"").output | ||
out.split("\n").each_with_object({}) do |line, pkg_hash| | ||
name, ver = line.split(" ") | ||
pkg_hash[name] = ver | ||
|
@@ -21,8 +23,12 @@ def self.import_key(file) | |
def self.info(pkg) | ||
params = { "-qi" => pkg} | ||
in_description = false | ||
out = run!(RPM_CMD, :params => params).output | ||
out = run!(rpm_cmd, :params => params).output | ||
# older versions of rpm may have multiple fields per line, | ||
# split up lines with multiple tags/values: | ||
out.gsub!(/(^.*:.*)\s\s+(.*:.*)$/, "\\1\n\\2") | ||
out.split("\n").each.with_object({}) do |line, rpm| | ||
next if !line || line.empty? | ||
tag,value = line.split(':') | ||
tag = tag.strip | ||
if tag == 'Description' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,53 @@ | ||
require 'spec_helper' | ||
|
||
describe LinuxAdmin::Distro do | ||
describe LinuxAdmin::Distros::Distro do | ||
describe "#local" do | ||
after(:each) do | ||
# distro generates a local copy, reset after each run | ||
LinuxAdmin::Distro.instance_variable_set(:@local, nil) | ||
end | ||
|
||
[['ubuntu', :ubuntu], | ||
['Fedora', :redhat], | ||
['red hat', :redhat], | ||
['CentOS', :redhat], | ||
['centos', :redhat]].each do |i,d| | ||
['Fedora', :fedora], | ||
['red hat', :rhel], | ||
['CentOS', :rhel], | ||
['centos', :rhel]].each do |i, d| | ||
context "/etc/issue contains '#{i}'" do | ||
before(:each) do | ||
File.should_receive(:exists?).with('/etc/issue').and_return(true) | ||
File.should_receive(:read).with('/etc/issue').and_return(i) | ||
LinuxAdmin::EtcIssue.instance.should_receive(:to_s).at_least(:once).and_return(i) | ||
File.should_receive(:exists?).at_least(:once).and_return(false) | ||
end | ||
|
||
it "returns Distros.#{d}" do | ||
LinuxAdmin::Distro.local.should == LinuxAdmin::Distros.send(d) | ||
distro = LinuxAdmin::Distros.send(d) | ||
described_class.local.should == distro | ||
end | ||
end | ||
end | ||
|
||
context "/etc/issue did not match" do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @movitto I know this isn't in the diff but this context seems wrong. It's really "/etc/issue doesn't exist" right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can tackle this when we have better ideas. |
||
before(:each) do | ||
File.should_receive(:exists?).with('/etc/issue').and_return(false) | ||
LinuxAdmin::EtcIssue.instance.should_receive(:to_s).at_least(:once).and_return('') | ||
end | ||
|
||
context "/etc/redhat-release exists" do | ||
it "returns Distros.redhat" do | ||
it "returns Distros.rhel" do | ||
File.should_receive(:exists?).with('/etc/redhat-release').and_return(true) | ||
LinuxAdmin::Distro.local.should == LinuxAdmin::Distros.redhat | ||
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 | ||
end | ||
end | ||
|
||
context "/etc/fedora-release exists" do | ||
it "returns Distros.redhat" 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) | ||
LinuxAdmin::Distro.local.should == LinuxAdmin::Distros.redhat | ||
File.should_receive(:exists?).at_least(:once).and_call_original | ||
described_class.local.should == LinuxAdmin::Distros.fedora | ||
end | ||
end | ||
end | ||
|
||
it "returns Distros.generic" do | ||
File.stub(:exists?).and_return(false) | ||
LinuxAdmin::Distro.local.should == LinuxAdmin::Distros.generic | ||
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 | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be detect or find?
We should return the first class that is detected?, right? Or return the generic one.