Merge lp:~zulcss/vmbuilder/vmbuilder-ec2-chuck into lp:vmbuilder/trunk

Proposed by Soren Hansen
Status: Needs review
Proposed branch: lp:~zulcss/vmbuilder/vmbuilder-ec2-chuck
Merge into: lp:vmbuilder/trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~zulcss/vmbuilder/vmbuilder-ec2-chuck
Reviewer Review Type Date Requested Status
Soren Hansen Pending
Review via email: mp+6151@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Soren Hansen (soren) wrote :

Chuck,

lp:~zulcss/vmbuilder/vmbuilder-ec2-chuck adds ec2-ami-tools, ncurses-term, ruby, libopenssl-ruby, and curl to the list of packages to install. Can you explain what purpose ncurses-term, ruby, libopenssl-ruby, and curl serve?

Why do you explicitly mount /sys on EC2? Doesn't mountkernfs.sh do that for you?

I don't understand the first chunk of changes to VMBuilder/plugins/ubuntu/distro.py in http://bazaar.launchpad.net/~zulcss/vmbuilder/vmbuilder-ec2-chuck/revision/294 Why does the choice of components depend on whether a ppa was defined?

Unmerged revisions

294. By Chuck Short

add support for multiverse

293. By Chuck Short

more multiverse

292. By Chuck Short

Add multiverse

291. By Chuck Short

move console inline with amazon.

290. By Chuck Short

Add ec2-ami-tools to the ec2-image.

289. By Chuck Short

added example part files.

288. By Chuck Short

no changes from this commit.

287. By Chuck Short

yarp yarp

286. By Chuck Short

password stuff

285. By Nick Barcet

