foreman_bootdisk 13.0.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +4 -0
  3. data/README.md +3 -2
  4. data/app/controllers/foreman_bootdisk/api/v2/disks_controller.rb +11 -9
  5. data/app/controllers/foreman_bootdisk/api/v2/subnet_disks_controller.rb +37 -31
  6. data/app/controllers/foreman_bootdisk/disks_controller.rb +20 -19
  7. data/app/helpers/concerns/foreman_bootdisk/hosts_helper_ext.rb +86 -45
  8. data/app/lib/foreman_bootdisk/scope/bootdisk.rb +2 -0
  9. data/app/lib/foreman_bootdisk/scope/full_host_bootdisk.rb +15 -0
  10. data/app/models/concerns/foreman_bootdisk/compute_resources/vmware.rb +4 -2
  11. data/app/models/concerns/foreman_bootdisk/host_ext.rb +43 -31
  12. data/app/models/concerns/foreman_bootdisk/orchestration/compute.rb +14 -10
  13. data/app/models/setting/bootdisk.rb +28 -23
  14. data/app/services/foreman_bootdisk/iso_generator.rb +127 -104
  15. data/app/services/foreman_bootdisk/renderer.rb +16 -13
  16. data/config/routes.rb +15 -13
  17. data/config/routes/mount_engine.rb +3 -1
  18. data/db/migrate/20130914211030_create_host_bootdisk_template.rb +4 -4
  19. data/db/migrate/20130915104500_edit_host_bootdisk_template_multinic.rb +4 -4
  20. data/db/migrate/20130915133321_create_kickstart_bootdisk_template.rb +4 -4
  21. data/db/migrate/20130915201457_create_generic_host_bootdisk_template.rb +4 -4
  22. data/db/migrate/20131021095100_edit_host_bootdisk_template_dns_secondary.rb +4 -4
  23. data/db/migrate/20140522185700_change_templatekind_to_bootdisk.rb +16 -14
  24. data/db/migrate/20171009225200_remove_duplicate_bootdisk_templates.rb +4 -2
  25. data/db/seeds.d/50-bootdisk_templates.rb +24 -22
  26. data/lib/foreman_bootdisk.rb +2 -0
  27. data/lib/foreman_bootdisk/engine.rb +22 -33
  28. data/lib/foreman_bootdisk/version.rb +3 -1
  29. data/lib/tasks/bootdisk.rake +34 -17
  30. data/locale/gemspec.rb +3 -1
  31. data/test/functional/foreman_bootdisk/api/v2/disks_controller_test.rb +35 -33
  32. data/test/functional/foreman_bootdisk/api/v2/subnet_disks_controller_test.rb +9 -7
  33. data/test/functional/foreman_bootdisk/disks_controller_test.rb +27 -25
  34. data/test/models/host/managed_test.rb +17 -13
  35. data/test/test_plugin_helper.rb +9 -7
  36. data/test/unit/access_permissions_test.rb +2 -0
  37. data/test/unit/concerns/compute_resources/vmware_test.rb +67 -63
  38. data/test/unit/concerns/host_test.rb +54 -54
  39. data/test/unit/concerns/orchestration/compute_test.rb +41 -39
  40. data/test/unit/foreman_bootdisk/renderer_test.rb +3 -1
  41. data/test/unit/foreman_bootdisk/scope/bootdisk_test.rb +3 -1
  42. data/test/unit/foreman_bootdisk/scope/full_host_bootdisk_test.rb +30 -0
  43. data/test/unit/iso_generator_test.rb +57 -40
  44. metadata +19 -3
