Permalink
Browse files

Fixes #19389 - Add medium_uri provider

  • Loading branch information...
ShimShtein authored and lzap committed Jul 4, 2018
1 parent 2455b57 commit ef1bbc264acfe0864bd24e7ce54e6b37dcda37ad
Showing with 447 additions and 211 deletions.
  1. +6 −1 app/controllers/api/v2/operatingsystems_controller.rb
  2. +6 −2 app/models/concerns/host_common.rb
  3. +8 −2 app/models/concerns/host_template_helpers.rb
  4. +10 −5 app/models/concerns/orchestration/tftp.rb
  5. +43 −40 app/models/operatingsystem.rb
  6. +0 −4 app/models/operatingsystems/aix.rb
  7. +2 −9 app/models/operatingsystems/altlinux.rb
  8. +2 −6 app/models/operatingsystems/archlinux.rb
  9. +17 −5 app/models/operatingsystems/coreos.rb
  10. +14 −6 app/models/operatingsystems/debian.rb
  11. +15 −9 app/models/operatingsystems/freebsd.rb
  12. +2 −2 app/models/operatingsystems/gentoo.rb
  13. +4 −8 app/models/operatingsystems/junos.rb
  14. +4 −4 app/models/operatingsystems/nxos.rb
  15. +1 −1 app/models/operatingsystems/rancheros.rb
  16. +2 −6 app/models/operatingsystems/redhat.rb
  17. +4 −7 app/models/operatingsystems/solaris.rb
  18. +2 −6 app/models/operatingsystems/suse.rb
  19. +6 −8 app/models/operatingsystems/windows.rb
  20. +8 −14 app/models/operatingsystems/xenserver.rb
  21. +5 −3 app/models/provisioning_template.rb
  22. +7 −1 app/registries/foreman/plugin.rb
  23. +59 −0 app/registries/foreman/plugin/medium_providers_registry.rb
  24. +66 −0 app/services/medium_providers/default.rb
  25. +54 −0 app/services/medium_providers/provider.rb
  26. +1 −1 app/views/unattended/provisioning_templates/PXEGrub/kickstart_default_pxegrub.erb
  27. +1 −1 app/views/unattended/provisioning_templates/PXEGrub2/kickstart_default_pxegrub2.erb
  28. +1 −2 app/views/unattended/provisioning_templates/PXELinux/alterator_default_pxelinux.erb
  29. +2 −2 app/views/unattended/provisioning_templates/PXELinux/kickstart_default_pxelinux.erb
  30. +1 −1 app/views/unattended/provisioning_templates/PXELinux/kickstart_ovirt_pxelinux.erb
  31. +2 −2 app/views/unattended/provisioning_templates/iPXE/autoyast_default_ipxe.erb
  32. +1 −1 app/views/unattended/provisioning_templates/iPXE/preseed_default_ipxe.erb
  33. +2 −2 app/views/unattended/provisioning_templates/provision/atomic_kickstart_default.erb
  34. +1 −1 app/views/unattended/provisioning_templates/provision/kickstart_ovirt.erb
  35. +2 −0 config/initializers/foreman.rb
  36. +20 −14 lib/foreman/renderer.rb
  37. +1 −1 lib/tasks/exports.rake
  38. +4 −0 test/controllers/unattended_controller_test.rb
  39. +0 −7 test/models/operatingsystem_test.rb
  40. +24 −19 test/models/operatingsystems/operatingsystems_test.rb
  41. +22 −7 test/models/orchestration/tftp_test.rb
  42. +1 −1 test/unit/foreman/renderer_test.rb
  43. +14 −0 test/unit/medium_providers/default_test.rb
@@ -93,9 +93,14 @@ def destroy
param :architecture, String

def bootfiles
Foreman::Deprecation.deprecation_warning("1.20", "Bootfiles should be calculated per host")

medium = Medium.authorized(:view_media).find(params[:medium])
arch = Architecture.authorized(:view_architectures).find(params[:architecture])
render :json => @operatingsystem.pxe_files(medium, arch)
host_mock = Openstruct.new(operatingsystem: @operatingsystem, medium: medium, architecture: arch)
medium_provider = MediumProviders::Default.new(host_mock)

