+ self.debian_info = DebianDistroInfo()
+ self.ubuntu_info = UbuntuDistroInfo()
+ self.bootdir = None
+ self.efi_arch_table = {
+ 'amd64': {
+ 'removable': '/EFI/boot/bootx64.efi', # destination location
+ 'install': '/EFI/debian/grubx64.efi', # package location
+ 'package': 'grub-efi-amd64', # bootstrap package
+ 'bin_package': 'grub-efi-amd64-bin', # binary only
+ 'extra': 'i386', # architecture to add binary package
+ 'exclusive': False, # only EFI supported for this arch.
+ 'target': 'x86_64-efi', # grub target name
+ },
+ 'i386': {
+ 'removable': '/EFI/boot/bootia32.efi',
+ 'install': '/EFI/debian/grubia32.efi',
+ 'package': 'grub-efi-ia32',
+ 'bin_package': 'grub-efi-ia32-bin',
+ 'extra': None,
+ 'exclusive': False,
+ 'target': 'i386-efi',
+ },
+ 'arm64': {
+ 'removable': '/EFI/boot/bootaa64.efi',
+ 'install': '/EFI/debian/grubaa64.efi',
+ 'package': 'grub-efi-arm64',
+ 'bin_package': 'grub-efi-arm64-bin',
+ 'extra': None,
+ 'exclusive': True,
+ 'target': 'arm64-efi',
+ }
+ }
+
+ def add_settings(self):
+ default_arch = subprocess.check_output(
+ ["dpkg", "--print-architecture"]).strip()
+
+ 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.bytesize(
+ ['bootsize'],
+ 'create boot partition of size SIZE (%default)',
+ metavar='BOOTSIZE',
+ default='0%')
+ self.settings.string(
+ ['boottype'],
+ 'specify file system type for /boot/',
+ default='ext2')
+ self.settings.bytesize(
+ ['bootoffset'],
+ 'Space to leave at start of the image for bootloader',
+ default='0')
+ self.settings.boolean(
+ ['use-uefi'],
+ 'Setup image for UEFI boot',
+ default=False)
+ self.settings.bytesize(
+ ['esp-size'],
+ 'Size of EFI System Partition - requires use-uefi',
+ default='5mib')
+ self.settings.string(
+ ['part-type'],
+ 'Partition type to use for this image',
+ default='msdos')
+ self.settings.string(
+ ['roottype'],
+ 'specify file system type for /',
+ default='ext4')
+ self.settings.bytesize(
+ ['swap'],
+ 'create swap space of size SIZE (min 256Mb)')
+ self.settings.string(
+ ['foreign'],
+ '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(
+ ['extlinux'],
+ 'install extlinux?',
+ default=True)
+ self.settings.string(
+ ['tarball'],
+ "tar up the disk's contents in FILE",
+ metavar='FILE')
+ self.settings.string(
+ ['apt-mirror'],
+ 'configure apt to use MIRROR',
+ metavar='URL')
+ self.settings.string(
+ ['mirror'],
+ 'use MIRROR as package source (%default)',
+ metavar='URL',
+ default='http://http.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.string_list(
+ ['custom-package'],
+ 'install package in DEB file onto system (not from mirror)',
+ metavar='DEB')
+ self.settings.boolean(
+ ['no-kernel'],
+ 'do not install a linux package')
+ self.settings.string(
+ ['kernel-package'],
+ 'install PACKAGE instead of the default kernel package',
+ metavar='PACKAGE')
+ self.settings.boolean(
+ ['enable-dhcp'],
+ 'enable DHCP on eth0')
+ self.settings.string(
+ ['root-password'],
+ 'set root password',
+ metavar='PASSWORD')
+ self.settings.boolean(
+ ['lock-root-password'],
+ 'lock root account so they cannot login?')
+ 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.string(
+ ['serial-console-command'],
+ 'command to manage the serial console, appended to /etc/inittab (%default)',
+ metavar='COMMAND',
+ default='/sbin/getty -L ttyS0 115200 vt100')
+ 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.')
+ 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 (default if extlinux used)')
+ self.settings.boolean(
+ ['grub'],
+ 'Install and configure grub2 - disables extlinux.')
+ self.settings.boolean(
+ ['sparse'],
+ 'Do not fill the image with zeros to keep a sparse disk image',
+ default=False)
+ self.settings.boolean(
+ ['pkglist'],
+ 'Create a list of package names included in the image.')
+ self.settings.boolean(
+ ['no-acpid'],
+ 'do not install the acpid package',
+ default=False)
+
+ def process_args(self, args): # pylint: disable=too-many-branches,too-many-statements
+ if not self.settings['image'] and not self.settings['tarball']:
+ raise cliapp.AppException(
+ 'You must give disk image filename, or tarball filename')
+ if self.settings['image'] and not self.settings['size']:
+ raise cliapp.AppException(
+ 'If disk image is specified, you must give image size.')
+ if not self.debian_info.valid(self.settings['distribution']):
+ if not self.ubuntu_info.valid(self.settings['distribution']):
+ raise cliapp.AppException(
+ '%s is not a valid Debian or Ubuntu suite or codename.'
+ % self.settings['distribution'])
+ if not self.settings['use-uefi'] and self.settings['esp-size'] != 5242880:
+ raise cliapp.AppException(
+ 'You must specify use-uefi for esp-size to have effect')
+ if self.settings['arch'] in self.efi_arch_table and\
+ self.efi_arch_table[self.settings['arch']]['exclusive'] and\
+ not self.settings['use-uefi']:
+ raise cliapp.AppException(
+ 'Only UEFI is supported on %s' % self.settings['arch'])
+ elif self.settings['use-uefi'] and self.settings['arch'] not in self.efi_arch_table:
+ raise cliapp.AppException(
+ '%s is not a supported UEFI architecture' % self.settings['arch'])
+ if self.settings['use-uefi'] and (
+ self.settings['bootsize'] or
+ self.settings['bootoffset']):
+ raise cliapp.AppException(
+ 'A separate boot partition is not supported with UEFI')