boxgrinder-build 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/CHANGELOG +14 -0
  2. data/README.md +136 -0
  3. data/Rakefile +11 -6
  4. data/bin/boxgrinder-build +199 -0
  5. data/boxgrinder-build.gemspec +26 -14
  6. data/lib/boxgrinder-build/appliance.rb +6 -6
  7. data/lib/boxgrinder-build/helpers/guestfs-helper.rb +5 -3
  8. data/lib/boxgrinder-build/helpers/image-helper.rb +6 -0
  9. data/lib/boxgrinder-build/helpers/plugin-helper.rb +15 -4
  10. data/lib/boxgrinder-build/plugins/base-plugin.rb +1 -0
  11. data/lib/boxgrinder-build/plugins/delivery/ebs/ebs-plugin.rb +280 -0
  12. data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +66 -0
  13. data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +242 -0
  14. data/lib/boxgrinder-build/plugins/delivery/s3/src/cert-ec2.pem +23 -0
  15. data/lib/boxgrinder-build/plugins/delivery/sftp/sftp-plugin.rb +152 -0
  16. data/lib/boxgrinder-build/plugins/delivery/usb/usb-plugin.rb +43 -0
  17. data/lib/boxgrinder-build/plugins/os/centos/centos-plugin.rb +46 -0
  18. data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +61 -0
  19. data/lib/boxgrinder-build/plugins/os/rhel/rhel-plugin.rb +67 -0
  20. data/lib/boxgrinder-build/plugins/os/rpm-based/kickstart.rb +118 -0
  21. data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-based-os-plugin.rb +202 -0
  22. data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-dependency-validator.rb +153 -0
  23. data/lib/boxgrinder-build/plugins/os/rpm-based/src/appliance.ks.erb +37 -0
  24. data/lib/boxgrinder-build/plugins/os/rpm-based/src/base.repo +4 -0
  25. data/lib/boxgrinder-build/plugins/os/rpm-based/src/motd.init +21 -0
  26. data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +239 -0
  27. data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_32bit +7 -0
  28. data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_64bit +7 -0
  29. data/lib/boxgrinder-build/plugins/platform/ec2/src/ifcfg-eth0 +7 -0
  30. data/lib/boxgrinder-build/plugins/platform/ec2/src/menu.lst +6 -0
  31. data/lib/boxgrinder-build/plugins/platform/ec2/src/rc_local +19 -0
  32. data/lib/boxgrinder-build/plugins/platform/virtualbox/virtualbox-plugin.rb +62 -0
  33. data/lib/boxgrinder-build/plugins/platform/vmware/src/README-enterprise +18 -0
  34. data/lib/boxgrinder-build/plugins/platform/vmware/src/README-personal +16 -0
  35. data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmdk +20 -0
  36. data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmx +45 -0
  37. data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +194 -0
  38. data/rubygem-boxgrinder-build.spec +73 -10
  39. data/spec/appliance-spec.rb +2 -2
  40. data/spec/helpers/guestfs-helper-spec.rb +4 -2
  41. data/spec/helpers/image-helper-spec.rb +4 -0
  42. data/spec/helpers/plugin-helper-spec.rb +0 -38
  43. data/spec/managers/plugin-manager-spec.rb +6 -6
  44. data/spec/plugins/delivery/ebs/ebs-plugin-spec.rb +230 -0
  45. data/spec/plugins/delivery/ebs/ebs.yaml +3 -0
  46. data/spec/plugins/delivery/local/local-plugin-spec.rb +133 -0
  47. data/spec/plugins/delivery/s3/s3-plugin-spec.rb +351 -0
  48. data/spec/plugins/delivery/sftp/sftp-plugin-spec.rb +26 -0
  49. data/spec/plugins/os/centos/centos-plugin-spec.rb +52 -0
  50. data/spec/plugins/os/fedora/fedora-plugin-spec.rb +73 -0
  51. data/spec/plugins/os/rhel/rhel-plugin-spec.rb +158 -0
  52. data/spec/plugins/os/rpm-based/kickstart-spec.rb +129 -0
  53. data/spec/plugins/os/rpm-based/rpm-based-os-plugin-spec.rb +162 -0
  54. data/spec/plugins/os/rpm-based/rpm-dependency-validator-spec.rb +50 -0
  55. data/spec/plugins/os/rpm-based/src/jeos-f13-plain.ks +20 -0
  56. data/spec/plugins/os/rpm-based/src/jeos-f13-without-version.ks +22 -0
  57. data/spec/plugins/os/rpm-based/src/jeos-f13.ks +23 -0
  58. data/spec/plugins/platform/ec2/ec2-plugin-spec.rb +339 -0
  59. data/spec/plugins/platform/virtualbox/virtualbox-plugin-spec.rb +118 -0
  60. data/spec/plugins/platform/vmware/vmware-plugin-spec.rb +299 -0
  61. metadata +149 -25
  62. data/README +0 -7
  63. data/bin/boxgrinder +0 -128
  64. data/lib/boxgrinder-build/helpers/thor-helper.rb +0 -85