render :json => @operatingsystem.pxe_files(medium_provider)
rescue => e
render_message(e.to_s, :status => :unprocessable_entity)
end
@@ -74,9 +74,13 @@ def parent_name
end
end

def host_medium_provider
@medium_provider ||= Foreman::Plugin.medium_providers.find_provider(self)
end

# Returns a url pointing to boot file
def url_for_boot(file)
"#{os.medium_uri(self)}/#{os.url_for_boot(file)}"
os.url_for_boot(medium_provider, file)
end

def puppetca?
@@ -112,7 +116,7 @@ def default_image_file
# We encode the hw_model into the image file name as not all Sparc flashes can contain all possible hw_models. The user can always
# edit it if required or use symlinks if they prefer.
hw_model = model.try :hardware_model if defined?(model_id)
operatingsystem.interpolate_medium_vars(nfs_path, architecture.name, operatingsystem) + \
host_medium_provider.interpolate_vars(nfs_path) + \
"#{operatingsystem.file_prefix}.#{architecture}#{hw_model.empty? ? '' : '.' + hw_model.downcase}.#{operatingsystem.image_extension}"
else
""
@@ -4,6 +4,8 @@ module HostTemplateHelpers
extend ActiveSupport::Concern
include ::Foreman::ForemanUrlRenderer

delegate :medium_uri, to: :medium_provider

# Calculates the media's path in relation to the domain and convert host to an IP
def install_path
operatingsystem.interpolate_medium_vars(operatingsystem.media_path(medium, domain), architecture.name, operatingsystem)
@@ -15,11 +17,11 @@ def jumpstart_path
end

def multiboot
operatingsystem.pxe_prefix(architecture, @host) + "-multiboot"
operatingsystem.pxe_prefix(medium_provider) + "-multiboot"
end

def miniroot
operatingsystem.initrd(architecture, @host)
operatingsystem.initrd(medium_provider)
end

attr_writer(:url_options)
@@ -31,4 +33,8 @@ def url_options
url_options[:host] = Setting[:foreman_url] if Setting[:foreman_url]
url_options
end

def medium_provider
@medium_provider ||= Foreman::Plugin.medium_providers.find_provider(@host)
end
end
@@ -56,15 +56,15 @@ def rebuild_tftp_kind_safe(kind)
def generate_pxe_template(kind)
# this is the only place we generate a template not via a web request
# therefore some workaround is required to "render" the template.
@kernel = host.operatingsystem.kernel(host.arch, host)
@initrd = host.operatingsystem.initrd(host.arch, host)
@kernel = host.operatingsystem.kernel(host_medium_provider)
@initrd = host.operatingsystem.initrd(host_medium_provider)
if host.operatingsystem.respond_to?(:mediumpath)
@mediapath = host.operatingsystem.mediumpath(host)
@mediapath = host.operatingsystem.mediumpath(host_medium_provider)
end

# Xen requires additional boot files.
if host.operatingsystem.respond_to?(:xen)
@xen = host.operatingsystem.xen(host.arch, host)
@xen = host.operatingsystem.xen(host_medium_provider)
end

# work around for ensuring that people can use @host as well, as tftp templates were usually confusing.
@@ -123,7 +123,8 @@ def delTFTP(kind)
def setTFTPBootFiles
logger.info "Fetching required TFTP boot files for #{host.name}"
valid = []
host.operatingsystem.pxe_files(host.medium, host.architecture, host).each do |bootfile_info|

host.operatingsystem.pxe_files(host_medium_provider).each do |bootfile_info|
for prefix, path in bootfile_info do
valid << each_unique_feasible_tftp_proxy do |proxy|
proxy.fetch_boot_file(:prefix => prefix.to_s, :path => path)
@@ -214,4 +215,8 @@ def local_boot_template_name(kind)
key = "local_boot_#{kind}"
host.host_params[key] || Setting[key]
end

def host_medium_provider
@medium_provider ||= Foreman::Plugin.medium_providers.find_provider(self.host)
end
end
@@ -128,26 +128,6 @@ def repos(host)
[]
end

def medium_uri(host, url = nil)
url ||= host.medium.path unless host.medium.nil?
url ||= ''
medium_vars_to_uri(url, host.architecture.name, host.operatingsystem)
end

