]> git.siccegge.de Git - forks/vmdebootstrap.git/blobdiff - vmdebootstrap
handle missing customise scripts cleanly with fallback to upstream examples.
[forks/vmdebootstrap.git] / vmdebootstrap
index 4ca922b3e0a54df0e9d535ce536404c146975f1a..546742985f7ec6d936f8ddab8d258618a22ba1f5 100755 (executable)
@@ -33,7 +33,9 @@ __version__ = '0.3'
 class VmDebootstrap(cliapp.Application):
 
     def add_settings(self):
-        default_arch = 'amd64'
+        default_arch = self.runcmd(
+            ["dpkg", "--print-architecture"],
+            ignore_fail=False).strip()
 
         self.settings.boolean(['verbose'], 'report what is going on')
         self.settings.string(['image'], 'put created disk image in FILE',
@@ -106,6 +108,14 @@ class VmDebootstrap(cliapp.Application):
                              'is complete.')
         self.settings.boolean(['squash'],
                               'use squashfs on the final image.')
+        self.settings.boolean(['configure-apt'],
+                              'Create an apt source based on the distribution '
+                              'and mirror selected.')
+        self.settings.boolean(['mbr'],
+                              'Run install-mbr (no longer done by default)')
+        self.settings.boolean(['grub'],
+                              'Install and configure grub2 - disables '
+                              'extlinux.')
 
     def process_args(self, args):
         if not self.settings['image'] and not self.settings['tarball']:
@@ -123,10 +133,12 @@ class VmDebootstrap(cliapp.Application):
             roottype = 'ext4'
             bootdev = None
             boottype = None
+            rootdir = None
             if self.settings['image']:
                 self.create_empty_image()
                 self.partition_image()
-                self.install_mbr()
+                if self.settings['mbr']:
+                    self.install_mbr()
                 (rootdev, bootdev) = self.setup_kpartx()
                 self.mkfs(rootdev, type=roottype)
                 rootdir = self.mount(rootdev)
@@ -150,9 +162,13 @@ class VmDebootstrap(cliapp.Application):
             self.create_users(rootdir)
             self.remove_udev_persistent_rules(rootdir)
             self.setup_networking(rootdir)
+            if self.settings['configure-apt']:
+                self.configure_apt(rootdir)
             self.customize(rootdir)
             if self.settings['image']:
-                if self.settings['extlinux']:
+                if self.settings['grub']:
+                    self.install_grub2(rootdev, rootdir)
+                elif self.settings['extlinux']:
                     self.install_extlinux(rootdev, rootdir)
                 self.append_serial_console(rootdir)
                 self.optimize_image(rootdir)
@@ -170,6 +186,10 @@ class VmDebootstrap(cliapp.Application):
                 self.chown(rootdir)
         except BaseException, e:
             self.message('EEEK! Something bad happened...')
+            if rootdir:
+                db_log = os.path.join(rootdir, 'debootstrap', 'debootstrap.log')
+                if os.path.exists(db_log):
+                    shutil.copy(db_log, os.getcwd())
             self.message(e)
             self.cleanup_system()
             raise
@@ -233,8 +253,9 @@ class VmDebootstrap(cliapp.Application):
                      'set', '1', 'boot', 'on'])
 
     def install_mbr(self):
-        self.message('Installing MBR')
-        self.runcmd(['install-mbr', self.settings['image']])
+        if os.path.exists("/sbin/install-mbr"):
+            self.message('Installing MBR')
+            self.runcmd(['install-mbr', self.settings['image']])
 
     def setup_kpartx(self):
         out = self.runcmd(['kpartx', '-avs', self.settings['image']])
@@ -268,6 +289,9 @@ class VmDebootstrap(cliapp.Application):
         else:
             necessary_packages = ['acpid']
 
+        if self.settings['grub']:
+            necessary_packages.append('grub2')
+
         include = self.settings['package']
 
         if not self.settings['no-kernel']:
