Revision 1285cc0d
Added by Dominic Cleal over 7 years ago
app/models/operatingsystem.rb | ||
---|---|---|
allow :name, :media_url, :major, :minor, :family, :to_s, :repos, :==, :release_name, :kernel, :initrd, :pxe_type, :medium_uri, :boot_files_uri, :password_hash
|
||
end
|
||
|
||
def self.inherited(child)
|
||
child.instance_eval do
|
||
# Ensure all subclasses behave in the same way as the parent, and remain
|
||
# identified as Operatingsystems instead of subclasses in UI paths etc.
|
||
#
|
||
# rubocop:disable Rails/Delegate
|
||
def model_name
|
||
superclass.model_name
|
||
end
|
||
# rubocop:enable Rails/Delegate
|
||
end
|
||
super
|
||
end
|
||
|
||
# As Rails loads an object it casts it to the class in the 'type' field. If we ensure that the type and
|
||
# family are the same thing then rails converts the record to a Debian or a solaris object as required.
|
||
# Manually managing the 'type' field allows us to control the inheritance chain and the available methods
|
app/models/operatingsystems/aix.rb | ||
---|---|---|
class AIX < Operatingsystem
|
||
PXEFILES = {:kernel => "powerpc", :initrd => "initrd"}
|
||
|
||
# Override the class representation, as this breaks many rails helpers
|
||
def class
|
||
Operatingsystem
|
||
end
|
||
|
||
def pxe_type
|
||
"nim"
|
||
end
|
app/models/operatingsystems/altlinux.rb | ||
---|---|---|
class Altlinux < Operatingsystem
|
||
PXEFILES = {:kernel => "vmlinuz", :initrd => "full.cz" }
|
||
|
||
def class
|
||
Operatingsystem
|
||
end
|
||
|
||
def boot_files_uri(medium, architecture)
|
||
raise ::Foreman::Exception.new(N_("invalid medium for %s"), to_s) unless media.include?(medium)
|
||
raise ::Foreman::Exception.new(N_("invalid architecture for %s"), to_s) unless architectures.include?(architecture)
|
app/models/operatingsystems/archlinux.rb | ||
---|---|---|
class Archlinux < Operatingsystem
|
||
PXEFILES = {:kernel => "linux", :initrd => "initrd"}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
# Simple output of the media url
|
||
def mediumpath(host)
|
||
medium_uri(host).to_s
|
app/models/operatingsystems/coreos.rb | ||
---|---|---|
class Coreos < Operatingsystem
|
||
PXEFILES = {:kernel => 'coreos_production_pxe.vmlinuz', :initrd => 'coreos_production_pxe_image.cpio.gz'}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
def pxe_type
|
||
'coreos'
|
||
end
|
app/models/operatingsystems/debian.rb | ||
---|---|---|
s.blank? ? description : s
|
||
end
|
||
|
||
def self.model_name
|
||
superclass.model_name
|
||
end
|
||
|
||
private
|
||
|
||
# tries to guess if this an ubuntu or a debian os
|
app/models/operatingsystems/freebsd.rb | ||
---|---|---|
# -as initrd we will use your custom FreeBSD-<arch>-<version>-mfs.img in boot
|
||
PXEFILES = {}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
# Simple output of the media url
|
||
def mediumpath(host)
|
||
medium_uri(host).to_s.gsub("x86_64","amd64")
|
app/models/operatingsystems/gentoo.rb | ||
---|---|---|
class Gentoo < Operatingsystem
|
||
PXEFILES = {}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
def mediumpath(host)
|
||
end
|
||
|
app/models/operatingsystems/junos.rb | ||
---|---|---|
medium_uri(host).to_s
|
||
end
|
||
|
||
def class
|
||
Operatingsystem
|
||
end
|
||
|
||
# The PXE type to use when generating actions and evaluating attributes. jumpstart, kickstart and preseed are currently supported.
|
||
def pxe_type
|
||
"ZTP"
|
app/models/operatingsystems/nxos.rb | ||
---|---|---|
medium_uri(host).to_s
|
||
end
|
||
|
||
def class
|
||
Operatingsystem
|
||
end
|
||
|
||
def template_kinds
|
||
["POAP"]
|
||
end
|
app/models/operatingsystems/redhat.rb | ||
---|---|---|
class Redhat < Operatingsystem
|
||
PXEFILES = {:kernel => "vmlinuz", :initrd => "initrd.img"}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
# outputs kickstart installation medium based on the medium type (NFS or URL)
|
||
# it also convert the $arch string to the current host architecture
|
||
def mediumpath(host)
|
app/models/operatingsystems/solaris.rb | ||
---|---|---|
class Solaris < Operatingsystem
|
||
PXEFILES = {:initrd => "x86.miniroot", :kernel => "multiboot"}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
def file_prefix
|
||
(self).to_s.gsub(/[\s\(\)]/,"-").gsub("--", "-").gsub(/-\Z/, "")
|
||
end
|
app/models/operatingsystems/suse.rb | ||
---|---|---|
class Suse < Operatingsystem
|
||
PXEFILES = {:kernel => "linux", :initrd => "initrd"}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
# Simple output of the media url
|
||
def mediumpath(host)
|
||
medium_uri(host).to_s
|
app/models/operatingsystems/windows.rb | ||
---|---|---|
class Windows < Operatingsystem
|
||
PXEFILES = {:kernel => "wimboot", :initrd => "bootmgr", :bcd => "bcd", :bootsdi => "boot.sdi", :bootwim => "boot.wim"}
|
||
|
||
class << self
|
||
delegate :model_name, :to => :superclass
|
||
end
|
||
|
||
def pxe_type
|
||
"waik"
|
||
end
|
app/models/operatingsystems/xenserver.rb | ||
---|---|---|
"XenServer"
|
||
end
|
||
|
||
def self.model_name
|
||
superclass.model_name
|
||
end
|
||
|
||
def bootfile(arch, type)
|
||
pxe_prefix(arch) + "-" + eval("#{self.family}::PXEFILES[:#{type}]").split("/")[-1]
|
||
end
|
app/services/puppet_fact_parser.rb | ||
---|---|---|
attr_reader :facts
|
||
|
||
def operatingsystem
|
||
orel = os_release
|
||
orel = os_release.dup
|
||
|
||
if os_name == "Archlinux"
|
||
# Archlinux is rolling release, so it has no release. We use 1.0 always
|
||
... | ... | |
end
|
||
if os.description.blank?
|
||
if os_name == 'SLES'
|
||
os.description = os_name + ' ' + orel.gsub!('.', ' SP')
|
||
os.description = os_name + ' ' + orel.gsub('.', ' SP')
|
||
elsif facts[:lsbdistdescription]
|
||
family = os.deduce_family || 'Operatingsystem'
|
||
os.description = family.constantize.shorten_description facts[:lsbdistdescription]
|
||
end
|
||
end
|
||
os.save!
|
||
os
|
||
|
||
if os.new_record?
|
||
os.save!
|
||
Operatingsystem.find_by_id(os.id) # complete reload to be an instance of the STI subclass
|
||
else
|
||
os.save!
|
||
os
|
||
end
|
||
end
|
||
|
||
def environment
|
test/unit/puppet_fact_parser_test.rb | ||
---|---|---|
assert_equal '192.168.0.1', parser.interfaces['eth0.0']['ipaddress']
|
||
end
|
||
|
||
test "should return an os" do
|
||
assert_kind_of Operatingsystem, importer.operatingsystem
|
||
end
|
||
|
||
test "should raise on an invalid os" do
|
||
@importer = PuppetFactParser.new({})
|
||
assert_raise ::Foreman::Exception do
|
||
importer.operatingsystem
|
||
end
|
||
end
|
||
test "should return an env" do
|
||
assert_kind_of Environment, importer.environment
|
||
end
|
||
... | ... | |
assert_kind_of Domain, importer.domain
|
||
end
|
||
|
||
test "should make non-numeric os version strings into numeric" do
|
||
@importer = PuppetFactParser.new({'operatingsystem' => 'AnyOS', 'operatingsystemrelease' => '1&2.3y4'})
|
||
data = importer.operatingsystem
|
||
assert_equal '12', data.major
|
||
assert_equal '34', data.minor
|
||
end
|
||
describe '#operatingsystem' do
|
||
let(:os) { importer.operatingsystem }
|
||
|
||
test "should allow OS version minor component to be nil" do
|
||
@importer = PuppetFactParser.new({'operatingsystem' => 'AnyOS', 'operatingsystemrelease' => '6'})
|
||
data = importer.operatingsystem
|
||
assert_equal "AnyOS 6", data.to_s
|
||
assert_equal '6', data.major
|
||
assert_empty data.minor
|
||
assert_equal data, importer.operatingsystem
|
||
end
|
||
test "should return an os" do
|
||
assert_kind_of Operatingsystem, os
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "release_name should be nil when lsbdistcodename isn't set on Debian" do
|
||
@importer = PuppetFactParser.new(debian_facts.delete_if { |k, v| k == "lsbdistcodename" })
|
||
assert_equal nil, @importer.operatingsystem.release_name
|
||
end
|
||
test "should raise on an invalid os" do
|
||
@importer = PuppetFactParser.new({})
|
||
assert_raise ::Foreman::Exception do
|
||
importer.operatingsystem
|
||
end
|
||
end
|
||
|
||
test "should set os.release_name to the lsbdistcodename fact on Debian" do
|
||
@importer = PuppetFactParser.new(debian_facts)
|
||
assert_equal 'wheezy', @importer.operatingsystem.release_name
|
||
end
|
||
test "should make non-numeric os version strings into numeric" do
|
||
@importer = PuppetFactParser.new({'operatingsystem' => 'AnyOS', 'operatingsystemrelease' => '1&2.3y4'})
|
||
assert_equal '12', os.major
|
||
assert_equal '34', os.minor
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should not set os.release_name to the lsbdistcodename on non-Debian OS" do
|
||
assert_not_equal 'Santiago', @importer.operatingsystem.release_name
|
||
end
|
||
test "should allow OS version minor component to be nil" do
|
||
@importer = PuppetFactParser.new({'operatingsystem' => 'AnyOS', 'operatingsystemrelease' => '6'})
|
||
assert_equal "AnyOS 6", os.to_s
|
||
assert_equal '6', os.major
|
||
assert_empty os.minor
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should set description field from lsbdistdescription" do
|
||
assert_equal "RHEL Server 6.2", @importer.operatingsystem.description
|
||
end
|
||
test "release_name should be nil when lsbdistcodename isn't set on Debian" do
|
||
@importer = PuppetFactParser.new(debian_facts.delete_if { |k, v| k == "lsbdistcodename" })
|
||
assert_equal nil, os.release_name
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should not alter description field if already set" do
|
||
# Need to instantiate @importer once with normal facts
|
||
assert @importer.operatingsystem.present?
|
||
# Now re-import with a different description
|
||
facts_with_desc = facts.merge({:lsbdistdescription => "A different string"})
|
||
@importer = PuppetFactParser.new facts_with_desc
|
||
assert_equal "RHEL Server 6.2", @importer.operatingsystem.description
|
||
end
|
||
test "should set os.release_name to the lsbdistcodename fact on Debian" do
|
||
@importer = PuppetFactParser.new(debian_facts)
|
||
assert_equal 'wheezy', os.release_name
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should set description correctly for SLES" do
|
||
@importer = PuppetFactParser.new(sles_facts)
|
||
assert_equal 'SLES 11 SP3', @importer.operatingsystem.description
|
||
end
|
||
test "should not set os.release_name to the lsbdistcodename on non-Debian OS" do
|
||
assert_not_equal 'Santiago', os.release_name
|
||
end
|
||
|
||
test "should not set description if lsbdistdescription is missing" do
|
||
facts.delete('lsbdistdescription')
|
||
@importer = PuppetFactParser.new(facts)
|
||
refute @importer.operatingsystem.description
|
||
end
|
||
test "should set description field from lsbdistdescription" do
|
||
assert_equal "RHEL Server 6.2", os.description
|
||
end
|
||
|
||
test 'should accept y.z minor version' do
|
||
FactoryGirl.create(:operatingsystem, name: "CentOS",
|
||
major: "7",
|
||
minor: "2.1511",
|
||
description: "CentOS Linux 7.2.1511")
|
||
assert_valid PuppetFactParser.new({ "operatingsystem" => "CentOS",
|
||
"lsbdistdescription" => "CentOS Linux release 7.2.1511 (Core) ",
|
||
"operatingsystemrelease" => "7.2.1511"
|
||
}).operatingsystem
|
||
end
|
||
test "should not alter description field if already set" do
|
||
# Need to instantiate @importer once with normal facts
|
||
first_os = @importer.operatingsystem
|
||
assert first_os.present?
|
||
# Now re-import with a different description
|
||
facts_with_desc = facts.merge({:lsbdistdescription => "A different string"})
|
||
@importer = PuppetFactParser.new facts_with_desc
|
||
second_os = @importer.operatingsystem
|
||
assert_equal "RHEL Server 6.2", second_os.description
|
||
assert_equal first_os, second_os
|
||
end
|
||
|
||
test "should set os.major and minor correctly from AIX facts" do
|
||
@importer = PuppetFactParser.new(aix_facts)
|
||
assert_equal 'AIX', @importer.operatingsystem.family
|
||
assert_equal '6100', @importer.operatingsystem.major
|
||
assert_equal '0604', @importer.operatingsystem.minor
|
||
end
|
||
test "should set description correctly for SLES" do
|
||
@importer = PuppetFactParser.new(sles_facts)
|
||
assert_equal 'SLES 11 SP3', os.description
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test 'should handle FreeBSD rolling releases correctly' do
|
||
@importer = PuppetFactParser.new(freebsd_stable_facts)
|
||
assert_equal '10', @importer.operatingsystem.major
|
||
assert_equal '1', @importer.operatingsystem.minor
|
||
end
|
||
test "should not set description if lsbdistdescription is missing" do
|
||
facts.delete('lsbdistdescription')
|
||
@importer = PuppetFactParser.new(facts)
|
||
refute os.description
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test 'should handle FreeBSD patch releases correctly' do
|
||
@importer = PuppetFactParser.new(freebsd_patch_facts)
|
||
assert_equal '10', @importer.operatingsystem.major
|
||
assert_equal '1', @importer.operatingsystem.minor
|
||
end
|
||
test 'should accept y.z minor version' do
|
||
FactoryGirl.create(:operatingsystem, name: "CentOS",
|
||
major: "7",
|
||
minor: "2.1511",
|
||
description: "CentOS Linux 7.2.1511")
|
||
@importer = PuppetFactParser.new("operatingsystem" => "CentOS",
|
||
"lsbdistdescription" => "CentOS Linux release 7.2.1511 (Core) ",
|
||
"operatingsystemrelease" => "7.2.1511")
|
||
assert_valid os
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should set os.major and minor correctly from Solaris 10 facts" do
|
||
@importer = PuppetFactParser.new(read_json_fixture('facts/solaris10.json'))
|
||
os = @importer.operatingsystem
|
||
assert_equal 'Solaris', os.family
|
||
assert_equal '10', os.major
|
||
assert_equal '9', os.minor
|
||
test "should set os.major and minor correctly from AIX facts" do
|
||
@importer = PuppetFactParser.new(aix_facts)
|
||
assert_equal 'AIX', os.family
|
||
assert_equal '6100', os.major
|
||
assert_equal '0604', os.minor
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test 'should handle FreeBSD rolling releases correctly' do
|
||
@importer = PuppetFactParser.new(freebsd_stable_facts)
|
||
assert_equal '10', os.major
|
||
assert_equal '1', os.minor
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test 'should handle FreeBSD patch releases correctly' do
|
||
@importer = PuppetFactParser.new(freebsd_patch_facts)
|
||
assert_equal '10', os.major
|
||
assert_equal '1', os.minor
|
||
assert_os_idempotent
|
||
end
|
||
|
||
test "should set os.major and minor correctly from Solaris 10 facts" do
|
||
@importer = PuppetFactParser.new(read_json_fixture('facts/solaris10.json'))
|
||
os = @importer.operatingsystem
|
||
assert_equal 'Solaris', os.family
|
||
assert_equal '10', os.major
|
||
assert_equal '9', os.minor
|
||
assert_os_idempotent
|
||
end
|
||
end
|
||
|
||
test "#get_interfaces" do
|
||
... | ... | |
def freebsd_patch_facts
|
||
read_json_fixture('facts/facts_freebsd_patch.json')['facts']
|
||
end
|
||
|
||
def assert_os_idempotent(previous_os = self.os)
|
||
assert_equal previous_os, importer.operatingsystem, 'Different operating system returned on second call'
|
||
assert_equal previous_os.attributes, importer.operatingsystem.attributes, 'Different operating system attributes set on second call'
|
||
end
|
||
end
|
Also available in: Unified diff
fixes #17354 - test and improve idempotency of OS fact parser