def medium_vars_to_uri(url, arch, os)
URI.parse(interpolate_medium_vars(url, arch, os)).normalize
end

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.minor.blank? ? os.major : [os.major, os.minor].compact.join('.')).
gsub('$release', os.release_name.presence || '')
end

# The OS is usually represented as the concatenation of the OS and the revision
def to_label
return description if description.present?
@@ -191,31 +171,49 @@ def available_loaders
["None", "PXELinux BIOS"]
end

# sets the prefix for the tfp files based on the os / arch combination
def pxe_prefix(arch, host)
"boot/#{self}-#{arch}-#{medium_digest(host)}".tr(" ","-")
# Compatibility method, don't want to break all templates that use it.
def medium_uri(host)
Foreman::Deprecation.deprecation_warning("1.20", "medium_uri is now accessible through @medium_provider.medium_uri in templates")
@medium_provider = Foreman::Plugin.medium_providers.find_provider(host)
@medium_provider.medium_uri
end

def medium_digest(host)
host.nil? ? '' : Digest::SHA1.hexdigest(medium_uri(host).to_s)
# sets the prefix for the tfp files based on medium unique identifier
def pxe_prefix(medium_provider)
unless medium_provider.is_a? MediumProviders::Provider
raise Foreman::Exception.new(N_('Please provide a medium provider. It can be found as @medium_provider in templates, or Foreman::Plugin.medium_providers.find_provider(host)'))
end
"boot/#{medium_provider.unique_id}"
end

def pxe_files(medium, arch, host = nil)
boot_files_uri(medium, arch, host).collect do |img|
{ pxe_prefix(arch).to_sym => img.to_s}
def pxe_files(medium_provider, _arch = nil, host = nil)
# Try to maintain backwards compatibility, if medium_provider could be constructed - do it with a warning.
if host
Foreman::Deprecation.deprecation_warning("1.20", "Please provide a medium provider. It can be found as @medium_provider in templates, or Foreman::Plugin.medium_providers.find_provider(host)")
medium_provider = Foreman::Plugin.medium_providers.find_provider(host)
end

unless medium_provider.is_a? MediumProviders::Provider
raise Foreman::Exception.new(N_('Please provide a medium provider. It can be found as @medium_provider in templates, or Foreman::Plugin.medium_providers.find_provider(host)'))
end
boot_files_uri(medium_provider).collect do |img|
{ pxe_prefix(medium_provider).to_sym => img.to_s}
end
end

def kernel(arch, host)
bootfile(arch,:kernel, host)
def kernel(medium_provider)
bootfile(medium_provider, :kernel)
end

def initrd(arch, host)
bootfile(arch,:initrd, host)
def initrd(medium_provider)
bootfile(medium_provider, :initrd)
end

def bootfile(arch, type, host)
pxe_prefix(arch, host) + "-" + self.family.constantize::PXEFILES[type.to_sym]
def bootfile(medium_provider, type)
unless medium_provider.is_a? MediumProviders::Provider
raise Foreman::Exception.new(N_('Please provide a medium provider. It can be found as @medium_provider in templates, or Foreman::Plugin.medium_providers.find_provider(host)'))
end
pxe_prefix(medium_provider) + "-" + self.family.constantize::PXEFILES[type.to_sym]
end

# Does this OS family support a build variant that is constructed from a prebuilt archive
@@ -265,12 +263,17 @@ def deduce_family
end
end

def boot_files_uri(medium, architecture, host = nil)
raise ::Foreman::Exception.new(N_("%{os} medium was not set for host '%{host}'"), :host => host, :os => self) if medium.nil?
raise ::Foreman::Exception.new(N_("Invalid medium '%{medium}' for '%{os}'"), :medium => medium, :os => self) unless media.include?(medium)
raise ::Foreman::Exception.new(N_("Invalid architecture '%{arch}' for '%{os}'"), :arch => architecture, :os => self) unless architectures.include?(architecture)
self.family.constantize::PXEFILES.values.map do |img|
medium_vars_to_uri("#{medium.path}/#{pxedir}/#{img}", architecture.name, self)
def boot_files_uri(medium_provider, &block)
boot_file_sources(medium_provider, &block).values
end

