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('debootstrap-tarball', metavar='FILE', help='Passed to debootstrap --unpack-tarball flag.')
58 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.')
59 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')
60 group.add_setting('proxy', metavar='URL', help='Use proxy at URL for cached packages')
61 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')
62 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.')
63 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')
64 group.add_setting('components', type='list', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).')
65 group.add_setting('ppa', metavar='PPA', type='list', help='Add ppa belonging to PPA to the vm\'s sources.list.')
66 group.add_setting('lang', metavar='LANG', default=get_locale(), help='Set the locale to LANG [default: %default]')
67 group.add_setting('timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]')
68
69 group = self.setting_group('Settings for the initial user')
70 group.add_setting('user', default='ubuntu', help='Username of initial user [default: %default]')
71 group.add_setting('name', default='Ubuntu', help='Full name of initial user [default: %default]')
72 group.add_setting('pass', default='ubuntu', help='Password of initial user [default: %default]')
73 group.add_setting('rootpass', help='Initial root password (WARNING: this has strong security implications).')
74 group.add_setting('uid', type='int', help='Initial UID value.')
75 group.add_setting('gid', help='Initial GID value.')
76 group.add_setting('lock-user', type='bool', default=False, help='Lock the initial user [default: %default]')
77
78 group = self.setting_group('Other options')
79 group.add_setting('ssh-key', metavar='PATH', help='Add PATH to root\'s ~/.ssh/authorized_keys (WARNING: this has strong security implications).')
80 group.add_setting('ssh-user-key', help='Add PATH to the user\'s ~/.ssh/authorized_keys.')
81 group.add_setting('manifest', metavar='PATH', help='If passed, a manifest will be written to PATH')
82
94
96 """While not all of these are strictly checks, their failure would inevitably
97 lead to failure, and since we can check them before we start setting up disk
98 and whatnot, we might as well go ahead an do this now."""
99
100 suite = self.get_setting('suite')
101 if not suite in self.suites:
102 raise VMBuilderUserError('Invalid suite: "%s". Valid suites are: %s' % (suite, ' '.join(self.suites)))
103
104 modname = 'VMBuilder.plugins.ubuntu.%s' % (suite, )
105 mod = __import__(modname, fromlist=[suite])
106 self.suite = getattr(mod, suite.capitalize())(self)
107
108 arch = self.get_setting('arch')
109 if arch not in self.valid_archs[self.host_arch] or \
110 not self.suite.check_arch_validity(arch):
111 raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (arch,
112 ' '.join(self.valid_archs[self.host_arch])))
113
114 components = self.get_setting('components')
115 if not components:
116 self.set_config_value_list = ['main', 'restricted', 'universe']
117 else:
118 if type(components) is str:
119 self.vm.components = self.vm.components.split(',')
120
121 self.context.virtio_net = self.use_virtio_net()
122
123
124 seedfile = self.context.get_setting('seedfile')
125 if seedfile and not os.path.exists(seedfile):
126 raise VMBuilderUserError("Seedfile '%s' does not exist" % seedfile)
127
128 lang = self.get_setting('lang')
129
130
131
132
133
134
135
139
160
164
167
171
174
175 - def post_mount(self, fs):
177
180
188
191
193 root_dev = VMBuilder.disk.bootpart(disks).get_grub_id()
194
195 tmpdir = '/tmp/vmbuilder-grub'
196 os.makedirs('%s%s' % (chroot_dir, tmpdir))
197 self.context.add_clean_cb(self.install_bootloader_cleanup)
198 devmapfile = os.path.join(tmpdir, 'device.map')
199 devmap = open('%s%s' % (chroot_dir, devmapfile), 'w')
200 for (disk, id) in zip(disks, range(len(disks))):
201 new_filename = os.path.join(tmpdir, os.path.basename(disk.filename))
202 open('%s%s' % (chroot_dir, new_filename), 'w').close()
203 run_cmd('mount', '--bind', disk.filename, '%s%s' % (chroot_dir, new_filename))
204 st = os.stat(disk.filename)
205 if stat.S_ISBLK(st.st_mode):
206 for (part, part_id) in zip(disk.partitions, range(len(disk.partitions))):
207 part_mountpnt = '%s%s%d' % (chroot_dir, new_filename, part_id+1)
208 open(part_mountpnt, 'w').close()
209 run_cmd('mount', '--bind', part.filename, part_mountpnt)
210 devmap.write("(hd%d) %s\n" % (id, new_filename))
211 devmap.close()
212 run_cmd('cat', '%s%s' % (chroot_dir, devmapfile))
213 self.suite.install_grub(chroot_dir)
214 self.run_in_target('grub', '--device-map=%s' % devmapfile, '--batch', stdin='''root %s
215 setup (hd0)
216 EOT''' % root_dev)
217 self.suite.install_menu_lst(disks)
218 self.install_bootloader_cleanup(chroot_dir)
219
221 if self.suite.xen_kernel_flavour:
222
223
224
225 if hasattr(self.context, 'ec2') and self.context.ec2:
226 logging.debug("selecting ec2 kernel")
227 self.xen_kernel = "2.6.ec2-kernel"
228 return self.xen_kernel
229 if not self.xen_kernel:
230 rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour)
231 version = ['0', '0','0', '0']
232
233 for line in rmad.splitlines():
234 sline = line.split('|')
235
236 if sline[2].strip().startswith(self.context.get_setting('suite')):
237 vt = sline[1].strip().split('.')
238 for i in range(4):
239 if int(vt[i]) > int(version[i]):
240 version = vt
241 break
242
243 if version[0] == '0':
244 raise VMBuilderException('Something is wrong, no valid xen kernel for the suite %s found by rmadison' % self.context.suite)
245
246 self.xen_kernel = '%s.%s.%s-%s' % (version[0],version[1],version[2],version[3])
247 return self.xen_kernel
248 else:
249 raise VMBuilderUserError('There is no valid xen kernel for the suite selected.')
250
254
257
260
266
272
275
278
281
284
286 lang = os.getenv('LANG')
287 if lang is None:
288 return 'C'
289
290
291 if lang.endswith('utf8'):
292 return lang[:-4] + 'UTF-8'
293 return lang
294
295 register_distro(Ubuntu)
296