boxgrinder-build 0.7.1 → 0.8.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/CHANGELOG +13 -0
- data/Manifest +3 -3
- data/Rakefile +1 -1
- data/bin/boxgrinder +121 -0
- data/boxgrinder-build.gemspec +12 -12
- data/lib/boxgrinder-build.rb +19 -0
- data/lib/boxgrinder-build/appliance.rb +30 -35
- data/lib/boxgrinder-build/helpers/appliance-customize-helper.rb +2 -2
- data/lib/boxgrinder-build/helpers/augeas-helper.rb +2 -2
- data/lib/boxgrinder-build/helpers/guestfs-helper.rb +16 -7
- data/lib/boxgrinder-build/helpers/image-helper.rb +48 -20
- data/lib/boxgrinder-build/helpers/linux-helper.rb +2 -2
- data/lib/boxgrinder-build/helpers/package-helper.rb +9 -12
- data/lib/boxgrinder-build/helpers/plugin-helper.rb +11 -19
- data/lib/boxgrinder-build/helpers/thor-helper.rb +82 -0
- data/lib/boxgrinder-build/managers/plugin-manager.rb +10 -25
- data/lib/boxgrinder-build/plugins/base-plugin.rb +50 -33
- data/rubygem-boxgrinder-build.spec +20 -5
- data/spec/appliance-spec.rb +60 -46
- data/spec/helpers/guestfs-helper-spec.rb +123 -37
- data/spec/helpers/image-helper-spec.rb +126 -56
- data/spec/helpers/package-helper-spec.rb +35 -0
- data/spec/helpers/plugin-helper-spec.rb +64 -20
- data/spec/managers/plugin-manager-spec.rb +33 -2
- data/spec/plugins/base-plugin-spec.rb +83 -27
- metadata +21 -20
- data/bin/boxgrinder-build +0 -91
- data/spec/rspec/src/appliances/jeos-f13.appl +0 -27
- data/spec/rspec/src/appliances/jeos-f13.ks +0 -23
@@ -5,23 +5,24 @@
|
|
5
5
|
|
6
6
|
Summary: A tool for creating appliances from simple plain text files
|
7
7
|
Name: rubygem-%{gemname}
|
8
|
-
Version: 0.
|
8
|
+
Version: 0.8.0
|
9
9
|
Release: 1%{?dist}
|
10
10
|
Group: Development/Languages
|
11
11
|
License: LGPLv3+
|
12
12
|
URL: http://www.jboss.org/boxgrinder
|
13
13
|
Source0: http://rubygems.org/gems/%{gemname}-%{version}.gem
|
14
|
+
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
14
15
|
|
15
16
|
Requires: ruby(abi) = %{rubyabi}
|
16
|
-
Requires: rubygem(
|
17
|
-
Requires: rubygem(boxgrinder-core) >= 0.
|
17
|
+
Requires: rubygem(thor)
|
18
|
+
Requires: rubygem(boxgrinder-core) >= 0.2.0
|
18
19
|
Requires: ruby-libguestfs
|
19
20
|
Requires: parted
|
20
21
|
Requires: e2fsprogs
|
21
22
|
|
22
23
|
BuildRequires: rubygem(rake)
|
23
24
|
BuildRequires: rubygem(rspec)
|
24
|
-
BuildRequires: rubygem(boxgrinder-core) >= 0.
|
25
|
+
BuildRequires: rubygem(boxgrinder-core) >= 0.2.0
|
25
26
|
BuildRequires: rubygem(echoe)
|
26
27
|
BuildRequires: ruby-libguestfs
|
27
28
|
|
@@ -65,7 +66,7 @@ popd
|
|
65
66
|
|
66
67
|
%files
|
67
68
|
%defattr(-, root, root, -)
|
68
|
-
%{_bindir}/boxgrinder
|
69
|
+
%{_bindir}/boxgrinder
|
69
70
|
%dir %{geminstdir}
|
70
71
|
%{geminstdir}/bin
|
71
72
|
%{geminstdir}/lib
|
@@ -85,6 +86,20 @@ popd
|
|
85
86
|
%{gemdir}/doc/%{gemname}-%{version}
|
86
87
|
|
87
88
|
%changelog
|
89
|
+
* Tue Jan 04 2011 <mgoldman@redhat.com> - 0.8.0-1
|
90
|
+
- Upstream release: 0.8.0
|
91
|
+
- Added BuildRoot tag to build for EPEL 5
|
92
|
+
- [BGBUILD-128] Allow to specify plugin configuration using CLI
|
93
|
+
- [BGBUILD-134] Replace rubygem-commander with rubygem-thor
|
94
|
+
- [BGBUILD-79] Allow to use BoxGrinder Build as a library
|
95
|
+
- [BGBUILD-127] Use appliance definition object instead of a file when using BG as a library
|
96
|
+
- [BGBUILD-68] Global .boxgrinder/config or rc style file for config
|
97
|
+
- [BGBUILD-131] Check if OS is supported before executing the plugin
|
98
|
+
- [BGBUILD-72] Add support for growing (not pre-allocated) disks for KVM/Xen
|
99
|
+
- [BGBUILD-133] Support a consolidated configuration file
|
100
|
+
- [BGBUILD-138] enablerepo path is not escaped when calling repoquery
|
101
|
+
- [BGBUILD-147] Allow to list installed plugins and version information
|
102
|
+
|
88
103
|
* Mon Dec 20 2010 <mgoldman@redhat.com> - 0.7.1-1
|
89
104
|
- Upstream release: 0.7.1
|
90
105
|
- [BGBUILD-123] Remove RPM database recreation code
|
data/spec/appliance-spec.rb
CHANGED
@@ -23,18 +23,16 @@ require 'logger'
|
|
23
23
|
|
24
24
|
module BoxGrinder
|
25
25
|
describe Appliance do
|
26
|
-
def prepare_appliance(options =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@options = options
|
31
|
-
@log = Logger.new('/dev/null')
|
26
|
+
def prepare_appliance(options = {}, definition_file = "#{File.dirname(__FILE__)}/rspec/src/appliances/jeos-f13.appl")
|
27
|
+
@log = LogHelper.new(:level => :trace, :type => :stdout)
|
28
|
+
@config = OpenCascade.new(:platform => :none, :delivery => :none, :force => false).merge(options)
|
32
29
|
|
33
30
|
@plugin_manager = mock(PluginManager)
|
34
31
|
|
35
32
|
PluginManager.stub!(:instance).and_return(@plugin_manager)
|
36
33
|
|
37
|
-
@appliance = Appliance.new(definition_file,
|
34
|
+
@appliance = Appliance.new(definition_file, @config, :log => @log)
|
35
|
+
@config = @appliance.instance_variable_get(:@config)
|
38
36
|
end
|
39
37
|
|
40
38
|
def prepare_appliance_config
|
@@ -51,53 +49,69 @@ module BoxGrinder
|
|
51
49
|
OpenCascade.new({
|
52
50
|
:partitions =>
|
53
51
|
{
|
54
|
-
'/'
|
52
|
+
'/' => {'size' => 2},
|
55
53
|
'/home' => {'size' => 3},
|
56
54
|
},
|
57
|
-
:arch
|
58
|
-
:base_arch
|
59
|
-
:cpus
|
60
|
-
:memory
|
55
|
+
:arch => 'i686',
|
56
|
+
:base_arch => 'i386',
|
57
|
+
:cpus => 1,
|
58
|
+
:memory => 256,
|
61
59
|
})
|
62
60
|
)
|
63
61
|
|
64
62
|
@appliance_config
|
65
63
|
end
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
# end
|
65
|
+
it "should create @config object without log" do
|
66
|
+
config = Appliance.new("file", OpenCascade.new(:platform => :ec2), :log => "ALOG").instance_variable_get(:@config)
|
70
67
|
|
71
|
-
|
72
|
-
|
68
|
+
config.size.should == 1
|
69
|
+
config[:log].should == nil
|
70
|
+
end
|
73
71
|
|
74
|
-
|
75
|
-
plugin_helper.should_receive(:load_plugins)
|
72
|
+
describe ".create" do
|
76
73
|
|
77
|
-
|
74
|
+
it "should prepare appliance to build" do
|
75
|
+
prepare_appliance
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
@appliance.should_not_receive(:remove_old_builds)
|
82
|
-
@appliance.should_receive(:execute_plugin_chain)
|
77
|
+
plugin_helper = mock(PluginHelper)
|
78
|
+
plugin_helper.should_receive(:load_plugins)
|
83
79
|
|
84
|
-
|
85
|
-
|
80
|
+
PluginHelper.should_receive(:new).with(@config, :log => @log).and_return(plugin_helper)
|
81
|
+
|
82
|
+
@appliance.should_receive(:read_definition)
|
83
|
+
@appliance.should_receive(:validate_definition)
|
84
|
+
@appliance.should_not_receive(:remove_old_builds)
|
85
|
+
@appliance.should_receive(:execute_plugin_chain)
|
86
|
+
|
87
|
+
@appliance.create
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should prepare appliance to build with removing old files" do
|
91
|
+
prepare_appliance(:force => true)
|
86
92
|
|
87
|
-
|
88
|
-
|
93
|
+
plugin_helper = mock(PluginHelper)
|
94
|
+
plugin_helper.should_receive(:load_plugins)
|
89
95
|
|
90
|
-
|
91
|
-
plugin_helper.should_receive(:load_plugins)
|
96
|
+
PluginHelper.should_receive(:new).with(@config, :log => @log).and_return(plugin_helper)
|
92
97
|
|
93
|
-
|
98
|
+
@appliance.should_receive(:read_definition)
|
99
|
+
@appliance.should_receive(:validate_definition)
|
100
|
+
@appliance.should_receive(:remove_old_builds)
|
101
|
+
@appliance.should_receive(:execute_plugin_chain)
|
102
|
+
|
103
|
+
@appliance.create
|
104
|
+
end
|
94
105
|
|
95
|
-
|
96
|
-
|
97
|
-
@appliance.should_receive(:remove_old_builds)
|
98
|
-
@appliance.should_receive(:execute_plugin_chain)
|
106
|
+
it "should not catch exceptions while building appliance" do
|
107
|
+
prepare_appliance(:force => true)
|
99
108
|
|
100
|
-
|
109
|
+
PluginHelper.should_receive(:new).with(@config, :log => @log).and_raise('something')
|
110
|
+
|
111
|
+
lambda {
|
112
|
+
@appliance.create
|
113
|
+
}.should raise_error(RuntimeError, 'something')
|
114
|
+
end
|
101
115
|
end
|
102
116
|
|
103
117
|
describe ".validate_definition" do
|
@@ -125,14 +139,14 @@ module BoxGrinder
|
|
125
139
|
end
|
126
140
|
|
127
141
|
it "should read definition with kickstart appliance definition file" do
|
128
|
-
prepare_appliance(
|
142
|
+
prepare_appliance({}, "#{File.dirname(__FILE__)}/rspec/src/appliances/jeos-f13.ks")
|
129
143
|
|
130
144
|
appliance_config = ApplianceConfig.new
|
131
145
|
|
132
146
|
appliance_helper = mock(ApplianceHelper)
|
133
147
|
appliance_helper.should_receive(:read_definitions).with("#{File.dirname(__FILE__)}/rspec/src/appliances/jeos-f13.ks").and_raise("Unknown format")
|
134
148
|
|
135
|
-
clazz
|
149
|
+
clazz = mock('PluginClass')
|
136
150
|
|
137
151
|
plugin_manager = mock(PluginManager)
|
138
152
|
plugin_manager.should_receive(:plugins).and_return({:os => {:fedora => {:class => clazz, :type => :os, :name => :fedora, :full_name => "Fedora", :versions => ["11", "12", "13", "14", "rawhide"]}}})
|
@@ -161,7 +175,7 @@ module BoxGrinder
|
|
161
175
|
end
|
162
176
|
|
163
177
|
it "should read definition with kickstart appliance definition file and fail because there was no plugin able to read .ks" do
|
164
|
-
prepare_appliance(
|
178
|
+
prepare_appliance({}, "#{File.dirname(__FILE__)}/rspec/src/appliances/jeos-f13.ks")
|
165
179
|
|
166
180
|
appliance_helper = mock(ApplianceHelper)
|
167
181
|
appliance_helper.should_receive(:read_definitions).with("#{File.dirname(__FILE__)}/rspec/src/appliances/jeos-f13.ks").and_raise("Unknown format")
|
@@ -214,7 +228,7 @@ module BoxGrinder
|
|
214
228
|
|
215
229
|
lambda {
|
216
230
|
@appliance.validate_definition
|
217
|
-
}.should raise_error(
|
231
|
+
}.should raise_error(RuntimeError, "No operating system plugins installed. Install one or more operating system plugin. See http://community.jboss.org/docs/DOC-15081 and http://community.jboss.org/docs/DOC-15214 for more info.")
|
218
232
|
end
|
219
233
|
|
220
234
|
it "should validate definition and fail because no supported operating system plugins is installed" do
|
@@ -233,7 +247,7 @@ module BoxGrinder
|
|
233
247
|
|
234
248
|
lambda {
|
235
249
|
@appliance.validate_definition
|
236
|
-
}.should raise_error(
|
250
|
+
}.should raise_error(RuntimeError, "Not supported operating system selected: fedora. Make sure you have installed right operating system plugin, see http://community.jboss.org/docs/DOC-15214. Supported OSes are: rhel")
|
237
251
|
end
|
238
252
|
|
239
253
|
it "should validate definition and fail because no supported operating system version plugins is installed" do
|
@@ -252,7 +266,7 @@ module BoxGrinder
|
|
252
266
|
|
253
267
|
lambda {
|
254
268
|
@appliance.validate_definition
|
255
|
-
}.should raise_error(
|
269
|
+
}.should raise_error(RuntimeError, "Not supported operating system version selected: 11. Supported versions are: xyz")
|
256
270
|
end
|
257
271
|
end
|
258
272
|
|
@@ -299,7 +313,7 @@ module BoxGrinder
|
|
299
313
|
end
|
300
314
|
|
301
315
|
it "should build appliance and convert it to VMware format" do
|
302
|
-
prepare_appliance(
|
316
|
+
prepare_appliance(:platform => :vmware)
|
303
317
|
|
304
318
|
@appliance.instance_variable_set(:@appliance_config, prepare_appliance_config)
|
305
319
|
@appliance.should_receive(:execute_os_plugin).and_return({})
|
@@ -317,7 +331,7 @@ module BoxGrinder
|
|
317
331
|
end
|
318
332
|
|
319
333
|
it "should build appliance and convert it to VMware format because deliverable already exists" do
|
320
|
-
prepare_appliance(
|
334
|
+
prepare_appliance(:platform => :vmware)
|
321
335
|
|
322
336
|
@appliance.instance_variable_set(:@appliance_config, prepare_appliance_config)
|
323
337
|
@appliance.should_receive(:execute_os_plugin).and_return({})
|
@@ -335,7 +349,7 @@ module BoxGrinder
|
|
335
349
|
end
|
336
350
|
|
337
351
|
it "should build appliance, convert it to EC2 format and deliver it using S3 ami type" do
|
338
|
-
prepare_appliance(
|
352
|
+
prepare_appliance(:platform => :ec2, :delivery => :ami)
|
339
353
|
|
340
354
|
@appliance.instance_variable_set(:@appliance_config, prepare_appliance_config)
|
341
355
|
@appliance.should_receive(:execute_os_plugin).and_return({:abc => 'def'})
|
@@ -352,7 +366,7 @@ module BoxGrinder
|
|
352
366
|
end
|
353
367
|
|
354
368
|
it "should build appliance, convert it to EC2 format and deliver it using delivery plugin with only one delivery type" do
|
355
|
-
prepare_appliance(
|
369
|
+
prepare_appliance(:platform => :ec2, :delivery => :same)
|
356
370
|
|
357
371
|
@appliance.instance_variable_set(:@appliance_config, prepare_appliance_config)
|
358
372
|
@appliance.should_receive(:execute_os_plugin).and_return({:abc => 'def'})
|
@@ -20,61 +20,147 @@ require 'boxgrinder-build/helpers/guestfs-helper'
|
|
20
20
|
|
21
21
|
module BoxGrinder
|
22
22
|
describe GuestFSHelper do
|
23
|
-
|
24
|
-
before(:all) do
|
25
|
-
@arch = `uname -m`.chomp.strip
|
26
|
-
end
|
27
|
-
|
28
23
|
before(:each) do
|
29
24
|
@log = Logger.new('/dev/null')
|
30
25
|
@helper = GuestFSHelper.new('a/raw/disk', :log => @log)
|
31
26
|
end
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
describe ".execute" do
|
29
|
+
it "should prepare and run guestfs" do
|
30
|
+
guestfs = mock('Guestfs')
|
31
|
+
guestfs.should_receive(:set_append).with('noapic')
|
32
|
+
guestfs.should_receive(:set_verbose)
|
33
|
+
guestfs.should_receive(:set_trace)
|
34
|
+
guestfs.should_receive(:set_selinux).with(1)
|
39
35
|
|
40
|
-
|
41
|
-
|
36
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(true)
|
37
|
+
@helper.should_receive(:load_selinux_policy)
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
guetfs.should_receive(:list_partitions).and_return(partitions)
|
39
|
+
guestfs.should_receive(:add_drive).with('a/raw/disk')
|
40
|
+
guestfs.should_receive(:set_network).with(1)
|
41
|
+
guestfs.should_receive(:launch)
|
42
|
+
guestfs.should_receive(:list_partitions).and_return(['/', '/boot'])
|
48
43
|
|
49
|
-
|
44
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
50
45
|
|
51
|
-
|
52
|
-
|
46
|
+
@helper.should_receive(:mount_partitions).with(no_args)
|
47
|
+
@helper.execute.should == @helper
|
48
|
+
end
|
53
49
|
|
54
|
-
|
55
|
-
|
50
|
+
it "should prepare and run guestfs wid IDE disk" do
|
51
|
+
guestfs = mock('Guestfs')
|
52
|
+
guestfs.should_receive(:set_append).with('noapic')
|
53
|
+
guestfs.should_receive(:set_verbose)
|
54
|
+
guestfs.should_receive(:set_trace)
|
55
|
+
guestfs.should_receive(:set_selinux).with(1)
|
56
56
|
|
57
|
-
|
57
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(true)
|
58
|
+
@helper.should_receive(:load_selinux_policy)
|
58
59
|
|
59
|
-
|
60
|
-
|
60
|
+
guestfs.should_receive(:add_drive_with_if).with('a/raw/disk', 'ide')
|
61
|
+
guestfs.should_receive(:set_network).with(1)
|
62
|
+
guestfs.should_receive(:launch)
|
63
|
+
guestfs.should_receive(:list_partitions).and_return(['/', '/boot'])
|
61
64
|
|
62
|
-
|
63
|
-
guestfs = prepare_and_launch(['/'])
|
65
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
+
@helper.should_receive(:mount_partitions).with(no_args)
|
68
|
+
@helper.execute(nil, :ide_disk => true).should == @helper
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
71
|
+
it "should prepare and run guestfs without HW accelerarion enabled for 64 bit host" do
|
72
|
+
guestfs = mock('Guestfs')
|
73
|
+
guestfs.should_receive(:set_append).with('noapic')
|
74
|
+
guestfs.should_receive(:set_verbose)
|
75
|
+
guestfs.should_receive(:set_trace)
|
76
|
+
guestfs.should_receive(:set_selinux).with(1)
|
77
|
+
|
78
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(false)
|
79
|
+
@helper.should_receive(:load_selinux_policy)
|
80
|
+
|
81
|
+
RbConfig::CONFIG.should_receive(:[]).with('host_cpu').and_return('x86_64')
|
82
|
+
|
83
|
+
guestfs.should_receive(:set_qemu).with('/usr/bin/qemu-system-x86_64')
|
84
|
+
guestfs.should_receive(:add_drive).with('a/raw/disk')
|
85
|
+
guestfs.should_receive(:set_network).with(1)
|
86
|
+
guestfs.should_receive(:launch)
|
87
|
+
guestfs.should_receive(:list_partitions).and_return(['/', '/boot'])
|
88
|
+
|
89
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
90
|
+
|
91
|
+
@helper.should_receive(:mount_partitions).with(no_args)
|
92
|
+
@helper.execute.should == @helper
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should prepare and run guestfs without HW accelerarion enabled for 32 bit host" do
|
96
|
+
guestfs = mock('Guestfs')
|
97
|
+
guestfs.should_receive(:set_append).with('noapic')
|
98
|
+
guestfs.should_receive(:set_verbose)
|
99
|
+
guestfs.should_receive(:set_trace)
|
100
|
+
guestfs.should_receive(:set_selinux).with(1)
|
70
101
|
|
71
|
-
|
72
|
-
|
102
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(false)
|
103
|
+
@helper.should_receive(:load_selinux_policy)
|
73
104
|
|
74
|
-
|
75
|
-
@helper.should_receive(:mount_partition).with("/dev/sda", "/")
|
105
|
+
RbConfig::CONFIG.should_receive(:[]).with('host_cpu').and_return('i386')
|
76
106
|
|
77
|
-
|
107
|
+
guestfs.should_receive(:set_qemu).with('/usr/bin/qemu')
|
108
|
+
guestfs.should_receive(:add_drive).with('a/raw/disk')
|
109
|
+
guestfs.should_receive(:set_network).with(1)
|
110
|
+
guestfs.should_receive(:launch)
|
111
|
+
guestfs.should_receive(:list_partitions).and_return(['/', '/boot'])
|
112
|
+
|
113
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
114
|
+
|
115
|
+
@helper.should_receive(:mount_partitions).with(no_args)
|
116
|
+
@helper.execute.should == @helper
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should prepare and run guestfs with one partition" do
|
120
|
+
guestfs = mock('Guestfs')
|
121
|
+
guestfs.should_receive(:set_append).with('noapic')
|
122
|
+
guestfs.should_receive(:set_verbose)
|
123
|
+
guestfs.should_receive(:set_trace)
|
124
|
+
guestfs.should_receive(:set_selinux).with(1)
|
125
|
+
|
126
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(true)
|
127
|
+
@helper.should_receive(:load_selinux_policy)
|
128
|
+
|
129
|
+
guestfs.should_receive(:add_drive).with('a/raw/disk')
|
130
|
+
guestfs.should_receive(:set_network).with(1)
|
131
|
+
guestfs.should_receive(:launch)
|
132
|
+
guestfs.should_receive(:list_partitions).and_return(['/'])
|
133
|
+
|
134
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
135
|
+
|
136
|
+
guestfs.should_receive(:list_partitions).and_return(['/'])
|
137
|
+
@helper.should_receive(:mount_partition).with("/", "/")
|
138
|
+
|
139
|
+
@helper.execute.should == @helper
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should prepare and run guestfs with no partitions" do
|
143
|
+
guestfs = mock('Guestfs')
|
144
|
+
guestfs.should_receive(:set_append).with('noapic')
|
145
|
+
guestfs.should_receive(:set_verbose)
|
146
|
+
guestfs.should_receive(:set_trace)
|
147
|
+
guestfs.should_receive(:set_selinux).with(1)
|
148
|
+
|
149
|
+
@helper.should_receive(:hw_virtualization_available?).and_return(true)
|
150
|
+
@helper.should_receive(:load_selinux_policy)
|
151
|
+
|
152
|
+
guestfs.should_receive(:add_drive).with('a/raw/disk')
|
153
|
+
guestfs.should_receive(:set_network).with(1)
|
154
|
+
guestfs.should_receive(:launch)
|
155
|
+
guestfs.should_receive(:list_partitions).and_return([])
|
156
|
+
|
157
|
+
Guestfs.should_receive(:create).and_return(guestfs)
|
158
|
+
|
159
|
+
guestfs.should_receive(:list_devices).and_return(['/dev/sda'])
|
160
|
+
@helper.should_receive(:mount_partition).with("/dev/sda", "/")
|
161
|
+
|
162
|
+
@helper.execute.should == @helper
|
163
|
+
end
|
78
164
|
end
|
79
165
|
|
80
166
|
it "should close guestfs in clean way" do
|
@@ -27,23 +27,24 @@ module BoxGrinder
|
|
27
27
|
@appliance_config = mock('ApplianceConfig')
|
28
28
|
|
29
29
|
@appliance_config.stub!(:name).and_return('full')
|
30
|
+
@appliance_config.stub!(:os).and_return(OpenCascade.new({:name => 'fedora', :version => '14'}))
|
30
31
|
@appliance_config.stub!(:hardware).and_return(
|
31
32
|
OpenCascade.new({
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
:partitions =>
|
34
|
+
{
|
35
|
+
'/' => {'size' => 2, 'type' => 'ext4'},
|
36
|
+
'/home' => {'size' => 3, 'type' => 'ext3'},
|
37
|
+
},
|
38
|
+
:arch => 'i686',
|
39
|
+
:base_arch => 'i386',
|
40
|
+
:cpus => 1,
|
41
|
+
:memory => 256,
|
42
|
+
})
|
42
43
|
)
|
43
44
|
|
44
|
-
@helper
|
45
|
+
@helper = ImageHelper.new(@config, @appliance_config, :log => Logger.new('/dev/null'))
|
45
46
|
|
46
|
-
@log
|
47
|
+
@log = @helper.instance_variable_get(:@log)
|
47
48
|
@exec_helper = @helper.instance_variable_get(:@exec_helper)
|
48
49
|
end
|
49
50
|
|
@@ -51,9 +52,9 @@ module BoxGrinder
|
|
51
52
|
@helper.should_receive(:calculate_disk_offsets).with('disk.raw').and_return(['0'])
|
52
53
|
FileUtils.should_receive(:mkdir_p).with('mount_dir')
|
53
54
|
@helper.should_receive(:get_loop_device).and_return('/dev/loop0')
|
54
|
-
@exec_helper.should_receive(:execute).with(
|
55
|
+
@exec_helper.should_receive(:execute).with("losetup -o 0 /dev/loop0 'disk.raw'")
|
55
56
|
@exec_helper.should_receive(:execute).with('e2label /dev/loop0').and_return('/')
|
56
|
-
@exec_helper.should_receive(:execute).with(
|
57
|
+
@exec_helper.should_receive(:execute).with("mount /dev/loop0 'mount_dir'")
|
57
58
|
|
58
59
|
@helper.mount_image('disk.raw', 'mount_dir').should == {"/"=>"/dev/loop0"}
|
59
60
|
end
|
@@ -62,14 +63,14 @@ module BoxGrinder
|
|
62
63
|
@helper.should_receive(:calculate_disk_offsets).with('disk.raw').and_return(['322', '562'])
|
63
64
|
FileUtils.should_receive(:mkdir_p).with('mount_dir')
|
64
65
|
@helper.should_receive(:get_loop_device).and_return('/dev/loop0')
|
65
|
-
@exec_helper.should_receive(:execute).with(
|
66
|
+
@exec_helper.should_receive(:execute).with("losetup -o 322 /dev/loop0 'disk.raw'")
|
66
67
|
@exec_helper.should_receive(:execute).with('e2label /dev/loop0').and_return('_/home')
|
67
68
|
@helper.should_receive(:get_loop_device).and_return('/dev/loop1')
|
68
|
-
@exec_helper.should_receive(:execute).with(
|
69
|
+
@exec_helper.should_receive(:execute).with("losetup -o 562 /dev/loop1 'disk.raw'")
|
69
70
|
@exec_helper.should_receive(:execute).with('e2label /dev/loop1').and_return('_/')
|
70
71
|
|
71
|
-
@exec_helper.should_receive(:execute).with(
|
72
|
-
@exec_helper.should_receive(:execute).with(
|
72
|
+
@exec_helper.should_receive(:execute).with("mount /dev/loop1 'mount_dir'")
|
73
|
+
@exec_helper.should_receive(:execute).with("mount /dev/loop0 'mount_dir/home'")
|
73
74
|
|
74
75
|
@helper.mount_image('disk.raw', 'mount_dir').should == {"/"=>"/dev/loop1", "/home"=>"/dev/loop0"}
|
75
76
|
end
|
@@ -101,7 +102,7 @@ module BoxGrinder
|
|
101
102
|
|
102
103
|
it "should calculate disks offsets" do
|
103
104
|
@helper.should_receive(:get_loop_device).and_return('/dev/loop0')
|
104
|
-
@exec_helper.should_receive(:execute).ordered.with(
|
105
|
+
@exec_helper.should_receive(:execute).ordered.with("losetup /dev/loop0 'disk.raw'")
|
105
106
|
@exec_helper.should_receive(:execute).ordered.with("parted /dev/loop0 'unit B print' | grep -e '^ [0-9]' | awk '{ print $2 }'").and_return("0B\n1234B\n")
|
106
107
|
@exec_helper.should_receive(:execute).ordered.with('losetup -d /dev/loop0')
|
107
108
|
@helper.should_receive(:sleep).with(1)
|
@@ -110,63 +111,132 @@ module BoxGrinder
|
|
110
111
|
end
|
111
112
|
|
112
113
|
it "should create a new empty disk image" do
|
113
|
-
@exec_helper.should_receive(:execute).with(
|
114
|
+
@exec_helper.should_receive(:execute).with("dd if=/dev/zero of='disk.raw' bs=1 count=0 seek=10240M")
|
114
115
|
|
115
116
|
@helper.create_disk('disk.raw', 10)
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
|
-
@exec_helper.should_receive(:execute).with("mke2fs -T ext4 -L '/' -F /dev/loop0")
|
119
|
+
describe ".create_filesystem" do
|
120
120
|
|
121
|
-
|
122
|
-
|
121
|
+
it "should create default filesystem on selected device" do
|
122
|
+
@exec_helper.should_receive(:execute).with("mke2fs -T ext4 -L '/' -F /dev/loop0")
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
OpenCascade.new({
|
127
|
-
:partitions =>
|
128
|
-
{
|
129
|
-
'/' => {'size' => 2, 'type' => 'ext3'},
|
130
|
-
'/home' => {'size' => 3, 'type' => 'ext3'},
|
131
|
-
},
|
132
|
-
:arch => 'i686',
|
133
|
-
:base_arch => 'i386',
|
134
|
-
:cpus => 1,
|
135
|
-
:memory => 256,
|
136
|
-
})
|
137
|
-
)
|
124
|
+
@helper.create_filesystem('/dev/loop0')
|
125
|
+
end
|
138
126
|
|
139
|
-
|
127
|
+
it "should create ext4 filesystem on selected device" do
|
128
|
+
@appliance_config.should_receive(:hardware).and_return(
|
129
|
+
OpenCascade.new({
|
130
|
+
:partitions =>
|
131
|
+
{
|
132
|
+
'/' => {'size' => 2, 'type' => 'ext3'},
|
133
|
+
'/home' => {'size' => 3, 'type' => 'ext3'},
|
134
|
+
},
|
135
|
+
:arch => 'i686',
|
136
|
+
:base_arch => 'i386',
|
137
|
+
:cpus => 1,
|
138
|
+
:memory => 256,
|
139
|
+
})
|
140
|
+
)
|
141
|
+
|
142
|
+
@exec_helper.should_receive(:execute).with("mke2fs -T ext3 -L '/' -F /dev/loop0")
|
143
|
+
|
144
|
+
@helper.create_filesystem('/dev/loop0')
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should create ext4 filesystem on selected device with a label" do
|
148
|
+
@exec_helper.should_receive(:execute).with("mke2fs -T ext4 -L '/home' -F /dev/loop0")
|
140
149
|
|
141
|
-
|
150
|
+
@helper.create_filesystem('/dev/loop0', :type => 'ext4', :label => '/home')
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should create ext4 filesystem on selected device with a label" do
|
154
|
+
lambda {
|
155
|
+
@helper.create_filesystem('/dev/loop0', :type => 'ext256', :label => '/home')
|
156
|
+
}.should raise_error(RuntimeError, "Unsupported filesystem specified: ext256")
|
157
|
+
end
|
142
158
|
end
|
143
159
|
|
144
|
-
|
145
|
-
|
160
|
+
describe ".sync_files" do
|
161
|
+
it "should sync files" do
|
162
|
+
@exec_helper.should_receive(:execute).with("rsync -Xura from_dir/* 'to_dir'")
|
163
|
+
@helper.sync_files('from_dir', 'to_dir')
|
164
|
+
end
|
146
165
|
|
147
|
-
|
166
|
+
it "should sync files with a space in path" do
|
167
|
+
@exec_helper.should_receive(:execute).with("rsync -Xura from\\ /dir/* 'to_dir'")
|
168
|
+
@helper.sync_files('from /dir', 'to_dir')
|
169
|
+
end
|
148
170
|
end
|
149
171
|
|
172
|
+
describe ".customize" do
|
173
|
+
it "should customize the disk image using GuestFS" do
|
174
|
+
guestfs = mock('GuestFS')
|
175
|
+
guestfs.should_receive(:abc)
|
176
|
+
|
177
|
+
guestfs_helper = mock(GuestFSHelper)
|
178
|
+
guestfs_helper.should_receive(:customize).with(:ide_disk => false).ordered.and_yield(guestfs, guestfs_helper)
|
179
|
+
guestfs_helper.should_receive(:def)
|
180
|
+
|
181
|
+
GuestFSHelper.should_receive(:new).with('disk.raw', :log => @log).and_return(guestfs_helper)
|
150
182
|
|
151
|
-
|
152
|
-
|
183
|
+
@helper.customize('disk.raw') do |guestfs, guestfs_helper|
|
184
|
+
guestfs.abc
|
185
|
+
guestfs_helper.def
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should customize the disk image using GuestFS and selectind ide_disk option for RHEL/CentOS 5" do
|
190
|
+
@appliance_config.stub!(:os).and_return(OpenCascade.new({:name => 'rhel', :version => '5'}))
|
191
|
+
|
192
|
+
guestfs = mock('GuestFS')
|
193
|
+
guestfs.should_receive(:abc)
|
194
|
+
|
195
|
+
guestfs_helper = mock(GuestFSHelper)
|
196
|
+
guestfs_helper.should_receive(:customize).with(:ide_disk => true).ordered.and_yield(guestfs, guestfs_helper)
|
197
|
+
guestfs_helper.should_receive(:def)
|
153
198
|
|
154
|
-
|
199
|
+
GuestFSHelper.should_receive(:new).with('disk.raw', :log => @log).and_return(guestfs_helper)
|
200
|
+
|
201
|
+
@helper.customize('disk.raw') do |guestfs, guestfs_helper|
|
202
|
+
guestfs.abc
|
203
|
+
guestfs_helper.def
|
204
|
+
end
|
205
|
+
end
|
155
206
|
end
|
156
207
|
|
157
|
-
|
158
|
-
|
159
|
-
|
208
|
+
describe ".convert_disk" do
|
209
|
+
it "should not convert the disk because it's in RAW format already" do
|
210
|
+
@exec_helper.should_receive(:execute).with("qemu-img info 'a/disk'").and_return("image: build/appliances/x86_64/fedora/13/f13-basic/fedora-plugin/f13-basic-sda.qcow2\nfile format: raw\nvirtual size: 2.0G (2147483648 bytes)\ndisk size: 531M\ncluster_size: 65536")
|
211
|
+
@exec_helper.should_receive(:execute).with("cp 'a/disk' 'destination'")
|
212
|
+
@helper.convert_disk('a/disk', :raw, 'destination')
|
213
|
+
end
|
160
214
|
|
161
|
-
|
162
|
-
|
163
|
-
|
215
|
+
it "should convert disk from vmdk to RAW format" do
|
216
|
+
@exec_helper.should_receive(:execute).with("qemu-img info 'a/disk'").and_return("image: build/appliances/x86_64/fedora/13/f13-basic/fedora-plugin/f13-basic-sda.vmdk\nfile format: vmdk\nvirtual size: 2.0G (2147483648 bytes)\ndisk size: 531M\ncluster_size: 65536")
|
217
|
+
@exec_helper.should_receive(:execute).with("qemu-img convert -f vmdk -O raw 'a/disk' 'destination'")
|
218
|
+
@helper.convert_disk('a/disk', :raw, 'destination')
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should convert disk from raw to vmdk format using old qemu-img" do
|
222
|
+
@exec_helper.should_receive(:execute).with("qemu-img info 'a/disk'").and_return("image: build/appliances/x86_64/fedora/13/f13-basic/fedora-plugin/f13-basic-sda.vmdk\nfile format: raw\nvirtual size: 2.0G (2147483648 bytes)\ndisk size: 531M\ncluster_size: 65536")
|
223
|
+
@helper.should_receive(:`).with("qemu-img --help | grep '\\-6'").and_return('something')
|
224
|
+
|
225
|
+
@exec_helper.should_receive(:execute).with("qemu-img convert -f raw -O vmdk -6 'a/disk' 'destination'")
|
226
|
+
@helper.convert_disk('a/disk', :vmdk, 'destination')
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should convert disk from raw to vmdk format using new qemu-img" do
|
230
|
+
@exec_helper.should_receive(:execute).with("qemu-img info 'a/disk'").and_return("image: build/appliances/x86_64/fedora/13/f13-basic/fedora-plugin/f13-basic-sda.vmdk\nfile format: raw\nvirtual size: 2.0G (2147483648 bytes)\ndisk size: 531M\ncluster_size: 65536")
|
231
|
+
@helper.should_receive(:`).with("qemu-img --help | grep '\\-6'").and_return('')
|
164
232
|
|
165
|
-
|
233
|
+
@exec_helper.should_receive(:execute).with("qemu-img convert -f raw -O vmdk -o compat6 'a/disk' 'destination'")
|
234
|
+
@helper.convert_disk('a/disk', :vmdk, 'destination')
|
235
|
+
end
|
166
236
|
|
167
|
-
|
168
|
-
|
169
|
-
|
237
|
+
it "should do nothing because destination already exists" do
|
238
|
+
File.should_receive(:exists?).with('destination').and_return(true)
|
239
|
+
@helper.convert_disk('a/disk', :vmdk, 'destination')
|
170
240
|
end
|
171
241
|
end
|
172
242
|
end
|