X-Git-Url: https://git.siccegge.de//index.cgi?a=blobdiff_plain;f=vmdebootstrap;h=64614ad8c5f91442a5e71b7579b38ee8e97d3a9b;hb=969da62d6ad1dbd96683645067acef035a79207e;hp=1de3e563a39c2e66348229e4e2809ac6736d216b;hpb=54291d325c2eec72ff56ce283398bcf6b3e12361;p=forks%2Fvmdebootstrap.git diff --git a/vmdebootstrap b/vmdebootstrap index 1de3e56..64614ad 100755 --- a/vmdebootstrap +++ b/vmdebootstrap @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2011, 2012 Lars Wirzenius +# Copyright 2011-2013 Lars Wirzenius # Copyright 2012 Codethink Limited # # This program is free software: you can redistribute it and/or modify @@ -23,6 +23,10 @@ import re import shutil import subprocess import tempfile +import time + + +__version__ = '0.3' class VmDebootstrap(cliapp.Application): @@ -48,7 +52,10 @@ class VmDebootstrap(cliapp.Application): 'set up foreign debootstrap environment using provided program (ie binfmt handler)') self.settings.string(['variant'], 'select debootstrap variant it not using the default') - self.settings.boolean(['no-extlinux'], 'do not install extlinux') + self.settings.boolean( + ['extlinux'], + 'install extlinux?', + default=True) self.settings.string(['tarball'], "tar up the disk's contents in FILE", metavar='FILE') self.settings.string(['mirror'], @@ -93,6 +100,9 @@ class VmDebootstrap(cliapp.Application): self.settings.boolean(['sudo'], 'install sudo, and if user is created, add them ' 'to sudo group') + self.settings.string(['owner'], + 'the user who will own the image when the build ' + 'is complete.') def process_args(self, args): if not self.settings['image'] and not self.settings['tarball']: @@ -106,19 +116,23 @@ class VmDebootstrap(cliapp.Application): self.mount_points = [] try: + rootdev = None + roottype = 'ext4' + bootdev = None + boottype = None if self.settings['image']: self.create_empty_image() self.partition_image() self.install_mbr() (rootdev,bootdev) = self.setup_kpartx() - self.mkfs(rootdev) + self.mkfs(rootdev, type=roottype) rootdir = self.mount(rootdev) if bootdev: if self.settings['boottype']: - fstype = self.settings['boottype'] + boottype = self.settings['boottype'] else: - fstype = 'ext2' - self.mkfs(bootdev, type=fstype) + boottype = 'ext2' + self.mkfs(bootdev, type=boottype) bootdir = '%s/%s' % (rootdir, 'boot/') os.mkdir(bootdir) bootdir = self.mount(bootdev, bootdir) @@ -126,7 +140,7 @@ class VmDebootstrap(cliapp.Application): rootdir = self.mkdtemp() self.debootstrap(rootdir) self.set_hostname(rootdir) - self.create_fstab(rootdir) + self.create_fstab(rootdir, rootdev, roottype, bootdev, boottype) self.install_debs(rootdir) self.cleanup_apt_cache(rootdir) self.set_root_password(rootdir) @@ -135,7 +149,7 @@ class VmDebootstrap(cliapp.Application): self.setup_networking(rootdir) self.customize(rootdir) if self.settings['image']: - if not self.settings['no-extlinux']: + if self.settings['extlinux']: self.install_extlinux(rootdev, rootdir) self.optimize_image(rootdir) @@ -145,8 +159,12 @@ class VmDebootstrap(cliapp.Application): if self.settings['tarball']: self.create_tarball(rootdir) + + if self.settings['owner']: + self.chown(rootdir) except BaseException, e: self.message('EEEK! Something bad happened...') + self.message(e) self.cleanup_system() raise else: @@ -177,11 +195,11 @@ class VmDebootstrap(cliapp.Application): return dirname def mount(self, device, path=None): - self.message('Mounting %s' % device) if not path: mount_point = self.mkdtemp() else: mount_point = path + self.message('Mounting %s on %s' % (device,mount_point)) self.runcmd(['mount', device, mount_point]) self.mount_points.append(mount_point) logging.debug('mounted %s on %s' % (device, mount_point)) @@ -213,7 +231,7 @@ class VmDebootstrap(cliapp.Application): self.runcmd(['install-mbr', self.settings['image']]) def setup_kpartx(self): - out = self.runcmd(['kpartx', '-av', self.settings['image']]) + out = self.runcmd(['kpartx', '-avs', self.settings['image']]) if self.settings['bootsize']: bootindex = 0 rootindex = 1 @@ -232,8 +250,8 @@ class VmDebootstrap(cliapp.Application): boot = '/dev/mapper/%s' % devices[bootindex] return (root,boot) - def mkfs(self, device, type='ext2'): - self.message('Creating filesystem') + def mkfs(self, device, type): + self.message('Creating filesystem %s' % type) self.runcmd(['mkfs', '-t', type, device]) def debootstrap(self, rootdir): @@ -281,19 +299,39 @@ class VmDebootstrap(cliapp.Application): f.write('%s\n' % hostname) etc_hosts = os.path.join(rootdir, 'etc', 'hosts') - with open(etc_hosts, 'r') as f: - data = f.read() - with open(etc_hosts, 'w') as f: - for line in data.splitlines(): - if line.startswith('127.0.0.1'): - line += ' %s' % hostname - f.write('%s\n' % line) - - def create_fstab(self, rootdir): + try: + with open(etc_hosts, 'r') as f: + data = f.read() + with open(etc_hosts, 'w') as f: + for line in data.splitlines(): + if line.startswith('127.0.0.1'): + line += ' %s' % hostname + f.write('%s\n' % line) + except IOError, e: + pass + + def create_fstab(self, rootdir, rootdev, roottype, bootdev, boottype): + def fsuuid(device): + out = self.runcmd(['blkid', '-c', '/dev/null', '-o', 'value', + '-s', 'UUID', device]) + return out.splitlines()[0].strip() + + if rootdev: + rootdevstr = 'UUID=%s' % fsuuid(rootdev) + else: + rootdevstr = '/dev/sda1' + + if bootdev: + bootdevstr = 'UUID=%s' % fsuuid(bootdev) + else: + bootdevstr = None + fstab = os.path.join(rootdir, 'etc', 'fstab') with open(fstab, 'w') as f: f.write('proc /proc proc defaults 0 0\n') - f.write('/dev/sda1 / ext4 errors=remount-ro 0 1\n') + f.write('%s / %s errors=remount-ro 0 1\n' % (rootdevstr, roottype)) + if bootdevstr: + f.write('%s /boot %s errors=remount-ro 0 2\n' % (bootdevstr, boottype)) def install_debs(self, rootdir): if not self.settings['custom-package']: @@ -445,10 +483,15 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s if self.settings['image']: for i in xrange(len(self.mount_points) - 1, -1, -1): mount_point = self.mount_points[i] - self.runcmd(['umount', mount_point], ignore_fail=True) + try: + self.runcmd(['umount', mount_point], ignore_fail=False) + except cliapp.AppException: + logging.debug("umount failed, sleeping and trying again") + time.sleep(5) + self.runcmd(['umount', mount_point], ignore_fail=False) self.runcmd(['kpartx', '-d', self.settings['image']], ignore_fail=True) - + for dirname in self.remove_dirs: shutil.rmtree(dirname) @@ -465,7 +508,14 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s self.message('Creating tarball of disk contents') self.runcmd(['tar', '-cf', self.settings['tarball'], '-C', rootdir, '.']) + def chown(self, rootdir): + # Change image owner after completed build + self.message("Changing owner to %s" % self.settings["owner"]) + subprocess.call(["chown", + self.settings["owner"], + self.settings["image"]]) + if __name__ == '__main__': - VmDebootstrap().run() + VmDebootstrap(version=__version__).run()