def url_for_boot(medium_provider, file, &block)
boot_file_sources(medium_provider, &block)[file]
end

def boot_file_sources(medium_provider, &block)
@boot_file_sources ||= self.family.constantize::PXEFILES.transform_values do |img|
"#{medium_provider.medium_uri(pxedir, &block)}/#{img}"
end
end

@@ -9,10 +9,6 @@ def pxedir
"boot/$arch/loader"
end

def url_for_boot(file)
pxedir + "/" + PXEFILES[file]
end

def display_family
"AIX"
end
@@ -1,12 +1,9 @@
class Altlinux < Operatingsystem
PXEFILES = {:kernel => "vmlinuz", :initrd => "full.cz" }

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)

def boot_files_uri(medium_provider)
PXEFILES.values.collect do |img|
URI.parse("#{medium_vars_to_uri(medium.path, architecture.name, self)}/syslinux/alt0/#{img}").normalize
URI.parse("#{medium_provider.medium_uri}/syslinux/alt0/#{img}").normalize
end
end

@@ -18,10 +15,6 @@ def pxedir
"boot"
end

def url_for_boot(file)
pxedir + "/" + PXEFILES[file]
end

def display_family
"Altlinux"
end
@@ -2,8 +2,8 @@ class Archlinux < Operatingsystem
PXEFILES = {:kernel => "linux", :initrd => "initrd"}

# Simple output of the media url
def mediumpath(host)
medium_uri(host).to_s
def mediumpath(medium_provider)
medium_provider.medium_uri.to_s
end

def pxe_type
@@ -14,10 +14,6 @@ def pxedir
"boot/$arch/loader"
end

def url_for_boot(file)
pxedir + "/" + PXEFILES[file]
end

def display_family
"Arch Linux"
end
@@ -5,20 +5,26 @@ def pxe_type
'coreos'
end

def mediumpath(host)
medium_uri(host, "#{host.medium.path}/#{host.architecture.name}-usr").to_s.gsub('x86_64', 'amd64')
def mediumpath(medium_provider)
medium_provider.medium_uri("/$arch").to_s do |vars|
transform_vars(vars)
end
end

def url_for_boot(file)
PXEFILES[file]
end

def pxedir
'$arch/$version'
'$arch-usr/$version'
end

def boot_files_uri(medium, architecture, host = nil)
super(medium, architecture, host).each{ |img_uri| img_uri.path = img_uri.path.gsub('x86_64', 'amd64-usr') }
def boot_file_sources(medium_provider, &block)
super do |vars|
vars = yield(vars) if block_given?

transform_vars(vars)
end
end

def display_family
@@ -29,4 +35,10 @@ def display_family
def use_release_name?
true
end

private

def transform_vars(vars)
vars[:arch] = vars[:arch].gsub('x86_64', 'amd64')
end
end
@@ -5,16 +5,20 @@ def pxedir
'dists/$release/main/installer-$arch/current/images/netboot/' + guess_os + '-installer/$arch'
end

def preseed_server(host)
medium_uri(host).select(:host, :port).compact.join(':')
def preseed_server(medium_provider)
medium_provider.medium_uri.select(:host, :port).compact.join(':')
end

def preseed_path(host)
medium_uri(host).select(:path, :query).compact.join('?')
def preseed_path(medium_provider)
medium_provider.medium_uri.select(:path, :query).compact.join('?')
end

def boot_files_uri(medium, architecture, host = nil)
super(medium, architecture, host).each{ |img_uri| img_uri.path = img_uri.path.gsub('x86_64', 'amd64') }
def boot_file_sources(medium_provider, &block)
super do |vars|
vars = yield(vars) if block_given?

transform_vars(vars)
end
end

def available_loaders
@@ -50,4 +54,8 @@ def self.shorten_description(description)
def guess_os
(name =~ /ubuntu/i) ? "ubuntu" : "debian"
end

def transform_vars(vars)
vars[:arch] = vars[:arch].gsub('x86_64', 'amd64')
end
end
Oops, something went wrong.

0 comments on commit ef1bbc2

Please sign in to comment.