1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import logging
20 import os
21 import shutil
22 import stat
23 import VMBuilder
24 from VMBuilder import register_distro, Distro
25 from VMBuilder.util import run_cmd
26 from VMBuilder.exception import VMBuilderUserError, VMBuilderException
27
29 name = 'Ubuntu'
30 arg = 'ubuntu'
31 suites = ['dapper', 'gutsy', 'hardy', 'intrepid', 'jaunty',
32 'karmic', 'lucid', 'maverick', 'natty', 'oneiric']
33
34
35 valid_archs = { 'amd64' : ['amd64', 'i386', 'lpia' ],
36 'i386' : [ 'i386', 'lpia' ],
37 'lpia' : [ 'i386', 'lpia' ] }
38
39 xen_kernel = ''
40
42 group = self.setting_group('Package options')
43 group.add_setting('addpkg', type='list', metavar='PKG', help='Install PKG into the guest (can be specified multiple times).')
44 group.add_setting('removepkg', type='list', metavar='PKG', help='Remove PKG from the guest (can be specified multiple times)')
45 group.add_setting('seedfile', metavar="SEEDFILE", help='Seed the debconf database with the contents of this seed file before installing packages')
46
47 group = self.setting_group('General OS options')
48 self.host_arch = run_cmd('dpkg', '--print-architecture').rstrip()
49 group.add_setting('arch', extra_args=['-a'], default=self.host_arch, help='Specify the target architecture. Valid options: amd64 i386 lpia (defaults to host arch)')
50 group.add_setting('hostname', default='ubuntu', help='Set NAME as the hostname of the guest. Default: ubuntu. Also uses this name as the VM name.')
51
52 group = self.setting_group('Installation options')
53 group.add_setting('suite', default='lucid', help='Suite to install. Valid options: %s [default: %%default]' % ' '.join(self.suites))
54 group.add_setting('flavour', extra_args=['--kernel-flavour'], help='Kernel flavour to use. Default and valid options depend on architecture and suite')
55 group.add_setting('variant', metavar='VARIANT', help='Passed to debootstrap --variant flag; use minbase, buildd, or fakechroot.')
56 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.')
57 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')
58 group.add_setting('proxy', metavar='URL', help='Use proxy at URL for cached packages')
59 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')
60 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.')
61 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')
62 group.add_setting('components', type='list', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
63 group.add_setting('ppa', metavar='PPA', type='list', help='Add ppa belonging to PPA to the vm\'s sources.list.')
64 group.add_setting('lang', metavar='LANG', default=get_locale(), help='Set the locale to LANG [default: %default]')
65 group.add_setting('timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]')
66
67 group = self.setting_group('Settings for the initial user')
68 group.add_setting('user', default='ubuntu', help='Username of initial user [default: %default]')
69 group.add_setting('name', default='Ubuntu', help='Full name of initial user [default: %default]')
70 group.add_setting('pass', default='ubuntu', help='Password of initial user [default: %default]')
71 group.add_setting('rootpass', help='Initial root password (WARNING: this has strong security implications).')
72 group.add_setting('uid', type='int', help='Initial UID value.')
73 group.add_setting('gid', help='Initial GID value.')
74 group.add_setting('lock-user', type='bool', default=False, help='Lock the initial user [default: %default]')
75
76 group = self.setting_group('Other options')
77 group.add_setting('ssh-key', metavar='PATH', help='Add PATH to root\'s ~/.ssh/authorized_keys (WARNING: this has strong security implications).')
78 group.add_setting('ssh-user-key', help='Add PATH to the user\'s ~/.ssh/authorized_keys.')
79 group.add_setting('manifest', metavar='PATH', help='If passed, a manifest will be written to PATH')
80
92
94 """While not all of these are strictly checks, their failure would inevitably
95 lead to failure, and since we can check them before we start setting up disk
96 and whatnot, we might as well go ahead an do this now."""
97
98 suite = self.get_setting('suite')
99 if not suite in self.suites:
100 raise VMBuilderUserError('Invalid suite: "%s". Valid suites are: %s' % (suite, ' '.join(self.suites)))
101
102 modname = 'VMBuilder.plugins.ubuntu.%s' % (suite, )
103 mod = __import__(modname, fromlist=[suite])
104 self.suite = getattr(mod, suite.capitalize())(self)
105
106 arch = self.get_setting('arch')
107 if arch not in self.valid_archs[self.host_arch] or \
108 not self.suite.check_arch_validity(arch):
109 raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (arch,
110 ' '.join(self.valid_archs[self.host_arch])))
111
112 components = self.get_setting('components')
113 if not components:
114 self.set_config_value_list = ['main', 'restricted', 'universe']
115 else:
116 if type(components) is str:
117 self.vm.components = self.vm.components.split(',')
118
119 self.context.virtio_net = self.use_virtio_net()
120
121
122 seedfile = self.context.get_setting('seedfile')
123 if seedfile and not os.path.exists(seedfile):
124 raise VMBuilderUserError("Seedfile '%s' does not exist" % seedfile)
125
126 lang = self.get_setting('lang')
127
128
129
130
131
132
133
137
158
162
165
169
172
173 - def post_mount(self, fs):
175
178
186
189
191 root_dev = VMBuilder.disk.bootpart(disks).get_grub_id()
192
193 tmpdir = '/tmp/vmbuilder-grub'
194 os.makedirs('%s%s' % (chroot_dir, tmpdir))
195 self.context.add_clean_cb(self.install_bootloader_cleanup)
196 devmapfile = os.path.join(tmpdir, 'device.map')
197 devmap = open('%s%s' % (chroot_dir, devmapfile), 'w')
198 for (disk, id) in zip(disks, range(len(disks))):
199 new_filename = os.path.join(tmpdir, os.path.basename(disk.filename))
200 open('%s%s' % (chroot_dir, new_filename), 'w').close()
201 run_cmd('mount', '--bind', disk.filename, '%s%s' % (chroot_dir, new_filename))
202 st = os.stat(disk.filename)
203 if stat.S_ISBLK(st.st_mode):
204 for (part, part_id) in zip(disk.partitions, range(len(disk.partitions))):
205 part_mountpnt = '%s%s%d' % (chroot_dir, new_filename, part_id+1)
206 open(part_mountpnt, 'w').close()
207 run_cmd('mount', '--bind', part.filename, part_mountpnt)
208 devmap.write("(hd%d) %s\n" % (id, new_filename))
209 devmap.close()
210 run_cmd('cat', '%s%s' % (chroot_dir, devmapfile))
211 self.suite.install_grub(chroot_dir)
212 self.run_in_target('grub', '--device-map=%s' % devmapfile, '--batch', stdin='''root %s
213 setup (hd0)
214 EOT''' % root_dev)
215 self.suite.install_menu_lst(disks)
216 self.install_bootloader_cleanup(chroot_dir)
217
219 if self.suite.xen_kernel_flavour:
220
221
222
223 if hasattr(self.context, 'ec2') and self.context.ec2:
224 logging.debug("selecting ec2 kernel")
225 self.xen_kernel = "2.6.ec2-kernel"
226 return self.xen_kernel
227 if not self.xen_kernel:
228 rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour)
229 version = ['0', '0','0', '0']
230
231 for line in rmad.splitlines():
232 sline = line.split('|')
233
234 if sline[2].strip().startswith(self.context.get_setting('suite')):
235 vt = sline[1].strip().split('.')
236 for i in range(4):
237 if int(vt[i]) > int(version[i]):
238 version = vt
239 break
240
241 if version[0] == '0':
242 raise VMBuilderException('Something is wrong, no valid xen kernel for the suite %s found by rmadison' % self.context.suite)
243
244 self.xen_kernel = '%s.%s.%s-%s' % (version[0],version[1],version[2],version[3])
245 return self.xen_kernel
246 else:
247 raise VMBuilderUserError('There is no valid xen kernel for the suite selected.')
248
252
255
258
264
270
273
276
279
282
284 lang = os.getenv('LANG')
285 if lang is None:
286 return 'C'
287
288
289 if lang.endswith('utf8'):
290 return lang[:-4] + 'UTF-8'
291 return lang
292
293 register_distro(Ubuntu)
294