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