Merge lp:~guilhem-fr/vmbuilder/oneiric-support into lp:vmbuilder

Proposed by Guilhem Lettron
Status: Needs review
Proposed branch: lp:~guilhem-fr/vmbuilder/oneiric-support
Merge into: lp:vmbuilder
Diff against target: 1849 lines (+729/-243)
26 files modified
VMBuilder/contrib/cli.py (+35/-22)
VMBuilder/disk.py (+90/-39)
VMBuilder/distro.py (+23/-15)
VMBuilder/hypervisor.py (+33/-18)
VMBuilder/plugins/__init__.py (+3/-1)
VMBuilder/plugins/ec2/__init__.py (+11/-11)
VMBuilder/plugins/kvm/__init__.py (+1/-1)
VMBuilder/plugins/kvm/disk.py (+38/-0)
VMBuilder/plugins/kvm/qemu_nbd.py (+117/-0)
VMBuilder/plugins/kvm/vm.py (+4/-0)
VMBuilder/plugins/ubuntu/dapper.py (+138/-34)
VMBuilder/plugins/ubuntu/distro.py (+76/-59)
VMBuilder/plugins/ubuntu/intrepid.py (+1/-0)
VMBuilder/plugins/ubuntu/karmic.py (+1/-0)
VMBuilder/plugins/ubuntu/lucid.py (+29/-1)
VMBuilder/plugins/ubuntu/oneiric.py (+22/-1)
VMBuilder/plugins/ubuntu/precise.py (+22/-0)
VMBuilder/plugins/ubuntu/templates/Copy of devicemap.tmpl (+17/-0)
VMBuilder/plugins/ubuntu/templates/devicemap.tmpl (+9/-3)
VMBuilder/plugins/ubuntu/templates/grubcfg.tmpl (+8/-0)
VMBuilder/plugins/ubuntu/templates/loadcfg.tmpl (+3/-0)
VMBuilder/plugins/ubuntu/templates/sources.list.tmpl (+10/-0)
VMBuilder/tests/disk_tests.py (+7/-7)
VMBuilder/tests/plugin_tests.py (+28/-28)
VMBuilder/util.py (+1/-1)
VMBuilder/vm.py (+2/-2)
To merge this branch: bzr merge lp:~guilhem-fr/vmbuilder/oneiric-support
Reviewer Review Type Date Requested Status
Scott Moser Pending
VMBuilder Pending
Review via email: mp+89858@code.launchpad.net

Description of the change

I change many work for grub2.

I cleanup code in the previous behaviour.
But, to be more "clean", I use another way for KVM hypervisor by using module "nbd" and "qemu-img" (who are dedicated to do this).

Any of my patches must break compatibility, but have a look and don't hesitate to critizise.

FYI, I use it in daily production cloud for my company.

Some parts need some works (especially ended scripts : /etc/fstab and device.map) but nothing blocking for me.

To post a comment you must log in.
Revision history for this message
Guilhem Lettron (guilhem-fr) wrote :

oops for .projects files... they must be ignored (work on eclipse IDE).

Revision history for this message
Serge Hallyn (serge-hallyn) wrote :

Hi,

Thanks for working on this tree.

I've resolved the conflicts and pushed the result to lp:~serge-hallyn/vmbuilder/merge-guilhem-fr.

I've not yet done any testing of the result.

Could you please elaborate upon:

 Some parts need some works (especially ended scripts : /etc/fstab and device.map) but nothing blocking for me.

Is that extra work just for cleanliness, or will things be broken without it?

Revision history for this message
Guilhem Lettron (guilhem-fr) wrote :

My solution works "out of the box".

To precise what I will do :
* fstab isn't "beautiful". It use /dev/sda[0-1] instead of UUID=****. UUID is usefull when you use virtio (/dev/vda**) as I do.
But VM work fine even if you don't have /dev/vda*

* when you boot for the first time VM, grub show you many fake system (generate from the host). But the first one is the good one, so no problem "out of the box".
I have work many hours to find the problem... but without any succes.
An "update-grub" in the VM clear all the fake.

So for me, my patches solve more problem than they give.

A last things to do for better use, is to prevent user (of KVM) when module "nbd" isn't load.

I don't find any python library to do this... suggestion ?

471. By Guilhem Lettron

big changes :
* add precise
* let parted do a _good_ alignment
* ...

472. By Guilhem Lettron

merge

473. By Guilhem Lettron

no idea what I do #meme

Unmerged revisions

473. By Guilhem Lettron

no idea what I do #meme

472. By Guilhem Lettron

merge

471. By Guilhem Lettron

