X-Git-Url: https://git.siccegge.de//index.cgi?a=blobdiff_plain;ds=sidebyside;f=vmdebootstrap;h=dd729251d4aadc628ceb32539ee90cf8759bbbde;hb=e3571547c2a9ce6b37739aae626c03de2aea96cb;hp=ce163b4f47a474112e4087e8b68d5f2adf18c05c;hpb=9507d09f75325c6157afbb6d0d9c08396ed43810;p=forks%2Fvmdebootstrap.git diff --git a/vmdebootstrap b/vmdebootstrap index ce163b4..dd72925 100755 --- a/vmdebootstrap +++ b/vmdebootstrap @@ -15,6 +15,7 @@ # along with this program. If not, see . import cliapp +import crypt import logging import os import re @@ -28,34 +29,43 @@ class VmDebootstrap(cliapp.Application): def add_settings(self): default_arch = 'amd64' - self.settings.add_boolean_setting(['verbose'], - 'report what is going on') - self.settings.add_string_setting(['image'], - 'put created disk image in FILE', - metavar='FILE') - self.settings.add_bytesize_setting(['size'], - 'create a disk image of size SIZE ' - '(%default)', - metavar='SIZE', - default='1G') - self.settings.add_string_setting(['mirror'], - 'use MIRROR as package source ' - '(%default)', - metavar='URL', - default='http://cdn.debian.net/debian/') - self.settings.add_string_setting(['arch'], - 'architecture to use ' - '(%default)', - metavar='ARCH', - default=default_arch) - self.settings.add_string_setting(['distribution'], - 'release to use (%default)', - metavar='NAME', - default='stable') - self.settings.add_string_list_setting(['package'], - 'install PACKAGE onto system') - self.settings.add_boolean_setting(['enable-dhcp'], - 'enable DHCP on eth0') + self.settings.boolean(['verbose'], 'report what is going on') + self.settings.string(['image'], 'put created disk image in FILE', + metavar='FILE') + self.settings.bytesize(['size'], + 'create a disk image of size SIZE (%default)', + metavar='SIZE', + default='1G') + self.settings.string(['mirror'], + 'use MIRROR as package source (%default)', + metavar='URL', + default='http://cdn.debian.net/debian/') + self.settings.string(['arch'], 'architecture to use (%default)', + metavar='ARCH', + default=default_arch) + self.settings.string(['distribution'], + 'release to use (%default)', + metavar='NAME', + default='stable') + self.settings.string_list(['package'], 'install PACKAGE onto system') + self.settings.boolean(['enable-dhcp'], 'enable DHCP on eth0') + self.settings.string(['root-password'], 'set root password', + metavar='PASSWORD') + self.settings.string(['customize'], + 'run SCRIPT after setting up system', + metavar='SCRIPT') + self.settings.string(['hostname'], + 'set name to HOSTNAME (%default)', + metavar='HOSTNAME', + default='debian') + self.settings.string_list(['user'], + 'create USER with PASSWORD', + metavar='USER/PASSWORD') + self.settings.boolean(['serial-console'], + 'configure image to use a serial console') + self.settings.boolean(['sudo'], + 'install sudo, and if user is created, add them ' + 'to sudo group') def process_args(self, args): if not self.settings['image']: @@ -74,11 +84,16 @@ class VmDebootstrap(cliapp.Application): self.mkfs(rootdev) rootdir = self.mount(rootdev) self.debootstrap(rootdir) + self.set_hostname(rootdir) + self.create_fstab(rootdir) self.set_root_password(rootdir) + self.create_users(rootdir) self.remove_udev_persistent_rules(rootdir) self.setup_networking(rootdir) self.install_extlinux(rootdev, rootdir) - except: + self.customize(rootdir) + except BaseException, e: + self.message('EEEK! Something bad happened...') self.cleanup() raise else: @@ -151,12 +166,14 @@ class VmDebootstrap(cliapp.Application): self.message('Debootstrapping') if self.settings['arch'] == 'i386': - kernel_arch = 'i686' + kernel_arch = '686' else: kernel_arch = self.settings['arch'] kernel_image = 'linux-image-2.6-%s' % kernel_arch include = [kernel_image] + self.settings['package'] + if self.settings['sudo'] and 'sudo' not in include: + include.append('sudo') self.runcmd(['debootstrap', '--arch=%s' % self.settings['arch'], @@ -165,10 +182,53 @@ class VmDebootstrap(cliapp.Application): rootdir, self.settings['mirror']]) + def set_hostname(self, rootdir): + hostname = self.settings['hostname'] + with open(os.path.join(rootdir, 'etc', 'hostname'), 'w') as f: + 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): + 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') + def set_root_password(self, rootdir): - self.message('Removing root password') - self.runcmd(['chroot', rootdir, 'passwd', '-d', 'root']) - + if self.settings['root-password']: + self.message('Setting root password') + self.set_password(rootdir, 'root', self.settings['root-password']) + else: + self.message('Locking root password') + self.runcmd(['chroot', rootdir, 'passwd', '-l', 'root']) + + def create_users(self, rootdir): + def create_user(user): + self.runcmd(['chroot', rootdir, 'adduser', '--gecos', user, + '--disabled-password', user]) + if self.settings['sudo']: + self.runcmd(['chroot', rootdir, 'adduser', user, 'sudo']) + + for userpass in self.settings['user']: + if '/' in userpass: + user, password = userpass.split('/', 1) + create_user(user) + self.set_password(rootdir, user, password) + else: + create_user(userpass) + + def set_password(self, rootdir, user, password): + encrypted = crypt.crypt(password, '..') + self.runcmd(['chroot', rootdir, 'usermod', '-p', encrypted, user]) + def remove_udev_persistent_rules(self, rootdir): self.message('Removing udev persistent cd and net rules') for x in ['70-persistent-cd.rules', '70-persistent-net.rules']: @@ -221,13 +281,23 @@ timeout 1 label linux kernel %(kernel)s -append initrd=%(initrd)s root=UUID=%(uuid)s ro quiet +append initrd=%(initrd)s root=UUID=%(uuid)s ro quiet %(kserial)s +%(extserial)s ''' % { 'kernel': kernel_image, 'initrd': initrd_image, 'uuid': uuid, + 'kserial': + 'console=ttyS0,115200' if self.settings['serial-console'] else '', + 'extserial': 'serial 0 115200' if self.settings['serial-console'] else '', }) f.close() + + if self.settings['serial-console']: + logging.debug('adding getty to serial console') + inittab = os.path.join(rootdir, 'etc/inittab') + with open(inittab, 'a') as f: + f.write('\nS0:23:respawn:/sbin/getty -L ttyS0 115200 vt100\n') self.runcmd(['extlinux', '--install', rootdir]) self.runcmd(['sync']) @@ -246,6 +316,12 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro quiet for dirname in self.remove_dirs: shutil.rmtree(dirname) + def customize(self, rootdir): + script = self.settings['customize'] + if script: + self.message('Running customize script %s' % script) + self.runcmd([script, rootdir]) + if __name__ == '__main__': VmDebootstrap().run()