Project

General

Profile

Download (7.4 KB) Statistics
| Branch: | Tag: | Revision:
2c83f744 Paul Kelly
require 'ostruct'
require 'uri'

286a2207 Ohad Levy
class Operatingsystem < ActiveRecord::Base
acfbc458 Marek Hulan
include Authorizable
5031bb10 Tomas Strachota
include ValidateOsFamily
d7611b24 Greg Sutcliffe
ff8cc704 Joseph Mitchell Magen
before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups)
d7611b24 Greg Sutcliffe
has_many_hosts
7d993b41 Joseph Mitchell Magen
has_many :hostgroups
dd42df0a Ohad Levy
has_many :images, :dependent => :destroy
db59a916 Jochen Schalanda
has_and_belongs_to_many :media
c6eee281 Ohad Levy
has_and_belongs_to_many :ptables
ffc12fd6 Ohad Levy
has_and_belongs_to_many :architectures
c6eee281 Ohad Levy
has_and_belongs_to_many :puppetclasses
cab0d8c6 Ohad Levy
has_and_belongs_to_many :config_templates
has_many :os_default_templates, :dependent => :destroy
accepts_nested_attributes_for :os_default_templates, :allow_destroy => true,
9c3f01c5 Ohad Levy
:reject_if => lambda { |v| v[:config_template_id].blank? }
cab0d8c6 Ohad Levy
f2c78d4a Joseph Magen
validates :major, :numericality => true, :presence => { :message => N_("Operating System version is required") }
11782648 Ohad Levy
has_many :os_parameters, :dependent => :destroy, :foreign_key => :reference_id
57526a20 Joseph Mitchell Magen
has_many :parameters, :dependent => :destroy, :foreign_key => :reference_id, :class_name => "OsParameter"
11782648 Ohad Levy
accepts_nested_attributes_for :os_parameters, :reject_if => lambda { |a| a[:value].blank? }, :allow_destroy => true
fe4629de rbirnie
has_many :trends, :as => :trendable, :class_name => "ForemanTrend"
b1f4f883 Joseph Mitchell Magen
attr_name :fullname
f2c78d4a Joseph Magen
validates :minor, :numericality => true, :allow_nil => true, :allow_blank => true
validates :name, :format => {:with => /\A(\S+)\Z/, :message => N_("can't be blank or contain white spaces.")}
9a9b3e75 Paul Kelly
before_validation :downcase_release_name
c5ea5361 Ohad Levy
#TODO: add validation for name and major uniqueness
286a2207 Ohad Levy
c2c32409 Greg Sutcliffe
before_save :set_family
5031bb10 Tomas Strachota
9c864cb6 Ohad Levy
audited :allow_mass_assignment => true
f2c78d4a Joseph Magen
default_scope lambda { order('operatingsystems.name') }
286a2207 Ohad Levy
c2c32409 Greg Sutcliffe
scoped_search :on => :name, :complete_value => :true
scoped_search :on => :major, :complete_value => :true
scoped_search :on => :minor, :complete_value => :true
scoped_search :on => :description, :complete_value => :true
scoped_search :on => :type, :complete_value => :true, :rename => "family"
8de14697 Ohad Levy
c2c32409 Greg Sutcliffe
scoped_search :in => :architectures, :on => :name, :complete_value => :true, :rename => "architecture"
scoped_search :in => :media, :on => :name, :complete_value => :true, :rename => "medium"
scoped_search :in => :config_templates, :on => :name, :complete_value => :true, :rename => "template"
8de14697 Ohad Levy
scoped_search :in => :os_parameters, :on => :value, :on_key=> :name, :complete_value => true, :rename => :params

48a65101 Greg Sutcliffe
FAMILIES = { 'Debian' => %r{Debian|Ubuntu}i,
'Redhat' => %r{RedHat|Centos|Fedora|Scientific|SLC}i,
'Suse' => %r{OpenSuSE|SLES|SLED}i,
'Windows' => %r{Windows}i,
ba71c565 Greg Sutcliffe
'Archlinux' => %r{Archlinux}i,
48a65101 Greg Sutcliffe
'Gentoo' => %r{Gentoo}i,
'Solaris' => %r{Solaris}i,
7e2880b6 Ruediger Mueck
'Freebsd' => %r{FreeBSD}i,
b80c6c00 Frank Wall
'AIX' => %r{AIX}i,
'Junos' => %r{Junos}i }
32847027 Justin Sherrill
class Jail < Safemode::Jail
6b27556a Amos Benari
allow :name, :media_url, :major, :minor, :family, :to_s, :repos, :==, :release_name, :kernel, :initrd, :pxe_type, :medium_uri
32847027 Justin Sherrill
end

2c83f744 Paul Kelly
# 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
5f75dccc Paul Kelly
def family
b34e9aea Ohad Levy
read_attribute(:type)
5f75dccc Paul Kelly
end

2c83f744 Paul Kelly
def family=(value)
self.type = value
end

def self.families
FAMILIES.keys.sort
end
5031bb10 Tomas Strachota
validate_inclusion_in_families :type
2c83f744 Paul Kelly
def self.families_as_collection
48a65101 Greg Sutcliffe
families.map do |f|
OpenStruct.new(:name => f.constantize.new.display_family, :value => f)
end
2c83f744 Paul Kelly
end