@@ -291,11 +315,13 @@ class VmDebootstrap(cliapp.Application):
             args.append(self.settings['variant'])
         args += [self.settings['distribution'],
                  rootdir, self.settings['mirror']]
+        logging.debug(" ".join(args))
         self.runcmd(args)
         if self.settings['foreign']:
             # First copy the binfmt handler over
             shutil.copy(self.settings['foreign'], '%s/usr/bin/' % rootdir)
             # Next, run the package install scripts etc.
+            self.message('Running debootstrap second stage')
             self.runcmd(['chroot', rootdir,
                          '/debootstrap/debootstrap', '--second-stage'])
 
@@ -428,7 +454,30 @@ class VmDebootstrap(cliapp.Application):
             with open(inittab, 'a') as f:
                 f.write('\nS0:23:respawn:%s\n' % serial_command)
 
+    def install_grub2(self, rootdev, rootdir):
+        self.message("Configuring grub2")
+        # rely on kpartx using consistent naming to map loop0p1 to loop0
+        install_dev = os.path.join('/dev', os.path.basename(rootdev)[:-2])
+        self.runcmd(['mount', '/dev', '-t', 'devfs', '-obind',
+                    '%s' % os.path.join(rootdir, 'dev')])
+        self.runcmd(['mount', '/proc', '-t', 'proc', '-obind',
+                    '%s' % os.path.join(rootdir, 'proc')])
+        self.runcmd(['mount', '/sys', '-t', 'sysfs', '-obind',
+                    '%s' % os.path.join(rootdir, 'sys')])
+        try:
+            self.runcmd(['chroot', rootdir, 'update-grub'])
+            self.runcmd(['chroot', rootdir, 'grub-install', install_dev])
+        except cliapp.AppException as e:
+            self.message("Failed to configure grub2. Using extlinux.")
+        self.runcmd(['umount', os.path.join(rootdir, 'sys')])
+        self.runcmd(['umount', os.path.join(rootdir, 'proc')])
+        self.runcmd(['umount', os.path.join(rootdir, 'dev')])
+        self.install_extlinux(rootdev, rootdir)
+
     def install_extlinux(self, rootdev, rootdir):
+        if not os.path.exists("/usr/bin/extlinux"):
+            self.message("extlinux not installed, skipping.")
+            return
         self.message('Installing extlinux')
 
         def find(pattern):
@@ -518,10 +567,17 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s
 
     def customize(self, rootdir):
         script = self.settings['customize']
-        if script:
-            self.message('Running customize script %s' % script)
-            with open('/dev/tty', 'w') as tty:
-                cliapp.runcmd([script, rootdir], stdout=tty, stderr=tty)
+        if not script:
+            return
+        if not os.path.exists(script):
+            example = os.path.join("/usr/share/vmdebootstrap/examples/", script)
+            if not os.path.exists(example):
+                self.message("Unable to find %s" % script)
+                return
+            script = example
+        self.message('Running customize script %s' % script)
+        with open('/dev/tty', 'w') as tty:
+            cliapp.runcmd([script, rootdir], stdout=tty, stderr=tty)
 
     def create_tarball(self, rootdir):
         # Create a tarball of the disk's contents
@@ -536,5 +592,20 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s
                          self.settings["owner"],
                          self.settings["image"]])
 
+    def configure_apt(self, rootdir):
+        # use the distribution and mirror to create an apt source
+        self.message("Configuring apt to use distribution and mirror")
+        conf = os.path.join(rootdir, 'etc', 'apt', 'sources.list.d', 'base.list')
+        logging.debug('configure apt %s' % conf)
+        f = open(conf, 'w')
+        f.write('''
+deb %(mirror)s %(distribution)s main
+#deb-src %(mirror)s %(distribution)s main
+''' % {
+            'mirror': self.settings['mirror'],
+            'distribution': self.settings['distribution']
+        })
+        f.close()
+
 if __name__ == '__main__':
     VmDebootstrap(version=__version__).run()