@@ -0,0 +1,230 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'logger'
20
+ require 'boxgrinder-build/plugins/delivery/ebs/ebs-plugin'
21
+ require 'hashery/opencascade'
22
+
23
+ module BoxGrinder
24
+
25
+ describe EBSPlugin do
26
+ before(:all) do
27
+ @arch = `uname -m`.chomp.strip
28
+ end
29
+
30
+ def prepare_plugin
31
+ @plugin = EBSPlugin.new
32
+
33
+ yield @plugin if block_given?
34
+
35
+ @config = mock('Config')
36
+ @config.stub!(:delivery_config).and_return({})
37
+ plugins = mock('Plugins')
38
+ plugins.stub!(:[]).with('ebs').and_return({})
39
+ @config.stub!(:[]).with(:plugins).and_return(plugins)
40
+
41
+ @appliance_config = mock('ApplianceConfig')
42
+
43
+ @appliance_config.stub!(:name).and_return('appliance_name')
44
+ @appliance_config.stub!(:version).and_return(1)
45
+ @appliance_config.stub!(:release).and_return(0)
46
+ @appliance_config.stub!(:os).and_return(OpenCascade.new({:name => 'fedora', :version => '14'}))
47
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new({:arch => 'x86_64', :base_arch => 'x86_64'}))
48
+ @appliance_config.stub!(:path).and_return(OpenCascade.new({:build => '/a/build/path'}))
49
+
50
+ @plugin = @plugin.init(
51
+ @config,
52
+ @appliance_config,
53
+ :log => Logger.new('/dev/null'),
54
+ :plugin_info => {:class => BoxGrinder::EBSPlugin, :type => :delivery, :name => :ebs, :full_name => "Elastic Block Storage"},
55
+ :config_file => "#{File.dirname(__FILE__)}/ebs.yaml"
56
+ )
57
+
58
+ @plugin_config = @plugin.instance_variable_get(:@plugin_config).merge(
59
+ {
60
+ 'access_key' => 'access_key',
61
+ 'secret_access_key' => 'secret_access_key',
62
+ 'bucket' => 'bucket',
63
+ 'account_number' => '0000-0000-0000',
64
+ 'cert_file' => '/path/to/cert/file',
65
+ 'key_file' => '/path/to/key/file'
66
+ }
67
+ )
68
+
69
+ @plugin.instance_variable_set(:@plugin_config, @plugin_config)
70
+ end
71
+
72
+ it "should register all operating systems with specific versions" do
73
+ prepare_plugin do |plugin|
74
+ avaibility_zone = mock('AZ')
75
+ avaibility_zone.should_receive(:string).and_return('avaibility-zone1')
76
+
77
+ plugin.should_receive(:open).with('http://169.254.169.254/latest/meta-data/placement/availability-zone').and_return(avaibility_zone)
78
+ end
79
+
80
+ supportes_oses = @plugin.instance_variable_get(:@supported_oses)
81
+
82
+ supportes_oses.size.should == 2
83
+ supportes_oses.keys.sort.should == ['fedora', 'rhel']
84
+ supportes_oses['rhel'].should == ['6']
85
+ supportes_oses['fedora'].should == ['13', '14', '15']
86
+ end
87
+
88
+ describe ".after_init" do
89
+ it "should set default avaibility zone to current one" do
90
+ prepare_plugin do |plugin|
91
+ avaibility_zone = mock('AZ')
92
+ avaibility_zone.should_receive(:string).and_return('avaibility-zone1')
93
+
94
+ plugin.should_receive(:open).with('http://169.254.169.254/latest/meta-data/placement/availability-zone').and_return(avaibility_zone)
95
+ end
96
+
97
+ @plugin.instance_variable_get(:@plugin_config)['availability_zone'].should == 'avaibility-zone1'
98
+ end
99
+
100
+ it "should not set default avaibility zone because we're not on EC2" do
101
+ prepare_plugin do |plugin|
102
+ plugin.should_receive(:open).with('http://169.254.169.254/latest/meta-data/placement/availability-zone').and_raise("Bleh")
103
+ end
104
+
105
+ @plugin.instance_variable_get(:@plugin_config)['availability_zone'].should == nil
106
+ end
107
+ end
108
+
109
+ describe '.already_registered?' do
110
+ it "should check if image is already registered and return false if there are no images registered for this account" do
111
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
112
+
113
+ plugin_config = mock('PluginConfiig')
114
+ plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
115
+
116
+ @plugin.instance_variable_set(:@plugin_config, plugin_config)
117
+
118
+ ec2 = mock('EC2')
119
+ ec2.should_receive(:describe_images).with(:owner_id => '000000000000')
120
+
121
+ @plugin.instance_variable_set(:@ec2, ec2)
122
+
123
+ @plugin.already_registered?('aname').should == false
124
+ end
125
+
126
+ it "should check if image is already registered and return false if there are no images with name aname_new" do
127
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
128
+
129
+ plugin_config = mock('PluginConfiig')
130
+ plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
131
+
132
+ @plugin.instance_variable_set(:@plugin_config, plugin_config)
133
+
134
+ ec2 = mock('EC2')
135
+ ec2.should_receive(:describe_images).with(:owner_id => '000000000000').and_return({'imagesSet' => {'item' => [{'name' => 'abc', 'imageId' => '1'}, {'name' => 'aname', 'imageId' => '2'}]}})
136
+
137
+ @plugin.instance_variable_set(:@ec2, ec2)
138
+
139
+ @plugin.already_registered?('aname_new').should == false
140
+ end
141
+
142
+ it "should check if image is already registered and return true image is registered" do
143
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
144
+
145
+ plugin_config = mock('PluginConfiig')
146
+ plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
147
+
148
+ @plugin.instance_variable_set(:@plugin_config, plugin_config)
149
+
150
+ ec2 = mock('EC2')
151
+ ec2.should_receive(:describe_images).with(:owner_id => '000000000000').and_return({'imagesSet' => {'item' => [{'name' => 'abc', 'imageId' => '1'}, {'name' => 'aname', 'imageId' => '2'}]}})
152
+
153
+ @plugin.instance_variable_set(:@ec2, ec2)
154
+
155
+ @plugin.already_registered?('aname').should == '2'
156
+ end
157
+ end
158
+
159
+ it "should adjust fstab" do
160
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
161
+
162
+ exec_helper = @plugin.instance_variable_get(:@exec_helper)
163
+
164
+ exec_helper.should_receive(:execute).with("cat a/dir/etc/fstab | grep -v '/mnt' | grep -v '/data' | grep -v 'swap' > a/dir/etc/fstab.new")
165
+ exec_helper.should_receive(:execute).with("mv a/dir/etc/fstab.new a/dir/etc/fstab")
166
+
167
+ @plugin.adjust_fstab('a/dir')
168
+ end
169
+
170
+ it "should get a new free device" do
171
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
172
+
173
+ File.should_receive(:exists?).with("/dev/sdf").and_return(false)
174
+ File.should_receive(:exists?).with("/dev/xvdf").and_return(false)
175
+
176
+ @plugin.free_device_suffix.should == "f"
177
+ end
178
+
179
+ it "should get a new free device next in order" do
180
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
181
+
182
+ File.should_receive(:exists?).with("/dev/sdf").and_return(false)
183
+ File.should_receive(:exists?).with("/dev/xvdf").and_return(true)
184
+ File.should_receive(:exists?).with("/dev/sdg").and_return(false)
185
+ File.should_receive(:exists?).with("/dev/xvdg").and_return(false)
186
+
187
+ @plugin.free_device_suffix.should == "g"
188
+ end
189
+
190
+ it "should should return true if on EC2" do
191
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
192
+
193
+ @plugin.should_receive(:open).with("http://169.254.169.254/1.0/meta-data/local-ipv4")
194
+
195
+ @plugin.valid_platform?.should == true
196
+ end
197
+
198
+ it "should should return true if NOT on EC2" do
199
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
200
+
201
+ @plugin.should_receive(:open).with("http://169.254.169.254/1.0/meta-data/local-ipv4").and_raise("Bleh")
202
+
203
+ @plugin.valid_platform?.should == false
204
+ end
205
+
206
+ describe ".ebs_appliance_name" do
207
+ it "should return basic appliance name" do
208
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
209
+ @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0/x86_64"
210
+ end
211
+
212
+ it "should return 2nd snapshot of appliance" do
213
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
214
+
215
+ @plugin_config.merge!('snapshot' => true)
216
+
217
+ ec2 = mock('EC2')
218
+ ec2.should_receive(:describe_images).twice.with(:owner_id => '000000000000').and_return({'imagesSet' => {'item' => [
219
+ {'imageId' => '1', 'name' => 'appliance_name/fedora/14/1.0/x86_64'},
220
+ {'imageId' => '2', 'name' => 'appliance_name/fedora/14/1.0-SNAPSHOT-1/x86_64'}
221
+ ]}})
222
+
223
+ @plugin.instance_variable_set(:@ec2, ec2)
224
+
225
+ @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0-SNAPSHOT-2/x86_64"
226
+ end
227
+ end
228
+ end
229
+ end
230
+
@@ -0,0 +1,3 @@
1
+ access_key: access_key
2
+ secret_access_key: secret_access_key
3
+ account_number: 0000-0000-0000
@@ -0,0 +1,133 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'boxgrinder-build/plugins/delivery/local/local-plugin'
20
+ require 'hashery/opencascade'
21
+
22
+ module BoxGrinder
23
+ describe LocalPlugin do
24
+
25
+ before(:each) do
26
+ @config = mock('Config')
27
+ @config.stub!(:delivery_config).and_return({})
28
+ plugins = mock('Plugins')
29
+ plugins.stub!(:[]).with('local').and_return({})
30
+ @config.stub!(:[]).with(:plugins).and_return(plugins)
31
+
32
+ @appliance_config = mock('ApplianceConfig')
33
+
34
+ @appliance_config.stub!(:path).and_return(OpenCascade.new({:build => 'build/path'}))
35
+ @appliance_config.stub!(:name).and_return('appliance')
36
+ @appliance_config.stub!(:version).and_return(1)
37
+ @appliance_config.stub!(:release).and_return(0)
38
+ @appliance_config.stub!(:os).and_return(OpenCascade.new({:name => :fedora, :version => '13'}))
39
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new({:arch => 'x86_64'}))
40
+
41
+ @plugin = LocalPlugin.new.init(@config, @appliance_config,
42
+ :log => Logger.new('/dev/null'),
43
+ :plugin_info => {:class => BoxGrinder::LocalPlugin, :type => :delivery, :name => :local, :full_name => "Local file system"},
44
+ :previous_deliverables => {:disk => "a_disk.raw", :metadata => 'metadata.xml'}
45
+ )
46
+
47
+ @config = @plugin.instance_variable_get(:@config)
48
+ @appliance_config = @plugin.instance_variable_get(:@appliance_config)
49
+ @exec_helper = @plugin.instance_variable_get(:@exec_helper)
50
+ @log = @plugin.instance_variable_get(:@log)
51
+ @dir = @plugin.instance_variable_get(:@dir)
52
+ end
53
+
54
+ describe ".execute" do
55
+
56
+ it "should package and deliver the appliance" do
57
+ @plugin.instance_variable_set(:@plugin_config, {
58
+ 'overwrite' => false,
59
+ 'path' => 'a/path',
60
+ 'package' => true
61
+ })
62
+
63
+ FileUtils.should_receive(:mkdir_p).with('a/path')
64
+ package_helper = mock(PackageHelper)
65
+ package_helper.should_receive(:package).with('.', "build/path/local-plugin/tmp/appliance-1.0-fedora-13-x86_64-raw.tgz").and_return("deliverable")
66
+
67
+ PackageHelper.should_receive(:new).with(@config, @appliance_config, :log => @log, :exec_helper => @exec_helper).and_return(package_helper)
68
+
69
+ @exec_helper.should_receive(:execute).with("cp 'build/path/local-plugin/tmp/appliance-1.0-fedora-13-x86_64-raw.tgz' 'a/path'")
70
+ @plugin.should_receive(:deliverables_exists?).and_return(false)
71
+
72
+ @plugin.execute
73
+ end
74
+
75
+ it "should not package, but deliver the appliance" do
76
+ @plugin.instance_variable_set(:@plugin_config, {
77
+ 'overwrite' => true,
78
+ 'path' => 'a/path',
79
+ 'package' => false
80
+ })
81
+
82
+ FileUtils.should_receive(:mkdir_p).with('a/path')
83
+ PackageHelper.should_not_receive(:new)
84
+
85
+ @exec_helper.should_receive(:execute).with("cp 'a_disk.raw' 'a/path'")
86
+ @exec_helper.should_receive(:execute).with("cp 'metadata.xml' 'a/path'")
87
+
88
+ @plugin.execute
89
+ end
90
+
91
+ it "should not deliver the package, because it is already delivered" do
92
+ @plugin.instance_variable_set(:@plugin_config, {
93
+ 'overwrite' => false,
94
+ 'path' => 'a/path',
95
+ 'package' => false
96
+ })
97
+
98
+ PackageHelper.should_not_receive(:new)
99
+
100
+ @exec_helper.should_not_receive(:execute)
101
+ @plugin.should_receive(:deliverables_exists?).and_return(true)
102
+
103
+ @plugin.execute
104
+ end
105
+ end
106
+
107
+ describe ".deliverables_exists?" do
108
+ it "should return true for package" do
109
+ @plugin.instance_variable_set(:@plugin_config, {
110
+ 'path' => 'a/path',
111
+ 'package' => true
112
+ })
113
+
114
+ File.should_receive(:exists?).with('a/path/appliance-1.0-fedora-13-x86_64-raw.tgz').and_return(true)
115
+
116
+ @plugin.deliverables_exists?.should == true
117
+ end
118
+
119
+ it "should return true for non-packaged appliance" do
120
+ @plugin.instance_variable_set(:@plugin_config, {
121
+ 'path' => 'a/path',
122
+ 'package' => false
123
+ })
124
+
125
+ File.should_receive(:exists?).with('a/path/a_disk.raw').and_return(true)
126
+ File.should_receive(:exists?).with('a/path/metadata.xml').and_return(true)
127
+
128
+ @plugin.deliverables_exists?.should == true
129
+ end
130
+ end
131
+ end
132
+ end
133
+