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,153 @@
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 'yaml'
20
+
21
+ module BoxGrinder
22
+ class Repo
23
+ def initialize( name, baseurl = nil, mirrorlist = nil )
24
+ @name = name
25
+ @baseurl = baseurl
26
+ @mirrorlist = mirrorlist
27
+ end
28
+
29
+ attr_reader :name
30
+ attr_reader :baseurl
31
+ attr_reader :mirrorlist
32
+ end
33
+
34
+ class RPMDependencyValidator
35
+ def initialize( config, appliance_config, dir, kickstart_file, options = {} )
36
+ @config = config
37
+ @appliance_config = appliance_config
38
+ @kickstart_file = kickstart_file
39
+ @dir = dir
40
+
41
+ @log = options[:log] || Logger.new(STDOUT)
42
+ @exec_helper = options[:exec_helper] || ExecHelper.new( { :log => @log } )
43
+
44
+ @yum_config_file = "#{@dir.tmp}/yum.conf"
45
+
46
+ # Because we're using repoquery command from our building environment, we must ensure, that our repository
47
+ # names are unique
48
+ @magic_hash = "boxgrinder-"
49
+ end
50
+
51
+ def resolve_packages
52
+ @log.info "Resolving packages added to #{@appliance_config.name} appliance definition file..."
53
+
54
+ repos = read_repos_from_kickstart_file
55
+ package_list = generate_package_list
56
+ repo_list = generate_repo_list( repos )
57
+
58
+ generate_yum_config( repos )
59
+
60
+ invalid_names = invalid_names( repo_list, package_list )
61
+
62
+ if invalid_names.size == 0
63
+ @log.info "All additional packages for #{@appliance_config.name} appliance successfully resolved."
64
+ else
65
+ raise "Package#{invalid_names.size > 1 ? "s" : ""} #{invalid_names.join(', ')} for #{@appliance_config.name} appliance not found in repositories. Please check package names in appliance definition file."
66
+ end
67
+ end
68
+
69
+ def invalid_names( repo_list, package_list )
70
+ @log.debug "Querying package database..."
71
+
72
+ unless @appliance_config.is64bit?
73
+ arches = "i386,i486,i586,i686"
74
+ else
75
+ arches = "x86_64"
76
+ end
77
+
78
+ repoquery_output = @exec_helper.execute( "repoquery --quiet --disablerepo=* --enablerepo=#{repo_list} -c '#{@yum_config_file}' list available #{package_list.join( ' ' )} --nevra --archlist=#{arches},noarch" )
79
+
80
+ invalid_names = []
81
+
82
+ for name in package_list
83
+ found = false
84
+
85
+ repoquery_output.each do |line|
86
+ line = line.strip
87
+
88
+ package = line.match( /^([\S]+)-\d+:/ )
89
+ package = package.nil? ? line : package[1]
90
+
91
+ if package.size > 0 and name.match( /^#{package.gsub(/[\+]/, '\\+')}/ )
92
+ found = true
93
+ end
94
+ end
95
+ invalid_names += [ name ] unless found
96
+ end
97
+
98
+ invalid_names
99
+ end
100
+
101
+ def generate_package_list
102
+ packages = []
103
+ for package in @appliance_config.packages
104
+ packages << package unless package.match /^@/
105
+ end
106
+ packages
107
+ end
108
+
109
+ def generate_repo_list(repos)
110
+ repo_list = ""
111
+
112
+ repos.each do |repo|
113
+ repo_list += "#{@magic_hash}#{repo.name},"
114
+ end
115
+
116
+ repo_list = repo_list[0, repo_list.length - 1]
117
+ end
118
+
119
+ def read_repos_from_kickstart_file
120
+ repos = `grep -e "^repo" '#{@kickstart_file}'`
121
+ repo_list = []
122
+
123
+ repos.each do |repo_line|
124
+ name = repo_line.match( /--name=([\w\-]+)/ )[1]
125
+ baseurl = repo_line.match( /--baseurl=([\w\-\:\/\.&\?=]+)/ )
126
+ mirrorlist = repo_line.match( /--mirrorlist=([\w\-\:\/\.&\?=]+)/ )
127
+
128
+ baseurl = baseurl[1] unless baseurl.nil?
129
+ mirrorlist = mirrorlist[1] unless mirrorlist.nil?
130
+
131
+ repo_list.push( Repo.new( name, baseurl, mirrorlist ) )
132
+ end
133
+
134
+ repo_list
135
+ end
136
+
137
+ def generate_yum_config( repo_list )
138
+ File.open( @yum_config_file, "w") do |f|
139
+
140
+ f.puts( "[main]\r\ncachedir=#{Dir.pwd}/#{@dir.tmp}/#{@magic_hash}#{@appliance_config.hardware.arch}-yum-cache/\r\n\r\n" )
141
+
142
+ for repo in repo_list
143
+ f.puts( "[#{@magic_hash}#{repo.name}]" )
144
+ f.puts( "name=#{repo.name}" )
145
+ f.puts( "baseurl=#{repo.baseurl}" ) unless repo.baseurl.nil?
146
+ f.puts( "mirrorlist=#{repo.mirrorlist}" ) unless repo.mirrorlist.nil?
147
+ f.puts( "enabled=1" )
148
+ f.puts
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,37 @@
1
+ lang en_US.UTF-8
2
+ keyboard us
3
+ timezone US/Eastern
4
+ auth --useshadow --enablemd5
5
+ selinux --permissive
6
+ firewall --disabled
7
+ bootloader --timeout=1
8
+ firstboot --disabled
9
+
10
+ <% if graphical %>
11
+ xconfig --startxonboot
12
+ services --enabled=NetworkManager --disabled=network
13
+ <% else %>
14
+ network --bootproto=dhcp --device=eth0 --onboot=on
15
+ services --enabled=network
16
+ <% end %>
17
+
18
+ rootpw --iscrypted <%= appliance_config.os.password.crypt((0...8).map { 65.+(rand(25)).chr }.join) %>
19
+
20
+ <% appliance_config.hardware.partitions.each do |root, partition| %>
21
+ part <%= root %> --size <%= (partition['size'].to_f * 1024).to_i %> --fstype <%= partition['type'] %> <% unless partition['options'].nil? %> --fsoptions '<%= partition['options'] %>' <% end %> <% if partition['passphrase'] %> --encrypted --passphrase='<%= partition['passphrase'] %>' <% end %> --ondisk sda --label <%= root %><% end %>
22
+
23
+ <% for repo in repos %>
24
+ <%= repo %><% end %>
25
+
26
+ %packages
27
+
28
+ <% appliance_config.packages.each do |package| %>
29
+ <%= package %><% end %>
30
+ %end
31
+ %post
32
+
33
+ <% if graphical %>
34
+ chkconfig --level 345 firstboot off 2>/dev/null<% end %>
35
+
36
+ %end
37
+
@@ -0,0 +1,4 @@
1
+ [#NAME#]
2
+ name=#NAME#
3
+ enabled=1
4
+ gpgcheck=0
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ #
3
+ # motd Prepares /etc/motd file
4
+ #
5
+ # chkconfig: 2345 99 05
6
+ # description: Prepares /etc/motd file
7
+ #
8
+ ### BEGIN INIT INFO
9
+ # Provides: ec2
10
+ # Default-Start: 2345
11
+ # Default-Stop: 0 1 6
12
+ # Short-Description: Prepares /etc/motd file
13
+ # Description: Prepares /etc/motd file
14
+ ### END INIT INFO
15
+
16
+ HOSTNAME=`/bin/uname -a | awk '{print $2}'`
17
+ IP_ADDRESS=`ip addr list eth0 | grep "inet " | cut -d' ' -f6 | cut -d/ -f1`
18
+
19
+ echo -e "\nAppliance:\t#APPLIANCE# #VERSION#\nHostname:\t$HOSTNAME\nIP Address:\t$IP_ADDRESS\n" > /etc/motd
20
+
21
+ exit 0
@@ -0,0 +1,239 @@
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/base-plugin'
20
+ require 'boxgrinder-build/helpers/linux-helper'
21
+ require 'tempfile'
22
+
23
+ module BoxGrinder
24
+ class EC2Plugin < BasePlugin
25
+ def after_init
26
+ register_deliverable(:disk => "#{@appliance_config.name}.ec2")
27
+
28
+ register_supported_os('fedora', ['13', '14', '15'])
29
+ register_supported_os('centos', ['5'])
30
+ register_supported_os('rhel', ['5', '6'])
31
+ end
32
+
33
+ def execute
34
+ @linux_helper = LinuxHelper.new(:log => @log)
35
+
36
+ @log.info "Converting #{@appliance_config.name} appliance image to EC2 format..."
37
+
38
+ create_ec2_disk
39
+ sync_files
40
+
41
+ @image_helper.customize(@deliverables.disk) do |guestfs, guestfs_helper|
42
+ if (@appliance_config.os.name == 'rhel' or @appliance_config.os.name == 'centos') and @appliance_config.os.version == '5'
43
+ # Not sure why it's messed but this prevents booting on AWS
44
+ recreate_journal(guestfs)
45
+
46
+ # Remove normal kernel
47
+ guestfs.sh("yum -y remove kernel")
48
+ # because we need to install kernel-xen package
49
+ guestfs.sh("yum -y install kernel-xen")
50
+ # and add require modules
51
+ @linux_helper.recreate_kernel_image(guestfs, ['xenblk', 'xennet'])
52
+ end
53
+
54
+ # TODO is this really needed?
55
+ @log.debug "Uploading '/etc/resolv.conf'..."
56
+ guestfs.upload("/etc/resolv.conf", "/etc/resolv.conf")
57
+ @log.debug "'/etc/resolv.conf' uploaded."
58
+
59
+ create_devices(guestfs)
60
+
61
+ guestfs.mkdir("/data") if @appliance_config.is64bit?
62
+
63
+ upload_fstab(guestfs)
64
+ enable_networking(guestfs)
65
+ upload_rc_local(guestfs)
66
+ add_ec2_user(guestfs)
67
+ change_configuration(guestfs_helper)
68
+ install_menu_lst(guestfs)
69
+
70
+ enable_nosegneg_flag(guestfs) if @appliance_config.os.name == 'fedora'
71
+
72
+ execute_post(guestfs_helper)
73
+ end
74
+
75
+ @log.info "Image converted to EC2 format."
76
+ end
77
+
78
+ def sync_files
79
+ ec2_disk_mount_dir = "#{@dir.tmp}/ec2-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
80
+ raw_disk_mount_dir = "#{@dir.tmp}/raw-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
81
+
82
+ tmp_disk = "#{@dir.tmp}/#{@appliance_config.name}.raw"
83
+
84
+ @log.debug "Conveting disk to RAW format..."
85
+ @image_helper.convert_disk(@previous_deliverables.disk, 'raw', tmp_disk)
86
+
87
+ begin
88
+ ec2_mounts = @image_helper.mount_image(@deliverables.disk, ec2_disk_mount_dir)
89
+ raw_mounts = @image_helper.mount_image(tmp_disk, raw_disk_mount_dir)
90
+ rescue => e
91
+ @log.error e
92
+ @log.error "Mouting failed, trying to clean up."
93
+
94
+ @image_helper.umount_image(tmp_disk, raw_disk_mount_dir, raw_mounts) unless raw_mounts.nil?
95
+ @image_helper.umount_image(@deliverables.disk, ec2_disk_mount_dir, ec2_mounts) unless ec2_mounts.nil?
96
+
97
+ raise "Error while mounting image. See logs for more info."
98
+ end
99
+
100
+ @image_helper.sync_files(raw_disk_mount_dir, ec2_disk_mount_dir)
101
+
102
+ @image_helper.umount_image(tmp_disk, raw_disk_mount_dir, raw_mounts)
103
+ @image_helper.umount_image(@deliverables.disk, ec2_disk_mount_dir, ec2_mounts)
104
+
105
+ FileUtils.rm_rf tmp_disk
106
+ end
107
+
108
+ def create_ec2_disk
109
+ begin
110
+ # TODO using whole 10GB is fine?
111
+ @image_helper.create_disk(@deliverables.disk, 10)
112
+ @image_helper.create_filesystem(@deliverables.disk)
113
+ rescue => e
114
+ @log.error e
115
+ raise "Error while preparing EC2 disk image. See logs for more info."
116
+ end
117
+ end
118
+
119
+ def execute_post(guestfs_helper)
120
+ unless @appliance_config.post['ec2'].nil?
121
+ @appliance_config.post['ec2'].each do |cmd|
122
+ guestfs_helper.sh(cmd, :arch => @appliance_config.hardware.arch)
123
+ end
124
+ @log.debug "Post commands from appliance definition file executed."
125
+ else
126
+ @log.debug "No commands specified, skipping."
127
+ end
128
+ end
129
+
130
+ def recreate_journal(guestfs)
131
+ @log.debug "Recreating EXT3 journal on root partition."
132
+ guestfs.sh("tune2fs -j #{guestfs.list_devices.first}")
133
+ @log.debug "Journal recreated."
134
+ end
135
+
136
+ def create_devices(guestfs)
137
+ return if guestfs.exists('/sbin/MAKEDEV') == 0
138
+
139
+ @log.debug "Creating required devices..."
140
+ guestfs.sh("/sbin/MAKEDEV -d /dev -x console")
141
+ guestfs.sh("/sbin/MAKEDEV -d /dev -x null")
142
+ guestfs.sh("/sbin/MAKEDEV -d /dev -x zero")
143
+ @log.debug "Devices created."
144
+ end
145
+
146
+ def disk_device_prefix
147
+ disk = 'xv'
148
+ disk = 's' if (@appliance_config.os.name == 'rhel' or @appliance_config.os.name == 'centos') and @appliance_config.os.version == '5'
149
+
150
+ disk
151
+ end
152
+
153
+ def upload_fstab(guestfs)
154
+ @log.debug "Uploading '/etc/fstab' file..."
155
+
156
+ fstab_file = @appliance_config.is64bit? ? "#{File.dirname(__FILE__)}/src/fstab_64bit" : "#{File.dirname(__FILE__)}/src/fstab_32bit"
157
+
158
+ fstab_data = File.open(fstab_file).read
159
+ fstab_data.gsub!(/#DISK_DEVICE_PREFIX#/, disk_device_prefix)
160
+ fstab_data.gsub!(/#FILESYSTEM_TYPE#/, @appliance_config.hardware.partitions['/']['type'])
161
+
162
+ fstab = Tempfile.new('fstab')
163
+ fstab << fstab_data
164
+ fstab.flush
165
+
166
+ guestfs.upload(fstab.path, "/etc/fstab")
167
+
168
+ fstab.close
169
+
170
+ @log.debug "'/etc/fstab' file uploaded."
171
+ end
172
+
173
+ def install_menu_lst(guestfs)
174
+ @log.debug "Uploading '/boot/grub/menu.lst' file..."
175
+ menu_lst_data = File.open("#{File.dirname(__FILE__)}/src/menu.lst").read
176
+
177
+ menu_lst_data.gsub!(/#TITLE#/, @appliance_config.name)
178
+ menu_lst_data.gsub!(/#KERNEL_VERSION#/, @linux_helper.kernel_version(guestfs))
179
+ menu_lst_data.gsub!(/#KERNEL_IMAGE_NAME#/, @linux_helper.kernel_image_name(guestfs))
180
+
181
+ menu_lst = Tempfile.new('menu_lst')
182
+ menu_lst << menu_lst_data
183
+ menu_lst.flush
184
+
185
+ guestfs.upload(menu_lst.path, "/boot/grub/menu.lst")
186
+
187
+ menu_lst.close
188
+ @log.debug "'/boot/grub/menu.lst' file uploaded."
189
+ end
190
+
191
+ # This fixes issues with Fedora 14 on EC2: https://bugzilla.redhat.com/show_bug.cgi?id=651861#c39
192
+ def enable_nosegneg_flag(guestfs)
193
+ @log.debug "Enabling nosegneg flag..."
194
+ guestfs.sh("echo \"hwcap 1 nosegneg\" > /etc/ld.so.conf.d/libc6-xen.conf")
195
+ guestfs.sh("/sbin/ldconfig")
196
+ @log.debug "Nosegneg enabled."
197
+ end
198
+
199
+ # https://issues.jboss.org/browse/BGBUILD-110
200
+ def add_ec2_user(guestfs)
201
+ @log.debug "Adding ec2-user user..."
202
+ guestfs.sh("useradd ec2-user")
203
+ guestfs.sh("echo -e 'ec2-user\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers")
204
+ @log.debug "User ec2-user added."
205
+ end
206
+
207
+ # enable networking on default runlevels
208
+ def enable_networking(guestfs)
209
+ @log.debug "Enabling networking..."
210
+ guestfs.sh("/sbin/chkconfig network on")
211
+ guestfs.upload("#{File.dirname(__FILE__)}/src/ifcfg-eth0", "/etc/sysconfig/network-scripts/ifcfg-eth0")
212
+ @log.debug "Networking enabled."
213
+ end
214
+
215
+ def upload_rc_local(guestfs)
216
+ @log.debug "Uploading '/etc/rc.local' file..."
217
+ rc_local = Tempfile.new('rc_local')
218
+ rc_local << guestfs.read_file("/etc/rc.local") + File.read("#{File.dirname(__FILE__)}/src/rc_local")
219
+ rc_local.flush
220
+
221
+ guestfs.upload(rc_local.path, "/etc/rc.local")
222
+
223
+ rc_local.close
224
+ @log.debug "'/etc/rc.local' file uploaded."
225
+ end
226
+
227
+ def change_configuration(guestfs_helper)
228
+ guestfs_helper.augeas do
229
+ # disable password authentication
230
+ set("/etc/ssh/sshd_config", "PasswordAuthentication", "no")
231
+
232
+ # disable root login
233
+ set("/etc/ssh/sshd_config", "PermitRootLogin", "no")
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ plugin :class => BoxGrinder::EC2Plugin, :type => :platform, :name => :ec2, :full_name => "Amazon Elastic Compute Cloud (Amazon EC2)"
@@ -0,0 +1,7 @@
1
+ LABEL=/ / #FILESYSTEM_TYPE# defaults 1 1
2
+ /dev/#DISK_DEVICE_PREFIX#da2 /mnt ext3 defaults 1 2
3
+ /dev/#DISK_DEVICE_PREFIX#da3 swap swap defaults 0 0
4
+ none /dev/pts devpts gid=5,mode=620 0 0
5
+ none /dev/shm tmpfs defaults 0 0
6
+ none /proc proc defaults 0 0
7
+ none /sys sysfs defaults 0 0
@@ -0,0 +1,7 @@
1
+ LABEL=/ / #FILESYSTEM_TYPE# defaults 1 1
2
+ /dev/#DISK_DEVICE_PREFIX#db /mnt ext3 defaults 0 0
3
+ /dev/#DISK_DEVICE_PREFIX#dc /data ext3 defaults 0 0
4
+ none /dev/pts devpts gid=5,mode=620 0 0
5
+ none /dev/shm tmpfs defaults 0 0
6
+ none /proc proc defaults 0 0
7
+ none /sys sysfs defaults 0 0
@@ -0,0 +1,7 @@
1
+ DEVICE=eth0
2
+ BOOTPROTO=dhcp
3
+ ONBOOT=yes
4
+ TYPE=Ethernet
5
+ USERCTL=yes
6
+ PEERDNS=yes
7
+ IPV6INIT=no
@@ -0,0 +1,6 @@
1
+ default=0
2
+ timeout=0
3
+ title #TITLE#
4
+ root (hd0)
5
+ kernel /boot/vmlinuz-#KERNEL_VERSION# ro root=LABEL=/ rd_NO_PLYMOUTH
6
+ initrd /boot/#KERNEL_IMAGE_NAME#-#KERNEL_VERSION#.img
@@ -0,0 +1,19 @@
1
+ curl http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key 2>/dev/null >/tmp/my-key
2
+
3
+ if [ $? -eq 0 ] ; then
4
+ for home in `find /home/* -maxdepth 0 -type d 2>/dev/null | tr '\n' ' '`; do
5
+ user=`echo $home | awk -F '/' '{ print $3 }'`
6
+
7
+ if [ ! -d $home/.ssh ] ; then
8
+ mkdir -p $home/.ssh
9
+ chmod 700 $home/.ssh
10
+ chown $user $home/.ssh
11
+ fi
12
+
13
+ cat /tmp/my-key >> $home/.ssh/authorized_keys
14
+ chmod 600 $home/.ssh/authorized_keys
15
+ chown $user $home/.ssh/authorized_keys
16
+
17
+ done
18
+ rm /tmp/my-key
19
+ fi
@@ -0,0 +1,62 @@
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/base-plugin'
20
+ require 'boxgrinder-build/helpers/appliance-customize-helper'
21
+
22
+ module BoxGrinder
23
+ class VirtualBoxPlugin < BasePlugin
24
+ def after_init
25
+ register_deliverable(:disk => "#{@appliance_config.name}.vmdk")
26
+ end
27
+
28
+ def execute
29
+ @log.info "Converting image to VirtualBox format..."
30
+
31
+ build_virtualbox
32
+ customize
33
+
34
+ @log.info "Image converted to VirtualBox format."
35
+ end
36
+
37
+ def build_virtualbox
38
+ @log.debug "Building VirtualBox image."
39
+
40
+ @log.debug "Using qemu-img to convert the image..."
41
+ @image_helper.convert_disk(@previous_deliverables.disk, :vmdk, @deliverables.disk)
42
+ @log.debug "Conversion done."
43
+
44
+ @log.debug "VirtualBox image was built."
45
+ end
46
+
47
+ def customize
48
+ unless @appliance_config.post['virtualbox'].nil?
49
+ @image_helper.customize(@deliverables.disk) do |guestfs, guestfs_helper|
50
+ @appliance_config.post['virtualbox'].each do |cmd|
51
+ guestfs_helper.sh(cmd, :arch => @appliance_config.hardware.arch)
52
+ end
53
+ @log.debug "Post commands from appliance definition file executed."
54
+ end
55
+ else
56
+ @log.debug "No commands specified, skipping."
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ plugin :class => BoxGrinder::VirtualBoxPlugin, :type => :platform, :name => :virtualbox, :full_name => "VirtualBox"
@@ -0,0 +1,18 @@
1
+ This package contains #APPLIANCE_NAME# image for VMware.
2
+
3
+ VMware Enterprise (VMware ESX/ESXi/, VMware vSphere)
4
+ ====================================================
5
+
6
+ Required files:
7
+ ---------------
8
+
9
+ #APPLIANCE_NAME#.raw
10
+ #APPLIANCE_NAME#-enterprise.vmx
11
+ #APPLIANCE_NAME#-enterprise.vmdk
12
+
13
+ Required steps:
14
+ ---------------
15
+
16
+ 1. Upload all files to ESX server using vSpehere/VI client.
17
+ 2. Add #APPLIANCE_NAME#.vmx to inventory.
18
+ 3. Run appliance.
@@ -0,0 +1,16 @@
1
+ This package contains #APPLIANCE_NAME# image for VMware.
2
+
3
+ VMware Personal (VMware Fusion, VMware Server, VMware Player)
4
+ =============================================================
5
+
6
+ Required files:
7
+ ---------------
8
+
9
+ #APPLIANCE_NAME#.vmx
10
+ #APPLIANCE_NAME#.vmdk
11
+
12
+ Required steps:
13
+ ---------------
14
+
15
+ 1. Add #APPLIANCE_NAME#.vmx to inventory.
16
+ 2. Run appliance.
@@ -0,0 +1,20 @@
1
+ # Disk DescriptorFile
2
+ version=1
3
+ CID=fffffffe
4
+ parentCID=ffffffff
5
+ createType="#TYPE#"
6
+
7
+ # Extent description
8
+ RW #TOTAL_SECTORS# #EXTENT_TYPE# "#NAME#.raw" #NUMBER#
9
+
10
+ # The Disk Data Base
11
+ #DDB
12
+
13
+ ddb.toolsVersion = "0"
14
+ ddb.adapterType = "lsilogic"
15
+ ddb.geometry.sectors = "#SECTORS#"
16
+ ddb.geometry.heads = "#HEADS#"
17
+ ddb.geometry.cylinders = "#CYLINDERS#"
18
+ ddb.encoding = "UTF-8"
19
+ ddb.virtualHWVersion = "#HW_VERSION#"
20
+ ddb.thinProvisioned = "#THIN_PROVISIONED#"
@@ -0,0 +1,45 @@
1
+
2
+ #!/usr/bin/vmware
3
+
4
+ config.version = "8"
5
+ virtualHW.version = "4"
6
+ guestOS = "#GUESTOS#"
7
+ displayName = "#NAME#"
8
+ annotation = "#SUMMARY# | Version: #VERSION# | Built using BoxGrinder"
9
+ guestinfo.vmware.product.long = "#NAME#"
10
+ guestinfo.vmware.product.url = "http://www.jboss.org/boxgrinder"
11
+ guestinfo.vmware.product.class = "virtual machine"
12
+ numvcpus = "#VCPU#"
13
+ memsize = "#MEM_SIZE#"
14
+ MemAllowAutoScaleDown = "FALSE"
15
+ MemTrimRate = "-1"
16
+ uuid.action = "create"
17
+ tools.remindInstall = "TRUE"
18
+ hints.hideAll = "TRUE"
19
+ tools.syncTime = "TRUE"
20
+ serial0.present = "FALSE"
21
+ serial1.present = "FALSE"
22
+ parallel0.present = "FALSE"
23
+ logging = "TRUE"
24
+ log.fileName = "#NAME#.log"
25
+ log.append = "TRUE"
26
+ log.keepOld = "3"
27
+ isolation.tools.hgfs.disable = "FALSE"
28
+ isolation.tools.dnd.disable = "FALSE"
29
+ isolation.tools.copy.enable = "TRUE"
30
+ isolation.tools.paste.enabled = "TRUE"
31
+ floppy0.present = "FALSE"
32
+
33
+ scsi0:0.present = "TRUE"
34
+ scsi0:0.fileName = "#NAME#.vmdk"
35
+ scsi0:0.mode = "persistent"
36
+ scsi0:0.startConnected = "TRUE"
37
+ scsi0:0.writeThrough = "TRUE"
38
+ scsi0.present = "TRUE"
39
+ scsi0.virtualDev = "lsilogic"
40
+
41
+ ethernet0.present = "TRUE"
42
+ ethernet0.connectionType = "nat"
43
+ ethernet0.addressType = "generated"
44
+ ethernet0.generatedAddressOffset = "0"
45
+ ethernet0.autoDetect = "TRUE"