Package VMBuilder :: Package plugins :: Package ubuntu :: Module dapper
[frames] | no frames]

Source Code for Module VMBuilder.plugins.ubuntu.dapper

  1  # 
  2  #    Uncomplicated VM Builder 
  3  #    Copyright (C) 2007-2009 Canonical Ltd. 
  4  #     
  5  #    See AUTHORS for list of contributors 
  6  # 
  7  #    This program is free software: you can redistribute it and/or modify 
  8  #    it under the terms of the GNU General Public License version 3, as 
  9  #    published by the Free Software Foundation. 
 10  # 
 11  #    This program is distributed in the hope that it will be useful, 
 12  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  #    GNU General Public License for more details. 
 15  # 
 16  #    You should have received a copy of the GNU General Public License 
 17  #    along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 18  # 
 19  import glob 
 20  import logging 
 21  import os 
 22  import suite 
 23  import shutil 
 24  import socket 
 25  import tempfile 
 26  import VMBuilder 
 27  import VMBuilder.disk as disk 
 28  from   VMBuilder.util import run_cmd 
 29   
30 -class Dapper(suite.Suite):
31 updategrub = "/sbin/update-grub" 32 grubroot = "/lib/grub" 33 valid_flavours = { 'i386' : ['386', '686', '686-smp', 'k7', 'k7-smp', 'server', 'server-bigiron'], 34 'amd64' : ['amd64-generic', 'amd64-k8', 'amd64-k8-smp', 'amd64-server', 'amd64-xeon']} 35 default_flavour = { 'i386' : 'server', 'amd64' : 'amd64-server' } 36 disk_prefix = 'hd' 37 xen_kernel_flavour = None 38 virtio_net = False 39 chpasswd_cmd = [ 'chpasswd', '--md5' ] 40
41 - def pre_install(self):
42 pass
43
44 - def check_kernel_flavour(self, arch, flavour):
45 return flavour in self.valid_flavours[arch]
46
47 - def check_arch_validity(self, arch):
48 return arch in self.valid_flavours.keys()
49
50 - def install(self, destdir):
51 self.destdir = destdir 52 53 logging.debug("debootstrapping") 54 self.debootstrap() 55 56 self.pre_install() 57 58 logging.debug("Setting up sources.list") 59 self.install_sources_list() 60 61 logging.debug("Setting up apt proxy") 62 self.install_apt_proxy() 63 64 logging.debug("Installing fstab") 65 self.install_fstab() 66 67 logging.debug("Creating devices") 68 self.create_devices() 69 70 if self.vm.hypervisor.needs_bootloader: 71 logging.debug("Installing grub") 72 self.install_grub() 73 74 logging.debug("Configuring guest networking") 75 self.config_network() 76 77 logging.debug("Preventing daemons from starting") 78 self.prevent_daemons_starting() 79 80 logging.debug('Binding /dev and /proc filesystems') 81 self.mount_dev_proc() 82 83 if self.vm.hypervisor.needs_bootloader: 84 logging.debug("Installing menu.list") 85 self.install_menu_lst() 86 87 logging.debug("Installing kernel") 88 self.install_kernel() 89 90 logging.debug("Creating device.map") 91 self.install_device_map() 92 93 logging.debug("Installing extra packages") 94 self.install_extras() 95 96 logging.debug("Creating initial user") 97 self.create_initial_user() 98 99 logging.debug("Installing ssh keys") 100 self.install_authorized_keys() 101 102 logging.debug("Copy host settings") 103 self.copy_settings() 104 105 logging.debug("Setting timezone") 106 self.set_timezone() 107 108 logging.debug("Making sure system is up-to-date") 109 self.update() 110 111 logging.debug("Setting up final sources.list") 112 self.install_sources_list(final=True) 113 114 logging.debug("cleaning apt") 115 self.run_in_target('apt-get', 'clean'); 116 117 logging.debug("Unmounting volatile lrm filesystems") 118 self.unmount_volatile() 119 120 logging.debug('Unbinding /dev and /proc filesystems') 121 self.unmount_dev_proc() 122 123 if hasattr(self.vm, 'ec2') and self.vm.ec2: 124 logging.debug("Configuring for ec2") 125 self.install_ec2() 126 127 logging.debug("Unpreventing daemons from starting") 128 self.unprevent_daemons_starting() 129 130 if self.vm.manifest: 131 logging.debug("Creating manifest") 132 manifest_contents = self.run_in_target('dpkg-query', '-W', '--showformat=${Package} ${Version}\n') 133 fp = open(self.vm.manifest, 'w') 134 fp.write(manifest_contents) 135 fp.close
136
137 - def update(self):
138 self.run_in_target('apt-get', '-y', '--force-yes', 'dist-upgrade', 139 env={ 'DEBIAN_FRONTEND' : 'noninteractive' })
140
141 - def install_authorized_keys(self):
142 if self.vm.ssh_key: 143 os.mkdir('%s/root/.ssh' % self.destdir, 0700) 144 shutil.copy(self.vm.ssh_key, '%s/root/.ssh/authorized_keys' % self.destdir) 145 os.chmod('%s/root/.ssh/authorized_keys' % self.destdir, 0644) 146 if self.vm.ssh_user_key: 147 os.mkdir('%s/home/%s/.ssh' % (self.destdir, self.vm.user), 0700) 148 shutil.copy(self.vm.ssh_user_key, '%s/home/%s/.ssh/authorized_keys' % (self.destdir, self.vm.user)) 149 os.chmod('%s/home/%s/.ssh/authorized_keys' % (self.destdir, self.vm.user), 0644) 150 self.run_in_target('chown', '-R', '%s:%s' % (self.vm.user,)*2, '/home/%s/.ssh/' % (self.vm.user)) 151 152 if self.vm.ssh_user_key or self.vm.ssh_key: 153 if not self.vm.addpkg: 154 self.vm.addpkg = [] 155 self.vm.addpkg += ['openssh-server']
156
157 - def mount_dev_proc(self):
158 run_cmd('mount', '--bind', '/dev', '%s/dev' % self.destdir) 159 self.vm.add_clean_cmd('umount', '%s/dev' % self.destdir, ignore_fail=True) 160 161 run_cmd('mount', '--bind', '/dev/pts', '%s/dev/pts' % self.destdir) 162 self.vm.add_clean_cmd('umount', '%s/dev/pts' % self.destdir, ignore_fail=True) 163 164 self.run_in_target('mount', '-t', 'proc', 'proc', '/proc') 165 self.vm.add_clean_cmd('umount', '%s/proc' % self.destdir, ignore_fail=True)
166
167 - def unmount_dev_proc(self):
168 run_cmd('umount', '%s/dev/pts' % self.destdir) 169 run_cmd('umount', '%s/dev' % self.destdir) 170 run_cmd('umount', '%s/proc' % self.destdir)
171
172 - def update_passwords(self):
173 # Set the user password, using md5 174 self.run_in_target(stdin=('%s:%s\n' % (self.vm.user, getattr(self.vm, 'pass'))), *self.chpasswd_cmd) 175 176 # Lock root account only if we didn't set the root password 177 if self.vm.rootpass: 178 self.run_in_target(stdin=('%s:%s\n' % ('root', self.vm.rootpass)), *self.chpasswd_cmd) 179 else: 180 self.run_in_target('usermod', '-L', 'root') 181 182 if self.vm.lock_user: 183 logging.info('Locking %s' %(self.vm.user)) 184 self.run_in_target('usermod', '-L', self.vm.user)
185
186 - def create_initial_user(self):
187 if self.vm.uid: 188 self.run_in_target('adduser', '--disabled-password', '--uid', self.vm.uid, '--gecos', self.vm.name, self.vm.user) 189 else: 190 self.run_in_target('adduser', '--disabled-password', '--gecos', self.vm.name, self.vm.user) 191 self.run_in_target('addgroup', '--system', 'admin') 192 self.run_in_target('adduser', self.vm.user, 'admin') 193 194 self.install_from_template('/etc/sudoers', 'sudoers') 195 for group in ['adm', 'audio', 'cdrom', 'dialout', 'floppy', 'video', 'plugdev', 'dip', 'netdev', 'powerdev', 'lpadmin', 'scanner']: 196 self.run_in_target('adduser', self.vm.user, group, ignore_fail=True) 197 198 self.update_passwords()
199
200 - def kernel_name(self):
201 return 'linux-image-%s' % (self.vm.flavour or self.default_flavour[self.vm.arch],)
202
203 - def config_network(self):
204 self.vm.install_file('/etc/hostname', self.vm.hostname) 205 self.install_from_template('/etc/hosts', 'etc_hosts', { 'hostname' : self.vm.hostname, 'domain' : self.vm.domain }) 206 self.install_from_template('/etc/network/interfaces', 'interfaces')
207
209 os.unlink('%s/usr/sbin/policy-rc.d' % self.destdir)
210
211 - def prevent_daemons_starting(self):
212 os.chmod(self.install_from_template('/usr/sbin/policy-rc.d', 'nostart-policy-rc.d'), 0755)
213
214 - def install_extras(self):
215 if not self.vm.addpkg and not self.vm.removepkg: 216 return 217 cmd = ['apt-get', 'install', '-y', '--force-yes'] 218 cmd += self.vm.addpkg or [] 219 cmd += ['%s-' % pkg for pkg in self.vm.removepkg or []] 220 self.run_in_target(env={ 'DEBIAN_FRONTEND' : 'noninteractive' }, *cmd)
221
222 - def unmount_volatile(self):
223 for mntpnt in glob.glob('%s/lib/modules/*/volatile' % self.destdir): 224 logging.debug("Unmounting %s" % mntpnt) 225 run_cmd('umount', mntpnt)
226
227 - def install_menu_lst(self):
228 self.run_in_target(self.updategrub, '-y') 229 self.mangle_grub_menu_lst() 230 self.run_in_target(self.updategrub) 231 self.run_in_target('grub-set-default', '0')
232
233 - def mangle_grub_menu_lst(self):
234 bootdev = disk.bootpart(self.vm.disks) 235 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.destdir) 236 run_cmd('sed', '-ie', 's/^# groot.*/# groot %s/g' % bootdev.get_grub_id(), '%s/boot/grub/menu.lst' % self.destdir) 237 run_cmd('sed', '-ie', '/^# kopt_2_6/ d', '%s/boot/grub/menu.lst' % self.destdir)
238
239 - def install_sources_list(self, final=False):
240 if final: 241 mirror, updates_mirror, security_mirror = self.vm.mirror, self.vm.mirror, self.vm.security_mirror 242 else: 243 mirror, updates_mirror, security_mirror = self.install_mirrors() 244 245 self.install_from_template('/etc/apt/sources.list', 'sources.list', { 'mirror' : mirror, 'security_mirror' : security_mirror, 'updates_mirror' : updates_mirror }) 246 247 # If setting up the final mirror, allow apt-get update to fail 248 # (since we might be on a complete different network than the 249 # final vm is going to be on). 250 self.run_in_target('apt-get', 'update', ignore_fail=final)
251
252 - def install_apt_proxy(self):
253 if self.vm.proxy is not None: 254 self.vm.install_file('/etc/apt/apt.conf', '// Proxy added by vmbuilder\nAcquire::http { Proxy "%s"; };' % self.vm.proxy)
255
256 - def install_fstab(self):
257 if self.vm.hypervisor.preferred_storage == VMBuilder.hypervisor.STORAGE_FS_IMAGE: 258 self.install_from_template('/etc/fstab', 'dapper_fstab_fsimage', { 'fss' : disk.get_ordered_filesystems(self.vm), 'prefix' : self.disk_prefix }) 259 else: 260 self.install_from_template('/etc/fstab', 'dapper_fstab', { 'parts' : disk.get_ordered_partitions(self.vm.disks), 'prefix' : self.disk_prefix })
261
262 - def install_device_map(self):
263 self.install_from_template('/boot/grub/device.map', 'devicemap', { 'prefix' : self.disk_prefix })
264
265 - def debootstrap(self):
266 cmd = ['/usr/sbin/debootstrap', '--arch=%s' % self.vm.arch] 267 if self.vm.variant: 268 cmd += ['--variant=%s' % self.vm.variant] 269 cmd += [self.vm.suite, self.destdir, self.debootstrap_mirror()] 270 kwargs = { 'env' : { 'DEBIAN_FRONTEND' : 'noninteractive' } } 271 if self.vm.proxy: 272 kwargs['env']['http_proxy'] = self.vm.proxy 273 run_cmd(*cmd, **kwargs)
274
275 - def debootstrap_mirror(self):
276 if self.vm.iso: 277 isodir = tempfile.mkdtemp() 278 self.vm.add_clean_cb(lambda:os.rmdir(isodir)) 279 run_cmd('mount', '-o', 'loop', '-t', 'iso9660', self.vm.iso, isodir) 280 self.vm.add_clean_cmd('umount', isodir) 281 self.iso_mounted = True 282 283 return 'file://%s' % isodir 284 else: 285 return self.install_mirrors()[0]
286 287
288 - def install_mirrors(self):
289 if self.vm.install_mirror: 290 mirror = self.vm.install_mirror 291 else: 292 mirror = self.vm.mirror 293 294 if self.vm.install_mirror: 295 updates_mirror = self.vm.install_mirror 296 else: 297 updates_mirror = self.vm.mirror 298 299 if self.vm.install_security_mirror: 300 security_mirror = self.vm.install_security_mirror 301 else: 302 security_mirror = self.vm.security_mirror 303 304 return (mirror, updates_mirror, security_mirror)
305
306 - def install_kernel(self):
307 self.install_from_template('/etc/kernel-img.conf', 'kernelimg', { 'updategrub' : self.updategrub }) 308 run_cmd('chroot', self.destdir, 'apt-get', '--force-yes', '-y', 'install', self.kernel_name(), 'grub')
309
310 - def install_grub(self):
311 self.run_in_target('apt-get', '--force-yes', '-y', 'install', 'grub') 312 run_cmd('rsync', '-a', '%s%s/%s/' % (self.destdir, self.grubroot, self.vm.arch == 'amd64' and 'x86_64-pc' or 'i386-pc'), '%s/boot/grub/' % self.destdir)
313
314 - def create_devices(self):
315 import VMBuilder.plugins.xen 316 317 if isinstance(self.vm.hypervisor, VMBuilder.plugins.xen.Xen): 318 self.run_in_target('mknod', '/dev/xvda', 'b', '202', '0') 319 self.run_in_target('mknod', '/dev/xvda1', 'b', '202', '1') 320 self.run_in_target('mknod', '/dev/xvda2', 'b', '202', '2') 321 self.run_in_target('mknod', '/dev/xvda3', 'b', '202', '3') 322 self.run_in_target('mknod', '/dev/xvc0', 'c', '204', '191')
323
324 - def install_from_template(self, *args, **kwargs):
325 return self.vm.distro.install_from_template(*args, **kwargs)
326
327 - def run_in_target(self, *args, **kwargs):
328 return self.vm.distro.run_in_target(*args, **kwargs)
329
330 - def copy_to_target(self, infile, destpath):
331 logging.debug("Copying %s on host to %s in guest" % (infile, destpath)) 332 dir = '%s/%s' % (self.destdir, os.path.dirname(destpath)) 333 if not os.path.isdir(dir): 334 os.makedirs(dir) 335 if os.path.isdir(infile): 336 shutil.copytree(infile, '%s/%s' % (self.destdir, destpath)) 337 else: 338 shutil.copy(infile, '%s/%s' % (self.destdir, destpath))
339
340 - def post_mount(self, fs):
341 if fs.mntpnt == '/': 342 logging.debug("Creating /var/run in root filesystem") 343 os.makedirs('%s/var/run' % fs.mntpath) 344 logging.debug("Creating /var/lock in root filesystem") 345 os.makedirs('%s/var/lock' % fs.mntpath)
346
347 - def copy_settings(self):
348 if os.path.exists('/etc/default/locale'): 349 self.copy_to_target('/etc/default/locale', '/etc/default/locale') 350 self.run_in_target('dpkg-reconfigure', '-fnoninteractive', '-pcritical', 'libc6') 351 self.run_in_target('locale-gen', 'en_US') 352 if self.vm.lang: 353 self.run_in_target('locale-gen', self.vm.lang) 354 self.install_from_template('/etc/default/locale', 'locale', { 'lang' : self.vm.lang }) 355 self.run_in_target('dpkg-reconfigure', '-fnoninteractive', '-pcritical', 'locales') 356 self.run_in_target('dpkg-reconfigure', '-pcritical', 'locales')
357
358 - def install_vmbuilder_log(self, logfile, rootdir):
359 shutil.copy(logfile, '%s/var/log/vmbuilder-install.log' % (rootdir,))
360
361 - def set_timezone(self):
362 if self.vm.timezone: 363 os.unlink('%s/etc/localtime' % self.destdir) 364 shutil.copy('%s/usr/share/zoneinfo/%s' % (self.destdir, self.vm.timezone), '%s/etc/localtime' % (self.destdir,))
365
366 - def install_ec2(self):
367 if self.vm.ec2: 368 logging.debug('This suite does not support ec2')
369
370 - def disable_hwclock_access(self):
371 fp = open('%s/etc/default/rcS' % self.destdir, 'a') 372 fp.write('HWCLOCKACCESS=no') 373 fp.close()
374