X-Git-Url: https://git.siccegge.de//index.cgi?a=blobdiff_plain;f=vmdebootstrap;h=b66a84ed182a87706ebd7fb786f130d4395f1815;hb=9def048429a4d28eb9e296f19222bbb437bed8ea;hp=ab9486b95647f607fd2ff908fcf12ee8386ae460;hpb=ec9b91e5f3382684c9b3f6157dd0cfb259de9850;p=forks%2Fvmdebootstrap.git diff --git a/vmdebootstrap b/vmdebootstrap index ab9486b..b66a84e 100755 --- a/vmdebootstrap +++ b/vmdebootstrap @@ -158,13 +158,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth 'Create an apt source based on the distribution and mirror selected.') self.settings.boolean( ['mbr'], - 'Run install-mbr (no longer done by default)') + 'Run install-mbr (default if extlinux used)') self.settings.boolean( ['grub'], 'Install and configure grub2 - disables extlinux.') self.settings.boolean( ['sparse'], - 'Dont fill the image with zeros to keep a sparse disk image', + 'Do not fill the image with zeros to keep a sparse disk image', default=False) self.settings.boolean( ['pkglist'], @@ -187,7 +187,7 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth if self.settings['image']: self.create_empty_image() self.partition_image() - if self.settings['mbr']: + if self.settings['mbr'] or self.settings['extlinux']: self.install_mbr() (rootdev, bootdev) = self.setup_kpartx() self.mkfs(rootdev, fstype=roottype) @@ -292,17 +292,41 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth str(self.settings['size'])]) def partition_image(self): + """ + Uses fat16 (msdos) partitioning by default, use part-type to change. + If bootoffset is specified, the first actual partition + starts at that offset to allow customisation scripts to + put bootloader images into the space, e.g. u-boot. + """ self.message('Creating partitions') self.runcmd(['parted', '-s', self.settings['image'], - 'mklabel', 'msdos']) + 'mklabel', self.settings['part-type']]) + partoffset = 0 + bootsize = 0 + if self.settings['bootoffset'] and self.settings['bootoffset'] is not '0': + # turn v.small offsets into something at least possible to create. + if self.settings['bootoffset'] < 1048576: + partoffset = 1 + logging.info( + "Setting bootoffset %smib to allow for %s bytes", + partoffset, self.settings['bootoffset']) + else: + partoffset = self.settings['bootoffset'] / (1024 * 1024) + self.message("Using bootoffset: %smib %s bytes" % (partoffset, self.settings['bootoffset'])) if self.settings['bootsize'] and self.settings['bootsize'] is not '0%': - bootsize = str(self.settings['bootsize'] / (1024 * 1024)) + bootsize = self.settings['bootsize'] / (1024 * 1024) + bootsize += partoffset + self.message("Using bootsize %smib: %s bytes" % (bootsize, self.settings['bootsize'])) + logging.debug("Starting boot partition at %sMb", bootsize) + self.runcmd(['parted', '-s', self.settings['image'], + 'mkpart', 'primary', 'fat16', str(partoffset), str(bootsize)]) + if partoffset == 0: self.runcmd(['parted', '-s', self.settings['image'], - 'mkpart', 'primary', 'fat16', '0%', bootsize]) + 'mkpart', 'primary', '0%', '100%']) else: - bootsize = '0%' - self.runcmd(['parted', '-s', self.settings['image'], - 'mkpart', 'primary', bootsize, '100%']) + logging.debug("Starting root partition at %sMb", partoffset) + self.runcmd(['parted', '-s', self.settings['image'], + 'mkpart', 'primary', str(bootsize), '100%']) self.runcmd(['parted', '-s', self.settings['image'], 'set', '1', 'boot', 'on']) @@ -316,8 +340,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth if os.path.exists("/sbin/install-mbr"): self.message('Installing MBR') self.runcmd(['install-mbr', self.settings['image']]) + else: + msg = "mbr enabled but /sbin/install-mbr not found" \ + " - please install the mbr package." + raise cliapp.AppException(msg) def setup_kpartx(self): + bootindex = None out = self.runcmd(['kpartx', '-avs', self.settings['image']]) if self.settings['bootsize']: bootindex = 0 @@ -326,12 +355,14 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth else: rootindex = 0 parts = 1 - boot = None + boot = None devices = [line.split()[2] for line in out.splitlines() if line.startswith('add map ')] if len(devices) != parts: - raise cliapp.AppException('Surprising number of partitions') + msg = 'Surprising number of partitions' + logging.debug("%s: devices=%s parts=%s", msg, devices, parts) + raise cliapp.AppException(msg) root = '/dev/mapper/%s' % devices[rootindex] if self.settings['bootsize']: boot = '/dev/mapper/%s' % devices[bootindex] @@ -345,15 +376,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth msg = "(%s)" % self.settings['variant'] if self.settings['variant'] else '' self.message('Debootstrapping %s %s' % (self.settings['distribution'], msg)) - if self.settings['foreign']: - necessary_packages = [] - else: - necessary_packages = ['acpid'] + include = self.settings['package'] - if self.settings['grub']: - necessary_packages.append('grub2') + if not self.settings['foreign']: + include.append('acpid') - include = self.settings['package'] + if self.settings['grub']: + include.append('grub2') if not self.settings['no-kernel']: if self.settings['arch'] == 'i386': @@ -367,9 +396,10 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth include.append('sudo') args = ['debootstrap', '--arch=%s' % self.settings['arch']] - if self.settings['package'] and len(necessary_packages) > 0: + + if self.settings['package']: args.append( - '--include=%s' % ','.join(necessary_packages + include)) + '--include=%s' % ','.join(include)) if self.settings['foreign']: args.append('--foreign') if self.settings['variant']: @@ -576,11 +606,9 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth conf = os.path.join(rootdir, 'extlinux.conf') logging.debug('configure extlinux %s', conf) - # python multiline string substitution is just ugly. - # use an external file or live with the mangling, no point in - # mangling the string to remove spaces just to keep it pretty in source. - f = open(conf, 'w') - f.write(''' + kserial = 'console=ttyS0,115200' if self.settings['serial-console'] else '' + extserial = 'serial 0 115200' if self.settings['serial-console'] else '' + msg = ''' default linux timeout 1 @@ -592,11 +620,16 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s 'kernel': kernel_image, # pylint: disable=bad-continuation 'initrd': initrd_image, # pylint: disable=bad-continuation 'uuid': uuid, # pylint: disable=bad-continuation - 'kserial': # pylint: disable=bad-continuation - 'console=ttyS0,115200' if self.settings['serial-console'] else '', # pylint: disable=bad-continuation - 'extserial': 'serial 0 115200' if self.settings['serial-console'] else '', # pylint: disable=bad-continuation - }) # pylint: disable=bad-continuation - f.close() # pylint: disable=bad-continuation + 'kserial': kserial, # pylint: disable=bad-continuation + 'extserial': extserial, # pylint: disable=bad-continuation + } # pylint: disable=bad-continuation + logging.debug("extlinux config:\n%s", msg) + + # python multiline string substitution is just ugly. + # use an external file or live with the mangling, no point in + # mangling the string to remove spaces just to keep it pretty in source. + f = open(conf, 'w') + f.write(msg) self.runcmd(['extlinux', '--install', rootdir]) self.runcmd(['sync']) @@ -658,8 +691,9 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s return script = example self.message('Running customize script %s' % script) + logging.info("rootdir=%s image=%s", rootdir, self.settings['image']) with open('/dev/tty', 'w') as tty: - cliapp.runcmd([script, rootdir], stdout=tty, stderr=tty) + cliapp.runcmd([script, rootdir, self.settings['image']], stdout=tty, stderr=tty) def create_tarball(self, rootdir): # Create a tarball of the disk's contents @@ -669,16 +703,20 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s def chown(self): # Change image owner after completed build + if self.settings['image']: + filename = self.settings['image'] + elif self.settings['tarball']: + filename = self.settings['tarball'] + else: + return self.message("Changing owner to %s" % self.settings["owner"]) - subprocess.call(["chown", - self.settings["owner"], - self.settings["image"]]) + subprocess.call(["chown", self.settings["owner"], filename]) def list_installed_pkgs(self, rootdir): # output the list of installed packages for sources identification self.message("Creating a list of installed binary package names") out = self.runcmd(['chroot', rootdir, - 'dpkg-query', '-W' "-f='${Package}.deb\n'"]) + 'dpkg-query', '-W', "-f='${Package}.deb\n'"]) with open('dpkg.list', 'w') as dpkg: dpkg.write(out) @@ -698,6 +736,8 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s line = '#deb-src %s %s main\n' % (mirror, self.settings['distribution']) f.write(line) f.close() + # ensure the apt sources have valid lists + self.runcmd(['chroot', rootdir, 'apt-get', 'update']) if __name__ == '__main__': VmDebootstrap(version=__version__).run()