summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Williams <codehelp@debian.org>2016-07-31 15:13:37 +0100
committerNeil Williams <codehelp@debian.org>2016-07-31 15:13:37 +0100
commit92f540c3c49410c14330c512c7e5ae9b546d87d9 (patch)
treedafb43b030748367f36dbe276d42d848e4a0f6ee
parent33ed14110e8a8deeb71770e80b6bba28fb3973c6 (diff)
downloadvmdebootstrap-92f540c3c49410c14330c512c7e5ae9b546d87d9.tar.gz
Deprecating extlinux
Working around extlinux failure with ext4. Adding notes on the reasons for moving to grub as default bootloader in a future release.
-rwxr-xr-xbin/vmdebootstrap37
-rw-r--r--doc/overview.rst17
-rw-r--r--vmdebootstrap/extlinux.py15
3 files changed, 53 insertions, 16 deletions
diff --git a/bin/vmdebootstrap b/bin/vmdebootstrap
index 97666d8..006e4af 100755
--- a/bin/vmdebootstrap
+++ b/bin/vmdebootstrap
@@ -39,7 +39,7 @@ from vmdebootstrap.filesystem import Filesystem
from vmdebootstrap.uefi import Uefi
from vmdebootstrap.network import Networking
-__version__ = '1.5'
+__version__ = '1.6'
# pylint: disable=invalid-name,line-too-long
# pylint: disable=missing-docstring,too-many-statements
@@ -87,7 +87,8 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
self.settings.string(['foreign'], 'set up foreign debootstrap environment '
'using provided program (ie binfmt handler)')
self.settings.string_list(['debootstrapopts'], 'pass additional options to debootstrap')
- self.settings.boolean(['extlinux'], 'install extlinux?', default=True)
+ self.settings.boolean(['extlinux'], 'install extlinux (deprecated: default will '
+ 'change in a future release to use grub)', 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',
@@ -192,6 +193,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
self.settings['extlinux'] and not self.settings['grub']:
raise cliapp.AppException(
'extlinux is not yet supported on btrfs. Use grub.')
+ if self.settings['roottype'] == 'ext4' and\
+ self.settings['extlinux'] and not self.settings['grub']:
+ msg = 'The image may fail to boot with ext4 and extlinux unless ' +\
+ 'vmdebootstrap is running on Jessie. Use grub or ext3 and ' +\
+ 'see the docs.'
+ print("\nWarning: %s\n" % msg)
+ logging.warn(msg)
uefi = self.handlers[Uefi.name]
oldstable = distro.was_oldstable(datetime.date(2015, 4, 26))
uefi.check_settings(oldstable=oldstable)
@@ -209,6 +217,7 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
base = self.handlers[Base.name]
filesystem = self.handlers[Filesystem.name]
extlinux = self.handlers[ExtLinux.name]
+ distro = self.handlers[Codenames.name]
base.create_empty_image()
self.partition_image()
extlinux.install_mbr()
@@ -219,7 +228,12 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
if self.settings['swap'] > 0:
base.message("Creating swap space")
runcmd(['mkswap', filesystem.devices['swapdev']])
- filesystem.mkfs(rootdev, fstype=roottype)
+ # stable or oldstable, use ^metadata_csum
+ opt = None
+ if distro.was_oldstable(datetime.date(2015, 4, 26)) or \
+ distro.was_stable(datetime.date(2015, 4, 26)):
+ opt = "^metadata_csum"
+ filesystem.mkfs(rootdev, fstype=roottype, opt=opt)
rootdir = self.mount(rootdev)
filesystem.devices['rootdir'] = rootdir
if self.settings['use-uefi']:
@@ -265,9 +279,11 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
uefi.configure_extra_efi(rootdir)
elif self.settings['grub']:
if not grub.install_grub2(rootdev, rootdir):
+ # FIXME: don't fall back.
extlinux.install_extlinux(rootdev, rootdir)
elif self.settings['extlinux']:
extlinux.install_extlinux(rootdev, rootdir)
+ extlinux.run_extlinux_install(rootdir)
# only append for wheezy (which became oldstable on 2015.04.25)
if distro.was_oldstable(datetime.date(2015, 4, 26)):
base.append_serial_console(rootdir)
@@ -301,8 +317,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
if distro.was_oldstable(datetime.date(2015, 4, 26)):
network.setup_wheezy_networking(rootdir)
else:
- network.setup_networking(rootdir)
- network.systemd_support(rootdir)
+ if self.settings['systemd-networkd']:
+ network.systemd_support(rootdir)
+ if not distro.was_stable(datetime.date(2015, 4, 26)):
+ network.enable_systemd_resolved(rootdir)
+ else:
+ # /etc/network/interfaces.d/
+ network.setup_networking(rootdir)
filesystem.configure_apt()
base.customize(rootdir)
cleanup_apt_cache(rootdir)
@@ -328,8 +349,8 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
rootdir = filesystem.devices['rootdir']
if rootdir:
db_log = os.path.join(rootdir, 'debootstrap', 'debootstrap.log')
- os.chmod(db_log, 0o644)
if os.path.exists(db_log):
+ os.chmod(db_log, 0o644)
shutil.copy(db_log, os.getcwd())
if self.settings['owner']:
runcmd(["chown", self.settings["owner"], db_log])
@@ -369,8 +390,7 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
logging.debug("umount failed, sleeping and trying again")
time.sleep(5)
runcmd(['umount', mount_point], ignore_fail=False)
- else:
- self.mount_points.remove(i)
+ self.mount_points.pop(i)
def partition_image(self):
"""
@@ -446,6 +466,7 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
uefi = self.handlers[Uefi.name]
grub = self.handlers[GrubHandler.name]
distro = self.handlers[Codenames.name]
+ extlinux = self.handlers[ExtLinux.name]
include = self.settings['package']
include.extend(base.base_packages())
diff --git a/doc/overview.rst b/doc/overview.rst
index 2d9b8c0..5471d9a 100644
--- a/doc/overview.rst
+++ b/doc/overview.rst
@@ -114,11 +114,10 @@ Options
Note: foreign debootstraps may take a significant
amount of time to complete and debootstrap will
retry five times if packages fail to install by default.
- --no-extlinux Skip installation of extlinux. Needs a customize script
+ --no-extlinux Skip installation of extlinux. Needs grub, a customize script
or alternative bootloader to make the image bootable.
- Useful for architectures where extlinux is not supportable.
- Depending on how the image is to be booted, the ``--mbr``
- option may also be necessary with extlinux.
+ extlinux is deprecated and this will become the default
+ in a future release.
--squash=DIRECTORY Run mksquashfs against the rootfs using xz
compression --- requires ``squashfs-tools`` to be installed.
The squashfs and other files needed to use the squashfs
@@ -264,6 +263,16 @@ Unless the ``--no-extlinux`` or ``--grub`` options are specified, the
image will use ``extlinux`` as a boot loader. ``bootsize`` is not
recommended when using ``extlinux`` --- use ``grub`` instead.
+.. note:: Unlike grub, extlinux support requires the installation of
+ packages outside the image which are used to install the extlinux
+ bootloader inside the image. extlinux support also involves the
+ use of ``sync`` which can cause issues on systems with multiple
+ filesystems mounted, particularly over a network or when building
+ multiple images simultaneously. Therefore, ``extlinux`` is
+ **deprecated** in vmdebootstrap. The default will change in a future
+ release and ``extlinux`` support may be dropped once Stretch is
+ released.
+
.. _extlinux_ext4:
extlinux support issues with ext4
diff --git a/vmdebootstrap/extlinux.py b/vmdebootstrap/extlinux.py
index b37ee7e..648fce4 100644
--- a/vmdebootstrap/extlinux.py
+++ b/vmdebootstrap/extlinux.py
@@ -91,12 +91,19 @@ append initrd=%(initrd)s root=UUID=%(uuid)s ro %(kserial)s
ext_f = open(conf, 'w')
ext_f.write(msg)
- runcmd(['extlinux', '--install', rootdir])
- runcmd(['sync'])
- time.sleep(2)
+ def run_extlinux_install(self, rootdir):
+ if os.path.exists("/usr/bin/extlinux"):
+ self.message('Running extlinux --install')
+ runcmd(['extlinux', '--install', rootdir])
+ runcmd(['sync'])
+ time.sleep(2)
+ else:
+ msg = "extlinux enabled but /usr/bin/extlinux not found" \
+ " - please install the extlinux package."
+ raise cliapp.AppException(msg)
def install_mbr(self):
- if not self.settings['mbr'] and not self.settings['extlinux']:
+ if not self.settings['mbr'] or not self.settings['extlinux']:
return
if os.path.exists("/sbin/install-mbr"):
self.message('Installing MBR')