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.
- data/CHANGELOG +14 -0
- data/README.md +136 -0
- data/Rakefile +11 -6
- data/bin/boxgrinder-build +199 -0
- data/boxgrinder-build.gemspec +26 -14
- data/lib/boxgrinder-build/appliance.rb +6 -6
- data/lib/boxgrinder-build/helpers/guestfs-helper.rb +5 -3
- data/lib/boxgrinder-build/helpers/image-helper.rb +6 -0
- data/lib/boxgrinder-build/helpers/plugin-helper.rb +15 -4
- data/lib/boxgrinder-build/plugins/base-plugin.rb +1 -0
- data/lib/boxgrinder-build/plugins/delivery/ebs/ebs-plugin.rb +280 -0
- data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +66 -0
- data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +242 -0
- data/lib/boxgrinder-build/plugins/delivery/s3/src/cert-ec2.pem +23 -0
- data/lib/boxgrinder-build/plugins/delivery/sftp/sftp-plugin.rb +152 -0
- data/lib/boxgrinder-build/plugins/delivery/usb/usb-plugin.rb +43 -0
- data/lib/boxgrinder-build/plugins/os/centos/centos-plugin.rb +46 -0
- data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +61 -0
- data/lib/boxgrinder-build/plugins/os/rhel/rhel-plugin.rb +67 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/kickstart.rb +118 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-based-os-plugin.rb +202 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-dependency-validator.rb +153 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/src/appliance.ks.erb +37 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/src/base.repo +4 -0
- data/lib/boxgrinder-build/plugins/os/rpm-based/src/motd.init +21 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +239 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_32bit +7 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_64bit +7 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/src/ifcfg-eth0 +7 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/src/menu.lst +6 -0
- data/lib/boxgrinder-build/plugins/platform/ec2/src/rc_local +19 -0
- data/lib/boxgrinder-build/plugins/platform/virtualbox/virtualbox-plugin.rb +62 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/src/README-enterprise +18 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/src/README-personal +16 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmdk +20 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmx +45 -0
- data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +194 -0
- data/rubygem-boxgrinder-build.spec +73 -10
- data/spec/appliance-spec.rb +2 -2
- data/spec/helpers/guestfs-helper-spec.rb +4 -2
- data/spec/helpers/image-helper-spec.rb +4 -0
- data/spec/helpers/plugin-helper-spec.rb +0 -38
- data/spec/managers/plugin-manager-spec.rb +6 -6
- data/spec/plugins/delivery/ebs/ebs-plugin-spec.rb +230 -0
- data/spec/plugins/delivery/ebs/ebs.yaml +3 -0
- data/spec/plugins/delivery/local/local-plugin-spec.rb +133 -0
- data/spec/plugins/delivery/s3/s3-plugin-spec.rb +351 -0
- data/spec/plugins/delivery/sftp/sftp-plugin-spec.rb +26 -0
- data/spec/plugins/os/centos/centos-plugin-spec.rb +52 -0
- data/spec/plugins/os/fedora/fedora-plugin-spec.rb +73 -0
- data/spec/plugins/os/rhel/rhel-plugin-spec.rb +158 -0
- data/spec/plugins/os/rpm-based/kickstart-spec.rb +129 -0
- data/spec/plugins/os/rpm-based/rpm-based-os-plugin-spec.rb +162 -0
- data/spec/plugins/os/rpm-based/rpm-dependency-validator-spec.rb +50 -0
- data/spec/plugins/os/rpm-based/src/jeos-f13-plain.ks +20 -0
- data/spec/plugins/os/rpm-based/src/jeos-f13-without-version.ks +22 -0
- data/spec/plugins/os/rpm-based/src/jeos-f13.ks +23 -0
- data/spec/plugins/platform/ec2/ec2-plugin-spec.rb +339 -0
- data/spec/plugins/platform/virtualbox/virtualbox-plugin-spec.rb +118 -0
- data/spec/plugins/platform/vmware/vmware-plugin-spec.rb +299 -0
- metadata +149 -25
- data/README +0 -7
- data/bin/boxgrinder +0 -128
- 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,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,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"
|