update help and man

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'VMBuilder/disk.py'
2--- VMBuilder/disk.py 2008-10-20 12:42:42 +0000
3+++ VMBuilder/disk.py 2008-11-12 17:28:29 +0000
4@@ -32,6 +32,7 @@
5 TYPE_EXT3 = 1
6 TYPE_XFS = 2
7 TYPE_SWAP = 3
8+TYPE_SYSFS = 4
9
10 class Disk(object):
11 def __init__(self, vm, size='5G', preallocated=False, filename=None):
12@@ -207,7 +208,7 @@
13 @rtype: string
14 @return: the filesystem type of the partition suitable for passing to parted
15 """
16- return { TYPE_EXT2: 'ext2', TYPE_EXT3: 'ext2', TYPE_XFS: 'ext2', TYPE_SWAP: 'linux-swap' }[self.type]
17+ return { TYPE_EXT2: 'ext2', TYPE_EXT3: 'ext2', TYPE_XFS: 'ext2', TYPE_SWAP: 'linux-swap', TYPE_SYSFS: 'sysfs' }[self.type]
18
19 def create(self, disk):
20 """Adds partition to the disk image (does not mkfs or anything like that)"""
21@@ -235,12 +236,14 @@
22 return self.disk.partitions.index(self)
23
24 class Filesystem(object):
25- def __init__(self, vm, size=0, preallocated=False, type=None, mntpnt=None, filename=None, devletter='a'):
26+ def __init__(self, vm, size=0, preallocated=False, type=None, mntpnt=None, filename=None, devletter='a', device=''):
27 self.vm = vm
28 self.filename = filename
29 self.size = parse_size(size)
30 self.preallocated = preallocated
31 self.devletter = devletter
32+ self.device = device
33+ self.dummy = (self.preallocated and (self.size == 0))
34
35 try:
36 if int(type) == type:
37@@ -253,7 +256,7 @@
38 self.mntpnt = mntpnt
39
40 def create(self):
41- logging.info('Creating filesystem')
42+ logging.info('Creating filesystem %s %d %s' % (self.mntpnt, self.size, self.dummy))
43 if not self.preallocated:
44 logging.info('Not preallocated, so we create it.')
45 if not self.filename:
46@@ -276,9 +279,10 @@
47 self.mkfs()
48
49 def mkfs(self):
50- cmd = self.mkfs_fstype() + [self.filename]
51- run_cmd(*cmd)
52- self.uuid = run_cmd('vol_id', '--uuid', self.filename).rstrip()
53+ if not self.dummy:
54+ cmd = self.mkfs_fstype() + [self.filename]
55+ run_cmd(*cmd)
56+ self.uuid = run_cmd('vol_id', '--uuid', self.filename).rstrip()
57
58 def mkfs_fstype(self):
59 if self.vm.suite in ['dapper', 'edgy', 'feisty', 'gutsy']:
60@@ -289,13 +293,13 @@
61 return { TYPE_EXT2: ['mkfs.ext2', '-F'], TYPE_EXT3: ['mkfs.ext3', '-F'], TYPE_XFS: ['mkfs.xfs'], TYPE_SWAP: ['mkswap'] }[self.type]
62
63 def fstab_fstype(self):
64- return { TYPE_EXT2: 'ext2', TYPE_EXT3: 'ext3', TYPE_XFS: 'xfs', TYPE_SWAP: 'swap' }[self.type]
65+ return { TYPE_EXT2: 'ext2', TYPE_EXT3: 'ext3', TYPE_XFS: 'xfs', TYPE_SWAP: 'swap', TYPE_SYSFS: 'sysfs' }[self.type]
66
67 def fstab_options(self):
68 return 'defaults'
69
70 def mount(self):
71- if self.type != TYPE_SWAP:
72+ if (self.type != TYPE_SWAP) and not self.dummy:
73 logging.debug('Mounting %s', self.mntpnt)
74 self.mntpath = '%s%s' % (self.vm.rootmnt, self.mntpnt)
75 if not os.path.exists(self.mntpath):
76@@ -305,15 +309,18 @@
77
78 def umount(self):
79 self.vm.cancel_cleanup(self.umount)
80- if self.type != TYPE_SWAP:
81+ if (self.type != TYPE_SWAP) and not self.dummy:
82 logging.debug('Unmounting %s', self.mntpath)
83 run_cmd('umount', self.mntpath)
84
85 def get_suffix(self):
86 """Returns 'a4' for a device that would be called /dev/sda4 in the guest..
87 This allows other parts of VMBuilder to set the prefix to something suitable."""
88- return '%s%d' % (self.devletters(), self.get_index() + 1)
89-
90+ if self.device:
91+ return self.device
92+ else:
93+ return '%s%d' % (self.devletters(), self.get_index() + 1)
94+
95 def devletters(self):
96 """
97 @rtype: string
98@@ -349,7 +356,8 @@
99 'ext3': TYPE_EXT3,
100 'xfs': TYPE_XFS,
101 'swap': TYPE_SWAP,
102- 'linux-swap': TYPE_SWAP }
103+ 'linux-swap': TYPE_SWAP,
104+ 'sysfs': TYPE_SYSFS }
105
106 def str_to_type(type):
107 try:
108
109=== modified file 'VMBuilder/plugins/__init__.py'
110--- VMBuilder/plugins/__init__.py 2008-09-29 12:28:03 +0000
111+++ VMBuilder/plugins/__init__.py 2008-11-27 21:03:58 +0000
112@@ -19,6 +19,7 @@
113 #
114 import os
115 import VMBuilder
116+from VMBuilder.util import run_cmd
117
118 def load_plugins():
119 for plugin in find_plugins():
120@@ -67,4 +68,11 @@
121 return False
122
123 def install_from_template(self, path, tmplname, context=None, mode=None):
124+ if not self.vm.fsmounted:
125+ raise VMBuilderException('install_from_template called while file system is not mounted')
126 return self.vm.install_file(path, VMBuilder.util.render_template(self.__module__.split('.')[2], self.vm, tmplname, context), mode=mode)
127+
128+ def run_in_target(self, *args, **kwargs):
129+ if not self.vm.fsmounted:
130+ raise VMBuilderException('install_from_template called while file system is not mounted')
131+ return run_cmd('chroot', self.vm.installdir, *args, **kwargs)
132
133=== modified file 'VMBuilder/plugins/cli/__init__.py'
134--- VMBuilder/plugins/cli/__init__.py 2008-10-23 21:11:22 +0000
135+++ VMBuilder/plugins/cli/__init__.py 2008-11-12 19:13:07 +0000
136@@ -46,7 +46,22 @@
137 vm.register_setting('--optsize', metavar='SIZE', type='int', default=0, help='Size (in MB) of the /opt filesystem. If not set, no /opt filesystem will be added.')
138 vm.register_setting('--swapsize', metavar='SIZE', type='int', default=1024, help='Size (in MB) of the swap partition [default: %default]')
139 vm.register_setting('--raw', metavar='PATH', type='string', help="Specify a file (or block device) to as first disk image.")
140- vm.register_setting('--part', metavar='PATH', type='string', help="Allows to specify a partition table in PATH each line of partfile should specify (root first): \n mountpoint size \none per line, separated by space, where size is in megabytes. You can have up to 4 virtual disks, a new disk starts on a line containing only '---'. ie: \n root 2000 \n /boot 512 \n swap 1000 \n --- \n /var 8000 \n /var/log 2000")
141+ vm.register_setting('--part', metavar='PATH', type='string', help="Allows to specify a partition table in PATH each line of partfile should specify (root first): \n \
142+ mountpoint size \n \
143+one per line, separated by space, where size is in megabytes. You can have up to 4 virtual disks, a new disk starts on a line containing only '---'. ie: \n \
144+ root 2000 \n \
145+ /boot 512 \n \
146+ swap 1000 \n \
147+ --- \n \
148+ /var 8000 \n \
149+ /var/log 2000 \n \
150+FSIMAGE partitions (Xen) also supports an addition third parameter which is the suffix of the device name that should be used ('a1' for /dev/sda1). \n \
151+For FSIMAGE, partitions which are declared with a size of 0 will be treated as fs to add at runtime but which do not need to be created by vmbuilder. ie: \n \
152+ root 4096 a1 \n \
153+ /mnt 0 b \n \
154+ /sys 0 \n \
155+FSIMAGE is not designed to use 'disks' as it does not have partition tables, so '---' will just be ignored.")
156+
157 self.set_usage(vm)
158
159 vm.optparser.disable_interspersed_args()
160@@ -103,16 +118,20 @@
161 if vm.hypervisor.preferred_storage == VMBuilder.hypervisor.STORAGE_FS_IMAGE:
162 try:
163 for line in file(vm.part):
164- pair = line.strip().split(' ',1)
165- if pair[0] == 'root':
166- vm.add_filesystem(pair[1], type='ext3', mntpnt='/')
167- elif pair[0] == 'swap':
168- vm.add_filesystem(pair[1], type='swap', mntpnt=None)
169- elif pair[0] == '---':
170+ elements = line.strip().split(' ')
171+ if elements[0] == 'root':
172+ vm.add_filesystem(elements[1], type='ext3', mntpnt='/')
173+ elif elements[0] == 'swap':
174+ vm.add_filesystem(elements[1], type='swap', mntpnt=None)
175+ elif elements[0] == '---':
176 # We just ignore the user's attempt to specify multiple disks
177 pass
178+ elif elements[0] == '/sys':
179+ vm.add_filesystem(elements[1], type='sysfs', mntpnt=elements[0], preallocated=True)
180+ elif len(elements) == 3:
181+ vm.add_filesystem(elements[1], type='ext3', mntpnt=elements[0], devletter='', device=elements[2], preallocated=(int(elements[1]) == 0))
182 else:
183- vm.add_filesystem(pair[1], type='ext3', mntpnt=pair[0])
184+ vm.add_filesystem(elements[1], type='ext3', mntpnt=elements[0])
185
186 except IOError, (errno, strerror):
187 vm.optparser.error("%s parsing --part option: %s" % (errno, strerror))
188
189=== modified file 'VMBuilder/plugins/ec2/__init__.py'
190--- VMBuilder/plugins/ec2/__init__.py 2008-10-23 21:11:22 +0000
191+++ VMBuilder/plugins/ec2/__init__.py 2008-12-18 13:02:30 +0000
192@@ -60,16 +60,16 @@
193 if not self.vm.ec2_kernel:
194 logging.debug('No ec2-aki choosen setting to default. Use --ec2-kernel to change this')
195 if self.vm.arch == 'amd64':
196- self.vm.ec2_kernel = 'aki-a53adfcc'
197+ self.vm.ec2_kernel = 'aki-d314f0ba'
198 else:
199- self.vm.ec2_kernel = 'aki-a71cf9ce'
200+ self.vm.ec2_kernel = 'aki-af14f0c6'
201
202 if not self.vm.ec2_ramdisk:
203 logging.debug('No ec2-ari choosen setting to default. Use --ec2-ramdisk to change this.')
204 if self.vm.arch == 'amd64':
205- self.vm.ec2_ramdisk = 'ari-b31cf9da'
206+ self.vm.ec2_ramdisk = 'ari-d014f0b9'
207 else:
208- self.vm.ec2_ramdisk = 'ari-a51cf9cc'
209+ self.vm.ec2_ramdisk = 'ari-ac14f0c5'
210
211 if not self.vm.ec2_bucket:
212 raise VMBuilderUserError('When building for EC2 you must provide an S3 bucket to hold the AMI')
213@@ -84,7 +84,25 @@
214 if not self.vm.addpkg:
215 self.vm.addpkg = []
216
217+ self.vm.addpkg += ['openssh-server']
218 self.vm.addpkg += ['ec2-init']
219+ self.vm.addpkg += ['openssh-server']
220+ self.vm.addpkg += ['ec2-modules']
221+ self.vm.addpkg += ['server^']
222+ self.vm.addpkg += ['standard^']
223+ self.vm.addpkg += ['ec2-ami-tools']
224+ self.vm.addpkg += ['ncurses-term']
225+ self.vm.addpkg += ['ruby', 'libopenssl-ruby', 'curl']
226+
227+ if not self.vm.ppa:
228+ self.vm.ppa = []
229+
230+ self.vm.ppa += ['ubuntu-ec2']
231+
232+ def post_install(self):
233+ logging.info("Running ec2 postinstall")
234+ self.install_from_template('/etc/event.d/xvc0', 'upstart')
235+ self.run_in_target('passwd', '-l', self.vm.user)
236
237 def deploy(self):
238 if not self.vm.ec2:
239@@ -94,7 +112,7 @@
240
241 run_cmd(*bundle_cmdline)
242
243- upload_cmdline = ['ec2-upload-bundle', '--manifest', '%s/%s.manifest.xml' % (self.vm.workdir, self.vm.ec2_name), '--bucket', self.vm.ec2_bucket, '--access-key', self.vm.ec2_access_key, '--secret-key', self.vm.ec2_secret_key]
244+ upload_cmdline = ['ec2-upload-bundle', '--retry', '--manifest', '%s/%s.manifest.xml' % (self.vm.workdir, self.vm.ec2_name), '--bucket', self.vm.ec2_bucket, '--access-key', self.vm.ec2_access_key, '--secret-key', self.vm.ec2_secret_key]
245 run_cmd(*upload_cmdline)
246
247 from boto.ec2.connection import EC2Connection
248
249=== added directory 'VMBuilder/plugins/ec2/templates'
250=== added file 'VMBuilder/plugins/ec2/templates/upstart.tmpl'
251--- VMBuilder/plugins/ec2/templates/upstart.tmpl 1970-01-01 00:00:00 +0000
252+++ VMBuilder/plugins/ec2/templates/upstart.tmpl 2008-12-17 17:04:38 +0000
253@@ -0,0 +1,16 @@
254+# tty1 - getty
255+#
256+# This service maintains a getty on tty1 from the point the system is
257+# started until it is shut down again.
258+
259+start on stopped rc2
260+start on stopped rc3
261+start on stopped rc4
262+start on stopped rc5
263+
264+stop on runlevel 0
265+stop on runlevel 1
266+stop on runlevel 6
267+
268+respawn
269+exec /sbin/getty 38400 xvc0 vt100-nav
270
271=== modified file 'VMBuilder/plugins/libvirt/__init__.py'
272--- VMBuilder/plugins/libvirt/__init__.py 2008-10-23 10:52:39 +0000
273+++ VMBuilder/plugins/libvirt/__init__.py 2008-11-06 15:38:45 +0000
274@@ -26,6 +26,7 @@
275 def register_options(self):
276 group = self.vm.setting_group('libvirt integration')
277 group.add_option('--libvirt', metavar='URI', help='Add VM to given URI')
278+ group.add_option('--bridge', metavar="BRIDGE", help='Set up bridged network connected to BRIDGE.')
279 self.vm.register_setting_group(group)
280
281 def all_domains(self):
282@@ -41,6 +42,9 @@
283 self.conn = libvirt.open(self.vm.libvirt)
284 if self.vm.hostname in self.all_domains() and not self.vm.overwrite:
285 raise VMBuilderUserError('Domain %s already exists at %s' % (self.vm.hostname, self.vm.libvirt))
286+
287+ if not self.vm.hypervisor.name == 'KVM':
288+ raise VMBuilderUserError('The libvirt plugin is only equiped to work with KVM at the moment.')
289
290 if not self.vm.hypervisor.name == 'KVM':
291 raise VMBuilderUserError('The libvirt plugin is only equiped to work with KVM at the moment.')
292
293=== modified file 'VMBuilder/plugins/libvirt/templates/libvirtxml.tmpl'
294--- VMBuilder/plugins/libvirt/templates/libvirtxml.tmpl 2008-09-18 09:11:09 +0000
295+++ VMBuilder/plugins/libvirt/templates/libvirtxml.tmpl 2008-11-06 15:36:18 +0000
296@@ -15,8 +15,16 @@
297 <on_crash>destroy</on_crash>
298 <devices>
299 <emulator>/usr/bin/kvm</emulator>
300+#if $bridge
301+ <interface type='bridge'>
302+ <source bridge='$bridge'/>
303+#else
304 <interface type='network'>
305 <source network='default'/>
306+#end if
307+#if $virtio_net
308+ <model type='virtio'/>
309+#end if
310 </interface>
311 <input type='mouse' bus='ps2'/>
312 <graphics type='vnc' port='-1' listen='127.0.0.1'/>
313
314=== modified file 'VMBuilder/plugins/ubuntu/dapper.py'
315--- VMBuilder/plugins/ubuntu/dapper.py 2008-10-23 10:38:15 +0000
316+++ VMBuilder/plugins/ubuntu/dapper.py 2008-11-27 21:06:31 +0000
317@@ -34,6 +34,9 @@
318 'amd64' : ['amd64-generic', 'amd64-k8', 'amd64-k8-smp', 'amd64-server', 'amd64-xeon']}
319 default_flavour = { 'i386' : 'server', 'amd64' : 'amd64-server' }
320 disk_prefix = 'hd'
321+ mirror = ''
322+ xen_kernel_flavour = None
323+ virtio_net = False
324
325 def check_kernel_flavour(self, arch, flavour):
326 return flavour in self.valid_flavours[arch]
327@@ -85,6 +88,12 @@
328 logging.debug("Installing ssh keys")
329 self.install_authorized_keys()
330
331+ logging.debug("Setting up final sources.list")
332+ self.install_sources_list("final")
333+
334+ logging.debug("Copy host settings")
335+ self.copy_settings()
336+
337 logging.debug("Making sure system is up-to-date")
338 self.update()
339
340@@ -118,7 +127,7 @@
341 self.run_in_target('adduser', self.vm.user, group, ignore_fail=True)
342
343 # Lock root account
344- self.run_in_target('chpasswd', stdin='root:!\n')
345+ self.run_in_target('chpasswd', '-e', stdin='root:!\n')
346
347 def kernel_name(self):
348 return 'linux-image-%s' % (self.vm.flavour or self.default_flavour[self.vm.arch],)
349@@ -168,9 +177,19 @@
350 run_cmd('sed', '-ie', 's/^# groot.*/# groot %s/g' % bootdev.get_grub_id(), '%s/boot/grub/menu.lst' % self.destdir)
351 run_cmd('sed', '-ie', '/^# kopt_2_6/ d', '%s/boot/grub/menu.lst' % self.destdir)
352
353- def install_sources_list(self):
354- self.install_from_template('/etc/apt/sources.list', 'sources.list')
355- self.run_in_target('apt-get', 'update')
356+ def install_sources_list(self, final=False):
357+ mirror = ''
358+
359+ if final:
360+ # avoid running a second time if mirror does not change
361+ if self.mirror != self.vm.mirror:
362+ mirror = self.vm.mirror
363+ else:
364+ mirror = self.mirror
365+
366+ if mirror:
367+ self.install_from_template('/etc/apt/sources.list', 'sources.list', { 'mirror' : mirror, 'rmirror' : self.vm.mirror })
368+ self.run_in_target('apt-get', 'update')
369
370 def install_fstab(self):
371 if self.vm.hypervisor.preferred_storage == VMBuilder.hypervisor.STORAGE_FS_IMAGE:
372@@ -183,10 +202,26 @@
373
374 def debootstrap(self):
375 cmd = ['/usr/sbin/debootstrap', '--arch=%s' % self.vm.arch, self.vm.suite, self.destdir ]
376- if self.vm.mirror:
377- cmd += [self.vm.mirror]
378+
379+ if self.vm.iso:
380+ isodir = '%s/isomnt' % self.destdir
381+ run_cmd ('mkdir', isodir)
382+ self.vm.add_clean_cmd('rmdir', isodir)
383+ run_cmd ('mount', '-o', 'loop', '-t', 'iso9660', self.vm.iso, isodir)
384+ self.vm.add_clean_cmd('umount', isodir)
385+ self.mirror = 'file://%s' % isodir
386+ elif self.vm.install_mirror:
387+ self.mirror = self.vm.install_mirror
388+ else:
389+ self.mirror = self.vm.mirror
390+
391+ cmd += [self.mirror]
392+
393 run_cmd(*cmd)
394
395+ if self.vm.iso:
396+ self.mirror = "file:///isomnt"
397+
398 def install_kernel(self):
399 self.install_from_template('/etc/kernel-img.conf', 'kernelimg', { 'updategrub' : self.updategrub })
400 run_cmd('chroot', self.destdir, 'apt-get', '--force-yes', '-y', 'install', self.kernel_name(), 'grub')
401@@ -207,9 +242,9 @@
402
403 def install_from_template(self, *args, **kwargs):
404 return self.vm.distro.install_from_template(*args, **kwargs)
405-
406+
407 def run_in_target(self, *args, **kwargs):
408- return run_cmd('chroot', self.destdir, *args, **kwargs)
409+ self.vm.distro.run_in_target(*args, **kwargs)
410
411 def post_mount(self, fs):
412 if fs.mntpnt == '/':
413@@ -218,3 +253,15 @@
414 logging.debug("Creating /var/lock in root filesystem")
415 os.makedirs('%s/var/lock' % fs.mntpath)
416
417+ def copy_settings(self):
418+ run_cmd('cp', '/etc/default/locale', '%s/etc/default/' % self.destdir)
419+ run_cmd('cp', '-a', '/etc/console-setup', '%s/etc/' % self.destdir)
420+ run_cmd('cp', '/etc/default/console-setup', '%s/etc/default/' % self.destdir)
421+ run_cmd('cp', '/etc/timezone', '%s/etc/' % self.destdir)
422+ self.run_in_target('dpkg-reconfigure', '-pcritical', 'tzdata')
423+ self.run_in_target('locale-gen', 'en_US')
424+ if self.vm.lang:
425+ self.run_in_target('locale-gen', self.vm.lang)
426+ self.install_from_template('/etc/default/locale', 'locale', { 'lang' : self.vm.lang })
427+ self.run_in_target('dpkg-reconfigure', '-pcritical', 'locales')
428+ self.run_in_target('dpkg-reconfigure', '-pcritical', 'console-setup')
429
430=== modified file 'VMBuilder/plugins/ubuntu/distro.py'
431--- VMBuilder/plugins/ubuntu/distro.py 2008-10-23 13:59:50 +0000
432+++ VMBuilder/plugins/ubuntu/distro.py 2008-12-18 13:02:30 +0000
433@@ -24,6 +24,7 @@
434 import socket
435 import logging
436 import types
437+import os
438
439 class Ubuntu(Distro):
440 name = 'Ubuntu'
441@@ -35,12 +36,9 @@
442 'i386' : [ 'i386', 'lpia' ],
443 'lpia' : [ 'i386', 'lpia' ] }
444
445-
446- def __init__(self, vm):
447- self.vm = vm
448- self.register_settings()
449-
450- def register_settings(self):
451+ xen_kernel = ''
452+
453+ def register_options(self):
454 group = self.vm.setting_group('Package options')
455 group.add_option('--addpkg', action='append', metavar='PKG', help='Install PKG into the guest (can be specfied multiple times).')
456 group.add_option('--removepkg', action='append', metavar='PKG', help='Remove PKG from the guest (can be specfied multiple times)')
457@@ -57,8 +55,10 @@
458 group.add_option('--flavour', '--kernel-flavour', help='Kernel flavour to use. Default and valid options depend on architecture and suite')
459 group.add_option('--iso', metavar='PATH', help='Use an iso image as the source for installation of file. Full path to the iso must be provided. If --mirror is also provided, it will be used in the final sources.list of the vm. This requires suite and kernel parameter to match what is available on the iso, obviously.')
460 group.add_option('--mirror', metavar='URL', help='Use Ubuntu mirror at URL instead of the default, which is http://archive.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise')
461+ group.add_option('--install-mirror', metavar='URL', help='Use Ubuntu mirror at URL for the installation only. Apt\'s sources.list will still use default or URL set by --mirror')
462 group.add_option('--components', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
463 group.add_option('--ppa', metavar='PPA', action='append', help='Add ppa belonging to PPA to the vm\'s sources.list.')
464+ group.add_option('--lang', metavar='LANG', default=self.get_locale(), help='Set the locale to LANG [default: %default]')
465 self.vm.register_setting_group(group)
466
467 group = self.vm.setting_group('Settings for the initial user')
468@@ -80,10 +80,19 @@
469 self.vm.mirror = 'http://archive.ubuntu.com/ubuntu'
470
471 if not self.vm.components:
472+ if self.vm.ppa:
473 self.vm.components = ['main', 'restricted', 'universe']
474+ else:
475+ self.vm.components = ['main', 'restricted', 'universe', 'multiverse']
476 else:
477 self.vm.components = self.vm.components.split(',')
478-
479+
480+ def get_locale(self):
481+ try:
482+ return os.environ['LANG']
483+ except:
484+ return None
485+
486 def preflight_check(self):
487 """While not all of these are strictly checks, their failure would inevitably
488 lead to failure, and since we can check them before we start setting up disk
489@@ -107,17 +116,21 @@
490 if type(self.vm.components) is str:
491 self.vm.components = self.vm.components.split(',')
492
493+ if self.vm.hypervisor.name == 'Xen':
494+ logging.info('Xen kernel default: linux-image-%s %s', self.suite.xen_kernel_flavour, self.xen_kernel_version())
495+
496+ self.vm.virtio_net = self.use_virtio_net()
497+
498 def install(self, destdir):
499 self.destdir = destdir
500-
501- self.xen_kernel_path = getattr(self.suite, 'xen_kernel_path', lambda : None)
502- self.xen_ramdisk_path = getattr(self.suite, 'xen_ramdisk_path', lambda: None)
503-
504 self.suite.install(destdir)
505
506 def post_mount(self, fs):
507 self.suite.post_mount(fs)
508
509+ def use_virtio_net(self):
510+ return self.suite.virtio_net
511+
512 def install_bootloader(self):
513 devmapfile = '%s/device.map' % self.vm.workdir
514 devmap = open(devmapfile, 'w')
515@@ -128,4 +141,37 @@
516 setup (hd0)
517 EOT''')
518
519+ def xen_kernel_version(self):
520+ if self.suite.xen_kernel_flavour:
521+ if not self.xen_kernel:
522+ rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour)
523+ version = ['0', '0','0', '0']
524+
525+ for line in rmad.splitlines():
526+ sline = line.split('|')
527+
528+ if sline[2].strip().startswith(self.vm.suite):
529+ vt = sline[1].strip().split('.')
530+ for i in range(4):
531+ if int(vt[i]) > int(version[i]):
532+ version = vt
533+ break
534+
535+ if version[0] == '0':
536+ raise VMBuilderException('Something is wrong, no valid xen kernel for the suite %s found by rmadison' % self.vm.suite)
537+
538+ self.xen_kernel = '%s.%s.%s-%s' % (version[0],version[1],version[2],version[3])
539+ return self.xen_kernel
540+ else:
541+ raise VMBuilderUserError('There is no valid xen kernel for the suite selected.')
542+
543+ def xen_kernel_path(self):
544+ path = '/boot/vmlinuz-%s-%s' % (self.xen_kernel_version(), self.suite.xen_kernel_flavour)
545+ return path
546+
547+ def xen_ramdisk_path(self):
548+ path = '/boot/initrd.img-%s-%s' % (self.xen_kernel_version(), self.suite.xen_kernel_flavour)
549+ return path
550+
551+
552 register_distro(Ubuntu)
553
554=== modified file 'VMBuilder/plugins/ubuntu/gutsy.py'
555--- VMBuilder/plugins/ubuntu/gutsy.py 2008-08-29 22:14:45 +0000
556+++ VMBuilder/plugins/ubuntu/gutsy.py 2008-11-03 18:23:47 +0000
557@@ -28,3 +28,4 @@
558 'amd64' : ['generic', 'rt', 'server'],
559 'lpia' : ['lpia', 'lpiacompat'] }
560 default_flavour = { 'i386' : 'virtual', 'amd64' : 'server', 'lpia' : 'lpia' }
561+ xen_kernel_flavour = 'xen'
562
563=== modified file 'VMBuilder/plugins/ubuntu/hardy.py'
564--- VMBuilder/plugins/ubuntu/hardy.py 2008-08-29 22:14:45 +0000
565+++ VMBuilder/plugins/ubuntu/hardy.py 2008-11-06 15:36:18 +0000
566@@ -21,6 +21,8 @@
567 from VMBuilder.plugins.ubuntu.gutsy import Gutsy
568
569 class Hardy(Gutsy):
570+ virtio_net = True
571+
572 def xen_kernel_path(self):
573 return '/boot/vmlinuz-2.6.24-19-xen'
574
575
576=== modified file 'VMBuilder/plugins/ubuntu/intrepid.py'
577--- VMBuilder/plugins/ubuntu/intrepid.py 2008-10-20 13:35:17 +0000
578+++ VMBuilder/plugins/ubuntu/intrepid.py 2008-11-03 18:23:47 +0000
579@@ -24,15 +24,10 @@
580 from VMBuilder.plugins.ubuntu.hardy import Hardy
581
582 class Intrepid(Hardy):
583- def xen_kernel_path(self):
584- return '/boot/vmlinuz-2.6.27-7-server'
585-
586- def xen_ramdisk_path(self):
587- return '/boot/initrd.img-2.6.27-7-server'
588+ xen_kernel_flavour = 'server'
589
590 def mangle_grub_menu_lst(self):
591 bootdev = disk.bootpart(self.vm.disks)
592 run_cmd('sed', '-ie', 's/^# kopt=root=\([^ ]*\)\(.*\)/# kopt=root=UUID=%s\\2/g' % bootdev.fs.uuid, '%s/boot/grub/menu.lst' % self.destdir)
593 run_cmd('sed', '-ie', 's/^# groot.*/# groot=%s/g' % bootdev.fs.uuid, '%s/boot/grub/menu.lst' % self.destdir)
594 run_cmd('sed', '-ie', '/^# kopt_2_6/ d', '%s/boot/grub/menu.lst' % self.destdir)
595-
596
597=== modified file 'VMBuilder/plugins/ubuntu/templates/dapper_fstab_fsimage.tmpl'
598--- VMBuilder/plugins/ubuntu/templates/dapper_fstab_fsimage.tmpl 2008-10-12 20:06:10 +0000
599+++ VMBuilder/plugins/ubuntu/templates/dapper_fstab_fsimage.tmpl 2008-11-12 17:28:29 +0000
600@@ -1,10 +1,13 @@
601 # /etc/fstab: static file system information.
602 #
603 # <file system> <mount point> <type> <options> <dump> <pass>
604-proc /proc proc defaults 0 0
605+none /proc proc defaults 0 0
606 #for $fs in $fss
607-#echo '/dev/%s%-40s %-15s %-7s %-15s %d %d\n' % ($prefix, fs.get_suffix(), fs.mntpnt, fs.fstab_fstype(), fs.fstab_options(), 0, 0)
608-#*
609-echo "/dev/$prefix$part.get_suffix() $part.mntpnt $part.fs.fstab_fstype() $part.fs.fstab_options() 0 0
610-*#
611+ #if fs.mntpnt == '/sys'
612+ #echo 'none%-40s %-15s %-7s %-15s %d %d' % ('', fs.mntpnt, fs.fstab_fstype(), fs.fstab_options(), 0, 0)
613+ #elif fs.mntpnt == '/'
614+ #echo '/dev/%s%-40s %-15s %-7s %-15s %d %d\n' % ($prefix, fs.get_suffix(), fs.mntpnt, fs.fstab_fstype(), fs.fstab_options(), 1, 1)
615+ #else
616+ #echo '/dev/%s%-40s %-15s %-7s %-15s %d %d\n' % ($prefix, fs.get_suffix(), fs.mntpnt, fs.fstab_fstype(), fs.fstab_options(), 0, 0)
617+ #end if
618 #end for
619
620=== added file 'VMBuilder/plugins/ubuntu/templates/locale.tmpl'
621--- VMBuilder/plugins/ubuntu/templates/locale.tmpl 1970-01-01 00:00:00 +0000
622+++ VMBuilder/plugins/ubuntu/templates/locale.tmpl 2008-11-02 17:14:47 +0000
623@@ -0,0 +1,1 @@
624+LANG="$lang"
625
626=== modified file 'VMBuilder/plugins/ubuntu/templates/sources.list.tmpl'
627--- VMBuilder/plugins/ubuntu/templates/sources.list.tmpl 2008-09-18 09:11:09 +0000
628+++ VMBuilder/plugins/ubuntu/templates/sources.list.tmpl 2008-10-31 20:00:39 +0000
629@@ -1,11 +1,19 @@
630 deb $mirror $suite #slurp
631 #echo ' '.join($components)
632
633-deb $mirror $suite-updates #slurp
634-#echo ' '.join($components)
635-
636-deb $mirror $suite-security #slurp
637-#echo ' '.join($components)
638+#if $iso
639+deb $rmirror $suite-updates #slurp
640+#echo ' '.join($components)
641+
642+deb $rmirror $suite-updates #slurp
643+#echo ' '.join($components)
644+#else
645+deb $mirror $suite-updates #slurp
646+#echo ' '.join($components)
647+
648+deb $mirror $suite-updates #slurp
649+#echo ' '.join($components)
650+#end if
651
652 deb http://security.ubuntu.com/ubuntu $suite-security #slurp
653 #echo ' '.join($components)
654
655=== modified file 'VMBuilder/plugins/xen/vm.py'
656--- VMBuilder/plugins/xen/vm.py 2008-09-16 08:19:29 +0000
657+++ VMBuilder/plugins/xen/vm.py 2008-11-11 23:01:03 +0000
658@@ -31,17 +31,29 @@
659 preferred_storage = VMBuilder.hypervisor.STORAGE_FS_IMAGE
660 needs_bootloader = False
661
662+ def register_options(self):
663+ group = self.vm.setting_group('Xen option')
664+ group.add_option('--xen-kernel', metavar='PATH', help='Path to the kernel to use (e.g.: /boot/vmlinux-2.6.27-7-server). Default depends on distribution and suite')
665+ group.add_option('--xen-ramdisk', metavar='PATH', help='Path to the ramdisk to use (e.g.: /boot/initrd.img-2.6.27-7-server). Default depends on distribution and suite.')
666+ self.vm.register_setting_group(group)
667+
668 def finalize(self):
669 destimages = []
670 for filesystem in self.vm.filesystems:
671- destfile = '%s/%s' % (self.vm.destdir, os.path.basename(filesystem.filename))
672- logging.info('Moving %s to %s' % (filesystem.filename, destfile))
673- self.vm.result_files.append(destfile)
674- run_cmd('cp', '--sparse=always', filesystem.filename, destfile)
675- os.unlink(filesystem.filename)
676- filesystem.filename = os.path.abspath(destfile)
677- destimages.append(destfile)
678+ if not filesystem.preallocated:
679+ destfile = '%s/%s' % (self.vm.destdir, os.path.basename(filesystem.filename))
680+ logging.info('Moving %s to %s' % (filesystem.filename, destfile))
681+ self.vm.result_files.append(destfile)
682+ run_cmd('cp', '--sparse=always', filesystem.filename, destfile)
683+ os.unlink(filesystem.filename)
684+ filesystem.filename = os.path.abspath(destfile)
685+ destimages.append(destfile)
686
687+ if not self.vm.xen_kernel:
688+ self.vm.xen_kernel = self.vm.distro.xen_kernel_path()
689+ if not self.vm.xen_ramdisk:
690+ self.vm.xen_ramdisk = self.vm.distro.xen_ramdisk_path()
691+
692 xenconf = '%s/xen.conf' % self.vm.destdir
693 fp = open(xenconf, 'w')
694 fp.write("""
695@@ -59,6 +71,7 @@
696 name = '%s'
697
698 dhcp = 'dhcp'
699+vif = ['']
700
701 on_poweroff = 'destroy'
702 on_reboot = 'restart'
703@@ -67,8 +80,8 @@
704 extra = 'xencons=tty console=tty1 console=hvc0'
705
706 """ % (self.vm.name,
707- self.vm.distro.xen_kernel_path(),
708- self.vm.distro.xen_ramdisk_path(),
709+ self.vm.xen_kernel,
710+ self.vm.xen_ramdisk,
711 self.vm.mem,
712 ',\n'.join(["'tap:aio:%s,xvda%d,w'" % (os.path.abspath(img), id+1) for (img, id) in zip(destimages, range(len(destimages)))]),
713 self.vm.name))
714
715=== modified file 'VMBuilder/util.py'
716--- VMBuilder/util.py 2008-10-17 22:01:20 +0000
717+++ VMBuilder/util.py 2008-11-02 17:14:47 +0000
718@@ -100,6 +100,16 @@
719 else:
720 stdin_arg = file('/dev/null', 'w')
721 proc_env = os.environ
722+ # save environment state
723+ try:
724+ sLANG = proc_env['LANG']
725+ except:
726+ sLANG = ''
727+ try:
728+ sLC = proc_env['LC_ALL']
729+ except:
730+ sLC = ''
731+
732 proc_env['LANG'] = 'C'
733 proc_env['LC_ALL'] = 'C'
734 proc_env.update(env)
735@@ -126,6 +136,10 @@
736 status = proc.wait()
737 if not ignore_fail and status != 0:
738 raise VMBuilderException, "Process (%s) returned %d. stdout: %s, stderr: %s" % (args.__repr__(), status, stdout, stderr)
739+
740+ #restore environement state
741+ proc_env['LANG'] = sLANG
742+ proc_env['LC_ALL'] = sLC
743 return stdout
744
745 def give_to_caller(path):
746
747=== modified file 'VMBuilder/vm.py'
748--- VMBuilder/vm.py 2008-10-23 21:11:22 +0000
749+++ VMBuilder/vm.py 2008-11-10 06:48:28 +0000
750@@ -72,6 +72,8 @@
751 #: directory where we build up the guest filesystem
752 self.tmproot = None
753
754+ self.fsmounted = False
755+
756 self.optparser = _MyOptParser(epilog="ubuntu-vm-builder is Copyright (C) 2007-2008 Canonical Ltd. and written by Soren Hansen <soren@canonical.com>.", usage='%prog hypervisor distro [options]')
757 self.optparser.arg_help = (('hypervisor', self.hypervisor_help), ('distro', self.distro_help))
758
759@@ -360,6 +362,8 @@
760 fs.mount()
761 self.distro.post_mount(fs)
762
763+ self.fsmounted = True
764+
765 def umount_partitions(self):
766 """Unmounts all the vm's partitions and filesystems"""
767 logging.info('Unmounting target filesystem')
768@@ -370,6 +374,8 @@
769 for disk in self.disks:
770 disk.unmap()
771
772+ self.fsmounted = False
773+
774 def install(self):
775 if self.in_place:
776 self.installdir = self.rootmnt
777
778=== modified file 'debian/changelog'
779--- debian/changelog 2008-10-24 22:37:48 +0000
780+++ debian/changelog 2008-12-17 14:06:11 +0000
781@@ -1,3 +1,9 @@
782+vm-builder (0.9.1-0ubuntu0~ppa1) intrepid; urgency=low
783+
784+ * Chnages for building ec2 images.
785+
786+ -- Chuck Short <zulcss@ubuntu.com> Sun, 02 Nov 2008 14:35:43 +0100
787+
788 vm-builder (0.9-0ubuntu3) intrepid; urgency=low
789
790 [ Johan Euphrosine ]
791
792=== modified file 'debian/control'
793--- debian/control 2008-10-24 12:15:12 +0000
794+++ debian/control 2008-11-06 11:09:50 +0000
795@@ -9,7 +9,7 @@
796
797 Package: python-vm-builder
798 Architecture: all
799-Depends: kvm (>= 1:69) | qemu, debootstrap, parted, kpartx, ubuntu-keyring, ${python:Depends}, dpkg-dev, python-cheetah
800+Depends: kvm (>= 1:69) | qemu, debootstrap, parted, kpartx, ubuntu-keyring, ${python:Depends}, dpkg-dev, python-cheetah, devscripts
801 Recommends: python-libvirt
802 XB-Python-Version: ${python:Versions}
803 Description: VM builder
804
805=== added file 'debian/python-vm-builder-ec2.docs'
806--- debian/python-vm-builder-ec2.docs 1970-01-01 00:00:00 +0000
807+++ debian/python-vm-builder-ec2.docs 2008-11-11 18:15:33 +0000
808@@ -0,0 +1,1 @@
809+examples
810
811=== added directory 'examples'
812=== added file 'examples/ec2-amd64-part-file.txt'
813--- examples/ec2-amd64-part-file.txt 1970-01-01 00:00:00 +0000
814+++ examples/ec2-amd64-part-file.txt 2008-12-17 14:24:09 +0000
815@@ -0,0 +1,2 @@
816+root 4096 a1
817+/mnt 0 b
818
819=== added file 'examples/ec2-firstboot.sh'
820--- examples/ec2-firstboot.sh 1970-01-01 00:00:00 +0000
821+++ examples/ec2-firstboot.sh 2008-11-11 18:15:33 +0000
822@@ -0,0 +1,20 @@
823+#!/bin/bash
824+
825+#
826+# Regenerate the ssh host key
827+#
828+
829+rm -f /etc/ssh/ssh_host_*_key*
830+
831+ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N '' | logger -s -t "ec2"
832+ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -N '' | logger -s -t "ec2"
833+
834+# This allows user to get host keys securely through console log
835+echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" | logger -s -t "ec2"
836+ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub | logger -s -t "ec2"
837+ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub | logger -s -t "ec2"
838+echo "-----END SSH HOST KEY FINGERPRINTS-----" | logger -s -t "ec2"
839+
840+depmod -a
841+
842+exit 0
843
844=== added file 'examples/ec2-firstlogin.sh'
845--- examples/ec2-firstlogin.sh 1970-01-01 00:00:00 +0000
846+++ examples/ec2-firstlogin.sh 2008-11-11 18:15:33 +0000
847@@ -0,0 +1,49 @@
848+#!/bin/bash
849+
850+trap cleanup 1 2 3 6
851+
852+cleanup() {
853+ exit 1
854+}
855+
856+ACCOUNT="ubuntu"
857+
858+echo
859+echo "======================================================"
860+echo "CONFIGURATION OF YOUR UBUNTU EC2 IMAGE"
861+echo "======================================================"
862+echo "Your EC2 image is about to be finished to be set up."
863+echo
864+echo "------------------------------------------------------"
865+
866+PASSWORD=$(uuidgen -r | head -c8)
867+
868+echo "New password for ${ACCOUNT} account: ${PASSWORD}"
869+echo "ubuntu:${PASSWORD}" | chpasswd -m
870+passwd -u ${ACCOUNT}
871+
872+echo "Setting up ssh public keys for the ${ACCOUNT} account."
873+[ ! -e /home/${ACCOUNT}/.ssh ] && mkdir -p /home/${ACCOUNT}/.ssh
874+cp -a /root/.ssh/authorized_keys* /home/${ACCOUNT}/.ssh
875+chown -R ${ACCOUNT}:${ACCOUNT} /home/${ACCOUNT}/.ssh
876+
877+echo
878+echo "------------------------------------------------------"
879+echo "Please select software that you wish to install:"
880+
881+tasksel --section server
882+
883+echo
884+echo "------------------------------------------------------"
885+echo
886+echo "We are now going to log you out of the root account."
887+echo "To perform administrative tasks please use the ${ACCOUNT} account"
888+echo "in combination with sudo using the password: ${PASSWORD}"
889+echo
890+echo "======================================================"
891+echo
892+
893+touch /root/firstlogin_done
894+
895+kill -HUP $PPID
896+
897
898=== added file 'examples/ec2-i386-part-file.txt'
899--- examples/ec2-i386-part-file.txt 1970-01-01 00:00:00 +0000
900+++ examples/ec2-i386-part-file.txt 2008-12-17 14:24:09 +0000
901@@ -0,0 +1,3 @@
902+root 4096 a1
903+/mnt 0 a2
904+swap 1024 a3
905
906=== modified file 'vmbuilder.1'
907--- vmbuilder.1 2008-10-23 13:59:50 +0000
908+++ vmbuilder.1 2008-11-12 19:13:07 +0000
909@@ -78,6 +78,13 @@
910 /var 8000
911 /var/log 2000
912 .RE
913+FSIMAGE partitions (Xen) also supports an addition third parameter which is the suffix of the device name that should be used ('a1' for /dev/sda1). For FSIMAGE, partitions which are declared with a size of 0 will be treated as fs to add at runtime but which do not need to be created by vmbuilder. ie:
914+.RS
915+ root 4096 a1
916+ /mnt 0 b
917+ /sys 0
918+.RE
919+FSIMAGE is not designed to use "disks" as it does not have partition tables, so '---' will just be ignored.
920 .RE
921 .TP
922 The following three options are not used if --part is specified:

Subscribers

People subscribed via source and target branches