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.
- data/bin/boxgrinder-build +81 -0
- data/docs/examples/appliances/appliances.appl +5 -0
- data/docs/examples/appliances/minimal.appl +9 -0
- data/docs/examples/appliances/mix.appl +8 -0
- data/docs/examples/appliances/packages.appl +13 -0
- data/lib/boxgrinder-build/appliance.rb +85 -18
- data/lib/boxgrinder-build/helpers/appliance-customize-helper.rb +2 -2
- data/lib/boxgrinder-build/helpers/guestfs-helper.rb +18 -15
- data/lib/boxgrinder-build/helpers/package-helper.rb +65 -0
- data/lib/boxgrinder-build/helpers/plugin-helper.rb +89 -0
- data/lib/boxgrinder-build/{defaults.rb → managers/base-plugin-manager.rb} +41 -8
- data/lib/{boxgrinder-build.rb → boxgrinder-build/managers/delivery-plugin-manager.rb} +15 -18
- data/lib/boxgrinder-build/managers/operating-system-plugin-manager.rb +6 -0
- data/{bin/boxgrinder → lib/boxgrinder-build/managers/platform-plugin-manager.rb} +6 -3
- data/lib/boxgrinder-build/plugins/base-plugin.rb +98 -0
- data/lib/boxgrinder-build/plugins/delivery/base/base-delivery-plugin.rb +43 -0
- data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +57 -0
- data/lib/boxgrinder-build/{helpers → plugins/delivery/s3}/aws-helper.rb +0 -0
- data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +133 -0
- data/lib/boxgrinder-build/{helpers/ssh-helper.rb → plugins/delivery/sftp/sftp-plugin.rb} +61 -42
- data/lib/boxgrinder-build/{appliance-kickstart.rb → plugins/os/base/kickstart.rb} +45 -55
- data/lib/boxgrinder-build/{images/raw-image.rb → plugins/os/base/rpm-based-os-plugin.rb} +63 -60
- data/lib/boxgrinder-build/{erb → plugins/os/base/src}/appliance.ks.erb +2 -5
- data/{src → lib/boxgrinder-build/plugins/os/base/src}/base.repo +0 -0
- data/{src → lib/boxgrinder-build/plugins/os/base/src}/motd.init +0 -0
- data/lib/boxgrinder-build/{validators/appliance-dependency-validator.rb → plugins/os/base/validators/rpm-dependency-validator.rb} +1 -1
- data/lib/boxgrinder-build/{models/ssh-config.rb → plugins/os/base-operating-system-plugin.rb} +10 -17
- data/lib/boxgrinder-build/plugins/os/centos/centos-plugin.rb +72 -0
- data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +66 -0
- data/lib/boxgrinder-build/plugins/os/rhel/rhel-plugin.rb +38 -0
- data/lib/boxgrinder-build/plugins/platform/base-platform-plugin.rb +37 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +283 -0
- data/{src → lib/boxgrinder-build/plugins/platform/ec2/src}/f12/yum.conf +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/f12-i386-boxgrinder.repo +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/f12-x86_64-boxgrinder.repo +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/fstab_32bit +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/fstab_64bit +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/ifcfg-eth0 +0 -0
- data/{src/ec2 → lib/boxgrinder-build/plugins/platform/ec2/src}/rc_local +1 -4
- data/{src/README.vmware → lib/boxgrinder-build/plugins/platform/vmware/src/README} +10 -10
- data/{src → lib/boxgrinder-build/plugins/platform/vmware/src}/base.vmdk +1 -1
- data/{src → lib/boxgrinder-build/plugins/platform/vmware/src}/base.vmx +0 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +181 -0
- data/lib/boxgrinder-build/validators/config-validator.rb +0 -19
- metadata +73 -44
- data/docs/examples/appliances/appliances-appliance/appliances-appliance.appl +0 -6
- data/docs/examples/appliances/appliances-appliance/appliances-appliance.pp +0 -16
- data/docs/examples/appliances/minimal-appliance/minimal-appliance.appl +0 -2
- data/docs/examples/appliances/minimal-appliance/minimal-appliance.pp +0 -16
- data/docs/examples/appliances/mix-appliance/mix-appliance.appl +0 -9
- data/docs/examples/appliances/mix-appliance/mix-appliance.pp +0 -16
- data/docs/examples/appliances/packages-appliance/packages-appliance.appl +0 -6
- data/docs/examples/appliances/packages-appliance/packages-appliance.pp +0 -16
- data/extras/sign-rpms +0 -12
- data/lib/boxgrinder-build/boxgrinder.rb +0 -93
- data/lib/boxgrinder-build/helpers/release-helper.rb +0 -136
- data/lib/boxgrinder-build/images/ec2-image.rb +0 -317
- data/lib/boxgrinder-build/images/vmware-image.rb +0 -214
- data/lib/boxgrinder-build/validators/appliance-definition-validator.rb +0 -89
- data/lib/progressbar/progressbar.rb +0 -236
- data/src/oddthesis/RPM-GPG-KEY-oddthesis +0 -30
- data/src/oddthesis/oddthesis.repo +0 -23
@@ -0,0 +1,283 @@
|
|
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-build/plugins/platform/base-platform-plugin'
|
22
|
+
|
23
|
+
module BoxGrinder
|
24
|
+
class EC2Plugin < BasePlatformPlugin
|
25
|
+
def info
|
26
|
+
{
|
27
|
+
:name => :ec2,
|
28
|
+
:full_name => "Amazon Elastic Compute Cloud (Amazon EC2)"
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
SUPPORTED_OSES = {
|
33
|
+
'fedora' => ["11"]
|
34
|
+
}
|
35
|
+
|
36
|
+
REGIONS = {'us_east' => 'url'}
|
37
|
+
|
38
|
+
KERNELS = {
|
39
|
+
'us_east' => {
|
40
|
+
'fedora' => {
|
41
|
+
'11' => {
|
42
|
+
'i386' => {:aki => 'aki-a71cf9ce', :ari => 'ari-a51cf9cc', :rpm => 'http://repo.oddthesis.org/packages/other/kernel-xen-2.6.21.7-2.fc8.i686.rpm'},
|
43
|
+
'x86_64' => {:aki => 'aki-b51cf9dc', :ari => 'ari-b31cf9da', :rpm => 'http://repo.oddthesis.org/packages/other/kernel-xen-2.6.21.7-2.fc8.x86_64.rpm'}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
def after_init
|
50
|
+
@deliverables[:disk] = "#{@appliance_config.path.dir.build}/ec2/#{@appliance_config.name}.ec2"
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def supported_os
|
55
|
+
supported = ""
|
56
|
+
|
57
|
+
SUPPORTED_OSES.each_key do |os_name|
|
58
|
+
supported << "#{os_name}, versions: #{SUPPORTED_OSES[os_name].join(", ")}"
|
59
|
+
end
|
60
|
+
|
61
|
+
supported
|
62
|
+
end
|
63
|
+
|
64
|
+
def execute(raw_disk)
|
65
|
+
if File.exists?(@deliverables[:disk])
|
66
|
+
@log.info "EC2 image for #{@appliance_config.name} appliance already exists, skipping..."
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
unless SUPPORTED_OSES[@appliance_config.os.name].include?(@appliance_config.os.version)
|
71
|
+
@log.error "EC2 platform plugin for Linux operating systems supports: #{supported_os}. Your OS is #{@appliance_config.os.name} #{@appliance_config.os.version}."
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
FileUtils.mkdir_p File.dirname(@deliverables[:disk])
|
76
|
+
|
77
|
+
@log.info "Converting #{@appliance_config.name} appliance image to EC2 format..."
|
78
|
+
|
79
|
+
begin
|
80
|
+
ec2_prepare_disk
|
81
|
+
ec2_create_filesystem
|
82
|
+
rescue => e
|
83
|
+
raise "Error while preparing EC2 disk image. See logs for more info"
|
84
|
+
end
|
85
|
+
|
86
|
+
raw_disk_offset = calculate_disk_offset(raw_disk)
|
87
|
+
|
88
|
+
ec2_disk_mount_dir = "#{@appliance_config.path.dir.build}/tmp/ec2-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
|
89
|
+
raw_disk_mount_dir = "#{@appliance_config.path.dir.build}/tmp/raw-#{rand(9999999999).to_s.center(10, rand(9).to_s)}"
|
90
|
+
|
91
|
+
|
92
|
+
begin
|
93
|
+
ec2_loop_device = mount_image(@deliverables[:disk], ec2_disk_mount_dir)
|
94
|
+
raw_loop_device = mount_image(raw_disk, raw_disk_mount_dir, raw_disk_offset)
|
95
|
+
rescue => e
|
96
|
+
raise "Error while mounting image. See logs for more info"
|
97
|
+
end
|
98
|
+
|
99
|
+
sync_files(raw_disk_mount_dir, ec2_disk_mount_dir)
|
100
|
+
|
101
|
+
umount_image(raw_disk, raw_disk_mount_dir, raw_loop_device)
|
102
|
+
umount_image(@deliverables[:disk], ec2_disk_mount_dir, ec2_loop_device)
|
103
|
+
|
104
|
+
customize(@deliverables[:disk]) do |guestfs, guestfs_helper|
|
105
|
+
create_devices(guestfs)
|
106
|
+
upload_fstab(guestfs)
|
107
|
+
|
108
|
+
guestfs.mkdir("/data") if @appliance_config.is64bit?
|
109
|
+
|
110
|
+
enable_networking(guestfs)
|
111
|
+
upload_rc_local(guestfs)
|
112
|
+
|
113
|
+
guestfs_helper.rebuild_rpm_database
|
114
|
+
|
115
|
+
install_additional_packages(guestfs)
|
116
|
+
change_configuration(guestfs)
|
117
|
+
|
118
|
+
# if @appliance_config.os.name.eql?("fedora") and @appliance_config.os.version.to_s.eql?("12")
|
119
|
+
# @log.debug "Downgrading udev package to use in EC2 environment..."
|
120
|
+
#
|
121
|
+
# repo_included = false
|
122
|
+
#
|
123
|
+
# @appliance_config.repos.each do |repo|
|
124
|
+
# repo_included = true if repo['baseurl'] == "http://repo.boxgrinder.org/boxgrinder/packages/fedora/12/RPMS/#{@appliance_config.hardware.arch}"
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# guestfs.upload( "#{File.dirname( __FILE__ )}/src/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo", "/etc/yum.repos.d/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo" ) unless repo_included
|
128
|
+
# guestfs.sh( "yum -y downgrade udev-142" )
|
129
|
+
# guestfs.upload( "#{File.dirname( __FILE__ )}/src/f12/yum.conf", "/etc/yum.conf" )
|
130
|
+
# guestfs.rm_rf( "/etc/yum.repos.d/f12-#{@appliance_config.hardware.arch}-boxgrinder.repo" ) unless repo_included
|
131
|
+
#
|
132
|
+
# @log.debug "Package udev downgraded."
|
133
|
+
#
|
134
|
+
# # TODO EC2 fix, remove that after Fedora pushes kernels to Amazon
|
135
|
+
# @log.debug "Disabling unnecessary services..."
|
136
|
+
# guestfs.sh( "/sbin/chkconfig ksm off" ) if guestfs.exists( "/etc/init.d/ksm" ) != 0
|
137
|
+
# guestfs.sh( "/sbin/chkconfig ksmtuned off" ) if guestfs.exists( "/etc/init.d/ksmtuned" ) != 0
|
138
|
+
# @log.debug "Services disabled."
|
139
|
+
# end
|
140
|
+
end
|
141
|
+
|
142
|
+
@log.info "Image converted to EC2 format."
|
143
|
+
end
|
144
|
+
|
145
|
+
def ec2_prepare_disk
|
146
|
+
# TODO add progress bar?
|
147
|
+
# TODO using whole 10GB is fine?
|
148
|
+
@log.debug "Preparing disk for EC2 image..."
|
149
|
+
@exec_helper.execute "dd if=/dev/zero of=#{@deliverables[:disk]} bs=1 count=0 seek=#{10 * 1024}M"
|
150
|
+
@log.debug "Disk for EC2 image prepared"
|
151
|
+
end
|
152
|
+
|
153
|
+
def ec2_create_filesystem
|
154
|
+
@log.debug "Creating filesystem..."
|
155
|
+
@exec_helper.execute "mkfs.ext3 -F #{@deliverables[:disk]}"
|
156
|
+
@log.debug "Filesystem created"
|
157
|
+
end
|
158
|
+
|
159
|
+
def calculate_disk_offset(disk)
|
160
|
+
loop_device = get_loop_device
|
161
|
+
|
162
|
+
@exec_helper.execute("sudo losetup #{loop_device} #{disk}")
|
163
|
+
offset = @exec_helper.execute("sudo parted #{loop_device} 'unit B print' | grep Number -A 1 | tail -n 1 | awk '{ print $2 }'").strip.chop.scan(/^\d+/).to_s
|
164
|
+
@exec_helper.execute("sudo losetup -d #{loop_device}")
|
165
|
+
|
166
|
+
offset
|
167
|
+
end
|
168
|
+
|
169
|
+
def mount_image(disk, mount_dir, offset = 0)
|
170
|
+
loop_device = get_loop_device
|
171
|
+
|
172
|
+
@log.debug "Mounting image #{File.basename(disk)} in #{mount_dir} using #{loop_device} with offset #{offset}"
|
173
|
+
FileUtils.mkdir_p(mount_dir)
|
174
|
+
@exec_helper.execute("sudo losetup -o #{offset.to_s} #{loop_device} #{disk}")
|
175
|
+
@exec_helper.execute("sudo mount #{loop_device} -t ext3 #{ mount_dir}")
|
176
|
+
|
177
|
+
loop_device
|
178
|
+
end
|
179
|
+
|
180
|
+
def umount_image(disk, mount_dir, loop_device)
|
181
|
+
@log.debug "Unmounting image #{File.basename(disk)}"
|
182
|
+
@exec_helper.execute("sudo umount -d #{loop_device}")
|
183
|
+
FileUtils.rm_rf(mount_dir)
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
def sync_files(from_dir, to_dir)
|
188
|
+
@log.debug "Syncing files between #{from_dir} and #{to_dir}..."
|
189
|
+
@exec_helper.execute "sudo rsync -u -r -a #{from_dir}/* #{to_dir}"
|
190
|
+
@log.debug "Sync finished."
|
191
|
+
end
|
192
|
+
|
193
|
+
def cache_rpms(rpms)
|
194
|
+
for name in rpms.keys
|
195
|
+
cache_file = "#{@config.dir.src_cache}/#{name}"
|
196
|
+
|
197
|
+
if (!File.exist?(cache_file))
|
198
|
+
FileUtils.mkdir_p(@config.dir.src_cache)
|
199
|
+
@exec_helper.execute("wget #{rpms[name]} -O #{cache_file}")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def create_devices(guestfs)
|
205
|
+
@log.debug "Creating required devices..."
|
206
|
+
guestfs.sh("/sbin/MAKEDEV -d /dev -x console")
|
207
|
+
guestfs.sh("/sbin/MAKEDEV -d /dev -x null")
|
208
|
+
guestfs.sh("/sbin/MAKEDEV -d /dev -x zero")
|
209
|
+
@log.debug "Devices created."
|
210
|
+
end
|
211
|
+
|
212
|
+
def upload_fstab(guestfs)
|
213
|
+
@log.debug "Uploading '/etc/fstab' file..."
|
214
|
+
fstab_file = @appliance_config.is64bit? ? "#{File.dirname(__FILE__)}/src/fstab_64bit" : "#{File.dirname(__FILE__)}/src/fstab_32bit"
|
215
|
+
guestfs.upload(fstab_file, "/etc/fstab")
|
216
|
+
@log.debug "'/etc/fstab' file uploaded."
|
217
|
+
end
|
218
|
+
|
219
|
+
# enable networking on default runlevels
|
220
|
+
def enable_networking(guestfs)
|
221
|
+
@log.debug "Enabling networking..."
|
222
|
+
guestfs.sh("/sbin/chkconfig network on")
|
223
|
+
guestfs.upload("#{File.dirname(__FILE__)}/src/ifcfg-eth0", "/etc/sysconfig/network-scripts/ifcfg-eth0")
|
224
|
+
@log.debug "Networking enabled."
|
225
|
+
end
|
226
|
+
|
227
|
+
def upload_rc_local(guestfs)
|
228
|
+
@log.debug "Uploading '/etc/rc.local' file..."
|
229
|
+
rc_local = Tempfile.new('rc_local')
|
230
|
+
rc_local << guestfs.read_file("/etc/rc.local") + File.read("#{File.dirname(__FILE__)}/src/rc_local")
|
231
|
+
rc_local.flush
|
232
|
+
|
233
|
+
guestfs.upload(rc_local.path, "/etc/rc.local")
|
234
|
+
|
235
|
+
rc_local.close
|
236
|
+
@log.debug "'/etc/rc.local' file uploaded."
|
237
|
+
end
|
238
|
+
|
239
|
+
def install_additional_packages(guestfs)
|
240
|
+
rpms = {
|
241
|
+
"ec2-ami-tools.noarch.rpm" => "http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm"
|
242
|
+
}
|
243
|
+
|
244
|
+
kernel_rpm = KERNELS['us_east'][@appliance_config.os.name][@appliance_config.os.version][@appliance_config.hardware.arch][:rpm]
|
245
|
+
rpms[File.basename(kernel_rpm)] = kernel_rpm unless kernel_rpm.nil?
|
246
|
+
|
247
|
+
cache_rpms(rpms)
|
248
|
+
|
249
|
+
@log.debug "Installing additional packages (#{rpms.keys.join(", ")})..."
|
250
|
+
guestfs.mkdir_p("/tmp/rpms")
|
251
|
+
|
252
|
+
for name in rpms.keys
|
253
|
+
cache_file = "#{@config.dir.src_cache}/#{name}"
|
254
|
+
guestfs.upload(cache_file, "/tmp/rpms/#{name}")
|
255
|
+
end
|
256
|
+
|
257
|
+
guestfs.sh("rpm -Uvh --nodeps /tmp/rpms/*.rpm")
|
258
|
+
guestfs.rm_rf("/tmp/rpms")
|
259
|
+
@log.debug "Additional packages installed."
|
260
|
+
end
|
261
|
+
|
262
|
+
def change_configuration(guestfs)
|
263
|
+
@log.debug "Changing configuration files using augeas..."
|
264
|
+
guestfs.aug_init("/", 0)
|
265
|
+
# disable password authentication
|
266
|
+
guestfs.aug_set("/files/etc/ssh/sshd_config/PasswordAuthentication", "no")
|
267
|
+
guestfs.aug_save
|
268
|
+
@log.debug "Augeas changes saved."
|
269
|
+
end
|
270
|
+
|
271
|
+
def get_loop_device
|
272
|
+
begin
|
273
|
+
loop_device = @exec_helper.execute("sudo losetup -f 2>&1").strip
|
274
|
+
rescue
|
275
|
+
raise "No free loop devices available, please free at least one. See 'losetup -d' command."
|
276
|
+
end
|
277
|
+
|
278
|
+
loop_device
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
end
|
283
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,6 +1,3 @@
|
|
1
|
-
|
2
|
-
homes=`find /home/* -maxdepth 0 -type d | tr '\n' ' '`
|
3
|
-
|
4
1
|
curl http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key 2>/dev/null >/tmp/my-key
|
5
2
|
|
6
3
|
if [ $? -eq 0 ] ; then
|
@@ -13,7 +10,7 @@ if [ $? -eq 0 ] ; then
|
|
13
10
|
cat /tmp/my-key >> /root/.ssh/authorized_keys
|
14
11
|
chmod 600 /root/.ssh/authorized_keys
|
15
12
|
|
16
|
-
for home in
|
13
|
+
for home in `find /home/* -maxdepth 0 -type d 2>/dev/null | tr '\n' ' '`; do
|
17
14
|
user=`echo $home | awk -F '/' '{ print $3 }'`
|
18
15
|
|
19
16
|
if [ ! -d $home/.ssh ] ; then
|
@@ -8,15 +8,15 @@ VMware Personal (VMware Fusion, VMware Server, VMware Player)
|
|
8
8
|
Required files:
|
9
9
|
---------------
|
10
10
|
|
11
|
-
#APPLIANCE_NAME
|
12
|
-
personal
|
13
|
-
personal
|
11
|
+
#APPLIANCE_NAME#.raw
|
12
|
+
#APPLIANCE_NAME#-personal.vmx
|
13
|
+
#APPLIANCE_NAME#-personal.vmdk
|
14
14
|
|
15
15
|
Required steps:
|
16
16
|
---------------
|
17
17
|
|
18
|
-
1. Extract
|
19
|
-
2. Add #APPLIANCE_NAME
|
18
|
+
1. Extract required files into one directory.
|
19
|
+
2. Add #APPLIANCE_NAME#-personal.vmx to inventory.
|
20
20
|
3. Run appliance.
|
21
21
|
|
22
22
|
VMware Enterprise (VMware ESX/ESXi/, VMware vSphere)
|
@@ -25,14 +25,14 @@ VMware Enterprise (VMware ESX/ESXi/, VMware vSphere)
|
|
25
25
|
Required files:
|
26
26
|
---------------
|
27
27
|
|
28
|
-
#APPLIANCE_NAME
|
29
|
-
enterprise
|
30
|
-
enterprise
|
28
|
+
#APPLIANCE_NAME#.raw
|
29
|
+
#APPLIANCE_NAME#-enterprise.vmx
|
30
|
+
#APPLIANCE_NAME#-enterprise.vmdk
|
31
31
|
|
32
32
|
Required steps:
|
33
33
|
---------------
|
34
34
|
|
35
|
-
1. Extract
|
35
|
+
1. Extract required files into one directory.
|
36
36
|
2. Upload all files to ESX server using vSpehere/VI client.
|
37
|
-
3. Add #APPLIANCE_NAME
|
37
|
+
3. Add #APPLIANCE_NAME#-enterprise.vmx to inventory.
|
38
38
|
4. Run appliance.
|
File without changes
|
@@ -0,0 +1,181 @@
|
|
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-build/plugins/platform/base-platform-plugin'
|
22
|
+
require 'boxgrinder-build/helpers/appliance-customize-helper'
|
23
|
+
|
24
|
+
module BoxGrinder
|
25
|
+
class VMwarePlugin < BasePlatformPlugin
|
26
|
+
def info
|
27
|
+
{
|
28
|
+
:name => :vmware,
|
29
|
+
:full_name => "VMware"
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_init
|
34
|
+
@deliverables[:disk] = "#{@appliance_config.path.dir.build}/vmware/#{@appliance_config.name}.raw"
|
35
|
+
|
36
|
+
@deliverables[:metadata] = {
|
37
|
+
:vmx_enterprise => "#{@appliance_config.path.dir.build}/vmware/#{@appliance_config.name}-enterprise.vmx",
|
38
|
+
:vmdk_enterprise => "#{@appliance_config.path.dir.build}/vmware/#{@appliance_config.name}-enterprise.vmdk",
|
39
|
+
:vmx_personal => "#{@appliance_config.path.dir.build}/vmware/#{@appliance_config.name}-personal.vmx",
|
40
|
+
:vmdk_personal => "#{@appliance_config.path.dir.build}/vmware/#{@appliance_config.name}-personal.vmdk"
|
41
|
+
}
|
42
|
+
|
43
|
+
@deliverables[:other] = {
|
44
|
+
:readme => "#{@appliance_config.path.dir.build}/vmware/README"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def execute( base_image_path )
|
50
|
+
@log.info "Converting image to VMware format..."
|
51
|
+
@log.debug "Copying VMware image file, this may take several minutes..."
|
52
|
+
|
53
|
+
FileUtils.mkdir_p File.dirname( @deliverables[:disk] )
|
54
|
+
|
55
|
+
@exec_helper.execute "cp #{base_image_path} #{@deliverables[:disk]}" if ( !File.exists?( @deliverables[:disk] ) || File.new( base_image_path ).mtime > File.new( @deliverables[:disk] ).mtime )
|
56
|
+
|
57
|
+
@log.debug "VMware image copied."
|
58
|
+
|
59
|
+
if @appliance_config.post.vmware.size > 0
|
60
|
+
customize( @deliverables[:disk] ) do |guestfs, guestfs_helper|
|
61
|
+
@appliance_config.post.vmware.each do |cmd|
|
62
|
+
@log.debug "Executing #{cmd}"
|
63
|
+
guestfs.sh( cmd )
|
64
|
+
end
|
65
|
+
@log.debug "Post commands from appliance definition file executed."
|
66
|
+
end
|
67
|
+
else
|
68
|
+
@log.debug "No commands specified, skipping."
|
69
|
+
end
|
70
|
+
|
71
|
+
build_vmware_enterprise
|
72
|
+
build_vmware_personal
|
73
|
+
|
74
|
+
readme = File.open( "#{File.dirname(__FILE__)}/src/README" ).read
|
75
|
+
readme.gsub!( /#APPLIANCE_NAME#/, @appliance_config.name )
|
76
|
+
readme.gsub!( /#NAME#/, @config.name )
|
77
|
+
readme.gsub!( /#VERSION#/, @config.version_with_release )
|
78
|
+
|
79
|
+
File.open( @deliverables[:other][:readme], "w") {|f| f.write( readme ) }
|
80
|
+
|
81
|
+
@log.info "Image converted to VMware format."
|
82
|
+
end
|
83
|
+
|
84
|
+
# returns value of cylinders, heads and sector for selected disk size (in GB)
|
85
|
+
|
86
|
+
def generate_scsi_chs(disk_size)
|
87
|
+
disk_size = (disk_size * 1024).to_i
|
88
|
+
|
89
|
+
gb_sectors = 2097152
|
90
|
+
|
91
|
+
if disk_size <= 1024
|
92
|
+
h = 128
|
93
|
+
s = 32
|
94
|
+
else
|
95
|
+
h = 255
|
96
|
+
s = 63
|
97
|
+
end
|
98
|
+
|
99
|
+
c = disk_size / 1024 * gb_sectors / (h*s)
|
100
|
+
total_sectors = gb_sectors * disk_size / 1024
|
101
|
+
|
102
|
+
return [ c, h, s, total_sectors ]
|
103
|
+
end
|
104
|
+
|
105
|
+
def change_vmdk_values( type )
|
106
|
+
vmdk_data = File.open( "#{File.dirname( __FILE__ )}/src/base.vmdk" ).read
|
107
|
+
|
108
|
+
disk_size = 0.0
|
109
|
+
@appliance_config.hardware.partitions.values.each { |part| disk_size += part['size'].to_f }
|
110
|
+
|
111
|
+
c, h, s, total_sectors = generate_scsi_chs( disk_size )
|
112
|
+
|
113
|
+
is_enterprise = type.eql?("vmfs")
|
114
|
+
|
115
|
+
vmdk_data.gsub!( /#NAME#/, @appliance_config.name )
|
116
|
+
vmdk_data.gsub!( /#TYPE#/, type )
|
117
|
+
vmdk_data.gsub!( /#EXTENT_TYPE#/, is_enterprise ? "VMFS" : "FLAT" )
|
118
|
+
vmdk_data.gsub!( /#NUMBER#/, is_enterprise ? "" : "0" )
|
119
|
+
vmdk_data.gsub!( /#HW_VERSION#/, is_enterprise ? "4" : "3" )
|
120
|
+
vmdk_data.gsub!( /#CYLINDERS#/, c.to_s )
|
121
|
+
vmdk_data.gsub!( /#HEADS#/, h.to_s )
|
122
|
+
vmdk_data.gsub!( /#SECTORS#/, s.to_s )
|
123
|
+
vmdk_data.gsub!( /#TOTAL_SECTORS#/, total_sectors.to_s )
|
124
|
+
|
125
|
+
vmdk_data
|
126
|
+
end
|
127
|
+
|
128
|
+
def change_common_vmx_values
|
129
|
+
vmx_data = File.open( "#{File.dirname( __FILE__ )}/src/base.vmx" ).read
|
130
|
+
|
131
|
+
# replace version with current appliance version
|
132
|
+
vmx_data.gsub!( /#VERSION#/, "#{@appliance_config.version}.#{@appliance_config.release}" )
|
133
|
+
# replace builder with current builder name and version
|
134
|
+
vmx_data.gsub!( /#BUILDER#/, "#{@config.name} #{@config.version_with_release}" )
|
135
|
+
# change name
|
136
|
+
vmx_data.gsub!( /#NAME#/, @appliance_config.name.to_s )
|
137
|
+
# and summary
|
138
|
+
vmx_data.gsub!( /#SUMMARY#/, @appliance_config.summary.to_s )
|
139
|
+
# replace guestOS informations to: linux or otherlinux-64, this seems to be the savests values
|
140
|
+
vmx_data.gsub!( /#GUESTOS#/, "#{@appliance_config.hardware.arch == "x86_64" ? "otherlinux-64" : "linux"}" )
|
141
|
+
# memory size
|
142
|
+
vmx_data.gsub!( /#MEM_SIZE#/, @appliance_config.hardware.memory.to_s )
|
143
|
+
# memory size
|
144
|
+
vmx_data.gsub!( /#VCPU#/, @appliance_config.hardware.cpus.to_s )
|
145
|
+
# network name
|
146
|
+
# vmx_data.gsub!( /#NETWORK_NAME#/, @image_config.network_name )
|
147
|
+
|
148
|
+
vmx_data
|
149
|
+
end
|
150
|
+
|
151
|
+
def build_vmware_personal
|
152
|
+
@log.debug "Building VMware personal image."
|
153
|
+
|
154
|
+
# create .vmx file
|
155
|
+
File.open( @deliverables[:metadata][:vmx_personal], "w" ) {|f| f.write( change_common_vmx_values ) }
|
156
|
+
|
157
|
+
# create disk descriptor file
|
158
|
+
File.open( @deliverables[:metadata][:vmdk_personal], "w" ) {|f| f.write( change_vmdk_values( "monolithicFlat" ) ) }
|
159
|
+
|
160
|
+
@log.debug "VMware personal image was built."
|
161
|
+
end
|
162
|
+
|
163
|
+
def build_vmware_enterprise
|
164
|
+
@log.debug "Building VMware enterprise image."
|
165
|
+
|
166
|
+
# defaults for ESXi (maybe for others too)
|
167
|
+
@appliance_config.hardware.network = "VM Network" if @appliance_config.hardware.network.eql?( "NAT" )
|
168
|
+
|
169
|
+
# create .vmx file
|
170
|
+
vmx_data = change_common_vmx_values
|
171
|
+
vmx_data += "ethernet0.networkName = \"#{@appliance_config.hardware.network}\""
|
172
|
+
|
173
|
+
File.open( @deliverables[:metadata][:vmx_enterprise], "w" ) {|f| f.write( vmx_data ) }
|
174
|
+
|
175
|
+
# create disk descriptor file
|
176
|
+
File.open( @deliverables[:metadata][:vmdk_enterprise], "w" ) {|f| f.write( change_vmdk_values( "vmfs" ) ) }
|
177
|
+
|
178
|
+
@log.debug "VMware enterprise image was built."
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -29,7 +29,6 @@ module BoxGrinder
|
|
29
29
|
|
30
30
|
def validate
|
31
31
|
validate_common
|
32
|
-
validate_vmware_files
|
33
32
|
validate_appliance_dir
|
34
33
|
end
|
35
34
|
|
@@ -45,23 +44,5 @@ module BoxGrinder
|
|
45
44
|
def validate_appliance_dir
|
46
45
|
raise ValidationError, "Appliances directory '#{@config.dir.appliances}' doesn't exists, please create it: 'mkdir -p #{@config.dir.appliances}'." if !File.exists?(File.dirname( @config.dir.appliances )) && !File.directory?(File.dirname( @config.dir.appliances ))
|
47
46
|
end
|
48
|
-
|
49
|
-
def validate_vmware_files
|
50
|
-
if File.exists?( "#{@config.dir.src}/base.vmdk" )
|
51
|
-
@config.files.base_vmdk = "#{@config.dir.src}/base.vmdk"
|
52
|
-
else
|
53
|
-
@config.files.base_vmdk = "#{@config.dir.base}/src/base.vmdk"
|
54
|
-
end
|
55
|
-
|
56
|
-
raise ValidationError, "base.vmdk file doesn't exists, please check you configuration)" unless File.exists?( @config.files.base_vmdk )
|
57
|
-
|
58
|
-
if File.exists?( "#{@config.dir.src}/base.vmx" )
|
59
|
-
@config.files.base_vmx = "#{@config.dir.src}/base.vmx"
|
60
|
-
else
|
61
|
-
@config.files.base_vmx = "#{@config.dir.base}/src/base.vmx"
|
62
|
-
end
|
63
|
-
|
64
|
-
raise ValidationError, "base.vmx file doesn't exists, please check you configuration)" unless File.exists?( @config.files.base_vmx )
|
65
|
-
end
|
66
47
|
end
|
67
48
|
end
|