system-builder 0.0.6 → 0.0.7
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/Manifest.txt +4 -1
- data/lib/system_builder/boot.rb +100 -8
- data/lib/system_builder/configurator.rb +30 -4
- data/lib/system_builder/{image.rb → disk_image.rb} +2 -2
- data/lib/system_builder/disk_squashfs_image.rb +165 -0
- data/lib/system_builder/iso_image.rb +55 -0
- data/lib/system_builder/live_image.rb +130 -0
- data/lib/system_builder/task.rb +21 -1
- data/lib/system_builder.rb +5 -2
- data/system-builder.gemspec +12 -15
- metadata +33 -25
data/Manifest.txt
CHANGED
@@ -18,7 +18,10 @@ lib/system_builder/boot.rb
|
|
18
18
|
lib/system_builder/cli.rb
|
19
19
|
lib/system_builder/configurator.rb
|
20
20
|
lib/system_builder/core_ext.rb
|
21
|
-
lib/system_builder/
|
21
|
+
lib/system_builder/disk_image.rb
|
22
|
+
lib/system_builder/disk_squashfs_image.rb
|
23
|
+
lib/system_builder/iso_image.rb
|
24
|
+
lib/system_builder/live_image.rb
|
22
25
|
lib/system_builder/task.rb
|
23
26
|
script/console
|
24
27
|
script/destroy
|
data/lib/system_builder/boot.rb
CHANGED
@@ -11,6 +11,18 @@ class SystemBuilder::DebianBoot
|
|
11
11
|
@@default_mirror = mirror
|
12
12
|
end
|
13
13
|
|
14
|
+
@@apt_proxy = nil
|
15
|
+
def self.apt_proxy=(proxy)
|
16
|
+
@@apt_proxy = proxy
|
17
|
+
end
|
18
|
+
def self.apt_proxy
|
19
|
+
@@apt_proxy
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.apt_options
|
23
|
+
"-o Acquire::http::Proxy='#{apt_proxy}'" if apt_proxy
|
24
|
+
end
|
25
|
+
|
14
26
|
def initialize(root)
|
15
27
|
@root = root
|
16
28
|
|
@@ -42,7 +54,7 @@ class SystemBuilder::DebianBoot
|
|
42
54
|
def bootstrap
|
43
55
|
unless File.exists?(root)
|
44
56
|
FileUtils::mkdir_p root
|
45
|
-
FileUtils::sudo "debootstrap", debbootstrap_options, version, root,
|
57
|
+
FileUtils::sudo "debootstrap", debbootstrap_options, version, root, debbootstrap_url
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
@@ -81,7 +93,7 @@ class SystemBuilder::DebianBoot
|
|
81
93
|
SystemBuilder::ProcConfigurator.new do |chroot|
|
82
94
|
puts "* create fstab"
|
83
95
|
chroot.image.open("/etc/fstab") do |f|
|
84
|
-
f.puts "LABEL=boot /boot
|
96
|
+
f.puts "LABEL=boot /boot auto defaults,noatime,ro 0 0"
|
85
97
|
%w{/tmp /var/run /var/log /var/lock /var/tmp}.each do |directory|
|
86
98
|
f.puts "tmpfs #{directory} tmpfs defaults,noatime 0 0"
|
87
99
|
end
|
@@ -108,10 +120,76 @@ class SystemBuilder::DebianBoot
|
|
108
120
|
end
|
109
121
|
|
110
122
|
def apt_configurator
|
111
|
-
|
112
|
-
|
113
|
-
|
123
|
+
AptConfigurator.new(self)
|
124
|
+
end
|
125
|
+
|
126
|
+
def apt_confd_proxy_file
|
127
|
+
"/etc/apt/apt.conf.d/02proxy-systembuilder"
|
128
|
+
end
|
129
|
+
|
130
|
+
class AptConfigurator
|
131
|
+
|
132
|
+
attr_reader :boot
|
133
|
+
def initialize(boot)
|
134
|
+
@boot = boot
|
135
|
+
end
|
136
|
+
|
137
|
+
def apt_proxy
|
138
|
+
SystemBuilder::DebianBoot.apt_proxy
|
139
|
+
end
|
140
|
+
|
141
|
+
def apt_options
|
142
|
+
SystemBuilder::DebianBoot.apt_options
|
143
|
+
end
|
144
|
+
|
145
|
+
def offline?
|
146
|
+
ENV['OFFLINE'] == 'true'
|
147
|
+
end
|
148
|
+
|
149
|
+
def debbootstrap_url
|
150
|
+
boot.debbootstrap_url
|
151
|
+
end
|
152
|
+
|
153
|
+
def mirror
|
154
|
+
boot.mirror
|
155
|
+
end
|
156
|
+
|
157
|
+
def sources_list(chroot)
|
158
|
+
File.readlines(chroot.image.file("/etc/apt/sources.list")).collect(&:strip)
|
159
|
+
end
|
160
|
+
|
161
|
+
def rewrite_sources_url(chroot)
|
162
|
+
return unless apt_proxy
|
163
|
+
|
164
|
+
chroot.image.open("/etc/apt/sources.list") do |f|
|
165
|
+
sources_list(chroot).each do |line|
|
166
|
+
f.puts line.gsub(/^deb #{debbootstrap_url}/, "deb #{mirror}")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def update(chroot)
|
172
|
+
chroot.sudo "apt-get #{apt_options} update" unless offline?
|
173
|
+
end
|
174
|
+
|
175
|
+
def apt_confd_file
|
176
|
+
boot.apt_confd_proxy_file
|
177
|
+
end
|
178
|
+
|
179
|
+
def configure_proxy(chroot)
|
180
|
+
return unless apt_proxy
|
181
|
+
|
182
|
+
chroot.image.open(apt_confd_file) do |f|
|
183
|
+
f.puts "Acquire::http { Proxy \"#{apt_proxy}\"; };"
|
184
|
+
end
|
114
185
|
end
|
186
|
+
|
187
|
+
def configure(chroot)
|
188
|
+
rewrite_sources_url(chroot)
|
189
|
+
update(chroot)
|
190
|
+
configure_proxy(chroot)
|
191
|
+
end
|
192
|
+
|
115
193
|
end
|
116
194
|
|
117
195
|
def policyrc_configurator
|
@@ -126,6 +204,10 @@ class SystemBuilder::DebianBoot
|
|
126
204
|
|
127
205
|
def apt_cleaner
|
128
206
|
Proc.new do |chroot|
|
207
|
+
if chroot.image.exists?(apt_confd_proxy_file)
|
208
|
+
puts "* remove apt proxy configuration"
|
209
|
+
chroot.sudo "rm #{apt_confd_proxy_file}"
|
210
|
+
end
|
129
211
|
puts "* clean apt caches"
|
130
212
|
chroot.sudo "apt-get clean"
|
131
213
|
puts "* autoremove packages"
|
@@ -160,6 +242,14 @@ class SystemBuilder::DebianBoot
|
|
160
242
|
end.compact
|
161
243
|
end
|
162
244
|
|
245
|
+
def debbootstrap_url
|
246
|
+
if self.class.apt_proxy
|
247
|
+
"#{self.class.apt_proxy}#{mirror.gsub('http:/','')}"
|
248
|
+
else
|
249
|
+
mirror
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
163
253
|
def image(&block)
|
164
254
|
@image ||= Image.new(root)
|
165
255
|
|
@@ -190,9 +280,10 @@ class SystemBuilder::DebianBoot
|
|
190
280
|
end
|
191
281
|
|
192
282
|
def rsync(target, *sources)
|
283
|
+
sources = sources.flatten
|
193
284
|
options = (Hash === sources.last ? sources.pop : {})
|
194
|
-
rsync_options = options.collect { |k,v| "--#{k}=#{v}" }
|
195
|
-
FileUtils::sudo "rsync -
|
285
|
+
rsync_options = options.collect { |k,v| v == true ? "--#{k}" : "--#{k}=#{v}" }
|
286
|
+
FileUtils::sudo "rsync -a #{rsync_options.join(' ')} #{sources.join(' ')} #{expand_path(target)}"
|
196
287
|
end
|
197
288
|
|
198
289
|
def open(filename, &block)
|
@@ -208,6 +299,7 @@ class SystemBuilder::DebianBoot
|
|
208
299
|
def expand_path(path)
|
209
300
|
File.join(@root,path)
|
210
301
|
end
|
302
|
+
alias_method :file, :expand_path
|
211
303
|
|
212
304
|
def exists?(path)
|
213
305
|
path = expand_path(path)
|
@@ -225,7 +317,7 @@ class SystemBuilder::DebianBoot
|
|
225
317
|
end
|
226
318
|
|
227
319
|
def apt_install(*packages)
|
228
|
-
sudo "apt-get install --yes --force-yes #{packages.join(' ')}"
|
320
|
+
sudo "apt-get install #{SystemBuilder::DebianBoot.apt_options} --yes --force-yes #{packages.join(' ')}"
|
229
321
|
end
|
230
322
|
|
231
323
|
def cp(*arguments)
|
@@ -20,6 +20,10 @@ module SystemBuilder
|
|
20
20
|
@manifest = manifest
|
21
21
|
end
|
22
22
|
|
23
|
+
def puppet_directories
|
24
|
+
%w{manifests files modules templates plugins}.collect { |d| "#{manifest}/#{d}" }.select { |d| File.directory?(d) }
|
25
|
+
end
|
26
|
+
|
23
27
|
def configure(chroot)
|
24
28
|
puts "* run puppet configuration"
|
25
29
|
|
@@ -30,12 +34,34 @@ module SystemBuilder
|
|
30
34
|
|
31
35
|
unless File.directory?(manifest)
|
32
36
|
chroot.image.install "/tmp/puppet.pp", manifest
|
33
|
-
chroot.sudo "puppet tmp/puppet.pp"
|
37
|
+
chroot.sudo "puppet --color=false tmp/puppet.pp | tee /tmp/puppet.log"
|
38
|
+
process_log_file(chroot.image.expand_path("/tmp/puppet.log"))
|
34
39
|
else
|
35
|
-
|
40
|
+
context_dir = "/tmp/puppet"
|
41
|
+
chroot.image.mkdir context_dir
|
42
|
+
|
43
|
+
chroot.image.rsync context_dir, puppet_directories, :exclude => "*~", :delete => true
|
44
|
+
|
45
|
+
chroot.image.mkdir "#{context_dir}/config"
|
46
|
+
chroot.image.open("#{context_dir}/config/fileserver.conf") do |f|
|
47
|
+
%w{files plugins}.each do |mount_point|
|
48
|
+
f.puts "[#{mount_point}]"
|
49
|
+
f.puts "path #{context_dir}/#{mount_point}"
|
50
|
+
f.puts "allow *"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
chroot.image.mkdir "#{context_dir}/tmp"
|
55
|
+
chroot.sudo "puppet --color=false --modulepath '#{context_dir}/modules' --confdir='#{context_dir}/config' --templatedir='#{context_dir}/templates' --manifestdir='#{context_dir}/manifests' --vardir=#{context_dir}/tmp '#{context_dir}/manifests/site.pp' | tee #{context_dir}/puppet.log"
|
56
|
+
|
57
|
+
process_log_file(chroot.image.expand_path("#{context_dir}/puppet.log"))
|
58
|
+
end
|
59
|
+
end
|
36
60
|
|
37
|
-
|
38
|
-
|
61
|
+
def process_log_file(log_file)
|
62
|
+
FileUtils.cp log_file, "puppet.log"
|
63
|
+
unless File.readlines("puppet.log").grep(/^err:/).empty?
|
64
|
+
raise "Error(s) during puppet configuration, see puppet.log file"
|
39
65
|
end
|
40
66
|
end
|
41
67
|
|
@@ -90,7 +90,7 @@ class SystemBuilder::DiskImage
|
|
90
90
|
|
91
91
|
def sync_root_fs
|
92
92
|
mount_root_fs do |mount_dir|
|
93
|
-
FileUtils::sudo "rsync -a --delete --exclude='boot/**' #{boot.root}/ #{mount_dir}"
|
93
|
+
FileUtils::sudo "rsync -a --delete --exclude='boot/**' --exclude='tmp/**' #{boot.root}/ #{mount_dir}"
|
94
94
|
end
|
95
95
|
FileUtils.touch file
|
96
96
|
end
|
@@ -113,7 +113,7 @@ class SystemBuilder::DiskImage
|
|
113
113
|
f.puts "default linux"
|
114
114
|
f.puts "label linux"
|
115
115
|
f.puts "kernel #{readlink_boot_file('vmlinuz')}"
|
116
|
-
f.puts "append ro root=#{root} initrd=#{readlink_boot_file('initrd.img')}"
|
116
|
+
f.puts "append ro root=#{root} initrd=#{readlink_boot_file('initrd.img')} console=tty0 console=ttyS0"
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
class SystemBuilder::DiskSquashfsImage
|
4
|
+
|
5
|
+
attr_accessor :boot, :size
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
|
+
@size = 512.megabytes
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
boot.configurators << SystemBuilder::ProcConfigurator.new do |chroot|
|
15
|
+
puts "* install initramfs-tools"
|
16
|
+
chroot.apt_install %w{initramfs-tools syslinux}
|
17
|
+
|
18
|
+
script = "/usr/share/initramfs-tools/scripts/local-top/mount_boot"
|
19
|
+
unless chroot.image.exists?(script)
|
20
|
+
chroot.image.open(script) do |f|
|
21
|
+
f.puts <<EOF
|
22
|
+
#!/bin/sh -x
|
23
|
+
case ${1:-} in
|
24
|
+
prereqs) echo ""; exit 0;;
|
25
|
+
esac
|
26
|
+
modprobe loop
|
27
|
+
mkdir /boot
|
28
|
+
mount -r -t ext3 LABEL=#{fs_label} /boot
|
29
|
+
exit 0
|
30
|
+
EOF
|
31
|
+
end
|
32
|
+
chroot.sudo "chmod +x #{script}"
|
33
|
+
|
34
|
+
chroot.image.mkdir "/usr/share/initramfs-tools/scripts/local-bottom"
|
35
|
+
chroot.image.open("/usr/share/initramfs-tools/scripts/local-bottom/umount_boot") do |f|
|
36
|
+
f.puts <<EOF
|
37
|
+
#!/bin/sh -x
|
38
|
+
case ${1:-} in
|
39
|
+
prereqs) echo ""; exit 0;;
|
40
|
+
esac
|
41
|
+
mount -n -o move /boot /root/boot
|
42
|
+
exit 0
|
43
|
+
EOF
|
44
|
+
end
|
45
|
+
chroot.sudo "chmod +x /usr/share/initramfs-tools/scripts/local-bottom/umount_boot"
|
46
|
+
|
47
|
+
chroot.image.open("/etc/initramfs-tools/modules") do |f|
|
48
|
+
f.puts "squashfs"
|
49
|
+
end
|
50
|
+
chroot.sudo "/usr/sbin/update-initramfs -u"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
boot.create
|
55
|
+
|
56
|
+
file_creation = (not File.exists?(file))
|
57
|
+
if file_creation
|
58
|
+
create_file
|
59
|
+
create_partition_table
|
60
|
+
|
61
|
+
format_boot_fs
|
62
|
+
end
|
63
|
+
|
64
|
+
sync_boot_fs
|
65
|
+
install_extlinux_files
|
66
|
+
|
67
|
+
compress_root_fs
|
68
|
+
install_extlinux
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_file
|
74
|
+
FileUtils::sh "dd if=/dev/zero of=#{file} count=#{size.in_megabytes.to_i} bs=1M"
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_partition_table
|
78
|
+
# Partition must be bootable for syslinux
|
79
|
+
FileUtils::sh "echo '#{free_sectors},,L,*' | /sbin/sfdisk --no-reread -uS -H16 -S63 #{file}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_boot_fs
|
83
|
+
loop_device = "/dev/loop0"
|
84
|
+
begin
|
85
|
+
FileUtils::sudo "losetup -o #{boot_fs_offset} #{loop_device} #{file}"
|
86
|
+
FileUtils::sudo "mke2fs -L #{fs_label} -jqF #{loop_device} #{boot_fs_block_size}"
|
87
|
+
ensure
|
88
|
+
FileUtils::sudo "losetup -d #{loop_device}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def mount_boot_fs(mount_dir = "/tmp/mount_boot_fs", &block)
|
93
|
+
FileUtils::mkdir_p mount_dir
|
94
|
+
|
95
|
+
begin
|
96
|
+
FileUtils::sudo "mount -o loop,offset=#{boot_fs_offset} #{file} #{mount_dir}"
|
97
|
+
yield mount_dir
|
98
|
+
ensure
|
99
|
+
FileUtils::sudo "umount #{mount_dir}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def compress_root_fs
|
104
|
+
mount_boot_fs do |mount_dir|
|
105
|
+
FileUtils::sudo "mksquashfs #{boot.root}/ #{mount_dir}/filesystem.squashfs -noappend -e #{boot.root}/"
|
106
|
+
end
|
107
|
+
FileUtils.touch file
|
108
|
+
end
|
109
|
+
|
110
|
+
def sync_boot_fs
|
111
|
+
mount_boot_fs do |mount_dir|
|
112
|
+
FileUtils::sudo "rsync -a --delete #{boot.root}/boot/ #{mount_dir}/"
|
113
|
+
FileUtils::sudo "ln -s #{readlink_boot_file('initrd.img')} #{mount_dir}/initrd.img"
|
114
|
+
FileUtils::sudo "ln -s #{readlink_boot_file('vmlinuz')} #{mount_dir}/vmlinuz.img"
|
115
|
+
end
|
116
|
+
FileUtils.touch file
|
117
|
+
end
|
118
|
+
|
119
|
+
def install_extlinux_files(options = {})
|
120
|
+
root = (options[:root] or "LABEL=#{fs_label}")
|
121
|
+
version = (options[:version] or Time.now.strftime("%Y%m%d%H%M"))
|
122
|
+
|
123
|
+
mount_boot_fs do |mount_dir|
|
124
|
+
SystemBuilder::DebianBoot::Image.new(mount_dir).tap do |image|
|
125
|
+
image.open("extlinux.conf") do |f|
|
126
|
+
f.puts "DEFAULT linux"
|
127
|
+
f.puts "LABEL linux"
|
128
|
+
f.puts "SAY Now booting #{version} from syslinux ..."
|
129
|
+
f.puts "KERNEL /vmlinuz"
|
130
|
+
f.puts "APPEND ro initrd=/initrd.img boot=local root=/boot/filesystem.squashfs rootflags=loop rootfstype=squashfs debug"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def install_extlinux
|
137
|
+
mount_boot_fs("#{boot.root}/boot") do
|
138
|
+
boot.chroot do |chroot|
|
139
|
+
chroot.sudo "extlinux --install -H16 -S63 /boot"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
FileUtils::sh "dd if=#{boot.root}/usr/lib/syslinux/mbr.bin of=#{file} conv=notrunc"
|
143
|
+
end
|
144
|
+
|
145
|
+
def fs_label
|
146
|
+
"boot"
|
147
|
+
end
|
148
|
+
|
149
|
+
def readlink_boot_file(boot_file)
|
150
|
+
File.basename(%x{readlink #{boot.root}/#{boot_file}}.strip)
|
151
|
+
end
|
152
|
+
|
153
|
+
def free_sectors
|
154
|
+
64
|
155
|
+
end
|
156
|
+
|
157
|
+
def boot_fs_offset
|
158
|
+
free_sectors * 512
|
159
|
+
end
|
160
|
+
|
161
|
+
def boot_fs_block_size
|
162
|
+
linux_partition_info = `/sbin/sfdisk -l #{file}`.scan(%r{#{file}.*Linux}).first
|
163
|
+
linux_partition_info.split[5].to_i
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
class SystemBuilder::IsoImage
|
4
|
+
|
5
|
+
attr_accessor :boot
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
boot.create
|
14
|
+
create_iso
|
15
|
+
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_iso
|
20
|
+
install_isolinux_files
|
21
|
+
make_iso_fs
|
22
|
+
end
|
23
|
+
|
24
|
+
def install_isolinux_files(options = {})
|
25
|
+
root = (options[:root] or "/dev/hdc")
|
26
|
+
version = (options[:version] or Time.now.strftime("%Y%m%d%H%M"))
|
27
|
+
|
28
|
+
boot.image do |image|
|
29
|
+
image.mkdir "/boot/isolinux"
|
30
|
+
|
31
|
+
image.open("/boot/isolinux/isolinux.cfg") do |f|
|
32
|
+
f.puts "default linux"
|
33
|
+
f.puts "label linux"
|
34
|
+
f.puts "kernel /vmlinuz"
|
35
|
+
f.puts "append ro root=#{root} initrd=/initrd.img"
|
36
|
+
end
|
37
|
+
|
38
|
+
image.install "/boot/isolinux", "/usr/lib/syslinux/isolinux.bin"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def readlink_boot_file(boot_file)
|
43
|
+
File.basename(%x{readlink #{boot.root}/#{boot_file}}.strip)
|
44
|
+
end
|
45
|
+
|
46
|
+
def make_iso_fs
|
47
|
+
FileUtils::sudo "mkisofs -quiet -R -o #{file} -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -A #{root_fs_label} -V #{root_fs_label} -graft-points -hide build/root/initrd.img -hide build/root/vmlinuz vmlinuz=#{boot.root}/boot/#{readlink_boot_file('vmlinuz')} initrd.img=#{boot.root}/boot/#{readlink_boot_file('initrd.img')} #{boot.root}"
|
48
|
+
FileUtils::sudo "chown $USER #{file}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def root_fs_label
|
52
|
+
"root"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
class SystemBuilder::LiveImage
|
4
|
+
|
5
|
+
attr_accessor :boot, :size
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
|
+
@size = 512.megabytes
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
boot.configurators << SystemBuilder::ProcConfigurator.new do |chroot|
|
15
|
+
puts "* install live-initramfs"
|
16
|
+
chroot.apt_install %w{live-initramfs}
|
17
|
+
end
|
18
|
+
|
19
|
+
boot.create
|
20
|
+
|
21
|
+
file_creation = (not File.exists?(file))
|
22
|
+
if file_creation
|
23
|
+
create_file
|
24
|
+
create_partition_table
|
25
|
+
|
26
|
+
format_boot_fs
|
27
|
+
end
|
28
|
+
|
29
|
+
install_syslinux_files
|
30
|
+
|
31
|
+
sync_boot_fs
|
32
|
+
compress_root_fs
|
33
|
+
install_syslinux
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_file
|
39
|
+
FileUtils::sh "dd if=/dev/zero of=#{file} count=#{size.in_megabytes.to_i} bs=1M"
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_partition_table
|
43
|
+
# Partition must be bootable for syslinux
|
44
|
+
FileUtils::sh "echo '#{free_sectors},,b,*' | /sbin/sfdisk --no-reread -uS -H16 -S63 #{file}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_boot_fs
|
48
|
+
loop_device = "/dev/loop0"
|
49
|
+
begin
|
50
|
+
FileUtils::sudo "losetup -o #{boot_fs_offset} #{loop_device} #{file}"
|
51
|
+
FileUtils::sudo "mkdosfs -v -F 32 #{loop_device} #{boot_fs_block_size}"
|
52
|
+
ensure
|
53
|
+
FileUtils::sudo "losetup -d #{loop_device}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def mount_boot_fs(&block)
|
58
|
+
# TODO use a smarter mount_dir
|
59
|
+
mount_dir = "/tmp/mount_boot_fs"
|
60
|
+
FileUtils::mkdir_p mount_dir
|
61
|
+
|
62
|
+
begin
|
63
|
+
FileUtils::sudo "mount -o loop,offset=#{boot_fs_offset} #{file} #{mount_dir}"
|
64
|
+
yield mount_dir
|
65
|
+
ensure
|
66
|
+
FileUtils::sudo "umount #{mount_dir}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def compress_root_fs
|
71
|
+
mount_boot_fs do |mount_dir|
|
72
|
+
FileUtils::sudo "mksquashfs #{boot.root}/ #{mount_dir}/live/filesystem.squashfs -e #{boot.root}/boot"
|
73
|
+
end
|
74
|
+
FileUtils.touch file
|
75
|
+
end
|
76
|
+
|
77
|
+
def sync_boot_fs
|
78
|
+
mount_boot_fs do |mount_dir|
|
79
|
+
FileUtils::sudo "rsync -a --delete #{boot.root}/boot/ #{mount_dir}/live"
|
80
|
+
end
|
81
|
+
FileUtils.touch file
|
82
|
+
end
|
83
|
+
|
84
|
+
def install_syslinux_files(options = {})
|
85
|
+
version = (options[:version] or Time.now.strftime("%Y%m%d%H%M"))
|
86
|
+
|
87
|
+
mount_boot_fs do |mount_dir|
|
88
|
+
SystemBuilder::DebianBoot::Image.new(mount_dir).tap do |image|
|
89
|
+
image.open("/syslinux.cfg") do |f|
|
90
|
+
f.puts "default linux"
|
91
|
+
f.puts "label linux"
|
92
|
+
f.puts "kernel /live/#{readlink_boot_file('vmlinuz')}"
|
93
|
+
f.puts "append ro boot=live initrd=/live/#{readlink_boot_file('initrd.img')} persistent=nofiles"
|
94
|
+
# console=tty0 console=ttyS0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
FileUtils.touch file
|
99
|
+
end
|
100
|
+
|
101
|
+
def readlink_boot_file(boot_file)
|
102
|
+
File.basename(%x{readlink #{boot.root}/#{boot_file}}.strip)
|
103
|
+
end
|
104
|
+
|
105
|
+
def install_syslinux
|
106
|
+
FileUtils::sh "syslinux -o #{boot_fs_offset} #{file}"
|
107
|
+
FileUtils::sh "dd if=/usr/lib/syslinux/mbr.bin of=#{file} conv=notrunc"
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert(export_file, options = {})
|
111
|
+
unless FileUtils.uptodate? export_file, file
|
112
|
+
arguments = []
|
113
|
+
arguments << "-O #{options[:format]}" if options[:format]
|
114
|
+
FileUtils::sh "qemu-img convert -f raw #{file} #{arguments.join(' ')} #{export_file}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def free_sectors
|
119
|
+
64
|
120
|
+
end
|
121
|
+
|
122
|
+
def boot_fs_offset
|
123
|
+
free_sectors * 512
|
124
|
+
end
|
125
|
+
|
126
|
+
def boot_fs_block_size
|
127
|
+
linux_partition_info = `/sbin/sfdisk -l #{file}`.scan(%r{#{file}.*W95 FAT32}).first
|
128
|
+
linux_partition_info.split[5].to_i
|
129
|
+
end
|
130
|
+
end
|
data/lib/system_builder/task.rb
CHANGED
@@ -24,13 +24,33 @@ class SystemBuilder::Task < Rake::TaskLib
|
|
24
24
|
@image.create
|
25
25
|
end
|
26
26
|
namespace :dist do
|
27
|
-
desc "Create
|
27
|
+
desc "Create vmware image in #{@image.file}.vdmk"
|
28
28
|
task :vmware do
|
29
29
|
@image.convert "#{@image.file}.vmdk", :format => "vmdk"
|
30
30
|
end
|
31
|
+
|
32
|
+
desc "Create iso image in #{@image.file}.iso"
|
33
|
+
task :iso do
|
34
|
+
SystemBuilder::IsoImage.new("#{@image.file}.iso").tap do |image|
|
35
|
+
image.boot = @image.boot
|
36
|
+
end.create_iso
|
37
|
+
end
|
31
38
|
end
|
32
39
|
task "dist:vmware" => "dist"
|
33
40
|
|
41
|
+
namespace :build do
|
42
|
+
desc "Configure the image system"
|
43
|
+
task :configure do
|
44
|
+
@image.boot.configure
|
45
|
+
@image.boot.clean
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Clean the image system"
|
49
|
+
task :clean do
|
50
|
+
@image.boot.clean
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
34
54
|
task :setup do
|
35
55
|
required_packages = []
|
36
56
|
required_packages << "qemu" # to convert image files
|
data/lib/system_builder.rb
CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
module SystemBuilder
|
5
|
-
VERSION = '0.0.
|
5
|
+
VERSION = '0.0.7'
|
6
6
|
|
7
7
|
@@configurations = {}
|
8
8
|
|
@@ -19,6 +19,9 @@ module SystemBuilder
|
|
19
19
|
end
|
20
20
|
|
21
21
|
require 'system_builder/core_ext'
|
22
|
-
require 'system_builder/
|
22
|
+
require 'system_builder/disk_image'
|
23
|
+
require 'system_builder/iso_image'
|
24
|
+
require 'system_builder/live_image'
|
25
|
+
require 'system_builder/disk_squashfs_image'
|
23
26
|
require 'system_builder/boot'
|
24
27
|
require 'system_builder/configurator'
|
data/system-builder.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{system-builder}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.7"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Alban Peignier"]
|
9
|
-
s.date = %q{2010-
|
9
|
+
s.date = %q{2010-04-17}
|
10
10
|
s.default_executable = %q{system-builder}
|
11
11
|
s.description = %q{FIX (describe your package)}
|
12
|
-
s.email = ["alban
|
12
|
+
s.email = ["alban@tryphon.eu"]
|
13
13
|
s.executables = ["system-builder"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "PostInstall.txt"]
|
15
|
-
s.files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "Rakefile", "bin/system-builder", "examples/Rakefile", "examples/config.rb", "examples/manifests/classes/test.pp", "examples/manifests/site.pp", "features/development.feature", "features/step_definitions/common_steps.rb", "features/support/common.rb", "features/support/env.rb", "features/support/matchers.rb", "lib/system_builder.rb", "lib/system_builder/boot.rb", "lib/system_builder/cli.rb", "lib/system_builder/configurator.rb", "lib/system_builder/core_ext.rb", "lib/system_builder/
|
16
|
-
s.homepage = %q{http://
|
15
|
+
s.files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "Rakefile", "bin/system-builder", "examples/Rakefile", "examples/config.rb", "examples/manifests/classes/test.pp", "examples/manifests/site.pp", "features/development.feature", "features/step_definitions/common_steps.rb", "features/support/common.rb", "features/support/env.rb", "features/support/matchers.rb", "lib/system_builder.rb", "lib/system_builder/boot.rb", "lib/system_builder/cli.rb", "lib/system_builder/configurator.rb", "lib/system_builder/core_ext.rb", "lib/system_builder/disk_image.rb", "lib/system_builder/disk_squashfs_image.rb", "lib/system_builder/iso_image.rb", "lib/system_builder/live_image.rb", "lib/system_builder/task.rb", "script/console", "script/destroy", "script/generate", "spec/spec.opts", "spec/spec_helper.rb", "spec/system_builder/boot_spec.rb", "spec/system_builder/cli_spec.rb", "system-builder.gemspec", "tasks/rspec.rake"]
|
16
|
+
s.homepage = %q{http://projects.tryphon.eu/system-builder}
|
17
17
|
s.rdoc_options = ["--main", "README.rdoc"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubyforge_project = %q{system-builder}
|
20
|
-
s.rubygems_version = %q{1.3.
|
20
|
+
s.rubygems_version = %q{1.3.6}
|
21
21
|
s.summary = %q{FIX (describe your package)}
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
@@ -25,17 +25,14 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.specification_version = 3
|
26
26
|
|
27
27
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
-
s.add_development_dependency(%q<rubyforge>, [">= 2.0.
|
29
|
-
s.add_development_dependency(%q<
|
30
|
-
s.add_development_dependency(%q<hoe>, [">= 2.5.0"])
|
28
|
+
s.add_development_dependency(%q<rubyforge>, [">= 2.0.4"])
|
29
|
+
s.add_development_dependency(%q<hoe>, [">= 2.6.0"])
|
31
30
|
else
|
32
|
-
s.add_dependency(%q<rubyforge>, [">= 2.0.
|
33
|
-
s.add_dependency(%q<
|
34
|
-
s.add_dependency(%q<hoe>, [">= 2.5.0"])
|
31
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
32
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
35
33
|
end
|
36
34
|
else
|
37
|
-
s.add_dependency(%q<rubyforge>, [">= 2.0.
|
38
|
-
s.add_dependency(%q<
|
39
|
-
s.add_dependency(%q<hoe>, [">= 2.5.0"])
|
35
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
36
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
40
37
|
end
|
41
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: system-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 7
|
9
|
+
version: 0.0.7
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Alban Peignier
|
@@ -9,39 +14,37 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-04-17 00:00:00 +02:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rubyforge
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
25
|
-
-
|
26
|
-
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 0
|
30
|
+
- 4
|
31
|
+
version: 2.0.4
|
27
32
|
type: :development
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.1
|
34
|
-
version:
|
33
|
+
version_requirements: *id001
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
35
|
name: hoe
|
37
|
-
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
41
|
+
segments:
|
42
|
+
- 2
|
43
|
+
- 6
|
44
|
+
- 0
|
45
|
+
version: 2.6.0
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
45
48
|
description: FIX (describe your package)
|
46
49
|
email:
|
47
50
|
- alban@tryphon.eu
|
@@ -74,7 +77,10 @@ files:
|
|
74
77
|
- lib/system_builder/cli.rb
|
75
78
|
- lib/system_builder/configurator.rb
|
76
79
|
- lib/system_builder/core_ext.rb
|
77
|
-
- lib/system_builder/
|
80
|
+
- lib/system_builder/disk_image.rb
|
81
|
+
- lib/system_builder/disk_squashfs_image.rb
|
82
|
+
- lib/system_builder/iso_image.rb
|
83
|
+
- lib/system_builder/live_image.rb
|
78
84
|
- lib/system_builder/task.rb
|
79
85
|
- script/console
|
80
86
|
- script/destroy
|
@@ -99,18 +105,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
105
|
requirements:
|
100
106
|
- - ">="
|
101
107
|
- !ruby/object:Gem::Version
|
108
|
+
segments:
|
109
|
+
- 0
|
102
110
|
version: "0"
|
103
|
-
version:
|
104
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
112
|
requirements:
|
106
113
|
- - ">="
|
107
114
|
- !ruby/object:Gem::Version
|
115
|
+
segments:
|
116
|
+
- 0
|
108
117
|
version: "0"
|
109
|
-
version:
|
110
118
|
requirements: []
|
111
119
|
|
112
120
|
rubyforge_project: system-builder
|
113
|
-
rubygems_version: 1.3.
|
121
|
+
rubygems_version: 1.3.6
|
114
122
|
signing_key:
|
115
123
|
specification_version: 3
|
116
124
|
summary: FIX (describe your package)
|