@@ -1,35 +1,47 @@
1
- require 'uri'
2
-
3
- module ForemanBootdisk::HostExt
4
- def bootdisk_template
5
- ProvisioningTemplate.unscoped.find_by_name(Setting[:bootdisk_host_template]) || raise(::Foreman::Exception.new(N_('Unable to find template specified by %s setting'), 'bootdisk_host_template'))
6
- end
7
-
8
- def bootdisk_template_render
9
- ForemanBootdisk::Renderer.new.render_template(template: bootdisk_template, host: self)
10
- end
11
-
12
- def bootdisk_build?
13
- provision_method == 'bootdisk'
14
- end
1
+ # frozen_string_literal: true
15
2
 
16
- def bootdisk?
17
- managed? && bootdisk_build? && SETTINGS[:unattended]
18
- end
19
-
20
- def bootdisk_downloadable?
21
- architecture.blank? || intel_arch?
22
- end
23
-
24
- def intel_arch?
25
- /i.86|x86[_-]64/ =~ architecture.name
26
- end
27
-
28
- def validate_media?
29
- super || (managed && bootdisk_build? && build?)
30
- end
3
+ require 'uri'
31
4
 
32
- def can_be_built?
33
- super || (managed? and SETTINGS[:unattended] and bootdisk_build? and !build?)
5
+ module ForemanBootdisk
6
+ module HostExt
7
+ def bootdisk_template
8
+ template = ProvisioningTemplate.unscoped.find_by(
9
+ name: Setting[:bootdisk_host_template]
10
+ )
11
+ unless template
12
+ raise ::Foreman::Exception.new(
13
+ N_('Unable to find template specified by %s setting'), 'bootdisk_host_template'
14
+ )
15
+ end
16
+ template
17
+ end
18
+
19
+ def bootdisk_template_render
20
+ ForemanBootdisk::Renderer.new.render_template(template: bootdisk_template, host: self)
21
+ end
22
+
23
+ def bootdisk_build?
24
+ provision_method == 'bootdisk'
25
+ end
26
+
27
+ def bootdisk?
28
+ managed? && bootdisk_build? && SETTINGS[:unattended]
29
+ end
30
+
31
+ def bootdisk_downloadable?
32
+ architecture.blank? || intel_arch?
33
+ end
34
+
35
+ def intel_arch?
36
+ /i.86|x86[_-]64/ =~ architecture.name
37
+ end
38
+
39
+ def validate_media?
40
+ super || (managed && bootdisk_build? && build?)
41
+ end
42
+
43
+ def can_be_built?
44
+ super || (managed? && SETTINGS[:unattended] && bootdisk_build? && !build?)
45
+ end
34
46
  end
35
47
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tmpdir'
2
4
 
3
5
  module ForemanBootdisk
@@ -21,6 +23,7 @@ module ForemanBootdisk
21
23
  def queue_bootdisk_compute
22
24
  return unless compute? && errors.empty? && new_record?
23
25
  return unless provision_method == 'bootdisk'
26
+
24
27
  queue.create(name: _('Generating ISO image for %s') % self, priority: 5,
25
28
  action: [self, :setGenerateIsoImage])
