Hello Neil, apologies for the long delay on this. I've attached a patch that solves this bug and two other bugs:
1. BuildBot Fixes: Attempts to build with a TTY device, and falls back to headless mode if TTY device is unavailable. This change allows BuildBot builds to complete. 2. Add customize-chroot support: Adds new "--customize-in-chroot" option to run the customize script in the chroot. This option feels necessary to safely support automated builds, because the building user needs to run vmdebootstrap as root. If the customize script is run in the chroot, we make it harder for users to shoot themselves in the foot and break their host/building system. 3. Fail Faster: Treat IO errors as build failures because they imply that other parts of the build (parts that will probably take much longer) will also fail. I've ended up wasting hours this way, because we got to the customize script, which took hours to fail. My branch (based off of Lars's 1ce8413f revision) is available at: https://github.com/NickDaly/vmdebootstrap Thanks for your time, Nick
diff --git a/vmdebootstrap b/vmdebootstrap index 24e38d0..f57fdad 100755 --- a/vmdebootstrap +++ b/vmdebootstrap @@ -115,6 +115,7 @@ class VmDebootstrap(cliapp.Application): self.settings.boolean(['sparse'], 'Dont fill the image with zeros to keep a sparse disk image', default=False) + self.settings.boolean(['customize-in-chroot'], 'Run customize-script within a chroot? Default: True') def process_args(self, args): if not self.settings['image'] and not self.settings['tarball']: @@ -349,16 +350,13 @@ class VmDebootstrap(cliapp.Application): f.write('%s\n' % hostname) etc_hosts = os.path.join(rootdir, 'etc', 'hosts') - 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 + 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, rootdev, roottype, bootdev, boottype): def fsuuid(device): @@ -599,6 +597,29 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s self.message("Unable to find %s" % script) return script = example + + chroot = self.settings['customize-in-chroot'] + + destscript = "{0}usr{0}sbin{0}{1}".format( + os.path.sep, script.rpartition(os.path.sep)[2]) + shutil.copy(script, rootdir + destscript) + + command = [] + if chroot: + command += ["chroot"] + command += [rootdir, destscript] + + if destscript: + self.message('Running customize script %s, %sin chroot.' % + (destscript, '' if chroot else 'not ')) + try: + with open('/dev/tty', 'w') as tty: + cliapp.runcmd(command, stdout=tty, stderr=tty) + except IOError as e: + # tty unavailable, try running in headless mode. + if subprocess.call(command): + raise cliapp.AppException("customize script failed!") + self.message('Running customize script %s' % script) with open('/dev/tty', 'w') as tty: cliapp.runcmd([script, rootdir], stdout=tty, stderr=tty)