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