big changes :
* add precise
* let parted do a _good_ alignment
* ...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'VMBuilder/contrib/cli.py'
2--- VMBuilder/contrib/cli.py 2012-05-24 13:49:34 +0000
3+++ VMBuilder/contrib/cli.py 2012-09-04 13:48:23 +0000
4@@ -23,7 +23,7 @@
5 import shutil
6 import sys
7 import tempfile
8-import VMBuilder
9+import VMBuilder.plugins
10 import VMBuilder.util as util
11 from VMBuilder.disk import parse_size
12 import VMBuilder.hypervisor
13@@ -194,7 +194,9 @@
14 hypervisor.get_setting_default(option) != val):
15 hypervisor.set_setting_fuzzy(option, val)
16
17+
18 chroot_dir = None
19+
20 if self.options.existing_chroot:
21 distro.set_chroot_dir(self.options.existing_chroot)
22 distro.call_hooks('preflight_check')
23@@ -213,18 +215,28 @@
24 else:
25 chroot_dir = util.tmpdir(tmp_root=self.options.tmp_root)
26 distro.set_chroot_dir(chroot_dir)
27- distro.build_chroot()
28+ distro.install()
29+ distro.prepare_chroot()
30+ distro.build()
31+ distro.clean_chroot()
32
33 if self.options.only_chroot:
34 print 'Chroot can be found in %s' % distro.chroot_dir
35 sys.exit(0)
36
37- self.set_disk_layout(optparser, hypervisor)
38- hypervisor.install_os()
39-
40+ self.set_disk_layout(hypervisor)
41+ hypervisor.create_environement()
42+ hypervisor.migrate()
43+ distro.set_chroot_dir(hypervisor.chroot_dir, hypervisor.dev_dir)
44+ distro.prepare_chroot()
45+ hypervisor.configure_os()
46+ distro.clean_chroot()
47+ hypervisor.close_environement()
48 os.mkdir(destdir)
49 self.fix_ownership(destdir)
50 hypervisor.finalise(destdir)
51+
52+
53 # If chroot_dir is not None, it means we created it,
54 # and if we reach here, it means the user didn't pass
55 # --only-chroot. Hence, we need to remove it to clean
56@@ -236,6 +248,7 @@
57 raise
58 finally:
59 if tmpfs_mount_point is not None:
60+# pass
61 util.clean_up_tmpfs(tmpfs_mount_point)
62 util.run_cmd('rmdir', tmpfs_mount_point)
63
64@@ -277,7 +290,7 @@
65 optparser.add_option_group(optgroup)
66
67 def versioninfo(self, option, opt, value, parser):
68- print ('%(major)d.%(minor)d.%(micro)s' %
69+ print ('%(major)d.%(minor)d.%(micro)s.r%(revno)d' %
70 VMBuilder.get_version_info())
71 sys.exit(0)
72
73@@ -301,18 +314,13 @@
74 elif opt_str == '--quiet':
75 VMBuilder.set_console_loglevel(logging.CRITICAL)
76
77- def set_disk_layout(self, optparser, hypervisor):
78+ def set_disk_layout(self, hypervisor):
79 default_filesystem = hypervisor.distro.preferred_filesystem()
80 if not self.options.part:
81 rootsize = parse_size(self.options.rootsize)
82 swapsize = parse_size(self.options.swapsize)
83 optsize = parse_size(self.options.optsize)
84 if hypervisor.preferred_storage == VMBuilder.hypervisor.STORAGE_FS_IMAGE:
85- tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
86- hypervisor.add_filesystem(filename=tmpfile,
87- size='%dM' % rootsize,
88- type='ext3',
89- mntpnt='/')
90 if swapsize > 0:
91 tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
92 hypervisor.add_filesystem(filename=tmpfile,
93@@ -325,6 +333,11 @@
94 size='%dM' % optsize,
95 type='ext3',
96 mntpnt='/opt')
97+ tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
98+ hypervisor.add_filesystem(filename=tmpfile,
99+ size='%dM' % rootsize,
100+ type='ext3',
101+ mntpnt='/')
102 else:
103 if self.options.raw:
104 for raw_disk in self.options.raw:
105@@ -335,23 +348,23 @@
106 tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
107 disk = hypervisor.add_disk(tmpfile, size='%dM' % size)
108 offset = 0
109- disk.add_part(offset, rootsize, default_filesystem, '/')
110- offset += rootsize
111 if swapsize > 0:
112 disk.add_part(offset, swapsize, 'swap', 'swap')
113 offset += swapsize
114 if optsize > 0:
115 disk.add_part(offset, optsize, default_filesystem, '/opt')
116+ offset += optsize
117+ disk.add_part(offset, rootsize, default_filesystem, '/')
118 else:
119 # We need to parse the file specified
120 if hypervisor.preferred_storage == VMBuilder.hypervisor.STORAGE_FS_IMAGE:
121 try:
122 for line in file(self.options.part):
123 elements = line.strip().split(' ')
124- if len(elements) < 4:
125- tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
126- else:
127- tmpfile = elements[3]
128+ if len(elements) < 4:
129+ tmpfile = util.tmp_filename(tmp_root=self.options.tmp_root)
130+ else:
131+ tmpfile = elements[3]
132
133 if elements[0] == 'root':
134 hypervisor.add_filesystem(elements[1],
135@@ -380,8 +393,8 @@
136 filename=tmpfile,
137 mntpnt=elements[0])
138 except IOError, (errno, strerror):
139- optparser.error("%s parsing --part option: %s" %
140- (errno, strerror))
141+ self.optparser.error("%s parsing --part option: %s" %
142+ (errno, strerror))
143 else:
144 try:
145 curdisk = list()
146@@ -403,8 +416,8 @@
147 self.do_disk(hypervisor, curdisk, size, disk_idx)
148
149 except IOError, (errno, strerror):
150- optparser.error("%s parsing --part option: %s" %
151- (errno, strerror))
152+ hypervisor.optparser.error("%s parsing --part option: %s" %
153+ (errno, strerror))
154
155 def do_disk(self, hypervisor, curdisk, size, disk_idx):
156 default_filesystem = hypervisor.distro.preferred_filesystem()
157
158=== modified file 'VMBuilder/disk.py'
159--- VMBuilder/disk.py 2012-01-25 13:48:24 +0000
160+++ VMBuilder/disk.py 2012-09-04 13:48:23 +0000
161@@ -26,9 +26,13 @@
162 import stat
163 import string
164 import time
165-from VMBuilder.util import run_cmd
166+from random import sample as random
167+from string import ascii_lowercase
168+import string
169+from VMBuilder.util import run_cmd, tmpdir
170 from VMBuilder.exception import VMBuilderUserError, VMBuilderException
171 from struct import unpack
172+#from util import run_cmd
173
174 TYPE_EXT2 = 0
175 TYPE_EXT3 = 1
176@@ -40,8 +44,8 @@
177 """
178 Virtual disk.
179
180- @type vm: Hypervisor
181- @param vm: The Hypervisor to which the disk belongs
182+ @type hypervisor: Hypervisor
183+ @param hypervisor: The Hypervisor to which the disk belongs
184 @type filename: string
185 @param filename: filename of the disk image
186 @type size: string or number
187@@ -51,8 +55,8 @@
188 this size will be created once L{create}() is called.
189 """
190
191- def __init__(self, vm, filename, size=None):
192- self.vm = vm
193+ def __init__(self, hypervisor, filename, size=None):
194+ self.hypervisor = hypervisor
195 "The hypervisor to which the disk belongs."
196
197 self.filename = filename
198@@ -66,6 +70,9 @@
199
200 self.size = 0
201 "The size of the disk. For preallocated disks, this is detected."
202+
203+ self.dev = None
204+ "mount point for this disk. example : /dev/loop1"
205
206 if not os.path.exists(self.filename):
207 if not size:
208@@ -87,7 +94,7 @@
209 the VM. E.g. the first disk of a VM would return 'a', while the 702nd would return 'zz'
210 """
211
212- return index_to_devname(self.vm.disks.index(self))
213+ return index_to_devname(self.hypervisor.disks.index(self))
214
215 def create(self):
216 """
217@@ -126,8 +133,25 @@
218 Call this after L{partition}.
219 """
220 logging.info('Creating loop devices corresponding to the created partitions')
221- self.vm.add_clean_cb(lambda : self.unmap(ignore_fail=True))
222- kpartx_output = run_cmd('kpartx', '-av', self.filename)
223+ self.hypervisor.add_clean_cb(lambda : self.unmap(ignore_fail=True))
224+ self.dev_loop = run_cmd('losetup', '-f').split('\n')[0]
225+ run_cmd('losetup', self.dev_loop, self.filename )
226+ # for another moment : http://pypi.python.org/pypi/losetup/
227+ rdevice = "".join(random(ascii_lowercase, 3))
228+ self.dev_mapper = rdevice + self.devletters()
229+ #TODO cleanup
230+ self.dev_kpartx = '/dev/mapper/%s' % self.dev_mapper
231+#TODO
232+
233+ self.dev_mknode = os.path.join(self.hypervisor.dev_dir, self.dev_mapper)
234+
235+ blockSize = run_cmd('blockdev', '--getsz', self.dev_loop).split('\n')[0]
236+ run_cmd('dmsetup', 'create', self.dev_mapper, '--table=0 %s linear %s 0' % (blockSize, self.dev_loop))
237+ kpartx_output = run_cmd('kpartx', '-av', self.dev_kpartx)
238+ info = os.stat(self.dev_kpartx)
239+ os.mknod(self.dev_mknode, stat.S_IFBLK, os.makedev(os.major(info.st_rdev), os.minor(info.st_rdev)))
240+ self.dev = os.path.join('/dev', self.dev_mapper)
241+# self.dev = self.dev_kpartx
242 parts = []
243 for line in kpartx_output.split('\n'):
244 if line == "" or line.startswith("gpt:") or line.startswith("dos:"):
245@@ -138,9 +162,26 @@
246 logging.error('Skipping unknown line in kpartx output (%s)' % line)
247 mapdevs = []
248 for line in parts:
249- mapdevs.append(line.split(' ')[2])
250+ splitted = line.split(' ')
251+ mapdevs.append(splitted[2])
252 for (part, mapdev) in zip(self.partitions, mapdevs):
253- part.set_filename('/dev/mapper/%s' % mapdev)
254+ mapper_filename = '/dev/mapper/%s' % mapdev
255+ part_dev = '/dev/%s' % mapdev #device view inside the chroot
256+ part_filename = os.path.join(self.hypervisor.dev_dir, mapdev) #device inside the host
257+ part.set_filename(part_filename)
258+# part.set_filename(mapper_filename)
259+ part.set_dev(part_dev)
260+# part.set_filename(mapper_filename)
261+ info = os.stat(mapper_filename)
262+ #print info
263+ os.mknod(part.filename, 0600 | stat.S_IFBLK, os.makedev(os.major(info.st_rdev), os.minor(info.st_rdev)))
264+#TODO
265+# part.set_dev('/dev/mapper/%s' % mapdev)
266+ # map /dev/mapper/loop1pX to /dev/loopX to using it
267+#TODO freeSlot = run_cmd('losetup', '-f').split('\n')[0]
268+# run_cmd('losetup', freeSlot, part.filename )
269+# part.set_dev(freeSlot)
270+
271
272 def mkfs(self):
273 """
274@@ -162,7 +203,7 @@
275 @rtype: number
276 @return: index of the disk (starting from 0 for the hypervisor's first disk)
277 """
278- return self.vm.disks.index(self)
279+ return self.hypervisor.disks.index(self)
280
281 def unmap(self, ignore_fail=False):
282 """
283@@ -177,7 +218,12 @@
284 max_tries = 3
285 while tries < max_tries:
286 try:
287- run_cmd('kpartx', '-d', self.filename, ignore_fail=False)
288+ for part in self.partitions:
289+ os.remove(part.filename)
290+ os.remove(self.dev_mknode)
291+ run_cmd('kpartx', '-d', self.dev_kpartx, ignore_fail=False)
292+ run_cmd('dmsetup', 'remove', self.dev_kpartx, ignore_fail=False )
293+ run_cmd('losetup', '-d', self.dev_loop, ignore_fail=False)
294 break
295 except:
296 pass
297@@ -187,8 +233,11 @@
298 if tries >= max_tries:
299 # try it one last time
300 logging.info("Could not unmap '%s' after '%d' attempts. Final attempt" % (self.filename, tries))
301- run_cmd('kpartx', '-d', self.filename, ignore_fail=ignore_fail)
302-
303+ #TODO
304+# utils.clean_up_tmpfs()
305+# run_cmd('kpartx', '-d', self.filename, ignore_fail=ignore_fail)
306+# run_cmd('dmsetup', 'remove', '-f', '/dev/mapper/%s' % self.dev_mapper, ignore_fail=ignore_fail )
307+# run_cmd('losetup', '-d', self.dev_loop, ignore_fail=ignore_fail)
308 for part in self.partitions:
309 logging.debug("Removing partition %s" % part.filename)
310 parted_oldmap=part.filename[len("/dev/mapper/"):-1]+"p"+part.filename[-1]
311@@ -276,14 +325,22 @@
312
313 self.filename = None
314 "The filename of this partition (the map device)"
315+
316+ self.dev = None
317+ "The dev device to use"
318
319- self.fs = Filesystem(vm=self.disk.vm, type=self.type, mntpnt=self.mntpnt)
320+ self.fs = Filesystem(hypervisor=self.disk.hypervisor, type=self.type, mntpnt=self.mntpnt)
321 "The enclosed filesystem"
322
323 def set_filename(self, filename):
324 self.filename = filename
325 self.fs.filename = filename
326
327+ def set_dev(self, dev):
328+ self.dev = dev
329+#TODO change this...
330+ self.fs.dev = dev
331+
332 def parted_fstype(self):
333 """
334 @rtype: string
335@@ -294,25 +351,17 @@
336 def create(self, disk):
337 """Adds partition to the disk image (does not mkfs or anything like that)"""
338 logging.info('Adding type %d partition to disk image: %s' % (self.type, disk.filename))
339- if self.begin == 0:
340- logging.info('Partition at beginning of disk - reserving first cylinder')
341- partition_start = "63s"
342- else:
343- partition_start = self.begin
344- run_cmd('parted', '--script', '--', disk.filename, 'mkpart', 'primary', self.parted_fstype(), partition_start, self.end)
345+ run_cmd( 'parted', '--script', '--align=opt', disk.filename, 'mkpart', 'primary', partition_start, self.end)
346
347 def mkfs(self):
348 """Adds Filesystem object"""
349 self.fs.mkfs()
350
351- def get_grub_id(self):
352- """The name of the partition as known by grub"""
353- return '(hd%d,%d)' % (self.disk.get_index(), self.get_index())
354-
355+ # must be refactor in a "linux" class
356 def get_suffix(self):
357 """Returns 'a4' for a device that would be called /dev/sda4 in the guest.
358 This allows other parts of VMBuilder to set the prefix to something suitable."""
359- return '%s%d' % (self.disk.devletters(), self.get_index() + 1)
360+ return '%s%d' % (self.disk.devletters(), self.get_index()+1)
361
362 def get_index(self):
363 """Index of the disk (starting from 0)"""
364@@ -328,9 +377,10 @@
365 self.type = str_to_type(type)
366
367 class Filesystem(object):
368- def __init__(self, vm=None, size=0, type=None, mntpnt=None, filename=None, devletter='a', device='', dummy=False):
369- self.vm = vm
370+ def __init__(self, hypervisor=None, size=0, type=None, mntpnt=None, filename=None, devletter='a', device='', dummy=False):
371+ self.hypervisor = hypervisor
372 self.filename = filename
373+ self.dev = None
374 self.size = parse_size(size)
375 self.devletter = devletter
376 self.device = device
377@@ -358,7 +408,7 @@
378 else:
379 raise VMBuilderException('mntpnt not set')
380
381- self.filename = '%s/%s' % (self.vm.workdir, self.filename)
382+ self.filename = '%s/%s' % (self.hypervisor.workdir, self.filename)
383 while os.path.exists('%s.img' % self.filename):
384 self.filename += '_'
385 self.filename += '.img'
386@@ -382,7 +432,7 @@
387 def mkfs_fstype(self):
388 map = { TYPE_EXT2: ['mkfs.ext2', '-F'], TYPE_EXT3: ['mkfs.ext3', '-F'], TYPE_EXT4: ['mkfs.ext4', '-F'], TYPE_XFS: ['mkfs.xfs'], TYPE_SWAP: ['mkswap'] }
389
390- if not self.vm.distro.has_256_bit_inode_ext3_support():
391+ if not self.hypervisor.distro.has_256_bit_inode_ext3_support():
392 map[TYPE_EXT3] = ['mkfs.ext3', '-I 128', '-F']
393
394 return map[self.type]
395@@ -400,10 +450,10 @@
396 if not os.path.exists(self.mntpath):
397 os.makedirs(self.mntpath)
398 run_cmd('mount', '-o', 'loop', self.filename, self.mntpath)
399- self.vm.add_clean_cb(self.umount)
400+ self.hypervisor.add_clean_cb(self.umount)
401
402 def umount(self):
403- self.vm.cancel_cleanup(self.umount)
404+ self.hypervisor.cancel_cleanup(self.umount)
405 if (self.type != TYPE_SWAP) and not self.dummy:
406 logging.debug('Unmounting %s', self.mntpath)
407 run_cmd('umount', self.mntpath)
408@@ -414,7 +464,7 @@
409 if self.device:
410 return self.device
411 else:
412- return '%s%d' % (self.devletters(), self.get_index() + 1)
413+ return '%s%d' % (self.devletters(), self.get_index())
414
415 def devletters(self):
416 """
417@@ -425,8 +475,8 @@
418 return self.devletter
419
420 def get_index(self):
421- """Index of the disk (starting from 0)"""
422- return self.vm.filesystems.index(self)
423+ """Index of the disk (starting from 1)"""
424+ return self.hypervisor.filesystems.index(self)+1
425
426 def set_type(self, type):
427 try:
428@@ -518,6 +568,7 @@
429 return 0
430 return 26 * devname_to_index_rec(devname[:-1]) + (string.ascii_lowercase.index(devname[-1]) + 1)
431
432+# must be sort out in a "linux" class
433 def index_to_devname(index, suffix=''):
434 if index < 0:
435 return suffix
436@@ -539,15 +590,15 @@
437
438 def qemu_img_path():
439 exes = ['kvm-img', 'qemu-img']
440- for dir in os.environ['PATH'].split(os.path.pathsep):
441+ for directory in os.environ['PATH'].split(os.path.pathsep):
442 for exe in exes:
443- path = '%s%s%s' % (dir, os.path.sep, exe)
444+ path = '%s%s%s' % (directory, os.path.sep, exe)
445 if os.access(path, os.X_OK):
446 return path
447
448 def vbox_manager_path():
449 exe = 'VBoxManage'
450- for dir in os.environ['PATH'].split(os.path.pathsep):
451- path = '%s%s%s' % (dir, os.path.sep, exe)
452+ for directory in os.environ['PATH'].split(os.path.pathsep):
453+ path = '%s%s%s' % (directory, os.path.sep, exe)
454 if os.access(path, os.X_OK):
455 return path
456
457=== modified file 'VMBuilder/distro.py'
458--- VMBuilder/distro.py 2011-05-16 20:00:30 +0000
459+++ VMBuilder/distro.py 2012-09-04 13:48:23 +0000
460@@ -65,7 +65,10 @@
461 def call_hooks(self, *args, **kwargs):
462 try:
463 call_hooks(self, *args, **kwargs)
464- except Exception:
465+ except Exception, e:
466+ logging.debug(e)
467+ if logging.root.isEnabledFor(logging.DEBUG):
468+ raw_input("AN ERROR Occured : press enter to continue...")
469 self.cleanup()
470 raise
471
472@@ -74,23 +77,28 @@
473 self.plugin_classes = VMBuilder._distro_plugins
474 super(Distro, self).__init__()
475
476- def set_chroot_dir(self, chroot_dir):
477- self.chroot_dir = chroot_dir
478-
479- def build_chroot(self):
480+ def set_chroot_dir(self, chroot_dir, dev_dir = '/dev'):
481+ self.chroot_dir = chroot_dir
482+ self.dev_dir = dev_dir
483+
484+ def prepare_chroot(self):
485+ self.call_hooks('prepare_chroot')
486+
487+ def clean_chroot(self):
488+ self.call_hooks('clean_chroot')
489+
490+ def build(self):
491+ self.call_hooks('install_os')
492+# self.cleanup()
493+
494+ def has_xen_support(self):
495+ """Install the distro into destdir"""
496+ raise NotImplemented('Distro subclasses need to implement the has_xen_support method')
497+
498+ def install(self):
499 self.call_hooks('preflight_check')
500 self.call_hooks('set_defaults')
501 self.call_hooks('bootstrap')
502- self.call_hooks('configure_os')
503- self.cleanup()
504-
505- def has_xen_support(self):
506- """Install the distro into destdir"""
507- raise NotImplemented('Distro subclasses need to implement the has_xen_support method')
508-
509- def install(self, destdir):
510- """Install the distro into destdir"""
511- raise NotImplemented('Distro subclasses need to implement the install method')
512
513 def post_mount(self, fs):
514 """Called each time a filesystem is mounted to let the distro add things to the filesystem"""
515
516=== modified file 'VMBuilder/hypervisor.py'
517--- VMBuilder/hypervisor.py 2011-05-16 20:00:30 +0000
518+++ VMBuilder/hypervisor.py 2012-09-04 13:48:23 +0000
519@@ -21,7 +21,7 @@
520 import logging
521 import os
522 import VMBuilder.distro
523-import VMBuilder.disk
524+#import VMBuilder.disk
525 from VMBuilder.util import run_cmd, tmpdir
526
527 STORAGE_DISK_IMAGE = 0
528@@ -49,28 +49,36 @@
529
530 def add_disk(self, *args, **kwargs):
531 """Adds a disk image to the virtual machine"""
532- from VMBuilder.disk import Disk
533-
534- disk = Disk(self, *args, **kwargs)
535+ disk = self._create_disk(*args, **kwargs)
536 self.disks.append(disk)
537 return disk
538-
539- def install_os(self):
540+
541+ def _create_disk(self, *args, **kwargs):
542+ return VMBuilder.disk.Disk(self, *args, **kwargs)
543+
544+ def create_environement(self):
545+ self.chroot_dir = tmpdir()
546+ self.dev_dir = '/dev'
547+ self.call_hooks('configure_mounting', self.disks, self.filesystems)
548+ self.call_hooks('mount_partitions', self.chroot_dir)
549+
550+ def close_environement(self):
551+ self.call_hooks('unmount_partitions')
552+ os.rmdir(self.chroot_dir)
553+
554+ def migrate(self):
555+ self.distro.set_chroot_dir(self.chroot_dir)
556+ run_cmd('rsync', '-aHA', '--exclude=/sys', '--exclude=/proc', '--exclude=/dev', '%s/' % self.distro.chroot_dir, self.chroot_dir)
557+
558+ def configure_os(self):
559 self.nics = [self.NIC()]
560 self.call_hooks('preflight_check')
561 self.call_hooks('configure_networking', self.nics)
562- self.call_hooks('configure_mounting', self.disks, self.filesystems)
563-
564- self.chroot_dir = tmpdir()
565- self.call_hooks('mount_partitions', self.chroot_dir)
566- run_cmd('rsync', '-aHA', '%s/' % self.distro.chroot_dir, self.chroot_dir)
567- self.distro.set_chroot_dir(self.chroot_dir)
568+ self.call_hooks('install_kernel')
569 if self.needs_bootloader:
570- self.call_hooks('install_bootloader', self.chroot_dir, self.disks)
571- self.call_hooks('install_kernel', self.chroot_dir)
572+ self.call_hooks('install_bootloader', self.disks)
573+ self.call_hooks('install_kernel')
574 self.distro.call_hooks('post_install')
575- self.call_hooks('unmount_partitions')
576- os.rmdir(self.chroot_dir)
577
578 def finalise(self, destdir):
579 self.call_hooks('convert',
580@@ -78,7 +86,7 @@
581 destdir)
582 self.call_hooks('deploy', destdir)
583
584- def mount_partitions(self, mntdir):
585+ def mount_partitions(self):
586 """Mounts all the vm's partitions and filesystems below .rootmnt"""
587 logging.info('Mounting target filesystems')
588 for fs in self.filesystems:
589@@ -91,7 +99,7 @@
590 disk.mkfs()
591 fss = VMBuilder.disk.get_ordered_filesystems(self)
592 for fs in fss:
593- fs.mount(mntdir)
594+ fs.mount(self.chroot_dir)
595 self.distro.post_mount(fs)
596
597 def unmount_partitions(self):
598@@ -108,6 +116,13 @@
599 for disk in disks:
600 disk.convert(destdir, self.filetype)
601
602+ def set_chroot_dir(self, chroot_dir):
603+ self.chroot_dir = chroot_dir
604+
605+ def cleanup(self):
606+ self.distro.cleanup()
607+ super(Hypervisor, self).cleanup()
608+
609 class NIC(object):
610 def __init__(self, type='dhcp', ip=None, network=None, netmask=None,
611 broadcast=None, dns=None, gateway=None):
612
613=== modified file 'VMBuilder/plugins/__init__.py'
614--- VMBuilder/plugins/__init__.py 2010-05-07 09:49:56 +0000
615+++ VMBuilder/plugins/__init__.py 2012-09-04 13:48:23 +0000
616@@ -80,7 +80,9 @@
617 return fullpath
618
619 def install_from_template(self, path, tmplname, context=None, mode=None):
620- return self.install_file(path, VMBuilder.util.render_template(self.__module__.split('.')[2], self.context, tmplname, context), mode=mode)
621+ module = self.__module__.split('.')
622+ result = VMBuilder.util.render_template(module[2], self.context, tmplname, context)
623+ return self.install_file(path, result, mode=mode)
624
625 def run_in_target(self, *args, **kwargs):
626 return util.run_cmd('chroot', self.chroot_dir, *args, **kwargs)
627
628=== modified file 'VMBuilder/plugins/ec2/__init__.py'
629--- VMBuilder/plugins/ec2/__init__.py 2010-02-18 15:54:51 +0000
630+++ VMBuilder/plugins/ec2/__init__.py 2012-09-04 13:48:23 +0000
631@@ -48,7 +48,7 @@
632 self.context.register_setting_group(group)
633
634 def preflight_check(self):
635- if not getattr(self.vm, 'ec2', False):
636+ if not getattr(self.hypervisor, 'ec2', False):
637 return True
638
639 if not self.context.hypervisor.name == 'Xen':
640@@ -79,11 +79,11 @@
641 raise VMBuilderUserError('When building for EC2 you must provide your EC2 user ID (your AWS account number, not your AWS access key ID)')
642
643 if not self.context.ec2_kernel:
644- self.context.ec2_kernel = self.vm.distro.get_ec2_kernel()
645+ self.context.ec2_kernel = self.hypervisor.distro.get_ec2_kernel()
646 logging.debug('%s - to be used for AKI.' %(self.context.ec2_kernel))
647
648 if not self.context.ec2_ramdisk:
649- self.context.ec2_ramdisk = self.vm.distro.ec2_ramdisk_id()
650+ self.context.ec2_ramdisk = self.hypervisor.distro.ec2_ramdisk_id()
651 logging.debug('%s - to be use for the ARI.' %(self.context.ec2_ramdisk))
652
653 if self.context.ec2_upload:
654@@ -107,7 +107,7 @@
655 self.context.addpkg += ['landscape-client']
656
657 def post_install(self):
658- if not getattr(self.vm, 'ec2', False):
659+ if not getattr(self.hypervisor, 'ec2', False):
660 return
661
662 logging.info("Running ec2 postinstall")
663@@ -121,29 +121,29 @@
664 self.context.distro.disable_hwclock_access()
665
666 def deploy(self):
667- if not getattr(self.vm, 'ec2', False):
668+ if not getattr(self.hypervisor, 'ec2', False):
669 return False
670
671 if self.context.ec2_bundle:
672 logging.info("Building EC2 bundle")
673- bundle_cmdline = ['ec2-bundle-image', '--image', self.context.filesystems[0].filename, '--cert', self.vm.ec2_cert, '--privatekey', self.vm.ec2_key, '--user', self.vm.ec2_user, '--prefix', self.vm.ec2_name, '-r', ['i386', 'x86_64'][self.vm.arch == 'amd64'], '-d', self.vm.workdir, '--kernel', self.vm.ec2_kernel, '--ramdisk', self.vm.ec2_ramdisk]
674+ bundle_cmdline = ['ec2-bundle-image', '--image', self.context.filesystems[0].filename, '--cert', self.hypervisor.ec2_cert, '--privatekey', self.hypervisor.ec2_key, '--user', self.hypervisor.ec2_user, '--prefix', self.hypervisor.ec2_name, '-r', ['i386', 'x86_64'][self.hypervisor.arch == 'amd64'], '-d', self.hypervisor.workdir, '--kernel', self.hypervisor.ec2_kernel, '--ramdisk', self.hypervisor.ec2_ramdisk]
675 run_cmd(*bundle_cmdline)
676
677- manifest = '%s/%s.manifest.xml' % (self.context.workdir, self.vm.ec2_name)
678+ manifest = '%s/%s.manifest.xml' % (self.context.workdir, self.hypervisor.ec2_name)
679 if self.context.ec2_upload:
680 logging.info("Uploading EC2 bundle")
681- upload_cmdline = ['ec2-upload-bundle', '--retry', '--manifest', manifest, '--bucket', self.context.ec2_bucket, '--access-key', self.vm.ec2_access_key, '--secret-key', self.vm.ec2_secret_key]
682+ upload_cmdline = ['ec2-upload-bundle', '--retry', '--manifest', manifest, '--bucket', self.context.ec2_bucket, '--access-key', self.hypervisor.ec2_access_key, '--secret-key', self.hypervisor.ec2_secret_key]
683 run_cmd(*upload_cmdline)
684
685 if self.context.ec2_register:
686 from boto.ec2.connection import EC2Connection
687- conn = EC2Connection(self.context.ec2_access_key, self.vm.ec2_secret_key)
688- amiid = conn.register_image('%s/%s.manifest.xml' % (self.context.ec2_bucket, self.vm.ec2_name))
689+ conn = EC2Connection(self.context.ec2_access_key, self.hypervisor.ec2_secret_key)
690+ amiid = conn.register_image('%s/%s.manifest.xml' % (self.context.ec2_bucket, self.hypervisor.ec2_name))
691 print 'Image registered as %s' % amiid
692 else:
693 self.context.result_files.append(manifest)
694 else:
695- self.context.result_files.append(self.vm.filesystems[0].filename)
696+ self.context.result_files.append(self.hypervisor.filesystems[0].filename)
697
698 return True
699
700
701=== modified file 'VMBuilder/plugins/kvm/__init__.py'
702--- VMBuilder/plugins/kvm/__init__.py 2009-06-10 13:40:41 +0000
703+++ VMBuilder/plugins/kvm/__init__.py 2012-09-04 13:48:23 +0000
704@@ -16,4 +16,4 @@
705 # You should have received a copy of the GNU General Public License
706 # along with this program. If not, see <http://www.gnu.org/licenses/>.
707 #
708-import vm
709+import vm
710\ No newline at end of file
711
712=== added file 'VMBuilder/plugins/kvm/disk.py'
713--- VMBuilder/plugins/kvm/disk.py 1970-01-01 00:00:00 +0000
714+++ VMBuilder/plugins/kvm/disk.py 2012-09-04 13:48:23 +0000
715@@ -0,0 +1,38 @@
716+#
717+# Uncomplicated VM Builder
718+# Copyright (C) 2007-2009 Canonical Ltd.
719+#
720+# See AUTHORS for list of contributors
721+#
722+# This program is free software: you can redistribute it and/or modify
723+# it under the terms of the GNU General Public License version 3, as
724+# published by the Free Software Foundation.
725+#
726+# This program is distributed in the hope that it will be useful,
727+# but WITHOUT ANY WARRANTY; without even the implied warranty of
728+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
729+# GNU General Public License for more details.
730+#
731+# You should have received a copy of the GNU General Public License
732+# along with this program. If not, see <http://www.gnu.org/licenses/>.
733+#
734+import VMBuilder.disk
735+from os import path
736+import qemu_nbd
737+
738+class Disk(VMBuilder.disk.Disk):
739+ def _init_(self, hypervisor, filename, size=None):
740+ super(VMBuilder.disk.Disk, self).__init__(hypervisor, filename, size)
741+
742+ def map_partitions(self):
743+ self.nbd = qemu_nbd.connect(self.filename, read_only=False)
744+ self.dev = path.join(self.hypervisor.dev_dir, self.nbd)
745+ for (part, mapdev) in zip(self.partitions, qemu_nbd.list_partitions_from_device(self.nbd)):
746+ mapdev = path.join(self.hypervisor.dev_dir, mapdev)
747+ part.set_dev(mapdev)
748+ part.set_filename(mapdev)
749+
750+ def unmap(self):
751+ qemu_nbd.disconnect(self.nbd)
752+ for part in self.partitions:
753+ part.set_filename(None)
754\ No newline at end of file
755
756=== added file 'VMBuilder/plugins/kvm/qemu_nbd.py'
757--- VMBuilder/plugins/kvm/qemu_nbd.py 1970-01-01 00:00:00 +0000
758+++ VMBuilder/plugins/kvm/qemu_nbd.py 2012-09-04 13:48:23 +0000
759@@ -0,0 +1,117 @@
760+#""" qemu-nbd wrapper """
761+#http://code.activestate.com/recipes/577593-qemu-nbd-python-wrapper/
762+
763+import os
764+from time import sleep
765+from itertools import ifilter
766+from VMBuilder.util import run_cmd
767+
768+def list_devices():
769+ return ifilter(
770+ lambda dev : len(dev.split('p')) == 1,
771+ _list_nbd()
772+ )
773+
774+def list_partitions():
775+ return ifilter(
776+ lambda part: len(part.split('p')) > 1,
777+ _list_nbd()
778+ )
779+
780+def list_partitions_from_device(device):
781+ return ifilter(
782+ lambda part: part.split('p')[0] == device,
783+ list_partitions()
784+ )
785+
786+def _list_nbd():
787+ return ifilter(
788+ lambda dev: dev.startswith("nbd"),
789+ os.listdir("/dev")
790+ )
791+
792+def find_available():
793+ devices = []
794+ busy = []
795+ for x in os.popen("cat /proc/partitions | grep nbd | awk '{print $4}'").readlines():
796+ #needed by pipe
797+ busy.append(x.strip())
798+
799+ for d in list_devices():
800+ if not d in busy:
801+ devices.append(d)
802+
803+ return devices
804+
805+def connect(image_file, read_only=True):
806+ image_file = os.path.realpath(image_file)
807+
808+ if not os.path.exists(image_file):
809+ return False
810+
811+ devices = find_available()
812+ if len(devices) == 0:
813+ return False
814+
815+ dev = devices[0]
816+
817+ if read_only:
818+ read_only = '-r'
819+ else:
820+ read_only = None
821+
822+ run_cmd('qemu-nbd', '-c', '/dev/%s' % dev, read_only, image_file)
823+ sleep(2) # partition discovery
824+ return dev
825+
826+def disconnect(dev=None):
827+ umount(dev)
828+
829+ if dev == None:
830+ for dev in list_devices():
831+ disconnect(dev)
832+ else:
833+ run_cmd('qemu-nbd', '-d', '/dev/%s' % dev)
834+
835+def mount(dev, partition=1, path=None):
836+ full_dev_path = '/dev/%sp%s' % (dev, partition)
837+
838+ if path == None:
839+ import tempfile
840+ path = tempfile.mkdtemp()
841+
842+ run_cmd('mount', full_dev_path, path)
843+
844+ return path
845+
846+def find_mount(dev=None):
847+ if dev == None:
848+ mounts = []
849+ for dev in list_devices():
850+ m = find_mount(dev)
851+ if m != None and m not in mounts:
852+ mounts.append(m)
853+
854+ return mounts
855+
856+ else:
857+ mount = None
858+
859+ sys_mount = os.popen('mount | grep %s' % dev).readline().strip().split(' ')
860+ if len(sys_mount) > 1:
861+ mount = {
862+ 'dev': sys_mount[0],
863+ 'mount': sys_mount[2],
864+ 'type': sys_mount[3]
865+ }
866+
867+ return mount
868+
869+def umount(dev=None):
870+ m = find_mount(dev)
871+
872+ if dev == None:
873+ for x in m:
874+ run_cmd('umount', x['mount'])
875+ elif m != None:
876+ run_cmd('umount', m['mount'])
877\ No newline at end of file
878
879=== modified file 'VMBuilder/plugins/kvm/vm.py'
880--- VMBuilder/plugins/kvm/vm.py 2010-09-24 11:57:05 +0000
881+++ VMBuilder/plugins/kvm/vm.py 2012-09-04 13:48:23 +0000
882@@ -18,6 +18,7 @@
883 #
884 from VMBuilder import register_hypervisor, Hypervisor
885 import VMBuilder
886+import disk
887 import os
888 import stat
889
890@@ -59,6 +60,9 @@
891
892 def libvirt_domain_type_name(self):
893 return 'kvm'
894+
895+ def _create_disk(self, *args, **kwargs):
896+ return disk.Disk(self, *args, **kwargs)
897
898 class QEMu(KVM):
899 name = 'QEMu'
900
901=== modified file 'VMBuilder/plugins/ubuntu/dapper.py'
902--- VMBuilder/plugins/ubuntu/dapper.py 2010-12-02 08:15:01 +0000
903+++ VMBuilder/plugins/ubuntu/dapper.py 2012-09-04 13:48:23 +0000
904@@ -22,6 +22,7 @@
905 import suite
906 import shutil
907 import tempfile
908+import time
909 import VMBuilder.disk as disk
910 from VMBuilder.util import run_cmd
911 from VMBuilder.exception import VMBuilderException
912@@ -35,8 +36,20 @@
913 disk_prefix = 'hd'
914 xen_kernel_flavour = None
915 virtio_net = False
916+ virtio_disk = False
917 chpasswd_cmd = [ 'chpasswd', '--md5' ]
918 preferred_filesystem = 'ext3'
919+ grub_version = 1
920+ grub_partitions_prefix = ''
921+ #prefix to partition. hd0,{prefix}1 (for example)
922+
923+ grub_part = None
924+ # partition with /boot/grub
925+
926+ grub_disk = None
927+ # disk where grub will be installed
928+
929+ grub_offset = 0
930
931 def pre_install(self):
932 pass
933@@ -72,7 +85,7 @@
934 self.call_hook('fix_ownership', manifest)
935
936 def update(self):
937- self.run_in_target('apt-get', '-y', '--force-yes', 'dist-upgrade',
938+ self.run_in_target('apt-get', '-y', '--force-yes', '--no-install-recommends', 'dist-upgrade',
939 env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
940
941 def install_authorized_keys(self):
942@@ -92,29 +105,67 @@
943
944 if ssh_user_key or ssh_key:
945 addpkg = self.context.get_setting('addpkg')
946- addpkg += ['openssh-server']
947+ #use ^ for tasksel
948+ addpkg += ['openssh-server^']
949 self.context.set_setting('addpkg', addpkg)
950
951- def mount_dev_proc(self):
952- run_cmd('mount', '--bind', '/dev', '%s/dev' % self.context.chroot_dir)
953+ def mount(self):
954+ run_cmd('mkdir', '-p', '%s/dev' % self.context.chroot_dir)
955+ run_cmd('mount', '--bind', '%s' % self.context.dev_dir, '%s/dev' % self.context.chroot_dir)
956 self.context.add_clean_cb(self.unmount_dev)
957+ logging.debug("add_clean_cb(self.unmount_dev)")
958+
959+ run_cmd('touch', '%s/dev/urandom' % self.context.chroot_dir)
960+ run_cmd('mount', '--bind', '/dev/urandom', '%s/dev/urandom' % self.context.chroot_dir)
961+ self.context.add_clean_cb(self.unmount_dev_urandom)
962+ logging.debug("add_clean_cb(self.unmount_dev_urandom)")
963
964- run_cmd('mount', '--bind', '/dev/pts', '%s/dev/pts' % self.context.chroot_dir)
965+ run_cmd('mkdir', '-p', '%s/dev/pts' % self.context.chroot_dir)
966+ run_cmd('mount', '-t', 'devpts', 'devpts-chroot', '%s/dev/pts' % self.context.chroot_dir)
967 self.context.add_clean_cb(self.unmount_dev_pts)
968+ logging.debug("add_clean_cb(self.unmount_dev_pts)")
969
970- self.run_in_target('mount', '-t', 'proc', 'proc', '/proc')
971+ run_cmd('mkdir', '-p', '%s/proc' % self.context.chroot_dir)
972+ run_cmd('mount', '-t', 'proc', 'proc-chroot', '%s/proc' % self.context.chroot_dir)
973 self.context.add_clean_cb(self.unmount_proc)
974+ logging.debug("add_clean_cb(self.unmount_proc)")
975+
976+ run_cmd('mkdir', '-p', '%s/sys' % self.context.chroot_dir)
977+ run_cmd('mount', '--bind', '/sys', '%s/sys' % self.context.chroot_dir)
978+ self.context.add_clean_cb(self.unmount_sys)
979+ logging.debug("add_clean_cb(self.unmount_sys)")
980+
981+ def umount(self):
982+ self.unmount_dev_urandom()
983+ self.unmount_dev_pts()
984+ self.unmount_dev()
985+ self.unmount_proc()
986+ self.unmount_sys()
987+ self.unmount_volatile()
988+
989+ def unmount_sys(self):
990+ self.context.cancel_cleanup(self.unmount_sys)
991+ time.sleep(1)
992+ run_cmd('umount', '%s/sys' % self.context.chroot_dir)
993
994 def unmount_proc(self):
995 self.context.cancel_cleanup(self.unmount_proc)
996+ time.sleep(1)
997 run_cmd('umount', '%s/proc' % self.context.chroot_dir)
998
999 def unmount_dev_pts(self):
1000 self.context.cancel_cleanup(self.unmount_dev_pts)
1001+ time.sleep(1)
1002 run_cmd('umount', '%s/dev/pts' % self.context.chroot_dir)
1003
1004+ def unmount_dev_urandom(self):
1005+ self.context.cancel_cleanup(self.unmount_dev_urandom)
1006+ time.sleep(1)
1007+ run_cmd('umount', '%s/dev/urandom' % self.context.chroot_dir)
1008+
1009 def unmount_dev(self):
1010 self.context.cancel_cleanup(self.unmount_dev)
1011+ time.sleep(1)
1012 run_cmd('umount', '%s/dev' % self.context.chroot_dir)
1013
1014 def update_passwords(self):
1015@@ -196,7 +247,7 @@
1016 if not addpkg and not removepkg:
1017 return
1018
1019- cmd = ['apt-get', 'install', '-y', '--force-yes']
1020+ cmd = ['apt-get', 'install', '-y', '--force-yes', '--no-install-recommends']
1021 cmd += addpkg or []
1022 cmd += ['%s-' % pkg for pkg in removepkg or []]
1023 self.run_in_target(env={ 'DEBIAN_FRONTEND' : 'noninteractive' }, *cmd)
1024@@ -208,29 +259,29 @@
1025
1026 def install_menu_lst(self, disks):
1027 self.run_in_target(self.updategrub, '-y')
1028- self.mangle_grub_menu_lst(disks)
1029 self.run_in_target(self.updategrub)
1030 self.run_in_target('grub-set-default', '0')
1031-
1032- def mangle_grub_menu_lst(self, disks):
1033- bootdev = disk.bootpart(disks)
1034- run_cmd('sed', '-ie', 's/^# kopt=root=\([^ ]*\)\(.*\)/# kopt=root=\/dev\/hd%s%d\\2/g' % (bootdev.disk.devletters(), bootdev.get_index()+1), '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1035- run_cmd('sed', '-ie', 's/^# groot.*/# groot %s/g' % bootdev.get_grub_id(), '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1036- run_cmd('sed', '-ie', '/^# kopt_2_6/ d', '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1037+ self.run_in_target(self.updategrub)
1038
1039 def install_sources_list(self, final=False):
1040 if final:
1041- mirror = updates_mirror = self.context.get_setting('mirror')
1042+ mirror = backport_mirror = proposed_mirror = updates_mirror = self.context.get_setting('mirror')
1043 security_mirror = self.context.get_setting('security-mirror')
1044 else:
1045- mirror, updates_mirror, security_mirror = self.install_mirrors()
1046+ mirror, updates_mirror, security_mirror, proposed_mirror, backport_mirror = self.install_mirrors()
1047
1048 components = self.context.get_setting('components')
1049 ppa = self.context.get_setting('ppa')
1050 suite = self.context.get_setting('suite')
1051+ proposed = self.context.get_setting('proposed')
1052+ backport = self.context.get_setting('backport')
1053 self.install_from_template('/etc/apt/sources.list', 'sources.list', { 'mirror' : mirror,
1054 'security_mirror' : security_mirror,
1055 'updates_mirror' : updates_mirror,
1056+ 'proposed' : proposed,
1057+ 'proposed_mirror' : proposed_mirror,
1058+ 'backport' : backport,
1059+ 'backport_mirror' : backport_mirror,
1060 'components' : components,
1061 'ppa' : ppa,
1062 'suite' : suite })
1063@@ -243,13 +294,36 @@
1064 def install_apt_proxy(self):
1065 proxy = self.context.get_setting('proxy')
1066 if proxy is not None:
1067- self.context.install_file('/etc/apt/apt.conf', '// Proxy added by vmbuilder\nAcquire::http { Proxy "%s"; };' % proxy)
1068+ self.context.install_file('/etc/apt/apt.conf.d/01proxy', '// Proxy added by vmbuilder\nAcquire::http { Proxy "%s"; };\n' % proxy)
1069
1070 def install_fstab(self, disks, filesystems):
1071- self.install_from_template('/etc/fstab', 'dapper_fstab', { 'parts' : disk.get_ordered_partitions(disks), 'prefix' : self.disk_prefix })
1072-
1073- def install_device_map(self):
1074- self.install_from_template('/boot/grub/device.map', 'devicemap', { 'prefix' : self.disk_prefix })
1075+ self.install_from_template('/etc/fstab', 'dapper_fstab',
1076+ { 'parts' : disk.get_ordered_partitions(disks),
1077+ 'prefix' : self.disk_prefix })
1078+ #TODO : use labels or UUID
1079+
1080+ def install_device_map(self, disks, final=True):
1081+ self.install_from_template('/boot/grub/device.map', 'devicemap',
1082+ { 'disk_prefix' : self.disk_prefix,
1083+ 'grub_partitions_prefix': self.grub_partitions_prefix,
1084+ 'disks': disks,
1085+ 'grub_offset': self.grub_offset,
1086+ 'final': final })
1087+
1088+ def install_grub_load_cfg(self):
1089+ self.install_from_template('/boot/grub/load.cfg', 'loadcfg',
1090+ { 'UUID': self.grub_part.fs.uuid,
1091+ 'grub_partitions_prefix': self.grub_partitions_prefix,
1092+ 'grub_disk': self.grub_disk,
1093+ 'grub_partition_root_index': self.grub_part.get_index() + self.grub_offset})
1094+
1095+ def install_grub_cfg(self, kernel):
1096+ self.install_from_template('/boot/grub/grub.cfg', 'grubcfg',
1097+ { 'UUID': self.grub_part.fs.uuid,
1098+ 'grub_disk': self.grub_disk,
1099+ 'grub_partitions_prefix': self.grub_partitions_prefix,
1100+ 'grub_partition_root_index': self.grub_part.get_index() + self.grub_offset,
1101+ 'KERNEL': kernel })
1102
1103 def debootstrap(self):
1104 arch = self.context.get_setting('arch')
1105@@ -289,7 +363,7 @@
1106 else:
1107 mirror = self.context.get_setting('mirror')
1108
1109- updates_mirror = mirror
1110+ backport_mirror = proposed_mirror = updates_mirror = mirror
1111
1112 install_security_mirror = self.context.get_setting('install-security-mirror')
1113 if install_security_mirror:
1114@@ -297,16 +371,46 @@
1115 else:
1116 security_mirror = self.context.get_setting('security-mirror')
1117
1118- return (mirror, updates_mirror, security_mirror)
1119-
1120- def install_kernel(self, destdir):
1121- run_cmd('chroot', destdir, 'apt-get', '--force-yes', '-y', 'install', self.kernel_name(), env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1122-
1123- def install_grub(self, chroot_dir):
1124- self.install_from_template('/etc/kernel-img.conf', 'kernelimg', { 'updategrub' : self.updategrub })
1125+ return (mirror, updates_mirror, security_mirror, proposed_mirror, backport_mirror)
1126+
1127+ def install_kernel(self):
1128+ self.run_in_target('apt-get', '--force-yes', '-y', '--no-install-recommends', 'install', self.kernel_name(), env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1129+
1130+ def prepare_grub(self, disks):
1131+ self.grub_part = disk.bootpart(disks)
1132+ self.grub_disk = disks[0]
1133+
1134+ def install_grub(self):
1135 arch = self.context.get_setting('arch')
1136- self.run_in_target('apt-get', '--force-yes', '-y', 'install', 'grub', env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1137- run_cmd('rsync', '-a', '%s%s/%s/' % (chroot_dir, self.grubroot, arch == 'amd64' and 'x86_64-pc' or 'i386-pc'), '%s/boot/grub/' % chroot_dir)
1138+ self.run_in_target('apt-get', '--force-yes', '-y', '--no-install-recommends', 'install', 'grub', env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1139+
1140+ def configure_grub(self, disks):
1141+
1142+ # Install device_map
1143+ self.install_device_map(disks,False)
1144+ self.install_grub_load_cfg()
1145+
1146+ def install_grub_ondisk(self):
1147+ self.run_in_target('grub-install',
1148+ self.grub_disk.dev)
1149+
1150+ def install_menu_lst(self, disks):
1151+ self.run_in_target('grub-set-default', '0')
1152+ self.run_in_target('cp', '/proc/mounts', '/etc/mtab')
1153+ self.run_in_target(self.updategrub)
1154+ self.mangle_grub_menu_lst(disks)
1155+ #Test generate file to stdout
1156+ self.run_in_target('grub-mkconfig')
1157+
1158+ def mangle_grub_menu_lst(self, disks):
1159+ bootdev = disk.bootpart(disks)
1160+ run_cmd('sed', '-ie', 's/^# kopt=root=\([^ ]*\)\(.*\)/# kopt=root=\/dev\/hd%s%d\\2/g' % (bootdev.disk.devletters(), bootdev.get_index()+1), '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1161+ run_cmd('sed', '-ie', 's/^# groot.*/# groot %s/g' % bootdev.get_grub_id(), '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1162+ run_cmd('sed', '-ie', '/^# kopt_2_6/ d', '%s/boot/grub/menu.lst' % self.context.chroot_dir)
1163+
1164+ def finalise_grub(self, disks):
1165+ self.install_menu_lst(disks)
1166+
1167
1168 def create_devices(self):
1169 pass
1170@@ -328,9 +432,9 @@
1171
1172 def copy_to_target(self, infile, destpath):
1173 logging.debug("Copying %s on host to %s in guest" % (infile, destpath))
1174- dir = '%s/%s' % (self.destdir, os.path.dirname(destpath))
1175- if not os.path.isdir(dir):
1176- os.makedirs(dir)
1177+ directory = '%s/%s' % (self.destdir, os.path.dirname(destpath))
1178+ if not os.path.isdir(directory):
1179+ os.makedirs(directory)
1180 if os.path.isdir(infile):
1181 shutil.copytree(infile, '%s/%s' % (self.destdir, destpath))
1182 else:
1183
1184=== modified file 'VMBuilder/plugins/ubuntu/distro.py'
1185--- VMBuilder/plugins/ubuntu/distro.py 2012-08-06 19:37:24 +0000
1186+++ VMBuilder/plugins/ubuntu/distro.py 2012-09-04 13:48:23 +0000
1187@@ -21,10 +21,12 @@
1188 import shutil
1189 import stat
1190 import VMBuilder
1191+import VMBuilder.disk as vmdisk
1192 from VMBuilder import register_distro, Distro
1193 from VMBuilder.util import run_cmd
1194 from VMBuilder.exception import VMBuilderUserError, VMBuilderException
1195
1196+
1197 class Ubuntu(Distro):
1198 name = 'Ubuntu'
1199 arg = 'ubuntu'
1200@@ -33,12 +35,13 @@
1201 'precise', 'quantal' ]
1202
1203 # Maps host arch to valid guest archs
1204- valid_archs = { 'amd64' : ['amd64', 'i386', 'lpia' ],
1205- 'i386' : [ 'i386', 'lpia' ],
1206- 'lpia' : [ 'i386', 'lpia' ] }
1207+ valid_archs = {'amd64': ['amd64', 'i386', 'lpia'],
1208+ 'i386': ['i386', 'lpia'],
1209+ 'lpia': ['i386', 'lpia']}
1210
1211 xen_kernel = ''
1212
1213+
1214 def register_options(self):
1215 group = self.setting_group('Package options')
1216 group.add_setting('addpkg', type='list', metavar='PKG', help='Install PKG into the guest (can be specified multiple times).')
1217@@ -54,16 +57,22 @@
1218 group.add_setting('suite', default='lucid', help='Suite to install. Valid options: %s [default: %%default]' % ' '.join(self.suites))
1219 group.add_setting('flavour', extra_args=['--kernel-flavour'], help='Kernel flavour to use. Default and valid options depend on architecture and suite')
1220 group.add_setting('variant', metavar='VARIANT', help='Passed to debootstrap --variant flag; use minbase, buildd, or fakechroot.')
1221- group.add_setting('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.')
1222+ group.add_setting('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 hypervisor. This requires suite and kernel parameter to match what is available on the iso, obviously.')
1223 group.add_setting('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')
1224 group.add_setting('proxy', metavar='URL', help='Use proxy at URL for cached packages')
1225 group.add_setting('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')
1226 group.add_setting('security-mirror', metavar='URL', help='Use Ubuntu security mirror at URL instead of the default, which is http://security.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise.')
1227 group.add_setting('install-security-mirror', metavar='URL', help='Use the security mirror at URL for installation only. Apt\'s sources.list will still use default or URL set by --security-mirror')
1228 group.add_setting('components', type='list', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
1229+ group.add_setting('backport', type='bool', default=False, help='add backport to sources.list')
1230+ group.add_setting('proposed', type='bool', default=False, help='add proposed to sources.list')
1231+<<<<<<< TREE
1232 group.add_setting('ppa', metavar='PPA', type='list', help='Add ppa belonging to PPA to the vm\'s sources.list.')
1233+=======
1234+ group.add_setting('ppa', metavar='PPA', type='list', help='Add ppa belonging to PPA to the hypervisor\'s sources.list.')
1235+>>>>>>> MERGE-SOURCE
1236 group.add_setting('lang', metavar='LANG', default=get_locale(), help='Set the locale to LANG [default: %default]')
1237- group.add_setting('timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]')
1238+ group.add_setting('timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the hypervisor. [default: %default]')
1239
1240 group = self.setting_group('Settings for the initial user')
1241 group.add_setting('user', default='ubuntu', help='Username of initial user [default: %default]')
1242@@ -89,22 +98,22 @@
1243 self.set_setting_default('mirror', 'http://archive.ubuntu.com/ubuntu')
1244 self.set_setting_default('security-mirror', 'http://security.ubuntu.com/ubuntu')
1245
1246- self.set_setting_default('components', ['main', 'restricted', 'universe'])
1247+ self.set_setting_default('components', ['main', 'restricted', 'universe'])
1248
1249 def preflight_check(self):
1250 """While not all of these are strictly checks, their failure would inevitably
1251 lead to failure, and since we can check them before we start setting up disk
1252 and whatnot, we might as well go ahead an do this now."""
1253
1254- suite = self.get_setting('suite')
1255+ suite = self.get_setting('suite')
1256 if not suite in self.suites:
1257 raise VMBuilderUserError('Invalid suite: "%s". Valid suites are: %s' % (suite, ' '.join(self.suites)))
1258-
1259+
1260 modname = 'VMBuilder.plugins.ubuntu.%s' % (suite, )
1261 mod = __import__(modname, fromlist=[suite])
1262 self.suite = getattr(mod, suite.capitalize())(self)
1263
1264- arch = self.get_setting('arch')
1265+ arch = self.get_setting('arch')
1266 if arch not in self.valid_archs[self.host_arch] or \
1267 not self.suite.check_arch_validity(arch):
1268 raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (arch,
1269@@ -115,7 +124,7 @@
1270 self.set_config_value_list = ['main', 'restricted', 'universe']
1271 else:
1272 if type(components) is str:
1273- self.vm.components = self.vm.components.split(',')
1274+ self.hypervisor.components = self.hypervisor.components.split(',')
1275
1276 self.context.virtio_net = self.use_virtio_net()
1277
1278@@ -127,7 +136,7 @@
1279 lang = self.get_setting('lang')
1280
1281 # FIXME
1282-# if getattr(self.vm, 'ec2', False):
1283+# if getattr(self.hypervisor, 'ec2', False):
1284 # self.get_ec2_kernel()
1285 # self.get_ec2_ramdisk()
1286 # self.apply_ec2_settings()
1287@@ -136,12 +145,40 @@
1288 self.suite.debootstrap()
1289 self.suite.pre_install()
1290
1291+<<<<<<< TREE
1292+<<<<<<< TREE
1293+=======
1294+>>>>>>> MERGE-SOURCE
1295+ def prepare_chroot(self):
1296+ self.suite.create_devices()
1297+ self.suite.mount()
1298+<<<<<<< TREE
1299+=======
1300+ self.run_in_target('cp', '/proc/mounts', '/etc/mtab')
1301+>>>>>>> MERGE-SOURCE
1302+
1303+ def clean_chroot(self):
1304+ self.suite.umount()
1305+
1306+ def install_os(self):
1307+<<<<<<< TREE
1308+=======
1309 def configure_os(self):
1310 self.suite.install_apt_proxy()
1311+>>>>>>> MERGE-SOURCE
1312+=======
1313+>>>>>>> MERGE-SOURCE
1314 self.suite.install_sources_list()
1315+<<<<<<< TREE
1316+ self.suite.install_apt_proxy()
1317+<<<<<<< TREE
1318+=======
1319 self.suite.create_devices()
1320+>>>>>>> MERGE-SOURCE
1321+=======
1322+>>>>>>> MERGE-SOURCE
1323 self.suite.prevent_daemons_starting()
1324- self.suite.mount_dev_proc()
1325+# self.suite.install_grub()
1326 self.suite.install_extras()
1327 self.suite.create_initial_user()
1328 self.suite.install_authorized_keys()
1329@@ -149,11 +186,7 @@
1330 self.suite.set_locale()
1331 self.suite.update()
1332 self.suite.install_sources_list(final=True)
1333- self.suite.run_in_target('apt-get', 'clean');
1334- self.suite.unmount_volatile()
1335- self.suite.unmount_proc()
1336- self.suite.unmount_dev_pts()
1337- self.suite.unmount_dev()
1338+ self.suite.run_in_target("apt-get", "clean")
1339 self.suite.unprevent_daemons_starting()
1340 self.suite.create_manifest()
1341
1342@@ -164,9 +197,9 @@
1343 def configure_mounting(self, disks, filesystems):
1344 self.suite.install_fstab(disks, filesystems)
1345
1346- def install(self, destdir):
1347- self.destdir = destdir
1348- self.suite.install(destdir)
1349+# def install(self, destdir):
1350+# self.destdir = destdir
1351+# self.suite.install(destdir)
1352
1353 def install_vmbuilder_log(self, logfile, rootdir):
1354 self.suite.install_vmbuilder_log(logfile, rootdir)
1355@@ -177,44 +210,27 @@
1356 def use_virtio_net(self):
1357 return self.suite.virtio_net
1358
1359- def install_bootloader_cleanup(self, chroot_dir):
1360- self.context.cancel_cleanup(self.install_bootloader_cleanup)
1361- tmpdir = '%s/tmp/vmbuilder-grub' % chroot_dir
1362- for disk in os.listdir(tmpdir):
1363- if disk != 'device.map':
1364- run_cmd('umount', os.path.join(tmpdir, disk))
1365- shutil.rmtree(tmpdir)
1366-
1367- def install_kernel(self, destdir):
1368- self.suite.install_kernel(destdir)
1369-
1370- def install_bootloader(self, chroot_dir, disks):
1371- root_dev = VMBuilder.disk.bootpart(disks).get_grub_id()
1372-
1373- tmpdir = '/tmp/vmbuilder-grub'
1374- os.makedirs('%s%s' % (chroot_dir, tmpdir))
1375- self.context.add_clean_cb(self.install_bootloader_cleanup)
1376- devmapfile = os.path.join(tmpdir, 'device.map')
1377- devmap = open('%s%s' % (chroot_dir, devmapfile), 'w')
1378- for (disk, id) in zip(disks, range(len(disks))):
1379- new_filename = os.path.join(tmpdir, os.path.basename(disk.filename))
1380- open('%s%s' % (chroot_dir, new_filename), 'w').close()
1381- run_cmd('mount', '--bind', disk.filename, '%s%s' % (chroot_dir, new_filename))
1382- st = os.stat(disk.filename)
1383- if stat.S_ISBLK(st.st_mode):
1384- for (part, part_id) in zip(disk.partitions, range(len(disk.partitions))):
1385- part_mountpnt = '%s%s%d' % (chroot_dir, new_filename, part_id+1)
1386- open(part_mountpnt, 'w').close()
1387- run_cmd('mount', '--bind', part.filename, part_mountpnt)
1388- devmap.write("(hd%d) %s\n" % (id, new_filename))
1389- devmap.close()
1390- run_cmd('cat', '%s%s' % (chroot_dir, devmapfile))
1391- self.suite.install_grub(chroot_dir)
1392- self.run_in_target('grub', '--device-map=%s' % devmapfile, '--batch', stdin='''root %s
1393-setup (hd0)
1394-EOT''' % root_dev)
1395+ def install_kernel(self):
1396+ self.suite.install_kernel()
1397+
1398+ def install_bootloader(self, disks):
1399+<<<<<<< TREE
1400+=======
1401+ self.suite.prepare_grub(disks)
1402+>>>>>>> MERGE-SOURCE
1403+ self.suite.install_grub()
1404+<<<<<<< TREE
1405+ dev_device = VMBuilder.disk.bootpart(disks).devletters()
1406+ self.run_in_target('grub-install', '--force --no-floppy /dev/sd%s' % dev_device)
1407 self.suite.install_menu_lst(disks)
1408- self.install_bootloader_cleanup(chroot_dir)
1409+=======
1410+ self.suite.configure_grub(disks)
1411+ self.suite.install_grub_ondisk()
1412+ #kernel = '3.0.0-12-virtual'
1413+ #self.suite.install_grub_cfg(kernel)
1414+ # Maybe useless. Removing device.map can be a better solution
1415+ self.suite.finalise_grub(disks)
1416+>>>>>>> MERGE-SOURCE
1417
1418 def xen_kernel_version(self):
1419 if self.suite.xen_kernel_flavour:
1420@@ -227,7 +243,7 @@
1421 return self.xen_kernel
1422 if not self.xen_kernel:
1423 rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour)
1424- version = ['0', '0','0', '0']
1425+ version = ['0', '0', '0', '0']
1426
1427 for line in rmad.splitlines():
1428 sline = line.split('|')
1429@@ -242,7 +258,7 @@
1430 if version[0] == '0':
1431 raise VMBuilderException('Something is wrong, no valid xen kernel for the suite %s found by rmadison' % self.context.suite)
1432
1433- self.xen_kernel = '%s.%s.%s-%s' % (version[0],version[1],version[2],version[3])
1434+ self.xen_kernel = '%s.%s.%s-%s' % (version[0], version[1], version[2], version[3])
1435 return self.xen_kernel
1436 else:
1437 raise VMBuilderUserError('There is no valid xen kernel for the suite selected.')
1438@@ -281,6 +297,7 @@
1439 def preferred_filesystem(self):
1440 return self.suite.preferred_filesystem
1441
1442+
1443 def get_locale():
1444 lang = os.getenv('LANG')
1445 if lang is None:
1446
1447=== modified file 'VMBuilder/plugins/ubuntu/intrepid.py'
1448--- VMBuilder/plugins/ubuntu/intrepid.py 2010-06-15 20:56:43 +0000
1449+++ VMBuilder/plugins/ubuntu/intrepid.py 2012-09-04 13:48:23 +0000
1450@@ -28,6 +28,7 @@
1451 xen_kernel_flavour = 'virtual'
1452 ec2_kernel_info = { 'i386' : 'aki-714daa18', 'amd64' : 'aki-4f4daa26' }
1453 ec2_ramdisk_info = { 'i386': 'ari-7e4daa17', 'amd64' : 'ari-4c4daa25' }
1454+ Virtio_disk = True
1455
1456 def install_ec2(self):
1457 # workaround for policy bug on ubuntu-server. (see bug #275432)
1458
1459=== modified file 'VMBuilder/plugins/ubuntu/karmic.py'
1460--- VMBuilder/plugins/ubuntu/karmic.py 2010-02-24 15:49:04 +0000
1461+++ VMBuilder/plugins/ubuntu/karmic.py 2012-09-04 13:48:23 +0000
1462@@ -25,6 +25,7 @@
1463
1464 preferred_filesystem = 'ext4'
1465
1466+
1467 def apply_ec2_settings(self):
1468 self.context.addpkg += ['standard^',
1469 'uec^']
1470
1471=== modified file 'VMBuilder/plugins/ubuntu/lucid.py'
1472--- VMBuilder/plugins/ubuntu/lucid.py 2012-07-24 04:09:25 +0000
1473+++ VMBuilder/plugins/ubuntu/lucid.py 2012-09-04 13:48:23 +0000
1474@@ -19,14 +19,42 @@
1475 import os
1476 from VMBuilder.util import run_cmd
1477 from VMBuilder.plugins.ubuntu.karmic import Karmic
1478+from VMBuilder.util import run_cmd
1479
1480 class Lucid(Karmic):
1481 valid_flavours = { 'i386' : ['386', 'generic', 'generic-pae', 'virtual'],
1482 'amd64' : ['generic', 'preempt', 'server', 'virtual'] }
1483-
1484 def divert_file(self, path, add):
1485 if add: action = "--add"
1486 else: action = "--remove"
1487 if not add:
1488 os.remove('%s/%s' % (self.context.chroot_dir, path))
1489 run_cmd('chroot', self.context.chroot_dir, 'dpkg-divert', '--local', '--rename', action, path)
1490+
1491+ grub_version = 2
1492+ grub_offset = 1
1493+
1494+ def install_grub(self):
1495+ self.run_in_target('apt-get', '--force-yes', '-y', 'install', 'grub-pc', env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1496+
1497+ def install_grub_ondisk(self):
1498+# self.run_in_target('grub-probe', '--device-map=/boot/grub/device.map', '-d', '(hd0)')
1499+ self.run_in_target('grub-install',
1500+ '--no-floppy',
1501+# '--grub-mkdevicemap=/boot/grub/device.map',
1502+ '--modules=ext2.mod',
1503+ '--modules=part_msdos.mod',
1504+ self.grub_disk.dev)
1505+ self.run_in_target('update-grub2')
1506+
1507+ def mangle_grub_menu_lst(self, disks):
1508+ run_cmd('sed', '-ie', '/insmod gzio/ a\ insmod part_msdos', '%s/boot/grub/grub.cfg' % self.context.chroot_dir)
1509+ dev_final = '(' + self.grub_disk.get_grub_id() + ',' + self.grub_partitions_prefix + str(self.grub_part.get_index() + self.grub_offset) + ')'
1510+ run_cmd('sed', '-ie', 's-/dev/loop[0-9]-%s-g' % dev_final, '%s/boot/grub/grub.cfg' % self.context.chroot_dir)
1511+ run_cmd('sed', '-ie', '/loopback/d', '%s/boot/grub/grub.cfg' % self.context.chroot_dir)
1512+ run_cmd('sed', '-ie', '/set root=(loop/d', '%s/boot/grub/grub.cfg' % self.context.chroot_dir)
1513+
1514+
1515+ def finalise_grub(self, disks):
1516+ self.install_menu_lst(disks)
1517+ self.install_device_map(disks,True)
1518
1519=== modified file 'VMBuilder/plugins/ubuntu/oneiric.py'
1520--- VMBuilder/plugins/ubuntu/oneiric.py 2012-07-24 04:09:25 +0000
1521+++ VMBuilder/plugins/ubuntu/oneiric.py 2012-09-04 13:48:23 +0000
1522@@ -16,7 +16,28 @@
1523 # You should have received a copy of the GNU General Public License
1524 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1525 #
1526+
1527 from VMBuilder.plugins.ubuntu.natty import Natty
1528
1529 class Oneiric(Natty):
1530- pass
1531+ grub_partitions_prefix = 'msdos'
1532+
1533+ def install_grub_ondisk(self):
1534+# self.run_in_target('grub-probe', '--device-map=/boot/grub/device.map', '-d', '(hd0)')
1535+ self.run_in_target('grub-install',
1536+ '--no-floppy',
1537+# '--grub-mkdevicemap=/boot/grub/device.map',
1538+ '--modules=ext2.mod',
1539+ '--modules=part_msdos.mod',
1540+ self.grub_disk.dev)
1541+ self.run_in_target('update-grub2')
1542+
1543+ def unmount_dev(self):
1544+ # no idea why, but something keep /dev busy briefly during the
1545+ # bootstrap
1546+ time.sleep(1)
1547+ super(Oneiric, self).unmount_dev()
1548+
1549+ def install_grub(self):
1550+ arch = self.context.get_setting('arch')
1551+ self.run_in_target('apt-get', '--force-yes', '-y', 'install', 'grub-pc', env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
1552
1553=== added file 'VMBuilder/plugins/ubuntu/precise.py'
1554--- VMBuilder/plugins/ubuntu/precise.py 1970-01-01 00:00:00 +0000
1555+++ VMBuilder/plugins/ubuntu/precise.py 2012-09-04 13:48:23 +0000
1556@@ -0,0 +1,22 @@
1557+#
1558+# Uncomplicated VM Builder
1559+# Copyright (C) 2010 Canonical Ltd.
1560+#
1561+# See AUTHORS for list of contributors
1562+#
1563+# This program is free software: you can redistribute it and/or modify
1564+# it under the terms of the GNU General Public License version 3, as
1565+# published by the Free Software Foundation.
1566+#
1567+# This program is distributed in the hope that it will be useful,
1568+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1569+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1570+# GNU General Public License for more details.
1571+#
1572+# You should have received a copy of the GNU General Public License
1573+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1574+#
1575+from VMBuilder.plugins.ubuntu.oneiric import Oneiric
1576+
1577+class Precise(Oneiric):
1578+ pass
1579\ No newline at end of file
1580
1581=== renamed file 'VMBuilder/plugins/ubuntu/precise.py' => 'VMBuilder/plugins/ubuntu/precise.py.moved'
1582=== added file 'VMBuilder/plugins/ubuntu/templates/Copy of devicemap.tmpl'
1583--- VMBuilder/plugins/ubuntu/templates/Copy of devicemap.tmpl 1970-01-01 00:00:00 +0000
1584+++ VMBuilder/plugins/ubuntu/templates/Copy of devicemap.tmpl 2012-09-04 13:48:23 +0000
1585@@ -0,0 +1,17 @@
1586+#if $final
1587+#for $disk in $disks
1588+(hd$disk.get_index()) /dev/$disk_prefix$disk.devletters()
1589+#for $part in $disk.partitions
1590+#set $grub_part_index = $part.get_index() + $grub_offset
1591+(hd$disk.get_index(),$grub_partitions_prefix$grub_part_index) /dev/$disk_prefix$part.get_suffix()
1592+#end for
1593+#end for
1594+#else
1595+#for $disk in $disks
1596+(hd$disk.get_index()) $disk.dev
1597+#for $part in $disk.partitions
1598+#set $grub_part_index = $part.get_index() + $grub_offset
1599+(hd$disk.get_index(),$grub_partitions_prefix$grub_part_index) $part.dev
1600+#end for
1601+#end for
1602+#end if
1603
1604=== modified file 'VMBuilder/plugins/ubuntu/templates/devicemap.tmpl'
1605--- VMBuilder/plugins/ubuntu/templates/devicemap.tmpl 2008-10-17 17:41:05 +0000
1606+++ VMBuilder/plugins/ubuntu/templates/devicemap.tmpl 2012-09-04 13:48:23 +0000
1607@@ -1,3 +1,9 @@
1608-#for $disk in $disks
1609-$disk.get_grub_id() /dev/$prefix$disk.devletters()
1610-#end for
1611+#if $final
1612+#for $disk in $disks
1613+(hd$disk.get_index()) /dev/$disk_prefix$disk.devletters()
1614+#end for
1615+#else
1616+#for $disk in $disks
1617+(hd$disk.get_index()) $disk.dev
1618+#end for
1619+#end if
1620
1621=== added file 'VMBuilder/plugins/ubuntu/templates/grubcfg.tmpl'
1622--- VMBuilder/plugins/ubuntu/templates/grubcfg.tmpl 1970-01-01 00:00:00 +0000
1623+++ VMBuilder/plugins/ubuntu/templates/grubcfg.tmpl 2012-09-04 13:48:23 +0000
1624@@ -0,0 +1,8 @@
1625+insmod gzio
1626+insmod part_msdos
1627+insmod ext2
1628+set root='(hd$grub_disk.get_index(),$grub_partitions_prefix$grub_partition_root_index)'
1629+search --no-floppy --fs-uuid --set=root $UUID
1630+linux /boot/vmlinuz-$KERNEL root=UUID=$UUID ro quiet splash
1631+initrd /boot/initrd.img-$KERNEL
1632+boot
1633\ No newline at end of file
1634
1635=== added file 'VMBuilder/plugins/ubuntu/templates/loadcfg.tmpl'
1636--- VMBuilder/plugins/ubuntu/templates/loadcfg.tmpl 1970-01-01 00:00:00 +0000
1637+++ VMBuilder/plugins/ubuntu/templates/loadcfg.tmpl 2012-09-04 13:48:23 +0000
1638@@ -0,0 +1,3 @@
1639+search.fs_uuid $UUID root
1640+set prefix=(\$root)/boot/grub
1641+set root=(hd$grub_disk.get_index(),$grub_partitions_prefix$grub_partition_root_index)
1642\ No newline at end of file
1643
1644=== modified file 'VMBuilder/plugins/ubuntu/templates/sources.list.tmpl'
1645--- VMBuilder/plugins/ubuntu/templates/sources.list.tmpl 2011-04-19 08:29:59 +0000
1646+++ VMBuilder/plugins/ubuntu/templates/sources.list.tmpl 2012-09-04 13:48:23 +0000
1647@@ -7,6 +7,16 @@
1648 deb $security_mirror $suite-security #slurp
1649 #echo ' '.join($components)
1650
1651+#if $backport
1652+deb $backport_mirror $suite-backport
1653+#echo ' '.join($components)
1654+#end if
1655+
1656+#if $proposed
1657+deb $proposed_mirror $suite-proposed
1658+#echo ' '.join($components)
1659+#end if
1660+
1661 #if $ppa
1662 #for $p in $ppa
1663 deb http://ppa.launchpad.net/$p/ubuntu $suite main
1664
1665=== modified file 'VMBuilder/tests/disk_tests.py'
1666--- VMBuilder/tests/disk_tests.py 2010-03-29 22:10:16 +0000
1667+++ VMBuilder/tests/disk_tests.py 2012-09-04 13:48:23 +0000
1668@@ -199,8 +199,8 @@
1669 self.tmpfile = get_temp_filename()
1670 os.unlink(self.tmpfile)
1671
1672- self.vm = MockHypervisor()
1673- self.disk = self.vm.add_disk(self.tmpfile, size='1G')
1674+ self.hypervisor = MockHypervisor()
1675+ self.disk = self.hypervisor.add_disk(self.tmpfile, size='1G')
1676 self.disk.create()
1677
1678 def tearDown(self):
1679@@ -215,7 +215,7 @@
1680 self.assertRaises(VMBuilderUserError, self.disk.add_part, 512, 514, 'ext3', '/')
1681
1682 def test_partition_table_empty(self):
1683- from VMBuilder.util import run_cmd
1684+# from VMBuilder.util import run_cmd
1685
1686 file_output = run_cmd('file', self.tmpfile)
1687 self.assertEqual('%s: data' % self.tmpfile, file_output.strip())
1688@@ -232,7 +232,7 @@
1689 Number Start End Size Type File system Flags''' % self.tmpfile, file_output.strip())
1690
1691 def test_partition_table_nonempty(self):
1692- from VMBuilder.util import run_cmd
1693+# from VMBuilder.util import run_cmd
1694
1695 self.disk.add_part(1, 1023, 'ext3', '/')
1696 self.disk.partition()
1697@@ -251,7 +251,7 @@
1698 self.disk.partition()
1699 self.disk.map_partitions()
1700 try:
1701- from VMBuilder.disk import detect_size
1702+# from VMBuilder.disk import detect_size
1703 self.assertEqual(detect_size(self.disk.partitions[0].filename), 1023000576)
1704 except:
1705 raise
1706@@ -275,7 +275,7 @@
1707
1708 tmpfile2 = get_temp_filename()
1709 os.unlink(tmpfile2)
1710- disk2 = self.vm.add_disk(tmpfile2, '1G')
1711+ disk2 = self.hypervisor.add_disk(tmpfile2, '1G')
1712 self.assertEqual(self.disk.get_grub_id(), '(hd0)')
1713 self.assertEqual(disk2.get_grub_id(), '(hd1)')
1714
1715@@ -284,6 +284,6 @@
1716
1717 tmpfile2 = get_temp_filename()
1718 os.unlink(tmpfile2)
1719- disk2 = self.vm.add_disk(tmpfile2, '1G')
1720+ disk2 = self.hypervisor.add_disk(tmpfile2, '1G')
1721 self.assertEqual(self.disk.get_index(), 0)
1722 self.assertEqual(disk2.get_index(), 1)
1723
1724=== modified file 'VMBuilder/tests/plugin_tests.py'
1725--- VMBuilder/tests/plugin_tests.py 2010-02-25 23:41:18 +0000
1726+++ VMBuilder/tests/plugin_tests.py 2012-09-04 13:48:23 +0000
1727@@ -13,8 +13,8 @@
1728 pass
1729
1730 def setUp(self):
1731- self.vm = self.VM()
1732- self.plugin = self.TestPlugin(self.vm)
1733+ self.hypervisor = self.VM()
1734+ self.plugin = self.TestPlugin(self.hypervisor)
1735 self.i = 0
1736
1737 def test_add_setting_group_and_setting(self):
1738@@ -22,17 +22,17 @@
1739 self.assertTrue(setting_group in self.plugin._setting_groups, "Setting not added correctly to plugin's registry of setting groups.")
1740
1741 setting_group.add_setting('testsetting')
1742- self.assertEqual(self.vm.get_setting('testsetting'), None, "Setting's default value is not None.")
1743-
1744- self.vm.set_setting_default('testsetting', 'newdefault')
1745- self.assertEqual(self.vm.get_setting('testsetting'), 'newdefault', "Setting does not return custom default value when no value is set.")
1746- self.assertEqual(self.vm.get_setting_default('testsetting'), 'newdefault', "Setting does not return custom default value through get_setting_default().")
1747-
1748- self.vm.set_setting('testsetting', 'foo')
1749- self.assertEqual(self.vm.get_setting('testsetting'), 'foo', "Setting does not return set value.")
1750-
1751- self.vm.set_setting_default('testsetting', 'newerdefault')
1752- self.assertEqual(self.vm.get_setting('testsetting'), 'foo', "Setting does not return set value after setting new default value.")
1753+ self.assertEqual(self.hypervisor.get_setting('testsetting'), None, "Setting's default value is not None.")
1754+
1755+ self.hypervisor.set_setting_default('testsetting', 'newdefault')
1756+ self.assertEqual(self.hypervisor.get_setting('testsetting'), 'newdefault', "Setting does not return custom default value when no value is set.")
1757+ self.assertEqual(self.hypervisor.get_setting_default('testsetting'), 'newdefault', "Setting does not return custom default value through get_setting_default().")
1758+
1759+ self.hypervisor.set_setting('testsetting', 'foo')
1760+ self.assertEqual(self.hypervisor.get_setting('testsetting'), 'foo', "Setting does not return set value.")
1761+
1762+ self.hypervisor.set_setting_default('testsetting', 'newerdefault')
1763+ self.assertEqual(self.hypervisor.get_setting('testsetting'), 'foo', "Setting does not return set value after setting new default value.")
1764
1765 def test_invalid_type_raises_exception(self):
1766 setting_group = self.plugin.setting_group('Test Setting Group')
1767@@ -42,13 +42,13 @@
1768 setting_group = self.plugin.setting_group('Test Setting Group')
1769
1770 setting_group.add_setting('strsetting')
1771- self.assertRaises(VMBuilderException, self.vm.set_setting_valid_options, 'strsetting', '')
1772- self.vm.set_setting_valid_options('strsetting', ['foo', 'bar'])
1773- self.assertEqual(self.vm.get_setting_valid_options('strsetting'), ['foo', 'bar'])
1774- self.vm.set_setting('strsetting', 'foo')
1775- self.assertRaises(VMBuilderException, self.vm.set_setting, 'strsetting', 'baz')
1776- self.vm.set_setting_valid_options('strsetting', None)
1777- self.vm.set_setting('strsetting', 'baz')
1778+ self.assertRaises(VMBuilderException, self.hypervisor.set_setting_valid_options, 'strsetting', '')
1779+ self.hypervisor.set_setting_valid_options('strsetting', ['foo', 'bar'])
1780+ self.assertEqual(self.hypervisor.get_setting_valid_options('strsetting'), ['foo', 'bar'])
1781+ self.hypervisor.set_setting('strsetting', 'foo')
1782+ self.assertRaises(VMBuilderException, self.hypervisor.set_setting, 'strsetting', 'baz')
1783+ self.hypervisor.set_setting_valid_options('strsetting', None)
1784+ self.hypervisor.set_setting('strsetting', 'baz')
1785
1786 def test_invalid_type_setting_raises_exception(self):
1787 setting_group = self.plugin.setting_group('Test Setting Group')
1788@@ -102,18 +102,18 @@
1789
1790 for setting_type in test_table:
1791 for good in setting_type['good']:
1792- try_good_setting(setting_type['type'], good, self.vm.get_setting, self.vm.set_setting)
1793- try_good_setting(setting_type['type'], good, self.vm.get_setting, self.vm.set_setting_default)
1794- try_good_setting(setting_type['type'], good, self.vm.get_setting_default, self.vm.set_setting_default)
1795- try_good_setting(setting_type['type'], good, self.vm.get_setting, self.vm.set_setting_fuzzy)
1796+ try_good_setting(setting_type['type'], good, self.hypervisor.get_setting, self.hypervisor.set_setting)
1797+ try_good_setting(setting_type['type'], good, self.hypervisor.get_setting, self.hypervisor.set_setting_default)
1798+ try_good_setting(setting_type['type'], good, self.hypervisor.get_setting_default, self.hypervisor.set_setting_default)
1799+ try_good_setting(setting_type['type'], good, self.hypervisor.get_setting, self.hypervisor.set_setting_fuzzy)
1800 for fuzzy in setting_type['fuzzy']:
1801- try_good_setting(setting_type['type'], fuzzy, self.vm.get_setting, self.vm.set_setting_fuzzy)
1802+ try_good_setting(setting_type['type'], fuzzy, self.hypervisor.get_setting, self.hypervisor.set_setting_fuzzy)
1803 for bad in setting_type['bad']:
1804- try_bad_setting(setting_type['type'], bad, self.vm.set_setting)
1805- try_bad_setting(setting_type['type'], bad, self.vm.set_setting_default)
1806+ try_bad_setting(setting_type['type'], bad, self.hypervisor.set_setting)
1807+ try_bad_setting(setting_type['type'], bad, self.hypervisor.set_setting_default)
1808
1809 def test_set_setting_raises_exception_on_invalid_setting(self):
1810- self.assertRaises(VMBuilderException, self.vm.set_setting_default, 'testsetting', 'newdefault')
1811+ self.assertRaises(VMBuilderException, self.hypervisor.set_setting_default, 'testsetting', 'newdefault')
1812
1813 def test_add_setting(self):
1814 setting_group = self.plugin.setting_group('Test Setting Group')
1815
1816=== modified file 'VMBuilder/util.py'
1817--- VMBuilder/util.py 2010-06-10 17:20:58 +0000
1818+++ VMBuilder/util.py 2012-09-04 13:48:23 +0000
1819@@ -81,7 +81,7 @@
1820 env = kwargs.get('env', {})
1821 stdin = kwargs.get('stdin', None)
1822 ignore_fail = kwargs.get('ignore_fail', False)
1823- args = [str(arg) for arg in argv]
1824+ args = [str(arg) for arg in argv if not arg is None]
1825 logging.debug(args.__repr__())
1826 if stdin:
1827 logging.debug('stdin was set and it was a string: %s' % (stdin,))
1828
1829=== modified file 'VMBuilder/vm.py'
1830--- VMBuilder/vm.py 2010-05-11 10:14:14 +0000
1831+++ VMBuilder/vm.py 2012-09-04 13:48:23 +0000
1832@@ -49,7 +49,7 @@
1833
1834 """
1835 def __init__(self, conf=None):
1836- self.hypervisor = None #: hypervisor object, representing the hypervisor the vm is destined for
1837+ self.hypervisor = None #: hypervisor object, representing the hypervisor the hypervisor is destined for
1838 self.distro = None
1839
1840 self.disks = []
1841@@ -70,7 +70,7 @@
1842
1843 self.fsmounted = False
1844
1845- self.optparser = _MyOptParser(epilog="ubuntu-vm-builder is Copyright (C) 2007-2009 Canonical Ltd. and written by Soren Hansen <soren@linux2go.dk>.", usage='%prog hypervisor distro [options]')
1846+ self.optparser = _MyOptParser(epilog="ubuntu-hypervisor-builder is Copyright (C) 2007-2009 Canonical Ltd. and written by Soren Hansen <soren@linux2go.dk>.", usage='%prog hypervisor distro [options]')
1847 self.optparser.arg_help = (('hypervisor', self.hypervisor_help), ('distro', self.distro_help))
1848
1849 self.confparser = ConfigParser.SafeConfigParser()

Subscribers

People subscribed via source and target branches