foreman_bootdisk 13.0.0 → 14.0.0

Sign up to get free protection for your applications and to get access to all the features.
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