boxgrinder-build 0.2.0 → 0.3.2

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.
Files changed (62) hide show
  1. data/bin/boxgrinder-build +81 -0
  2. data/docs/examples/appliances/appliances.appl +5 -0
  3. data/docs/examples/appliances/minimal.appl +9 -0
  4. data/docs/examples/appliances/mix.appl +8 -0
  5. data/docs/examples/appliances/packages.appl +13 -0
  6. data/lib/boxgrinder-build/appliance.rb +85 -18
  7. data/lib/boxgrinder-build/helpers/appliance-customize-helper.rb +2 -2
  8. data/lib/boxgrinder-build/helpers/guestfs-helper.rb +18 -15
  9. data/lib/boxgrinder-build/helpers/package-helper.rb +65 -0
  10. data/lib/boxgrinder-build/helpers/plugin-helper.rb +89 -0
  11. data/lib/boxgrinder-build/{defaults.rb → managers/base-plugin-manager.rb} +41 -8
  12. data/lib/{boxgrinder-build.rb → boxgrinder-build/managers/delivery-plugin-manager.rb} +15 -18
  13. data/lib/boxgrinder-build/managers/operating-system-plugin-manager.rb +6 -0
  14. data/{bin/boxgrinder → lib/boxgrinder-build/managers/platform-plugin-manager.rb} +6 -3
  15. data/lib/boxgrinder-build/plugins/base-plugin.rb +98 -0
  16. data/lib/boxgrinder-build/plugins/delivery/base/base-delivery-plugin.rb +43 -0
  17. data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +57 -0
  18. data/lib/boxgrinder-build/{helpers → plugins/delivery/s3}/aws-helper.rb +0 -0
  19. data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +133 -0
  20. data/lib/boxgrinder-build/{helpers/ssh-helper.rb → plugins/delivery/sftp/sftp-plugin.rb} +61 -42
  21. data/lib/boxgrinder-build/{appliance-kickstart.rb → plugins/os/base/kickstart.rb} +45 -55
  22. data/lib/boxgrinder-build/{images/raw-image.rb → plugins/os/base/rpm-based-os-plugin.rb} +63 -60
  23. data/lib/boxgrinder-build/{erb → plugins/os/base/src}/appliance.ks.erb +2 -5
  24. data/{src → lib/boxgrinder-build/plugins/os/base/src}/base.repo +0 -0
  25. data/{src → lib/boxgrinder-build/plugins/os/base/src}/motd.init +0 -0
  26. data/lib/boxgrinder-build/{validators/appliance-dependency-validator.rb → plugins/os/base/validators/rpm-dependency-validator.rb} +1 -1
  27. data/lib/boxgrinder-build/{models/ssh-config.rb → plugins/os/base-operating-system-plugin.rb} +10 -17
  28. data/lib/boxgrinder-build/plugins/os/centos/centos-plugin.rb +72 -0
  29. data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +66 -0
  30. data/lib/boxgrinder-build/plugins/os/rhel/rhel-plugin.rb +38 -0
  31. data/lib/boxgrinder-build/plugins/platform/base-platform-plugin.rb +37 -0
  32. data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +283 -0
  33. data/{src → lib/boxgrinder-build/plugins/platform/ec2/src}/f12/yum.conf +0 -0
  34. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/f12-i386-boxgrinder.repo +0 -0
  35. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/f12-x86_64-boxgrinder.repo +0 -0
  36. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/fstab_32bit +0 -0
  37. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/fstab_64bit +0 -0
  38. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/ifcfg-eth0 +0 -0
  39. data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/rc_local +1 -4
  40. data/{src/README.vmware → lib/boxgrinder-build/plugins/platform/vmware/src/README} +10 -10
  41. data/{src → lib/boxgrinder-build/plugins/platform/vmware/src}/base.vmdk +1 -1
  42. data/{src → lib/boxgrinder-build/plugins/platform/vmware/src}/base.vmx +0 -0
  43. data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +181 -0
  44. data/lib/boxgrinder-build/validators/config-validator.rb +0 -19
  45. metadata +73 -44
  46. data/docs/examples/appliances/appliances-appliance/appliances-appliance.appl +0 -6
  47. data/docs/examples/appliances/appliances-appliance/appliances-appliance.pp +0 -16
  48. data/docs/examples/appliances/minimal-appliance/minimal-appliance.appl +0 -2
  49. data/docs/examples/appliances/minimal-appliance/minimal-appliance.pp +0 -16
  50. data/docs/examples/appliances/mix-appliance/mix-appliance.appl +0 -9
  51. data/docs/examples/appliances/mix-appliance/mix-appliance.pp +0 -16
  52. data/docs/examples/appliances/packages-appliance/packages-appliance.appl +0 -6
  53. data/docs/examples/appliances/packages-appliance/packages-appliance.pp +0 -16
  54. data/extras/sign-rpms +0 -12
  55. data/lib/boxgrinder-build/boxgrinder.rb +0 -93
  56. data/lib/boxgrinder-build/helpers/release-helper.rb +0 -136
  57. data/lib/boxgrinder-build/images/ec2-image.rb +0 -317
  58. data/lib/boxgrinder-build/images/vmware-image.rb +0 -214
  59. data/lib/boxgrinder-build/validators/appliance-definition-validator.rb +0 -89
  60. data/lib/progressbar/progressbar.rb +0 -236
  61. data/src/oddthesis/RPM-GPG-KEY-oddthesis +0 -30
  62. data/src/oddthesis/oddthesis.repo +0 -23
