foreman_bootdisk 1.1.0 → 1.2.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.
- data/CHANGES.md +5 -1
- data/README.md +63 -12
- data/app/controllers/bootdisk/disks_controller.rb +9 -0
- data/app/controllers/concerns/bootdisk/unattended_controller_ext.rb +12 -0
- data/app/helpers/concerns/bootdisk/hosts_helper_ext.rb +4 -1
- data/app/models/concerns/bootdisk/config_template_ext.rb +13 -1
- data/app/models/setting/bootdisk.rb +1 -0
- data/app/services/bootdisk/renderer.rb +12 -0
- data/app/views/bootdisk/generic_host_v1.erb +25 -0
- data/config/routes.rb +5 -1
- data/db/migrate/20130914211030_create_host_bootdisk_template.rb +1 -0
- data/db/migrate/20130915133321_create_kickstart_bootdisk_template.rb +1 -0
- data/db/migrate/20130915201457_create_generic_host_bootdisk_template.rb +14 -0
- data/lib/bootdisk/engine.rb +3 -0
- data/lib/bootdisk/version.rb +3 -0
- data/lib/foreman_bootdisk.rb +2 -1
- data/lib/tasks/bootdisk.rake +12 -1
- metadata +10 -4
data/CHANGES.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## v1.
|
3
|
+
## v1.2.0
|
4
|
+
* add generic image, relying on DHCP and a MAC/IP search
|
5
|
+
* fix inability to associate provided templates with OSes
|
6
|
+
|
7
|
+
# v1.1.0
|
4
8
|
* per-host USB image support using isohybrid
|
5
9
|
* templates updated for multi-NIC support
|
6
10
|
* Ruby 1.8.7 fixes
|
data/README.md
CHANGED
@@ -39,6 +39,7 @@ Some configuration is set under More>Settings>Bootdisk in the Foreman UI.
|
|
39
39
|
* `bootdisk_ipxe_dir` points to the directory containing ipxe.lkrn
|
40
40
|
* `bootdisk_syslinux_dir` points to the directory containing syslinux images
|
41
41
|
* `bootdisk_host_template` is the name of the per-host boot disk template
|
42
|
+
* `bootdisk_generic_host_template` is the name of the generic boot disk template
|
42
43
|
|
43
44
|
For per-host images, ensure host IP addresses and subnets are populated, and
|
44
45
|
the subnet's gateway, subnet mask and DNS resolver(s) are correctly configured
|
@@ -61,23 +62,45 @@ following configuration will do this:
|
|
61
62
|
|
62
63
|
network --bootproto <%= @static ? "static" : "dhcp" %> --hostname <%= @host %> <%= "--ip=#{@host.ip} --netmask=#{@host.subnet.mask} --gateway=#{@host.subnet.gateway} --nameserver=#{@host.subnet.dns_primary},#{@host.subnet.dns_secondary}" if @static %>
|
63
64
|
|
64
|
-
##
|
65
|
-
|
66
|
-
The
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
65
|
+
## Available images
|
66
|
+
|
67
|
+
The image types have trade-offs, but are all meant for environments without
|
68
|
+
total control over the network infrastructure - so no DHCP reservations or
|
69
|
+
TFTP settings are needed.
|
70
|
+
|
71
|
+
<table>
|
72
|
+
<tr>
|
73
|
+
<th>Type</th>
|
74
|
+
<th>Generic</th>
|
75
|
+
<th>DHCP required</th>
|
76
|
+
<th>DHCP reservation</th>
|
77
|
+
<th>Pre-register host</th>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<td>Per-host image</td>
|
81
|
+
<td>No</td>
|
82
|
+
<td>No</td>
|
83
|
+
<td>No</td>
|
84
|
+
<td>Yes</td>
|
85
|
+
</tr>
|
86
|
+
<tr>
|
87
|
+
<td>Generic image</td>
|
88
|
+
<td>Yes</td>
|
89
|
+
<td>Yes</td>
|
90
|
+
<td>No</td>
|
91
|
+
<td>Yes</td>
|
92
|
+
</tr>
|
93
|
+
</table>
|
94
|
+
|
95
|
+
### Per-host images
|
73
96
|
|
74
97
|
Using the host and subnet data in Foreman, per-host images can be created with
|
75
98
|
fully static networking. The behaviour is dynamic, as the image chainloads
|
76
99
|
from Foreman, so the current OS and build state will be provided by Foreman
|
77
100
|
instead of being stored in the image.
|
78
101
|
|
79
|
-
To generate the image from the web interface, view the host page
|
80
|
-
"Boot disk" button.
|
102
|
+
To generate the image from the web interface, view the host page, click the
|
103
|
+
"Boot disk" button and select "Host 'FQDN' image".
|
81
104
|
|
82
105
|
To generate from the command line:
|
83
106
|
|
@@ -85,10 +108,38 @@ To generate from the command line:
|
|
85
108
|
|
86
109
|
Optionally set `OUTPUT=/path/foo.iso` to change the output destination.
|
87
110
|
|
88
|
-
|
111
|
+
### Generic image
|
112
|
+
|
113
|
+
This provides a single ISO that can be used by all hosts, but since IP details
|
114
|
+
can't be stored inside, it requires a DHCP pool on the network to bootstrap.
|
115
|
+
It will boot and contact Foreman for template of a registered host matching a
|
116
|
+
MAC address or the IP the host was assigned by DHCP.
|
117
|
+
|
118
|
+
The installation can continue on either the DHCP or static IP depending on how
|
119
|
+
the OS gPXE template is configured, and could configure the assigned IP
|
120
|
+
address statically for the installed system via the kickstart file.
|
121
|
+
|
122
|
+
To generate the image from the web interface, view a host page, click the
|
123
|
+
"Boot disk" button and select "Generic image".
|
124
|
+
|
125
|
+
To generate from the command line:
|
126
|
+
|
127
|
+
foreman-rake bootdisk:generate:generic
|
128
|
+
|
129
|
+
Optionally set `OUTPUT=/path/foo.iso` to change the output destination.
|
130
|
+
|
131
|
+
### Host group images
|
89
132
|
|
90
133
|
TODO
|
91
134
|
|
135
|
+
### USB images
|
136
|
+
|
137
|
+
The ISO images generated are run through `isohybrid` which makes them bootable
|
138
|
+
as disks too, suitable for copying to a USB device.
|
139
|
+
|
140
|
+
Use `dd if=fqdn.iso of=/dev/sdb` or similar to copy the image to a USB disk.
|
141
|
+
Ensure the device name is correct to avoid writing over the wrong disk.
|
142
|
+
|
92
143
|
# Issues
|
93
144
|
|
94
145
|
Report issues on the Redmine project: [foreman_bootdisk](http://projects.theforeman.org/projects/bootdisk/issues/new)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Bootdisk
|
2
|
+
class DisksController < ::ApplicationController
|
3
|
+
def generic_iso
|
4
|
+
Bootdisk::ISOGenerator.new(Bootdisk::Renderer.new.generic_template_render).generate do |iso|
|
5
|
+
send_data File.read(iso), :filename => "bootdisk_#{Setting[:foreman_url]}.iso"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Bootdisk::UnattendedControllerExt
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
alias_method_chain :find_host_by_ip_or_mac, :param_mac
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_host_by_ip_or_mac_with_param_mac
|
9
|
+
request.env['HTTP_X_RHN_PROVISIONING_MAC_0'] = "unknown #{params['mac']}" unless request.env.has_key?('HTTP_X_RHN_PROVISIONING_MAC_0')
|
10
|
+
find_host_by_ip_or_mac_without_param_mac
|
11
|
+
end
|
12
|
+
end
|
@@ -8,7 +8,10 @@ module Bootdisk::HostsHelperExt
|
|
8
8
|
def host_title_actions_with_bootdisk(host, vm)
|
9
9
|
title_actions(
|
10
10
|
button_group(
|
11
|
-
|
11
|
+
select_action_button(_('Boot disk'),
|
12
|
+
display_link_if_authorized(_("Host '%s' image") % @host.name.split('.')[0], hash_for_bootdisk_iso_host_path(:id => @host), :class=>'btn'),
|
13
|
+
display_link_if_authorized(_("Generic image"), hash_for_generic_iso_disks_path, :class=>'btn')
|
14
|
+
)
|
12
15
|
)
|
13
16
|
)
|
14
17
|
host_title_actions_without_bootdisk(host, vm)
|
@@ -17,7 +17,19 @@ module Bootdisk::ConfigTemplateExt
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def bootdisk_readonly
|
20
|
-
|
20
|
+
c = changes
|
21
|
+
|
22
|
+
# ignore CRLF changes
|
23
|
+
if c['template'] && (c['template'][0].nil? || c['template'][0].gsub("\n", "\r\n") == c['template'][1])
|
24
|
+
c.delete 'template'
|
25
|
+
end
|
26
|
+
|
27
|
+
# ignore nil to false changes
|
28
|
+
c.delete 'snippet' if c['snippet'] == [nil, false]
|
29
|
+
|
30
|
+
# allow the user to associate it, just not change the content
|
31
|
+
other_attrs = c.keys.find { |f| !['template_combinations', 'template_associations'].include? f }
|
32
|
+
if BOOTDISK_TMPLS.include?(name_was) && other_attrs
|
21
33
|
errors.add(:base, _("Template is read-only as it's supplied in foreman_bootdisk. Please copy it to a new template to customize."))
|
22
34
|
end
|
23
35
|
end
|
@@ -11,6 +11,7 @@ class Setting::Bootdisk< ::Setting
|
|
11
11
|
self.set('bootdisk_ipxe_dir', _('Path to directory containing iPXE images'), ipxe),
|
12
12
|
self.set('bootdisk_syslinux_dir', _('Path to directory containing syslinux images'), syslinux),
|
13
13
|
self.set('bootdisk_host_template', _('gPXE template to use for host-specific boot disks'), 'Boot disk gPXE - host'),
|
14
|
+
self.set('bootdisk_generic_host_template', _('gPXE template to use for generic host boot disks'), 'Boot disk gPXE - generic host'),
|
14
15
|
].compact.each { |s| self.create s.update(:category => "Setting::Bootdisk") }
|
15
16
|
end
|
16
17
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Bootdisk
|
2
|
+
class Renderer
|
3
|
+
include ::Foreman::Renderer
|
4
|
+
include Rails.application.routes.url_helpers
|
5
|
+
|
6
|
+
def generic_template_render
|
7
|
+
tmpl = ConfigTemplate.find_by_name(Setting[:bootdisk_generic_host_template]) || raise(::Foreman::Exception.new(N_('Unable to find template specified by %s setting'), 'bootdisk_generic_host_template'))
|
8
|
+
@host = Struct.new(:token).new(nil)
|
9
|
+
unattended_render(tmpl.template)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!ipxe
|
2
|
+
# Example foreman_bootdisk generic host template
|
3
|
+
#
|
4
|
+
# This template is generic, but it will chainload to Foreman so expects the
|
5
|
+
# host to be registered already.
|
6
|
+
#
|
7
|
+
# It loops through all interfaces using DHCP, requesting a template from
|
8
|
+
# Foreman in the hope that one of the MACs or IPs matches.
|
9
|
+
#
|
10
|
+
# Copy this template to customize it, the original is read-only.
|
11
|
+
|
12
|
+
# loop over net* until we can get a template
|
13
|
+
<% (0..32).each do |i| -%>
|
14
|
+
:net<%= i %>
|
15
|
+
isset ${net<%= i -%>/mac} || goto no_nic
|
16
|
+
echo net<%= i -%> is a ${net<%= i -%>/chip} with MAC ${net<%= i -%>/mac}
|
17
|
+
dhcp net<%= i %> || goto net<%= i+1 %>
|
18
|
+
chain <%= (u = URI.parse(foreman_url("gPXE")); u.query = "#{u.query}&mac="; u.to_s) %>${net<%= i -%>/mac} || goto net<%= i+1 %>
|
19
|
+
exit 0
|
20
|
+
<% end -%>
|
21
|
+
|
22
|
+
:no_nic
|
23
|
+
echo Failed to chainload from any network interface
|
24
|
+
sleep 30
|
25
|
+
exit 1
|
data/config/routes.rb
CHANGED
@@ -3,6 +3,7 @@ class CreateHostBootdiskTemplate < ActiveRecord::Migration
|
|
3
3
|
ConfigTemplate.find_or_create_by_name(
|
4
4
|
:name => 'Boot disk gPXE - host',
|
5
5
|
:template_kind_id => TemplateKind.find_by_name('gPXE').try(:id),
|
6
|
+
:snippet => false,
|
6
7
|
:template => File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'host_v1.erb'))
|
7
8
|
)
|
8
9
|
end
|
@@ -3,6 +3,7 @@ class CreateKickstartBootdiskTemplate < ActiveRecord::Migration
|
|
3
3
|
ConfigTemplate.find_or_create_by_name(
|
4
4
|
:name => 'Kickstart boot disk gPXE',
|
5
5
|
:template_kind_id => TemplateKind.find_by_name('gPXE').try(:id),
|
6
|
+
:snippet => false,
|
6
7
|
:template => File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'kickstart_v1.erb'))
|
7
8
|
)
|
8
9
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateGenericHostBootdiskTemplate < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
ConfigTemplate.find_or_create_by_name(
|
4
|
+
:name => 'Boot disk gPXE - generic host',
|
5
|
+
:template_kind_id => TemplateKind.find_by_name('gPXE').try(:id),
|
6
|
+
:snippet => false,
|
7
|
+
:template => File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'generic_host_v1.erb'))
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
ConfigTemplate.destroy_all(:name => 'Boot disk gPXE - generic host')
|
13
|
+
end
|
14
|
+
end
|
data/lib/bootdisk/engine.rb
CHANGED
@@ -2,6 +2,8 @@ require 'foreman_bootdisk'
|
|
2
2
|
|
3
3
|
module Bootdisk
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
+
engine_name Bootdisk::ENGINE_NAME
|
6
|
+
|
5
7
|
config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
|
6
8
|
config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
|
7
9
|
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
@@ -19,6 +21,7 @@ module Bootdisk
|
|
19
21
|
Host::Managed.send(:include, Bootdisk::HostExt)
|
20
22
|
HostsController.send(:include, Bootdisk::HostsControllerExt)
|
21
23
|
HostsHelper.send(:include, Bootdisk::HostsHelperExt)
|
24
|
+
UnattendedController.send(:include, Bootdisk::UnattendedControllerExt)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
data/lib/foreman_bootdisk.rb
CHANGED
data/lib/tasks/bootdisk.rake
CHANGED
@@ -6,7 +6,18 @@ namespace :bootdisk do
|
|
6
6
|
tmpl = host.bootdisk_template_render
|
7
7
|
|
8
8
|
Bootdisk::ISOGenerator.new(tmpl).generate do |image|
|
9
|
-
output = ENV['OUTPUT'] || "#{host.name}
|
9
|
+
output = ENV['OUTPUT'] || "#{host.name}.iso"
|
10
|
+
FileUtils.cp image, output
|
11
|
+
puts "Wrote #{output}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate a generic boot disk. OUTPUT=path'
|
16
|
+
task :generic => :environment do
|
17
|
+
tmpl = Bootdisk::Renderer.new.generic_template_render
|
18
|
+
|
19
|
+
Bootdisk::ISOGenerator.new(tmpl).generate do |image|
|
20
|
+
output = ENV['OUTPUT'] || "bootdisk_#{Setting[:foreman_url]}.iso"
|
10
21
|
FileUtils.cp image, output
|
11
22
|
puts "Wrote #{output}"
|
12
23
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_bootdisk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 1.
|
10
|
+
version: 1.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dominic Cleal
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-09-
|
18
|
+
date: 2013-09-17 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Plugin for Foreman that creates iPXE-based boot disks to provision hosts without the need for PXE infrastructure.
|
@@ -32,12 +32,16 @@ files:
|
|
32
32
|
- CHANGES.md
|
33
33
|
- LICENSE
|
34
34
|
- README.md
|
35
|
+
- app/controllers/bootdisk/disks_controller.rb
|
35
36
|
- app/controllers/concerns/bootdisk/hosts_controller_ext.rb
|
37
|
+
- app/controllers/concerns/bootdisk/unattended_controller_ext.rb
|
36
38
|
- app/helpers/concerns/bootdisk/hosts_helper_ext.rb
|
37
39
|
- app/models/concerns/bootdisk/config_template_ext.rb
|
38
40
|
- app/models/concerns/bootdisk/host_ext.rb
|
39
41
|
- app/models/setting/bootdisk.rb
|
40
42
|
- app/services/bootdisk/iso_generator.rb
|
43
|
+
- app/services/bootdisk/renderer.rb
|
44
|
+
- app/views/bootdisk/generic_host_v1.erb
|
41
45
|
- app/views/bootdisk/host_v1.erb
|
42
46
|
- app/views/bootdisk/host_v2.erb
|
43
47
|
- app/views/bootdisk/kickstart_v1.erb
|
@@ -45,7 +49,9 @@ files:
|
|
45
49
|
- db/migrate/20130914211030_create_host_bootdisk_template.rb
|
46
50
|
- db/migrate/20130915104500_edit_host_bootdisk_template_multinic.rb
|
47
51
|
- db/migrate/20130915133321_create_kickstart_bootdisk_template.rb
|
52
|
+
- db/migrate/20130915201457_create_generic_host_bootdisk_template.rb
|
48
53
|
- lib/bootdisk/engine.rb
|
54
|
+
- lib/bootdisk/version.rb
|
49
55
|
- lib/foreman_bootdisk.rb
|
50
56
|
- lib/tasks/bootdisk.rake
|
51
57
|
homepage: http://github.com/theforeman/foreman_bootdisk
|