26
29
  queue.create(name: _('Upload ISO image to datastore for %s') % self, priority: 6,
@@ -44,10 +47,10 @@ module ForemanBootdisk
44
47
  end
45
48
 
46
49
  def setGenerateIsoImage
47
- logger.info 'Generating ISO image for %s' % name
50
+ logger.info format('Generating ISO image for %s', name)
48
51
  bootdisk_generate_iso_image
49
- rescue => e
50
- failure _('Failed to generate ISO image for instance %{name}: %{message}') % { name: name, message: e.message }, e
52
+ rescue StandardError => e
53
+ failure format(_('Failed to generate ISO image for instance %{name}: %{message}'), name: name, message: e.message), e
51
54
  end
52
55
 
53
56
  def delGenerateIsoImage; end
@@ -55,29 +58,30 @@ module ForemanBootdisk
55
58
  def setIsoImage
56
59
  logger.info "Uploading ISO image #{bootdisk_isofile} for #{name}"
57
60
  bootdisk_upload_iso
58
- rescue => e
59
- failure _('Failed to upload ISO image for instance %{name}: %{message}') % { name: name, message: e.message }, e
61
+ rescue StandardError => e
62
+ failure format(_('Failed to upload ISO image for instance %{name}: %{message}'), name: name, message: e.message), e
60
63
  end
61
64
 
62
65
  def delIsoImage; end
63
66
 
64
67
  def setAttachIsoImage
65
- logger.info 'Attaching ISO image to CDROM drive for %s' % name
68
+ logger.info format('Attaching ISO image to CDROM drive for %s', name)
66
69
  bootdisk_attach_iso
67
- rescue => e
68
- failure _('Failed to attach ISO image to CDROM drive of instance %{name}: %{message}') % { name: name, message: e.message }, e
70
+ rescue StandardError => e
71
+ failure format(_('Failed to attach ISO image to CDROM drive of instance %{name}: %{message}'), name: name, message: e.message), e
69
72
  end
70
73
 
71
74
  def delAttachIsoImage; end
72
75
 
73
76
  def rebuild_with_bootdisk
74
77
  return true unless bootdisk?
78
+
75
79
  begin
76
80
  bootdisk_generate_iso_image
77
81
  bootdisk_upload_iso
78
82
  bootdisk_attach_iso
79
- rescue => e
80
- Foreman::Logging.exception "Failed to rebuild Bootdisk image for #{name}", e, :level => :error
83
+ rescue StandardError => e
84
+ Foreman::Logging.exception "Failed to rebuild Bootdisk image for #{name}", e, level: :error
81
85
  return false
82
86
  end
83
87
  end
@@ -1,30 +1,35 @@
1
- class Setting::Bootdisk< ::Setting
2
- def self.load_defaults
3
- return unless ApplicationRecord.connection.table_exists?('settings')
4
- return unless super
1
+ # frozen_string_literal: true
5
2
 
6
- ipxe = ['/usr/lib/ipxe'].find { |p| File.exist?(p) } || '/usr/share/ipxe'
7
- isolinux = ['/usr/lib/ISOLINUX'].find { |p| File.exist?(p) } || '/usr/share/syslinux'
8
- syslinux = ['/usr/lib/syslinux/modules/bios', '/usr/lib/syslinux'].find { |p| File.exist?(p) } || '/usr/share/syslinux'
9
- templates = -> { Hash[ProvisioningTemplate.where(:template_kind => TemplateKind.where(:name => 'Bootdisk')).map{|temp| [temp[:name], temp[:name]]}] }
3
+ class Setting
4
+ class Bootdisk < ::Setting
5
+ def self.load_defaults
6
+ return unless ApplicationRecord.connection.table_exists?('settings')
7
+ return unless super
10
8
 
11
- Setting.transaction do
12
- [
13
- self.set('bootdisk_ipxe_dir', N_('Path to directory containing iPXE images'), ipxe, N_('iPXE directory')),
14
- self.set('bootdisk_isolinux_dir', N_('Path to directory containing isolinux images'), isolinux, N_('ISOLINUX directory')),
15
- self.set('bootdisk_syslinux_dir', N_('Path to directory containing syslinux images'), syslinux, N_('SYSLINUX directory')),
16
- self.set('bootdisk_host_template', N_('iPXE template to use for host-specific boot disks'), 'Boot disk iPXE - host', N_('Host image template'), nil, :collection => templates),
17
- self.set('bootdisk_generic_host_template', N_('iPXE template to use for generic host boot disks'), 'Boot disk iPXE - generic host', N_('Generic image template'), nil, :collection => templates),
18
- self.set('bootdisk_mkiso_command', N_('Command to generate ISO image, use genisoimage or mkisofs'), 'genisoimage', N_('ISO generation command')),
19
- self.set('bootdisk_cache_media', N_('Installation media files will be cached for full host images'), true, N_('Installation media caching')),
20
- ].compact.each { |s| self.create s.update(:category => "Setting::Bootdisk") }
21
- end
9
+ ipxe = ['/usr/lib/ipxe'].find { |p| File.exist?(p) } || '/usr/share/ipxe'
10
+ isolinux = ['/usr/lib/ISOLINUX'].find { |p| File.exist?(p) } || '/usr/share/syslinux'
11
+ syslinux = ['/usr/lib/syslinux/modules/bios', '/usr/lib/syslinux'].find { |p| File.exist?(p) } || '/usr/share/syslinux'
12
+ templates = -> { Hash[ProvisioningTemplate.where(template_kind: TemplateKind.where(name: 'Bootdisk')).map { |temp| [temp[:name], temp[:name]] }] }
22
13
 
23
- true
14
+ Setting.transaction do
15
+ [
16
+ set('bootdisk_ipxe_dir', N_('Path to directory containing iPXE images'), ipxe, N_('iPXE directory')),
17
+ set('bootdisk_isolinux_dir', N_('Path to directory containing isolinux images'), isolinux, N_('ISOLINUX directory')),
18
+ set('bootdisk_syslinux_dir', N_('Path to directory containing syslinux images'), syslinux, N_('SYSLINUX directory')),
19
+ set('bootdisk_host_template', N_('iPXE template to use for host-specific boot disks'),
20
+ 'Boot disk iPXE - host', N_('Host image template'), nil, collection: templates),
21
+ set('bootdisk_generic_host_template', N_('iPXE template to use for generic host boot disks'),
22
+ 'Boot disk iPXE - generic host', N_('Generic image template'), nil, collection: templates),
23
+ set('bootdisk_mkiso_command', N_('Command to generate ISO image, use genisoimage or mkisofs'), 'genisoimage', N_('ISO generation command')),
24
+ set('bootdisk_cache_media', N_('Installation media files will be cached for full host images'), true, N_('Installation media caching'))
25
+ ].compact.each { |s| create s.update(category: 'Setting::Bootdisk') }
26
+ end
24
27
 
25
- end
28
+ true
29
+ end
26
30
 
27
- def self.humanized_category
28
- N_('Boot disk')
31
+ def self.humanized_category
32
+ N_('Boot disk')
33
+ end
29
34
  end
30
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'tempfile'
3
5
  require 'tmpdir'
@@ -6,137 +8,158 @@ require 'uri'
6
8
  # Generates an iPXE ISO hybrid image
7
9
  #
8
10
  # requires syslinux, ipxe/ipxe-bootimgs, genisoimage, isohybrid
9
- class ForemanBootdisk::ISOGenerator
10
- def self.generate_full_host(host, opts = {}, &block)
11
- raise ::Foreman::Exception.new(N_('Host is not in build mode, so the template cannot be rendered')) unless host.build?
12
-
13
- tmpl = host.send(:generate_pxe_template, :PXELinux)
14
- unless tmpl
15
- err = host.errors.full_messages.to_sentence
16
- raise ::Foreman::Exception.new(N_('Unable to generate disk template, PXELinux template not found or: %s'), err)
11
+ module ForemanBootdisk
12
+ class ISOGenerator
13
+ def self.generate_full_host(host, opts = {}, &block)
14
+ raise Foreman::Exception, N_('Host is not in build mode, so the template cannot be rendered') unless host.build?
15
+
16
+ tmpl = render_pxelinux_template(host)
17
+
18
+ # pxe_files and filename conversion is utterly bizarre
19
+ # aim to convert filenames to something usable under ISO 9660, to match as rendered in the template
20
+ # and then still ensure that the fetch() process stores them under the same name
21
+ files = host.operatingsystem.family.constantize::PXEFILES.keys.each_with_object({}) do |type, hash|
22
+ filename = host.operatingsystem.bootfile(host.medium_provider, type)
23
+ iso_filename = iso9660_filename(filename)
24
+ hash[iso_filename] = host.url_for_boot(type)
25
+ end
26
+
27
+ generate(opts.merge(isolinux: tmpl, files: files), &block)
17
28
  end
18
29
 
19
- # pxe_files and filename conversion is utterly bizarre
20
- # aim to convert filenames to something usable under ISO 9660, update the template to match
21
- # and then still ensure that the fetch() process stores them under the same name
22
- files = host.operatingsystem.pxe_files(host.medium, host.architecture, host)
23
- files.map! do |bootfile_info|
24
- bootfile_info.map do |f|
25
- suffix = f[1].split('/').last
26
- iso_f0 = iso9660_filename(f[0].to_s + '_' + suffix)
27
- tmpl.gsub!(f[0].to_s + '-' + suffix, iso_f0)
28
- ForemanBootdisk.logger.debug("Boot file #{iso_f0}, source #{f[1]}")
29
- [iso_f0, f[1]]
30
+ def self.render_pxelinux_template(host)
31
+ pxelinux_template = host.provisioning_template(kind: :PXELinux)
32
+
33
+ raise Foreman::Exception, N_('Unable to generate disk template, PXELinux template not found.') unless pxelinux_template
34
+
35
+ template = ForemanBootdisk::Renderer.new.render_template(
36
+ template: pxelinux_template,
37
+ host: host,
38
+ scope_class: ForemanBootdisk::Scope::FullHostBootdisk
39
+ )
40
+
41
+ unless template
42
+ err = host.errors.full_messages.to_sentence
43
+ raise ::Foreman::Exception.new(N_('Unable to generate disk PXELinux template: %s'), err)
30
44
  end
45
+
46
+ template
31
47
  end
32
48
 
33
- generate(opts.merge(:isolinux => tmpl, :files => files), &block)
34
- end
49
+ def self.generate(opts = {})
50
+ opts[:isolinux] = <<~ISOLINUX if opts[:isolinux].nil? && opts[:ipxe]
51
+ default ipxe
52
+ label ipxe
53
+ kernel /ipxe
54
+ initrd /script
55
+ ISOLINUX
35
56
 
36
- def self.generate(opts = {}, &block)
37
- opts[:isolinux] = <<-EOS if opts[:isolinux].nil? && opts[:ipxe]
38
- default ipxe
39
- label ipxe
40
- kernel /ipxe
41
- initrd /script
42
- EOS
57
+ Dir.mktmpdir('bootdisk') do |wd|
58
+ Dir.mkdir(File.join(wd, 'build'))
43
59
 
44
- Dir.mktmpdir('bootdisk') do |wd|
45
- Dir.mkdir(File.join(wd, 'build'))
60
+ if opts[:isolinux]
61
+ isolinux_source_file = File.join(Setting[:bootdisk_isolinux_dir], 'isolinux.bin')
62
+ raise Foreman::Exception, N_('Please ensure the isolinux/syslinux package(s) are installed.') unless File.exist?(isolinux_source_file)
46
63
 
47
- if opts[:isolinux]
48
- unless File.exists?(File.join(Setting[:bootdisk_isolinux_dir], 'isolinux.bin'))
49
- raise ::Foreman::Exception.new(N_("Please ensure the isolinux/syslinux package(s) are installed."))
50
- end
51
- FileUtils.cp(File.join(Setting[:bootdisk_isolinux_dir], 'isolinux.bin'), File.join(wd, 'build', 'isolinux.bin'))
52
- if File.exist?(File.join(Setting[:bootdisk_syslinux_dir], 'ldlinux.c32'))
53
- FileUtils.cp(File.join(Setting[:bootdisk_syslinux_dir], 'ldlinux.c32'), File.join(wd, 'build', 'ldlinux.c32'))
54
- end
55
- File.open(File.join(wd, 'build', 'isolinux.cfg'), 'w') do |file|
56
- file.write(opts[:isolinux])
64
+ FileUtils.cp(isolinux_source_file, File.join(wd, 'build', 'isolinux.bin'))
65
+
66
+ ldlinux_source_file = File.join(Setting[:bootdisk_syslinux_dir], 'ldlinux.c32')
67
+ FileUtils.cp(ldlinux_source_file, File.join(wd, 'build', 'ldlinux.c32')) if File.exist?(ldlinux_source_file)
68
+
69
+ File.open(File.join(wd, 'build', 'isolinux.cfg'), 'w') do |file|
70
+ file.write(opts[:isolinux])
71
+ end
57
72
  end
58
- end
59
73
 
60
- if opts[:ipxe]
61
- unless File.exists?(File.join(Setting[:bootdisk_ipxe_dir], 'ipxe.lkrn'))
62
- raise ::Foreman::Exception.new(N_("Please ensure the ipxe-bootimgs package is installed."))
74
+ if opts[:ipxe]
75
+ ipxe_source_file = File.join(Setting[:bootdisk_ipxe_dir], 'ipxe.lkrn')
76
+ raise Foreman::Exception, N_('Please ensure the ipxe-bootimgs package is installed.') unless File.exist?(ipxe_source_file)
77
+
78
+ FileUtils.cp(ipxe_source_file, File.join(wd, 'build', 'ipxe'))
79
+ File.open(File.join(wd, 'build', 'script'), 'w') { |file| file.write(opts[:ipxe]) }
63
80
  end
64
- FileUtils.cp(File.join(Setting[:bootdisk_ipxe_dir], 'ipxe.lkrn'), File.join(wd, 'build', 'ipxe'))
65
- File.open(File.join(wd, 'build', 'script'), 'w') { |file| file.write(opts[:ipxe]) }
66
- end
67
81
 
68
- if opts[:files]
69
- opts[:files].each do |bootfile_info|
70
- for file, source in bootfile_info do
71
- fetch(File.join(wd, 'build', file), source)
82
+ if opts[:files]
83
+ if opts[:files].respond_to?(:each)
84
+ opts[:files].each do |file, source|
85
+ fetch(File.join(wd, 'build', file), source)
86
+ end
72
87
  end
73
- end if opts[:files].respond_to? :each
74
- end
88
+ end
75
89
 
76
- iso = if opts[:dir]
77
- Tempfile.new(['bootdisk', '.iso'], opts[:dir]).path
78
- else
79
- File.join(wd, 'output.iso')
80
- end
81
- unless system("#{Setting[:bootdisk_mkiso_command]} -o #{iso} -iso-level 2 -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table #{File.join(wd, 'build')}")
82
- raise ::Foreman::Exception.new(N_("ISO build failed"))
83
- end
90
+ iso = if opts[:dir]
91
+ Tempfile.new(['bootdisk', '.iso'], opts[:dir]).path
92
+ else
93
+ File.join(wd, 'output.iso')
94
+ end
95
+ raise Foreman::Exception, N_('ISO build failed') unless system(build_mkiso_command(output_file: iso, source_directory: File.join(wd, 'build')))
96
+
97
+ # Make the ISO bootable as a HDD/USB disk too
98
+ raise Foreman::Exception, N_('ISO hybrid conversion failed') unless system('isohybrid', iso)
84
99
 
85
- # Make the ISO bootable as a HDD/USB disk too
86
- unless system("isohybrid", iso)
87
- raise ::Foreman::Exception.new(N_("ISO hybrid conversion failed"))
100
+ yield iso
88
101
  end
102
+ end
89
103
 
90
- yield iso
104
+ def self.build_mkiso_command(output_file:, source_directory:)
105
+ arguments = [
106
+ "-o #{output_file}",
107
+ '-iso-level 2',
108
+ '-b isolinux.bin',
109
+ '-c boot.cat',
110
+ '-no-emul-boot',
111
+ '-boot-load-size 4',
112
+ '-boot-info-table'
113
+ ]
114
+ [Setting[:bootdisk_mkiso_command], arguments, source_directory].flatten.join(' ')
91
115
  end
92
- end
93
116
 
94
- def self.token_expiry(host)
95
- expiry = host.token.try(:expires)
96
- return '' if Setting[:token_duration] == 0 || expiry.blank?
97
- '_' + expiry.strftime('%Y%m%d_%H%M')
98
- end
117
+ def self.token_expiry(host)
118
+ expiry = host.token.try(:expires)
119
+ return '' if Setting[:token_duration].zero? || expiry.blank?
120
+
121
+ '_' + expiry.strftime('%Y%m%d_%H%M')
122
+ end
99
123
 
100
- private
101
-
102
- def self.fetch(path, uri)
103
- dir = File.dirname(path)
104
- FileUtils.mkdir_p(dir) unless File.exist?(dir)
105
-
106
- use_cache = !!Setting[:bootdisk_cache_media]
107
- write_cache = false
108
- File.open(path, 'w') do |file|
109
- file.binmode
110
-
111
- if use_cache && !(contents = Rails.cache.fetch(uri, :raw => true)).nil?
112
- ForemanBootdisk.logger.info("Retrieved #{uri} from local cache (use foreman-rake tmp:cache:clear to empty)")
113
- file.write(contents)
114
- else
115
- ForemanBootdisk.logger.info("Fetching #{uri}")
116
- write_cache = use_cache
117
- uri = URI(uri)
118
- Net::HTTP.start(uri.host, uri.port) do |http|
119
- request = Net::HTTP::Get.new uri.request_uri
120
-
121
- http.request request do |response|
122
- response.read_body do |chunk|
123
- file.write chunk
124
+ def self.fetch(path, uri)
125
+ dir = File.dirname(path)
126
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
127
+
128
+ use_cache = !!Setting[:bootdisk_cache_media]
129
+ write_cache = false
130
+ File.open(path, 'w') do |file|
131
+ file.binmode
132
+
133
+ if use_cache && !(contents = Rails.cache.fetch(uri, raw: true)).nil?
134
+ ForemanBootdisk.logger.info("Retrieved #{uri} from local cache (use foreman-rake tmp:cache:clear to empty)")
135
+ file.write(contents)
136
+ else
137
+ ForemanBootdisk.logger.info("Fetching #{uri}")
138
+ write_cache = use_cache
139
+ uri = URI(uri)
140
+ Net::HTTP.start(uri.host, uri.port) do |http|
141
+ request = Net::HTTP::Get.new(uri.request_uri)
142
+
143
+ http.request(request) do |response|
144
+ response.read_body do |chunk|
145
+ file.write chunk
146
+ end
124
147
  end
125
148
  end
126
149
  end
127
150
  end
128
- end
129
151
 
130
- if write_cache
152
+ return unless write_cache
153
+
131
154
  ForemanBootdisk.logger.debug("Caching contents of #{uri}")
132
- Rails.cache.write(uri, File.read(path), :raw => true)
155
+ Rails.cache.write(uri, File.read(path), raw: true)
133
156
  end
134
- end
135
157
 
136
- # isolinux supports up to ISO 9660 level 2 filenames
137
- def self.iso9660_filename(name)
138
- dir = File.dirname(name)
139
- file = File.basename(name).upcase.tr_s('^A-Z0-9_', '_').last(28)
140
- dir == '.' ? file : File.join(dir.upcase.tr_s('^A-Z0-9_', '_').last(28), file)
158
+ # isolinux supports up to ISO 9660 level 2 filenames
159
+ def self.iso9660_filename(name)
160
+ dir = File.dirname(name)
161
+ file = File.basename(name).upcase.tr_s('^A-Z0-9_', '_').last(28)
162
+ dir == '.' ? file : File.join(dir.upcase.tr_s('^A-Z0-9_', '_').last(28), file)
163
+ end
141
164
  end
142
165
  end