@@ -1,317 +0,0 @@
1
- # JBoss, Home of Professional Open Source
2
- # Copyright 2009, Red Hat Middleware LLC, and individual contributors
3
- # by the @authors tag. See the copyright.txt in the distribution for a
4
- # full listing of individual contributors.
5
- #
6
- # This is free software; you can redistribute it and/or modify it
7
- # under the terms of the GNU Lesser General Public License as
8
- # published by the Free Software Foundation; either version 2.1 of
9
- # the License, or (at your option) any later version.
10
- #
11
- # This software is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- # Lesser General Public License for more details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public
17
- # License along with this software; if not, write to the Free
18
- # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
- # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
-
21
- require 'rake/tasklib'
22
- require 'fileutils'
23
- require 'boxgrinder-core/validators/errors'
24
- require 'yaml'
25
- require 'AWS'
26
- require 'aws/s3'
27
- require 'boxgrinder-build/helpers/aws-helper'
28
- include AWS::S3
29
-
30
- module BoxGrinder
31
- class EC2Image < Rake::TaskLib
32
-
33
- def initialize( config, appliance_config, options = {} )
34
- @config = config
35
- @appliance_config = appliance_config
36
-
37
- @log = options[:log] || Logger.new(STDOUT)
38
- @exec_helper = options[:exec_helper] || ExecHelper.new( :log => @log )
39
-
40
- define_tasks
41
- end
42
-
43
- def define_tasks
44
- directory @appliance_config.path.dir.ec2.build
45
- directory @appliance_config.path.dir.ec2.bundle
46
-
47
- # TODO we should depend on actual disk file, not xml I think
48
- file @appliance_config.path.file.ec2.disk => [ @appliance_config.path.file.raw.xml, @appliance_config.path.dir.ec2.build ] do
49
- convert_image_to_ec2_format
50
- end
51
-
52
- file @appliance_config.path.file.ec2.manifest => [ @appliance_config.path.file.ec2.disk, @appliance_config.path.dir.ec2.bundle ] do
53
- @aws_helper = AWSHelper.new( @config, @appliance_config )
54
- bundle_image
55
- end
56
-
57
- task "appliance:#{@appliance_config.name}:ec2:bundle" => [ @appliance_config.path.file.ec2.manifest ]
58
-
59
- task "appliance:#{@appliance_config.name}:ec2:upload" => [ "appliance:#{@appliance_config.name}:ec2:bundle" ] do
60
- @aws_helper = AWSHelper.new( @config, @appliance_config )
61
- upload_image
62
- end
63
-
64
- task "appliance:#{@appliance_config.name}:ec2:register" => [ "appliance:#{@appliance_config.name}:ec2:upload" ] do
65
- @aws_helper = AWSHelper.new( @config, @appliance_config )
66
- register_image
67
- end
68
-
69
- desc "Build #{@appliance_config.simple_name} appliance for Amazon EC2"
70
- task "appliance:#{@appliance_config.name}:ec2" => [ @appliance_config.path.file.ec2.disk ]
71
- end
72
-
73
- def bundle_image
74
- @log.info "Bundling AMI..."
75
-
76
- @exec_helper.execute( "ec2-bundle-image -i #{@appliance_config.path.file.ec2.disk} --kernel #{AWS_DEFAULTS[:kernel_id][@appliance_config.hardware.arch]} --ramdisk #{AWS_DEFAULTS[:ramdisk_id][@appliance_config.hardware.arch]} -c #{@aws_helper.aws_data['cert_file']} -k #{@aws_helper.aws_data['key_file']} -u #{@aws_helper.aws_data['account_number']} -r #{@appliance_config.hardware.arch} -d #{@appliance_config.path.dir.ec2.bundle}" )
77
-
78
- @log.info "Bundling AMI finished."
79
- end
80
-
81
- def appliance_already_uploaded?
82
- begin
83
- bucket = Bucket.find( @aws_helper.aws_data['bucket_name'] )
84
- rescue
85
- return false
86
- end
87
-
88
- manifest_location = @aws_helper.bucket_manifest_key( @appliance_config.name )
89
- manifest_location = manifest_location[ manifest_location.index( "/" ) + 1, manifest_location.length ]
90
-
91
- for object in bucket.objects do
92
- return true if object.key.eql?( manifest_location )
93
- end
94
-
95
- false
96
- end
97
-
98
- def upload_image
99
- if appliance_already_uploaded?
100
- @log.debug "Image for #{@appliance_config.simple_name} appliance is already uploaded, skipping..."
101
- return
102
- end
103
-
104
- @log.info "Uploading #{@appliance_config.simple_name} AMI to bucket '#{@aws_helper.aws_data['bucket_name']}'..."
105
-
106
- @exec_helper.execute( "ec2-upload-bundle -b #{@aws_helper.bucket_key( @appliance_config.name )} -m #{@appliance_config.path.file.ec2.manifest} -a #{@aws_helper.aws_data['access_key']} -s #{@aws_helper.aws_data['secret_access_key']} --retry" )
107
- end
108
-
109
- def register_image
110
- ami_info = @aws_helper.ami_info( @appliance_config.name )
111
-
112
- if ami_info
113
- @log.info "Image is registered under id: #{ami_info.imageId}"
114
- return
115
- else
116
- ami_info = @aws_helper.ec2.register_image( :image_location => @aws_helper.bucket_manifest_key( @appliance_config.name ) )
117
- @log.info "Image successfully registered under id: #{ami_info.imageId}."
118
- end
119
- end
120
-
121
- def convert_image_to_ec2_format
122
- @log.info "Converting #{@appliance_config.simple_name} appliance image to EC2 format..."
123
-
124
- ec2_disk_mount_dir = "#{@config.dir.build}/#{@appliance_config.appliance_path}/tmp/ec2-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
125
- raw_disk_mount_dir = "#{@config.dir.build}/#{@appliance_config.appliance_path}/tmp/raw-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
126
-
127
- ec2_prepare_disk
128
- ec2_create_filesystem
129
-
130
- raw_disk_offset = calculate_disk_offset( @appliance_config.path.file.raw.disk )
131
-
132
- ec2_loop_device = mount_image(@appliance_config.path.file.ec2.disk, ec2_disk_mount_dir )
133
- raw_loop_device = mount_image(@appliance_config.path.file.raw.disk, raw_disk_mount_dir, raw_disk_offset )
134
-
135
- sync_files( raw_disk_mount_dir, ec2_disk_mount_dir )
136
-
137
- umount_image( @appliance_config.path.file.raw.disk, raw_disk_mount_dir, raw_loop_device )
138
- umount_image( @appliance_config.path.file.ec2.disk, ec2_disk_mount_dir, ec2_loop_device )
139
-
140
- guestfs_helper = GuestFSHelper.new( @appliance_config.path.file.ec2.disk, :log => @log )
141
- guestfs = guestfs_helper.guestfs
142
-
143
- create_devices( guestfs )
144
- upload_fstab( guestfs )
145
-
146
- guestfs.mkdir( "/data" ) if @appliance_config.is64bit?
147
-
148
- enable_networking( guestfs )
149
- upload_rc_local( guestfs )
150
-
151
- guestfs_helper.rebuild_rpm_database
152
-
153
- install_additional_packages( guestfs )
154
- change_configuration( guestfs )
155
-
156
- if @appliance_config.os.name.eql?("fedora") and @appliance_config.os.version.to_s.eql?("12")
157
- @log.debug "Downgrading udev package to use in EC2 environment..."
158
-
159
- repo_included = false
160
-
161
- @appliance_config.repos.each do |repo|
162
- repo_included = true if repo['baseurl'] == "http://repo.boxgrinder.org/boxgrinder/packages/fedora/12/RPMS/#{@appliance_config.hardware.arch}"
163
- end
164
-
165
- guestfs.upload( "#{@config.dir.base}/src/ec2/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo", "/etc/yum.repos.d/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo" ) unless repo_included
166
- guestfs.sh( "yum -y downgrade udev-142" )
167
- guestfs.upload( "#{@config.dir.base}/src/f12/yum.conf", "/etc/yum.conf" )
168
- guestfs.rm_rf( "/etc/yum.repos.d/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo" ) unless repo_included
169
-
170
- @log.debug "Package udev downgraded."
171
-
172
- # TODO EC2 fix, remove that after Fedora pushes kernels to Amazon
173
- @log.debug "Disabling unnecessary services..."
174
- guestfs.sh( "/sbin/chkconfig ksm off" ) if guestfs.exists( "/etc/init.d/ksm" ) != 0
175
- guestfs.sh( "/sbin/chkconfig ksmtuned off" ) if guestfs.exists( "/etc/init.d/ksmtuned" ) != 0
176
- @log.debug "Services disabled."
177
- end
178
-
179
- guestfs.close
180
-
181
- @log.info "Image converted to EC2 format."
182
- end
183
-
184
- def ec2_prepare_disk
185
- # TODO add progress bar?
186
- @log.debug "Preparing disk for EC2 image..."
187
- @exec_helper.execute "dd if=/dev/zero of=#{@appliance_config.path.file.ec2.disk} bs=1 count=0 seek=#{10 * 1024}M"
188
- @log.debug "Disk for EC2 image prepared"
189
- end
190
-
191
- def ec2_create_filesystem
192
- @log.debug "Creating filesystem..."
193
- @exec_helper.execute "mkfs.ext3 -F #{@appliance_config.path.file.ec2.disk}"
194
- @log.debug "Filesystem created"
195
- end
196
-
197
- def calculate_disk_offset( disk )
198
- loop_device = get_loop_device
199
-
200
- @exec_helper.execute( "sudo losetup #{loop_device} #{disk}" )
201
- offset = @exec_helper.execute("sudo parted -m #{loop_device} 'unit B print' | grep '^1' | awk -F: '{ print $2 }'").strip.chop
202
- @exec_helper.execute( "sudo losetup -d #{loop_device}" )
203
-
204
- offset
205
- end
206
-
207
- def mount_image( disk, mount_dir, offset = 0 )
208
- loop_device = get_loop_device
209
-
210
- @log.debug "Mounting image #{File.basename( disk )} in #{mount_dir} using #{loop_device} with offset #{offset}"
211
- FileUtils.mkdir_p( mount_dir )
212
- @exec_helper.execute( "sudo losetup -o #{offset.to_s} #{loop_device} #{disk}" )
213
- @exec_helper.execute( "sudo mount #{loop_device} -t ext3 #{ mount_dir}")
214
-
215
- loop_device
216
- end
217
-
218
- def umount_image( disk, mount_dir, loop_device )
219
- @log.debug "Unmounting image #{File.basename( disk )}"
220
- @exec_helper.execute( "sudo umount -d #{loop_device}" )
221
- FileUtils.rm_rf( mount_dir )
222
- end
223
-
224
-
225
- def sync_files( from_dir, to_dir )
226
- @log.debug "Syncing files between #{from_dir} and #{to_dir}..."
227
- @exec_helper.execute "sudo rsync -u -r -a #{from_dir}/* #{to_dir}"
228
- @log.debug "Sync finished."
229
- end
230
-
231
- def cache_rpms( rpms )
232
- for name in rpms.keys
233
- cache_file = "#{@config.dir.src_cache}/#{name}"
234
-
235
- if ( ! File.exist?( cache_file ) )
236
- FileUtils.mkdir_p( @config.dir.src_cache )
237
- @exec_helper.execute( "wget #{rpms[name]} -O #{cache_file}" )
238
- end
239
- end
240
- end
241
-
242
- def create_devices( guestfs )
243
- @log.debug "Creating required devices..."
244
- guestfs.sh( "/sbin/MAKEDEV -d /dev -x console" )
245
- guestfs.sh( "/sbin/MAKEDEV -d /dev -x null" )
246
- guestfs.sh( "/sbin/MAKEDEV -d /dev -x zero" )
247
- @log.debug "Devices created."
248
- end
249
-
250
- def upload_fstab( guestfs )
251
- @log.debug "Uploading '/etc/fstab' file..."
252
- fstab_file = @appliance_config.is64bit? ? "#{@config.dir.base}/src/ec2/fstab_64bit" : "#{@config.dir.base}/src/ec2/fstab_32bit"
253
- guestfs.upload( fstab_file, "/etc/fstab" )
254
- @log.debug "'/etc/fstab' file uploaded."
255
- end
256
-
257
- # enable networking on default runlevels
258
- def enable_networking( guestfs )
259
- @log.debug "Enabling networking..."
260
- guestfs.sh( "/sbin/chkconfig network on" )
261
- guestfs.upload( "#{@config.dir.base}/src/ec2/ifcfg-eth0", "/etc/sysconfig/network-scripts/ifcfg-eth0" )
262
- @log.debug "Networking enabled."
263
- end
264
-
265
- def upload_rc_local( guestfs )
266
- @log.debug "Uploading '/etc/rc.local' file..."
267
- rc_local = Tempfile.new('rc_local')
268
- rc_local << guestfs.read_file( "/etc/rc.local" ) + File.read( "#{@config.dir.base}/src/ec2/rc_local" )
269
- rc_local.flush
270
-
271
- guestfs.upload( rc_local.path, "/etc/rc.local" )
272
-
273
- rc_local.close
274
- @log.debug "'/etc/rc.local' file uploaded."
275
- end
276
-
277
- def install_additional_packages( guestfs )
278
- rpms = {
279
- File.basename(AWS_DEFAULTS[:kernel_rpm][@appliance_config.hardware.arch]) => AWS_DEFAULTS[:kernel_rpm][@appliance_config.hardware.arch],
280
- "ec2-ami-tools.noarch.rpm" => "http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm"
281
- }
282
-
283
- cache_rpms( rpms )
284
-
285
- @log.debug "Installing additional packages (#{rpms.keys.join( ", " )})..."
286
- guestfs.mkdir_p("/tmp/rpms")
287
-
288
- for name in rpms.keys
289
- cache_file = "#{@config.dir.src_cache}/#{name}"
290
- guestfs.upload( cache_file, "/tmp/rpms/#{name}" )
291
- end
292
-
293
- guestfs.sh( "rpm -Uvh --nodeps /tmp/rpms/*.rpm" )
294
- guestfs.rm_rf("/tmp/rpms")
295
- @log.debug "Additional packages installed."
296
- end
297
-
298
- def change_configuration( guestfs )
299
- @log.debug "Changing configuration files using augeas..."
300
- guestfs.aug_init( "/", 0 )
301
- # disable password authentication
302
- guestfs.aug_set( "/files/etc/ssh/sshd_config/PasswordAuthentication", "no" )
303
- guestfs.aug_save
304
- @log.debug "Augeas changes saved."
305
- end
306
-
307
- def get_loop_device
308
- begin
309
- loop_device = @exec_helper.execute("sudo losetup -f 2>&1").strip
310
- rescue
311
- raise "No free loop devices available, please free at least one. See 'losetup -d' command."
312
- end
313
-
314
- loop_device
315
- end
316
- end
317
- end
@@ -1,214 +0,0 @@
1
- # JBoss, Home of Professional Open Source
2
- # Copyright 2009, Red Hat Middleware LLC, and individual contributors
3
- # by the @authors tag. See the copyright.txt in the distribution for a
4
- # full listing of individual contributors.
5
- #
6
- # This is free software; you can redistribute it and/or modify it
7
- # under the terms of the GNU Lesser General Public License as
8
- # published by the Free Software Foundation; either version 2.1 of
9
- # the License, or (at your option) any later version.
10
- #
11
- # This software is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- # Lesser General Public License for more details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public
17
- # License along with this software; if not, write to the Free
18
- # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
- # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
-
21
- require 'rake/tasklib'
22
- require 'rexml/document'
23
- require 'boxgrinder-build/helpers/appliance-customize-helper'
24
-
25
- module BoxGrinder
26
-
27
- class VMwareImage < Rake::TaskLib
28
-
29
- def initialize( config, appliance_config, options = {} )
30
- @config = config
31
- @appliance_config = appliance_config
32
-
33
- @log = options[:log] || Logger.new(STDOUT)
34
- @exec_helper = options[:exec_helper] || ExecHelper.new( { :log => @log } )
35
-
36
- define_tasks
37
- end
38
-
39
- def define_tasks
40
- directory @appliance_config.path.dir.vmware.build
41
- directory @appliance_config.path.dir.vmware.personal
42
- directory @appliance_config.path.dir.vmware.enterprise
43
-
44
- task "appliance:#{@appliance_config.name}:vmware:personal" => [ @appliance_config.path.file.vmware.disk, @appliance_config.path.dir.vmware.personal ] do
45
- build_vmware_personal
46
- end
47
-
48
- task "appliance:#{@appliance_config.name}:vmware:enterprise" => [ @appliance_config.path.file.vmware.disk, @appliance_config.path.dir.vmware.enterprise ] do
49
- build_vmware_enterprise
50
- end
51
-
52
- desc "Build #{@appliance_config.name} appliance for VMware"
53
- task "appliance:#{@appliance_config.name}:vmware" => [ "appliance:#{@appliance_config.name}:vmware:personal", "appliance:#{@appliance_config.name}:vmware:enterprise" ]
54
-
55
- file @appliance_config.path.file.vmware.disk => [ @appliance_config.path.dir.vmware.build, @appliance_config.path.file.raw.xml ] do
56
- convert_to_vmware
57
- end
58
- end
59
-
60
- # returns value of cylinders, heads and sector for selected disk size (in GB)
61
-
62
- def generate_scsi_chs(disk_size)
63
- disk_size = disk_size * 1024
64
-
65
- gb_sectors = 2097152
66
-
67
- if disk_size == 1024
68
- h = 128
69
- s = 32
70
- else
71
- h = 255
72
- s = 63
73
- end
74
-
75
- c = disk_size / 1024 * gb_sectors / (h*s)
76
- total_sectors = gb_sectors * disk_size / 1024
77
-
78
- return [ c, h, s, total_sectors ]
79
- end
80
-
81
- def change_vmdk_values( type )
82
- vmdk_data = File.open( @config.files.base_vmdk ).read
83
-
84
- disk_size = 0
85
- @appliance_config.hardware.partitions.values.each { |part| disk_size += part['size'] }
86
-
87
- c, h, s, total_sectors = generate_scsi_chs( disk_size )
88
-
89
- is_enterprise = type.eql?("vmfs")
90
-
91
- vmdk_data.gsub!( /#NAME#/, @appliance_config.name )
92
- vmdk_data.gsub!( /#TYPE#/, type )
93
- vmdk_data.gsub!( /#EXTENT_TYPE#/, is_enterprise ? "VMFS" : "FLAT" )
94
- vmdk_data.gsub!( /#NUMBER#/, is_enterprise ? "" : "0" )
95
- vmdk_data.gsub!( /#HW_VERSION#/, is_enterprise ? "4" : "3" )
96
- vmdk_data.gsub!( /#CYLINDERS#/, c.to_s )
97
- vmdk_data.gsub!( /#HEADS#/, h.to_s )
98
- vmdk_data.gsub!( /#SECTORS#/, s.to_s )
99
- vmdk_data.gsub!( /#TOTAL_SECTORS#/, total_sectors.to_s )
100
-
101
- vmdk_data
102
- end
103
-
104
- def change_common_vmx_values
105
- vmx_data = File.open( @config.files.base_vmx ).read
106
-
107
- # replace version with current appliance version
108
- vmx_data.gsub!( /#VERSION#/, "#{@appliance_config.version}.#{@appliance_config.release}" )
109
- # replace builder with current builder name and version
110
- vmx_data.gsub!( /#BUILDER#/, "#{@config.name} #{@config.version_with_release}" )
111
- # change name
112
- vmx_data.gsub!( /#NAME#/, @appliance_config.name.to_s )
113
- # and summary
114
- vmx_data.gsub!( /#SUMMARY#/, @appliance_config.summary.to_s )
115
- # replace guestOS informations to: linux or otherlinux-64, this seems to be the savests values
116
- vmx_data.gsub!( /#GUESTOS#/, "#{@appliance_config.hardware.arch == "x86_64" ? "otherlinux-64" : "linux"}" )
117
- # memory size
118
- vmx_data.gsub!( /#MEM_SIZE#/, @appliance_config.hardware.memory.to_s )
119
- # memory size
120
- vmx_data.gsub!( /#VCPU#/, @appliance_config.hardware.cpus.to_s )
121
- # network name
122
- # vmx_data.gsub!( /#NETWORK_NAME#/, @appliance_config.network_name )
123
-
124
- vmx_data
125
- end
126
-
127
- def create_hardlink_to_disk_image( vmware_raw_file )
128
- # Hard link RAW disk to VMware destination folder
129
- FileUtils.ln( @appliance_config.path.file.vmware.disk, vmware_raw_file ) if ( !File.exists?( vmware_raw_file ) || File.new( @appliance_config.path.file.raw.disk ).mtime > File.new( vmware_raw_file ).mtime )
130
- end
131
-
132
- def build_vmware_personal
133
- @log.debug "Building VMware personal image."
134
-
135
- # link disk image
136
- create_hardlink_to_disk_image( @appliance_config.path.file.vmware.personal.disk )
137
-
138
- # create .vmx file
139
- File.open( @appliance_config.path.file.vmware.personal.vmx, "w" ) {|f| f.write( change_common_vmx_values ) }
140
-
141
- # create disk descriptor file
142
- File.open( @appliance_config.path.file.vmware.personal.vmdk, "w" ) {|f| f.write( change_vmdk_values( "monolithicFlat" ) ) }
143
-
144
- @log.debug "VMware personal image was built."
145
- end
146
-
147
- def build_vmware_enterprise
148
- @log.debug "Building VMware enterprise image."
149
-
150
- # link disk image
151
- create_hardlink_to_disk_image( @appliance_config.path.file.vmware.enterprise.disk )
152
-
153
- # defaults for ESXi (maybe for others too)
154
- @appliance_config.hardware.network = "VM Network" if @appliance_config.hardware.network.eql?( "NAT" )
155
-
156
- # create .vmx file
157
- vmx_data = change_common_vmx_values
158
- vmx_data += "ethernet0.networkName = \"#{@appliance_config.hardware.network}\""
159
-
160
- File.open( @appliance_config.path.file.vmware.enterprise.vmx, "w" ) {|f| f.write( vmx_data ) }
161
-
162
- # create disk descriptor file
163
- File.open( @appliance_config.path.file.vmware.enterprise.vmdk, "w" ) {|f| f.write( change_vmdk_values( "vmfs" ) ) }
164
-
165
- @log.debug "VMware enterprise image was built."
166
- end
167
-
168
- def convert_to_vmware
169
- @log.info "Converting image to VMware format..."
170
- @log.debug "Copying VMware image file, this may take several minutes..."
171
-
172
- @exec_helper.execute "cp #{@appliance_config.path.file.raw.disk} #{@appliance_config.path.file.vmware.disk}" if ( !File.exists?( @appliance_config.path.file.vmware.disk ) || File.new( @appliance_config.path.file.raw.disk ).mtime > File.new( @appliance_config.path.file.vmware.disk ).mtime )
173
-
174
- @log.debug "VMware image copied."
175
-
176
- customize
177
-
178
- @log.info "Image converted to VMware format."
179
- end
180
-
181
- def customize
182
- @log.debug "Customizing VMware image..."
183
- ApplianceCustomizeHelper.new( @config, @appliance_config, @appliance_config.path.file.vmware.disk, :log => @log ).customize do |customizer, guestfs|
184
- # install_vmware_tools( customizer )
185
- execute_post_operations( guestfs )
186
- end
187
- @log.debug "Image customized."
188
- end
189
-
190
- def execute_post_operations( guestfs )
191
- @log.debug "Executing post commands..."
192
- for cmd in @appliance_config.post.vmware
193
- @log.debug "Executing #{cmd}"
194
- guestfs.sh( cmd )
195
- end
196
- @log.debug "Post commands executed."
197
- end
198
-
199
- def install_vmware_tools( customizer )
200
- @log.debug "Installing VMware tools..."
201
-
202
- if @appliance_config.is_os_version_stable?
203
- rpmfusion_repo_rpm = [ "http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-rawhide.noarch.rpm", "http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-rawhide.noarch.rpm" ]
204
- else
205
- rpmfusion_repo_rpm = [ "http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm", "http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm" ]
206
- end
207
-
208
- #TODO this takes about 11 minutes, need to find a quicker way to install kmod-open-vm-tools package
209
- customizer.install_packages( @appliance_config.path.file.vmware.disk, { :packages => { :yum => [ "kmod-open-vm-tools" ] }, :repos => rpmfusion_repo_rpm } )
210
-
211
- @log.debug "VMware tools installed."
212
- end
213
- end
214
- end
@@ -1,89 +0,0 @@
1
- # JBoss, Home of Professional Open Source
2
- # Copyright 2009, Red Hat Middleware LLC, and individual contributors
3
- # by the @authors tag. See the copyright.txt in the distribution for a
4
- # full listing of individual contributors.
5
- #
6
- # This is free software; you can redistribute it and/or modify it
7
- # under the terms of the GNU Lesser General Public License as
8
- # published by the Free Software Foundation; either version 2.1 of
9
- # the License, or (at your option) any later version.
10
- #
11
- # This software is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- # Lesser General Public License for more details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public
17
- # License along with this software; if not, write to the Free
18
- # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
- # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
-
21
- require 'boxgrinder-core/validators/errors'
22
-
23
- module BoxGrinder
24
- class ApplianceDefinitionValidator
25
- def initialize( appliance_definition )
26
- @appliance_definition = appliance_definition
27
- end
28
-
29
- def validate
30
- check_for_missing_field( 'name' )
31
-
32
- validate_os
33
- validate_hardware
34
- validate_repos
35
- end
36
-
37
- protected
38
-
39
- def check_for_missing_field( name )
40
- raise ApplianceValidationError, "Missing field: appliance definition file should have field '#{name}'" if @appliance_definition[name].nil?
41
- end
42
-
43
- def validate_os
44
- return if @appliance_definition['os'].nil?
45
-
46
- raise ApplianceValidationError, "Unsupported OS: operating system '#{@appliance_definition['os']['name']}' is not supported. Supported OS types: #{SUPPORTED_OSES.keys.join(", ")}. Please correct your appliance definition file, thanks." if !@appliance_definition['os']['name'].nil? and !SUPPORTED_OSES.keys.include?( @appliance_definition['os']['name'] )
47
-
48
- #unless @appliance_definition['os']['version'].nil?
49
- #@appliance_definition['os']['version'] = @appliance_definition['os']['version'].to_s
50
- #raise ApplianceValidationError, "Not valid OS version: operating system version '#{@appliance_definition['os']['version']}' is not supported for OS type '#{@appliance_definition['os']['name']}'. Supported OS versions for this OS type are: #{SUPPORTED_OSES[@appliance_definition['os']['name']].join(", ")}. Please correct your definition file '#{@appliance_definition_file}', thanks" if !SUPPORTED_OSES[@appliance_definition['os']['name'].nil? ? APPLIANCE_DEFAULTS[:os][:name] : @appliance_definition['os']['name']].include?( @appliance_definition['os']['version'] )
51
- #end
52
- end
53
-
54
- def validate_hardware
55
- return if @appliance_definition['hardware'].nil?
56
-
57
- unless @appliance_definition['hardware']['cpus'].nil?
58
- raise ApplianceValidationError, "Not valid CPU amount: '#{@appliance_definition['hardware']['cpus']}' is not allowed here. Please correct your appliance definition file, thanks." if @appliance_definition['hardware']['cpus'] =~ /\d/
59
- raise ApplianceValidationError, "Not valid CPU amount: Too many or too less CPU's: '#{@appliance_definition['hardware']['cpus']}'. Please choose from 1-4. Please correct your appliance definition file, thanks." unless @appliance_definition['hardware']['cpus'] >= 1 and @appliance_definition['hardware']['cpus'] <= 4
60
- end
61
-
62
- unless @appliance_definition['hardware']['memory'].nil?
63
- raise ApplianceValidationError, "Not valid memory amount: '#{@appliance_definition['hardware']['memory']}' is wrong value. Please correct your appliance definition file, thanks." if @appliance_definition['hardware']['memory'] =~ /\d/
64
- raise ApplianceValidationError, "Not valid memory amount: '#{@appliance_definition['hardware']['memory']}' is not allowed here. Memory should be a multiplicity of 64. Please correct your appliance definition file, thanks." if (@appliance_definition['hardware']['memory'].to_i % 64 > 0)
65
- end
66
-
67
- unless @appliance_definition['hardware']['partitions'].nil?
68
- raise ApplianceValidationError, "Not valid partitions format: Please correct your appliance definition file, thanks." unless @appliance_definition['hardware']['partitions'].class.eql?(Array)
69
-
70
- for partition in @appliance_definition['hardware']['partitions']
71
- raise ApplianceValidationError, "Not valid partition format: '#{partition}' is wrong value. Please correct your appliance definition file, thanks." unless partition.class.eql?(Hash)
72
- raise ApplianceValidationError, "Not valid partition format: Keys 'root' and 'size' should be specified for every partition. Please correct your appliance definition file, thanks." if !partition.keys.include?("root") or !partition.keys.include?("size")
73
- raise ApplianceValidationError, "Not valid partition size: '#{partition['size']}' is not a valid value. Please correct your appliance definition file, thanks." if partition['size'] =~ /\d/ or partition['size'].to_i < 1
74
- end
75
- end
76
- end
77
-
78
- def validate_repos
79
- return if @appliance_definition['repos'].nil?
80
- raise ApplianceValidationError, "Not valid repos format: Please correct your appliance definition file, thanks." unless @appliance_definition['repos'].class.eql?(Array)
81
-
82
- for repo in @appliance_definition['repos']
83
- raise ApplianceValidationError, "Not valid repo format: '#{repo}' is wrong value. Please correct your appliance definition file, thanks." unless repo.class.eql?(Hash)
84
- raise ApplianceValidationError, "Not valid repo format: Please specify name for repository. Please correct your appliance definition file, thanks." unless repo.keys.include?('name')
85
- raise ApplianceValidationError, "Not valid repo format: There is no 'mirrorlist' or 'baseurl' specified for '#{repo['name']}' repository. Please correct your appliance definition file, thanks." unless repo.keys.include?('mirrorlist') or repo.keys.include?('baseurl')
86
- end
87
- end
88
- end
89
- end