summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Williams <codehelp@debian.org>2015-11-04 16:41:17 +0000
committerNeil Williams <codehelp@debian.org>2015-11-04 16:41:17 +0000
commit4ecfee0fcc6d136553d0ead973854f57c14a91bc (patch)
tree6a9723dad29d49f6602786d610ec747f54e5536f
parent3855370a24530cd0541519b906045c7ccb66c28e (diff)
downloadvmdebootstrap-4ecfee0fcc6d136553d0ead973854f57c14a91bc.tar.gz
Change squashfs behaviour to a tree, not the image.
-rwxr-xr-xbin/vmdebootstrap23
-rw-r--r--doc/live.rst10
-rw-r--r--man/vmdebootstrap.rst28
-rw-r--r--vmdebootstrap/filesystem.py69
4 files changed, 52 insertions, 78 deletions
diff --git a/bin/vmdebootstrap b/bin/vmdebootstrap
index 1b788d3..c44ff25 100755
--- a/bin/vmdebootstrap
+++ b/bin/vmdebootstrap
@@ -166,13 +166,9 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
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.string(
- ['squash-file'], 'filename for the squashfs '
- '- cannot be used with --image',
- metavar='FILE',
- default='rootfs.squash')
+ ['squash'], 'use squashfs on the rootfs - '
+ 'cannot be used with --image', metavar='DIRECTORY')
self.settings.boolean(
['configure-apt'], 'Create an apt source based on '
'the distribution and mirror selected.')
@@ -198,6 +194,9 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
handler.define_settings(self.settings)
distro = self.handlers[Codenames.name]
+ if self.settings['squash'] and self.settings['image']:
+ raise cliapp.AppException(
+ '--image can no longer be used with --squash')
if not self.settings['image'] and not (
self.settings['tarball'] or self.settings['squash']):
raise cliapp.AppException(
@@ -279,7 +278,6 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
extlinux.install_extlinux(rootdev, rootdir)
base.append_serial_console(rootdir)
self.optimize_image(rootdir)
- filesystem.squash_image()
def start_ops(self):
base = self.handlers[Base.name]
@@ -291,6 +289,7 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
rootdev = filesystem.devices['rootdev']
else:
rootdir = self.mkdtemp()
+ filesystem.devices['rootdir'] = rootdir
rootdev = filesystem.devices['rootdev']
logging.debug("rootdir=%s rootdev=%s", rootdir, rootdev)
self.debootstrap(rootdir)
@@ -315,9 +314,13 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
if self.settings['tarball']:
base.create_tarball(rootdir)
- else:
- filesystem.squash_filesystem()
+ elif self.settings['squash']:
+ filesystem.squash_rootfs()
filesystem.chown()
+ # need to copy boot/efi/* if configured.
+ # but that is a task for the uefi module.
+ # if self.settings['use-uefi'] and self.settings['squash']:
+ # export uefi files
except BaseException as e:
base.message('EEEK! Something bad happened...')
@@ -326,6 +329,8 @@ class VmDebootstrap(cliapp.Application): # pylint: disable=too-many-public-meth
db_log = os.path.join(rootdir, 'debootstrap', 'debootstrap.log')
if os.path.exists(db_log):
shutil.copy(db_log, os.getcwd())
+ if self.settings['owner']:
+ runcmd(["chown", self.settings["owner"], db_log])
base.message(e)
self.cleanup_system()
raise
diff --git a/doc/live.rst b/doc/live.rst
index 002072c..0106de9 100644
--- a/doc/live.rst
+++ b/doc/live.rst
@@ -87,10 +87,6 @@ Initial schemes for vmdebootstrap creation of live images
customisation hook, remove that source and replace the original.
#. ``mksquashfs`` can fail without indication of why and when it does, the image
- file can be 4Kb or so of junk. To prevent this, avoid running
- vmdebootstrap with the ``--squash`` option and run mksquashfs as a second step
- **after** copying the raw image to a new file for safety / debugging.
- Newer versions of vmdebootstrap will emit a warning and not delete
- the original file if the squashfs output is less than 1MB. This can
- occur if the drive runs out of space but squashfs does not report
- an error.
+ file can be 4Kb or so of junk. ``vmdebootstrap`` will fail if the
+ squashfs output is less than 1MB. This can occur if the drive runs
+ out of space but squashfs does not report an error.
diff --git a/man/vmdebootstrap.rst b/man/vmdebootstrap.rst
index 74bb153..90fad4c 100644
--- a/man/vmdebootstrap.rst
+++ b/man/vmdebootstrap.rst
@@ -107,23 +107,19 @@ Options
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.
- --squash Run mksquashfs against the final image using xz
+ --squash=DIRECTORY Run mksquashfs against the rootfs using xz
compression - requires ``squashfs-tools`` to be installed.
- The final file will have the ``.squashfs`` suffix.
- By default, mksquashfs is allowed to use all processors
- which may result in high load. Run ``mksquashfs``
- separately if you need to control the number of
- processors used per run. squashfs can also have issues
- with large image files (where large is a factor of the
- amount of data inside the image rather than the size
- of the image itself). These errors can result in invalid
- images (e.g. image does not boot) or corrupted images
- (truncated file). This is a known bug in squashfs.
- Avoid using the --squash option and consider squashing
- the loopback mounted directory tree of the image.
- ``vmdebootstrap`` will check if the squashed filesystem
- is less than 1MB and leave the unsquashed image in
- place with a warning about a possible squashfs failure.
+ The squashfs and other files needed to use the squashfs
+ to make a bootable system will be put into the specified directory.
+ The directory will contain a ``filesystem.squashfs``
+ as well as the top level contents of the ``boot/``
+ directory. (If using UEFI, the ``boot/efi`` directory
+ as well.) By default, ``mksquashfs`` is allowed to use
+ all processors which may result in high load. squashfs
+ can also have issues with large root filesystems. These
+ errors can result in truncated files. This is a known
+ bug in squashfs. ``vmdebootstrap`` will fail if the
+ squashed filesystem is less than 1MB.
--configure-apt Use the specified mirror and distribution to create a
suitable apt source inside the VM. Can be useful if
debootstrap fails to create it automatically.
diff --git a/vmdebootstrap/filesystem.py b/vmdebootstrap/filesystem.py
index 796f7d8..23c7fef 100644
--- a/vmdebootstrap/filesystem.py
+++ b/vmdebootstrap/filesystem.py
@@ -22,9 +22,9 @@
import os
+import shutil
import cliapp
import logging
-import subprocess
from vmdebootstrap.base import Base, runcmd
# pylint: disable=missing-docstring
@@ -58,10 +58,12 @@ class Filesystem(Base):
filename = self.settings['image']
elif self.settings['tarball']:
filename = self.settings['tarball']
+ elif self.settings['squash']:
+ filename = self.settings['squash']
else:
return
self.message("Changing owner to %s" % self.settings["owner"])
- subprocess.call(["chown", self.settings["owner"], filename])
+ runcmd(["chown", "-R", self.settings["owner"], filename])
def update_initramfs(self):
rootdir = self.devices['rootdir']
@@ -160,69 +162,44 @@ class Filesystem(Base):
elif self.settings['swap'] > 0:
fstab.write("/dev/sda2 swap swap defaults 0 0\n")
- def squash_filesystem(self):
+ def squash_rootfs(self):
"""
- Run squashfs on the temporary directory
- """
- if not self.settings['squash']:
- return
- if self.settings['image']:
- return
- if not os.path.exists('/usr/bin/mksquashfs'):
- logging.warning("Squash selected but mksquashfs not found!")
- return
- logging.debug(
- "%s usage: %s", self.settings['image'],
- runcmd(['du', self.settings['image']]))
- self.message("Running mksquashfs")
- output = self.settings['squash-file']
- if os.path.exists(output):
- os.unlink(output)
- msg = runcmd(
- ['mksquashfs', self.devices['rootdir'],
- output, '-no-progress', '-comp', 'xz'], ignore_fail=False)
- logging.debug(msg)
- check_size = os.path.getsize(output)
- if check_size < (1024 * 1024):
- logging.warning(
- "%s appears to be too small! %s bytes",
- output, check_size)
- else:
- logging.debug("squashed size: %s", check_size)
-
- def squash_image(self):
- """
- Run squashfs on the image.
+ Run squashfs on the rootfs within the image.
+ Copy the initrd and the kernel out, squashfs the rest.
+ Also UEFI files, if enabled, ESP partition as a vfat image. TBD.
"""
if not self.settings['squash']:
return
if not os.path.exists('/usr/bin/mksquashfs'):
logging.warning("Squash selected but mksquashfs not found!")
return
- logging.debug(
- "%s usage: %s", self.settings['image'],
- runcmd(['du', self.settings['image']]))
- self.message("Running mksquashfs")
- suffixed = "%s.squashfs" % self.settings['image']
+ if not os.path.exists(self.settings['squash']):
+ os.mkdir(self.settings['squash'])
+ suffixed = os.path.join(self.settings['squash'], "filesystem.squashfs")
if os.path.exists(suffixed):
os.unlink(suffixed)
+ self.message("Running mksquashfs on rootfs.")
msg = runcmd(
- ['mksquashfs', self.settings['image'],
- suffixed,
+ ['mksquashfs', self.devices['rootdir'], suffixed,
'-no-progress', '-comp', 'xz'], ignore_fail=False)
logging.debug(msg)
check_size = os.path.getsize(suffixed)
+ logging.debug("Created squashfs: %s" % suffixed)
if check_size < (1024 * 1024):
logging.warning(
"%s appears to be too small! %s bytes",
suffixed, check_size)
else:
logging.debug("squashed size: %s", check_size)
- os.unlink(self.settings['image'])
- self.settings['image'] = suffixed
- logging.debug(
- "%s usage: %s", self.settings['image'],
- runcmd(['du', self.settings['image']]))
+ bootdir = os.path.join(self.devices['rootdir'], 'boot')
+ # copying the boot/* files
+ self.message("Copying boot files out of squashfs")
+ for filename in os.listdir(bootdir):
+ if os.path.isdir(filename) or os.path.islink(filename):
+ continue
+ shutil.copyfile(
+ os.path.join(bootdir, filename),
+ os.path.join(self.settings['squash'], filename))
def configure_apt(self):
rootdir = self.devices['rootdir']