6b27556a Amos Benari
# Operating system family can override this method to provide an array of
# hashes, each describing a repository. For example, to describe a yum repo,
# the following structure can be returned by the method:
# [{ :baseurl => "https://dl.thesource.com/get/it/here",
# :name => "awesome",
# :description => "awesome product repo"",
# :enabled => 1,
# :gpgcheck => 1
# }]
def repos host
[]
end

db59a916 Jochen Schalanda
def medium_uri host, url = nil
url ||= host.medium.path
medium_vars_to_uri(url, host.architecture.name, host.os)
0f77c7f2 Ohad Levy
end

db59a916 Jochen Schalanda
def medium_vars_to_uri (url, arch, os)
a6db0470 Paul Kelly
URI.parse(interpolate_medium_vars(url, arch, os)).normalize
5f75dccc Paul Kelly
end

a6db0470 Paul Kelly
def interpolate_medium_vars path, arch, os
return "" if path.empty?

path.gsub('$arch', arch).
gsub('$major', os.major).
gsub('$minor', os.minor).
gsub('$version', [os.major, os.minor ].compact.join('.')).
gsub('$release', os.release_name ? os.release_name : "" )
end

68f7a705 Ohad Levy
# The OS is usually represented as the concatenation of the OS and the revision
286a2207 Ohad Levy
def to_label
c2c32409 Greg Sutcliffe
description.blank? ? to_s : description
fd8666ab Ohad Levy
end

def release
"#{major}#{('.' + minor) unless minor.empty?}"
286a2207 Ohad Levy
end

290c4d84 Ohad Levy
def to_s
c2c32409 Greg Sutcliffe
"#{name} #{release}"
290c4d84 Ohad Levy
end

3312a03d Ohad Levy
def fullname
c2c32409 Greg Sutcliffe
to_s
3312a03d Ohad Levy
end
5f75dccc Paul Kelly
b1f4f883 Joseph Mitchell Magen
def self.find_by_fullname(fullname)
a = fullname.split(" ")
b = a[1].split('.') if a[1]
cond = {:name => a[0]}
cond.merge!(:major => b[0]) if b && b[0]
cond.merge!(:minor => b[1]) if b && b[1]
self.where(cond).first
end

0f77c7f2 Ohad Levy
# sets the prefix for the tfp files based on the os / arch combination
def pxe_prefix(arch)
"boot/#{to_s}-#{arch}".gsub(" ","-")
end

db59a916 Jochen Schalanda
def pxe_files(medium, arch)
boot_files_uri(medium, arch).collect do |img|
0f77c7f2 Ohad Levy
{ pxe_prefix(arch).to_sym => img.to_s}
end
end

218bd6e0 Justin Sherrill
def kernel arch
bootfile(arch,:kernel)
end

def initrd arch
bootfile(arch,:initrd)
end

a6db0470 Paul Kelly
def bootfile arch, type
pxe_prefix(arch) + "-" + eval("#{self.family}::PXEFILES[:#{type}]")
end

# Does this OS family support a build variant that is constructed from a prebuilt archive
def supports_image
false
end

# override in sub operatingsystem classes as required.
def pxe_variant
"syslinux"
end

# The kind of PXE configuration template used. PXELinux and PXEGrub are currently supported
def template_kind
"PXELinux"
end

#handle things like gpxelinux/ gpxe / pxelinux here
672f931d Paul Kelly
def boot_filename host=nil
a6db0470 Paul Kelly
"pxelinux.0"
end

# Does this OS family use release_name in its naming scheme
def use_release_name?
false
end

def image_extension
eed31c34 Ohad Levy
raise ::Foreman::Exception.new(N_("Attempting to construct an operating system image filename but %s cannot be built from an image"), family)
a6db0470 Paul Kelly
end

06bf16e9 Ohad Levy
# If this OS family requires access to its media via NFS
def require_nfs_access_to_medium
false
end

48a65101 Greg Sutcliffe
# Pretty method for displaying the Family name
def display_family
"Unknown"
end

c2c32409 Greg Sutcliffe
def self.shorten_description description
# This method should be overridden in the OS subclass
# to handle shortening the specific formats of lsbdistdescription
# returned by Facter on that OS
description
end

2c83f744 Paul Kelly
def deduce_family
c2c32409 Greg Sutcliffe
self.family || self.class.families.find do |f|
5031bb10 Tomas Strachota
name =~ FAMILIES[f]
2c83f744 Paul Kelly
end
end

c2c32409 Greg Sutcliffe
private
def set_family
self.family ||= self.deduce_family
end

9a9b3e75 Paul Kelly
def downcase_release_name
2e31dbca Ohad Levy
self.release_name.downcase! unless defined?(Rake) or release_name.nil? or release_name.empty?
9a9b3e75 Paul Kelly
end

a6db0470 Paul Kelly
def boot_files_uri(medium, architecture)
93117958 Bryan Kearney
raise (_("invalid medium for %s") % to_s) unless media.include?(medium)
raise (_("invalid architecture for %s") % to_s) unless architectures.include?(architecture)
a6db0470 Paul Kelly
eval("#{self.family}::PXEFILES").values.collect do |img|
68f7a705 Ohad Levy
medium_vars_to_uri("#{medium.path}/#{pxedir}/#{img}", architecture.name, self)
a6db0470 Paul Kelly
end
0f77c7f2 Ohad Levy
end

286a2207 Ohad Levy
end