foreman_bootdisk 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +10 -0
- data/README.md +19 -14
- data/app/helpers/concerns/bootdisk/hosts_helper_ext.rb +1 -4
- data/app/models/concerns/bootdisk/config_template_ext.rb +4 -1
- data/app/services/bootdisk/iso_generator.rb +11 -4
- data/app/views/bootdisk/host_v1.erb +21 -0
- data/app/views/bootdisk/host_v2.erb +38 -0
- data/app/views/bootdisk/kickstart_v1.erb +5 -0
- data/db/migrate/20130914211030_create_host_bootdisk_template.rb +1 -23
- data/db/migrate/20130915104500_edit_host_bootdisk_template_multinic.rb +11 -0
- data/db/migrate/20130915133321_create_kickstart_bootdisk_template.rb +13 -0
- data/lib/foreman_bootdisk.rb +1 -1
- data/lib/tasks/bootdisk.rake +2 -6
- metadata +50 -24
- checksums.yaml +0 -7
data/CHANGES.md
ADDED
data/README.md
CHANGED
@@ -5,9 +5,9 @@ DHCP and TFTP services. However many users don't have these available, so
|
|
5
5
|
foreman_bootdisk provides both a per-host and generic boot disks to enable
|
6
6
|
deployments in datacentres without these capabilities.
|
7
7
|
|
8
|
-
Boot images
|
9
|
-
either from physical media or virtual disk/CDROM (via a lights out
|
10
|
-
device).
|
8
|
+
Boot images are written as hybrid ISO images (usable as ISOs or USB disks),
|
9
|
+
and booted either from physical media or virtual disk/CDROM (via a lights out
|
10
|
+
management device).
|
11
11
|
|
12
12
|
# Installation
|
13
13
|
|
@@ -25,6 +25,7 @@ RPM users can install the "ruby193-rubygem-foreman_bootdisk" or
|
|
25
25
|
|
26
26
|
* iPXE images are required
|
27
27
|
* syslinux is required
|
28
|
+
* mkisofs and isohybrid are required
|
28
29
|
|
29
30
|
gPXE images are unsupported due to lack of initrd support, but the name will
|
30
31
|
crop up as Foreman's script support is still named after the project.
|
@@ -49,11 +50,10 @@ The templates used on the boot disks themselves are read-only so they can be
|
|
49
50
|
updated in new versions of the plugin. To customise, copy the contents to a
|
50
51
|
new template and set the name in More>Settings>Bootdisk.
|
51
52
|
|
52
|
-
An OS gPXE provisioning template is required,
|
53
|
-
(as supplied by
|
54
|
-
tab and that the gPXE template is selected under the Templates tab
|
55
|
-
|
56
|
-
TODO: missing Debian template, kickstart gPXE template assumes `net0`
|
53
|
+
An OS gPXE provisioning template is required, preferably "Kickstart boot disk
|
54
|
+
gPXE" (as supplied by this plugin). Ensure the OSes are ticked under the
|
55
|
+
Associations tab and that the gPXE template is selected under the Templates tab
|
56
|
+
on the OS.
|
57
57
|
|
58
58
|
Lastly, the OS provision template (i.e. kickstart/preseed) should provide the
|
59
59
|
static IP details required to configure the OS. For a kickstart file, the
|
@@ -61,6 +61,14 @@ following configuration will do this:
|
|
61
61
|
|
62
62
|
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
63
|
|
64
|
+
## USB images
|
65
|
+
|
66
|
+
The ISO images generated are run through `isohybrid` which makes them bootable
|
67
|
+
as disks too, suitable for copying to a USB device.
|
68
|
+
|
69
|
+
Use `dd if=fqdn.iso of=/dev/sdb` or similar to copy the image to a USB disk.
|
70
|
+
Ensure the device name is correct to avoid writing over the wrong disk.
|
71
|
+
|
64
72
|
## Per-host images
|
65
73
|
|
66
74
|
Using the host and subnet data in Foreman, per-host images can be created with
|
@@ -68,15 +76,14 @@ fully static networking. The behaviour is dynamic, as the image chainloads
|
|
68
76
|
from Foreman, so the current OS and build state will be provided by Foreman
|
69
77
|
instead of being stored in the image.
|
70
78
|
|
71
|
-
To generate the image from the web interface, view the host page
|
72
|
-
"Boot disk" button
|
79
|
+
To generate the image from the web interface, view the host page and click the
|
80
|
+
"Boot disk" button.
|
73
81
|
|
74
82
|
To generate from the command line:
|
75
83
|
|
76
84
|
foreman-rake bootdisk:generate:host NAME=foo.example.com
|
77
85
|
|
78
|
-
Optionally set `
|
79
|
-
`OUTPUT=/path/foo.iso` to change the output destination.
|
86
|
+
Optionally set `OUTPUT=/path/foo.iso` to change the output destination.
|
80
87
|
|
81
88
|
## Generic host group images
|
82
89
|
|
@@ -88,8 +95,6 @@ Report issues on the Redmine project: [foreman_bootdisk](http://projects.thefore
|
|
88
95
|
|
89
96
|
## Known issues
|
90
97
|
|
91
|
-
* USB support not implemented
|
92
|
-
* Templates only support first NIC
|
93
98
|
* No Debian guidance or templates
|
94
99
|
* No SELinux policy support
|
95
100
|
|
@@ -8,10 +8,7 @@ module Bootdisk::HostsHelperExt
|
|
8
8
|
def host_title_actions_with_bootdisk(host, vm)
|
9
9
|
title_actions(
|
10
10
|
button_group(
|
11
|
-
|
12
|
-
display_link_if_authorized(_("ISO image"), hash_for_bootdisk_iso_host_path(:id => @host), :class=>'btn'),
|
13
|
-
display_link_if_authorized(_("USB image"), hash_for_bootdisk_iso_host_path(:id => @host), :class=>'btn'),
|
14
|
-
)
|
11
|
+
display_link_if_authorized(_("Boot disk"), hash_for_bootdisk_iso_host_path(:id => @host), :class=>'btn')
|
15
12
|
)
|
16
13
|
)
|
17
14
|
host_title_actions_without_bootdisk(host, vm)
|
@@ -3,18 +3,21 @@
|
|
3
3
|
module Bootdisk::ConfigTemplateExt
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
BOOTDISK_TMPLS = ['Boot disk gPXE - host', 'Kickstart boot disk gPXE']
|
7
|
+
|
6
8
|
included do
|
7
9
|
before_destroy :bootdisk_destroy?
|
8
10
|
validate :bootdisk_readonly
|
9
11
|
end
|
10
12
|
|
11
13
|
def bootdisk_destroy?
|
14
|
+
return true if ARGV.find { |a| a.start_with? "db:migrate" }
|
12
15
|
bootdisk_readonly
|
13
16
|
errors.empty?
|
14
17
|
end
|
15
18
|
|
16
19
|
def bootdisk_readonly
|
17
|
-
if
|
20
|
+
if BOOTDISK_TMPLS.include? name_was
|
18
21
|
errors.add(:base, _("Template is read-only as it's supplied in foreman_bootdisk. Please copy it to a new template to customize."))
|
19
22
|
end
|
20
23
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
# Generates an iPXE ISO image
|
1
|
+
# Generates an iPXE ISO hybrid image
|
2
2
|
#
|
3
|
-
# requires syslinux, ipxe/ipxe-bootimgs, mkisofs
|
3
|
+
# requires syslinux, ipxe/ipxe-bootimgs, mkisofs, isohybrid
|
4
4
|
class Bootdisk::ISOGenerator
|
5
5
|
attr_reader :script
|
6
6
|
|
@@ -11,22 +11,29 @@ class Bootdisk::ISOGenerator
|
|
11
11
|
def generate(&block)
|
12
12
|
Dir.mktmpdir('bootdisk') do |wd|
|
13
13
|
Dir.mkdir(File.join(wd, 'build'))
|
14
|
-
File.
|
14
|
+
File.open(File.join(wd, 'build', 'isolinux.cfg'),'w') do |file|
|
15
|
+
file.write(<<EOF)
|
15
16
|
default ipxe
|
16
17
|
label ipxe
|
17
18
|
kernel /ipxe
|
18
19
|
initrd /script
|
19
20
|
EOF
|
21
|
+
end
|
20
22
|
|
21
23
|
FileUtils.cp(File.join(Setting[:bootdisk_syslinux_dir], 'isolinux.bin'), File.join(wd, 'build', 'isolinux.bin'))
|
22
24
|
FileUtils.cp(File.join(Setting[:bootdisk_ipxe_dir], 'ipxe.lkrn'), File.join(wd, 'build', 'ipxe'))
|
23
|
-
File.
|
25
|
+
File.open(File.join(wd, 'build', 'script'),'w') { |file| file.write(script) }
|
24
26
|
|
25
27
|
iso = File.join(wd, 'output.iso')
|
26
28
|
unless system("mkisofs -o #{iso} -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table #{File.join(wd, 'build')}")
|
27
29
|
raise ::Foreman::Exception.new(N_("ISO build failed"))
|
28
30
|
end
|
29
31
|
|
32
|
+
# Make the ISO bootable as a HDD/USB disk too
|
33
|
+
unless system("isohybrid", iso)
|
34
|
+
raise ::Foreman::Exception.new(N_("ISO hybrid conversion failed"))
|
35
|
+
end
|
36
|
+
|
30
37
|
yield iso
|
31
38
|
end
|
32
39
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!ipxe
|
2
|
+
# Example foreman_bootdisk host template
|
3
|
+
# This template is rendered for use inside a host-specific boot disk.
|
4
|
+
#
|
5
|
+
# Copy this template to customize it, the original is read-only.
|
6
|
+
|
7
|
+
# TODO: loop over net* until the host's MAC matches
|
8
|
+
ifopen net0
|
9
|
+
set net0/ip <%= @host.ip %>
|
10
|
+
set net0/netmask <%= @host.subnet.mask %>
|
11
|
+
set net0/gateway <%= @host.subnet.gateway %>
|
12
|
+
route
|
13
|
+
|
14
|
+
# Note, iPXE can only use one DNS server
|
15
|
+
set dns <%= @host.subnet.dns_primary %> <%= @host.subnet.dns_secondary %>
|
16
|
+
set net0/dns ${dns}
|
17
|
+
set domain <%= @host.domain.to_s %>
|
18
|
+
|
19
|
+
# Chainload from Foreman rather than embedding OS info here, so the behaviour
|
20
|
+
# is entirely dynamic.
|
21
|
+
chain <%= foreman_url("gPXE") %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!ipxe
|
2
|
+
# Example foreman_bootdisk host template
|
3
|
+
# This template is rendered for use inside a host-specific boot disk.
|
4
|
+
#
|
5
|
+
# Copy this template to customize it, the original is read-only.
|
6
|
+
|
7
|
+
# loop over net* until the host's MAC matches
|
8
|
+
<% (0..32).each do |i| -%>
|
9
|
+
:net<%= i %>
|
10
|
+
isset ${net<%= i -%>/mac} || goto no_nic
|
11
|
+
echo net<%= i -%> is a ${net<%= i -%>/chip} with MAC ${net<%= i -%>/mac}
|
12
|
+
iseq ${net<%= i -%>/mac} <%= @host.mac -%> || goto net<%= i+1 %>
|
13
|
+
ifopen net<%= i %>
|
14
|
+
set idx:int32 <%= i %>
|
15
|
+
goto loop_success
|
16
|
+
<% end -%>
|
17
|
+
|
18
|
+
:loop_success
|
19
|
+
echo Configuring net${idx} for static IP address
|
20
|
+
ifopen net${idx}
|
21
|
+
set netX/ip <%= @host.ip %>
|
22
|
+
set netX/netmask <%= @host.subnet.mask %>
|
23
|
+
set netX/gateway <%= @host.subnet.gateway %>
|
24
|
+
route
|
25
|
+
|
26
|
+
# Note, iPXE can only use one DNS server
|
27
|
+
set dns <%= @host.subnet.dns_primary %> <%= @host.subnet.dns_secondary %>
|
28
|
+
set domain <%= @host.domain.to_s %>
|
29
|
+
|
30
|
+
# Chainload from Foreman rather than embedding OS info here, so the behaviour
|
31
|
+
# is entirely dynamic.
|
32
|
+
chain <%= foreman_url("gPXE") %>
|
33
|
+
exit 0
|
34
|
+
|
35
|
+
:no_nic
|
36
|
+
echo Cannot find interface with MAC <%= @host.mac %>
|
37
|
+
sleep 30
|
38
|
+
exit 1
|
@@ -0,0 +1,5 @@
|
|
1
|
+
#!gpxe
|
2
|
+
kernel <%= "#{@host.url_for_boot(:kernel)}" %> ks=<%= foreman_url("provision")%>?static=yes ksdevice=<%= @host.mac %> network kssendmac ip=${netX/ip} netmask=${netX/netmask} gateway=${netX/gateway} dns=${dns}
|
3
|
+
initrd <%= "#{@host.url_for_boot(:initrd)}" %>
|
4
|
+
|
5
|
+
boot
|
@@ -3,29 +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
|
-
:template =>
|
7
|
-
#!ipxe
|
8
|
-
# Example foreman_bootdisk host template
|
9
|
-
# This template is rendered for use inside a host-specific boot disk.
|
10
|
-
#
|
11
|
-
# Copy this template to customize it, the original is read-only.
|
12
|
-
|
13
|
-
# TODO: loop over net* until the host's MAC matches
|
14
|
-
ifopen net0
|
15
|
-
set net0/ip <%= @host.ip %>
|
16
|
-
set net0/netmask <%= @host.subnet.mask %>
|
17
|
-
set net0/gateway <%= @host.subnet.gateway %>
|
18
|
-
route
|
19
|
-
|
20
|
-
# Note, iPXE can only use one DNS server
|
21
|
-
set dns <%= @host.subnet.dns_primary %> <%= @host.subnet.dns_secondary %>
|
22
|
-
set net0/dns ${dns}
|
23
|
-
set domain <%= @host.domain.to_s %>
|
24
|
-
|
25
|
-
# Chainload from Foreman rather than embedding OS info here, so the behaviour
|
26
|
-
# is entirely dynamic.
|
27
|
-
chain <%= foreman_url("gPXE") %>
|
28
|
-
EOS
|
6
|
+
:template => File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'host_v1.erb'))
|
29
7
|
)
|
30
8
|
end
|
31
9
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class EditHostBootdiskTemplateMultinic < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
ConfigTemplate.find_by_name('Boot disk gPXE - host').update_attribute(
|
4
|
+
:template, File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'host_v2.erb')))
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
ConfigTemplate.find_by_name('Boot disk gPXE - host').update_attribute(
|
9
|
+
:template, File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'host_v1.erb')))
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateKickstartBootdiskTemplate < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
ConfigTemplate.find_or_create_by_name(
|
4
|
+
:name => 'Kickstart boot disk gPXE',
|
5
|
+
:template_kind_id => TemplateKind.find_by_name('gPXE').try(:id),
|
6
|
+
:template => File.read(File.join(Bootdisk::Engine.root, 'app', 'views', 'bootdisk', 'kickstart_v1.erb'))
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
ConfigTemplate.destroy_all(:name => 'Kickstart boot disk gPXE')
|
12
|
+
end
|
13
|
+
end
|
data/lib/foreman_bootdisk.rb
CHANGED
data/lib/tasks/bootdisk.rake
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
namespace :bootdisk do
|
2
2
|
namespace :generate do
|
3
|
-
desc 'Generate a static boot disk for a specific host. NAME=fqdn,
|
3
|
+
desc 'Generate a static boot disk for a specific host. NAME=fqdn, OUTPUT path'
|
4
4
|
task :host => :environment do
|
5
5
|
host = Host::Base.find_by_name(ENV['NAME']) || raise("cannot find host '#{ENV['NAME']}', specify NAME=fqdn")
|
6
6
|
tmpl = host.bootdisk_template_render
|
7
7
|
|
8
|
-
|
9
|
-
case type
|
10
|
-
when 'usb'; Bootdisk::USBGenerator
|
11
|
-
else; Bootdisk::ISOGenerator
|
12
|
-
end.new(tmpl).generate do |image|
|
8
|
+
Bootdisk::ISOGenerator.new(tmpl).generate do |image|
|
13
9
|
output = ENV['OUTPUT'] || "#{host.name}.#{type}"
|
14
10
|
FileUtils.cp image, output
|
15
11
|
puts "Wrote #{output}"
|
metadata
CHANGED
@@ -1,24 +1,35 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_bootdisk
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
5
11
|
platform: ruby
|
6
|
-
authors:
|
12
|
+
authors:
|
7
13
|
- Dominic Cleal
|
8
14
|
autorequire:
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
|
-
|
17
|
+
|
18
|
+
date: 2013-09-15 00:00:00 Z
|
12
19
|
dependencies: []
|
13
|
-
|
14
|
-
|
20
|
+
|
21
|
+
description: Plugin for Foreman that creates iPXE-based boot disks to provision hosts without the need for PXE infrastructure.
|
15
22
|
email: dcleal@redhat.com
|
16
23
|
executables: []
|
24
|
+
|
17
25
|
extensions: []
|
18
|
-
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- CHANGES.md
|
19
29
|
- LICENSE
|
20
30
|
- README.md
|
21
|
-
files:
|
31
|
+
files:
|
32
|
+
- CHANGES.md
|
22
33
|
- LICENSE
|
23
34
|
- README.md
|
24
35
|
- app/controllers/concerns/bootdisk/hosts_controller_ext.rb
|
@@ -27,33 +38,48 @@ files:
|
|
27
38
|
- app/models/concerns/bootdisk/host_ext.rb
|
28
39
|
- app/models/setting/bootdisk.rb
|
29
40
|
- app/services/bootdisk/iso_generator.rb
|
41
|
+
- app/views/bootdisk/host_v1.erb
|
42
|
+
- app/views/bootdisk/host_v2.erb
|
43
|
+
- app/views/bootdisk/kickstart_v1.erb
|
30
44
|
- config/routes.rb
|
31
45
|
- db/migrate/20130914211030_create_host_bootdisk_template.rb
|
46
|
+
- db/migrate/20130915104500_edit_host_bootdisk_template_multinic.rb
|
47
|
+
- db/migrate/20130915133321_create_kickstart_bootdisk_template.rb
|
32
48
|
- lib/bootdisk/engine.rb
|
33
49
|
- lib/foreman_bootdisk.rb
|
34
50
|
- lib/tasks/bootdisk.rake
|
35
51
|
homepage: http://github.com/theforeman/foreman_bootdisk
|
36
|
-
licenses:
|
52
|
+
licenses:
|
37
53
|
- GPL-3
|
38
|
-
metadata: {}
|
39
54
|
post_install_message:
|
40
55
|
rdoc_options: []
|
41
|
-
|
56
|
+
|
57
|
+
require_paths:
|
42
58
|
- lib
|
43
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
53
77
|
requirements: []
|
78
|
+
|
54
79
|
rubyforge_project:
|
55
|
-
rubygems_version:
|
80
|
+
rubygems_version: 1.8.25
|
56
81
|
signing_key:
|
57
|
-
specification_version:
|
82
|
+
specification_version: 3
|
58
83
|
summary: Create boot disks to provision hosts with Foreman
|
59
84
|
test_files: []
|
85
|
+
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: b3533e45d6b16fee4d6c491d48539d5363cf856e
|
4
|
-
data.tar.gz: c60a73d067c98d1ad7fdcebe0b858513ac2c48f9
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: ca8ceaa8d47f2ffe6ebae5c77debca1c02cd23d30cb6803c764691994a77ee4778da498c566605965ec5e4e01e394e75e7dec68b635f768988946b658c7a89dc
|
7
|
-
data.tar.gz: 5e70814bcbdea0e5e10a3eee1c050a07c75e159bd101d3ab251307f25980dd175dcfdb772797c57241c46342fe9eff6a5ff31a672ded3fe2a5cf3eaf4aa0de49
|