diff --git a/src/pylorax/treebuilder.py b/src/pylorax/treebuilder.py index c02d0ea6..395d71e2 100644 --- a/src/pylorax/treebuilder.py +++ b/src/pylorax/treebuilder.py @@ -23,6 +23,7 @@ logger = logging.getLogger("pylorax.treebuilder") import os, re from os.path import basename from shutil import copytree, copy2 +from subprocess import CalledProcessError from pathlib import Path import itertools @@ -228,8 +229,14 @@ class RuntimeBuilder(object): workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir") os.makedirs(joinpaths(workdir, "LiveOS")) - imgutils.mkrootfsimg(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"), - "Anaconda", size=size) + # Catch problems with the rootfs being too small and clearly log them + try: + imgutils.mkrootfsimg(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"), + "Anaconda", size=size) + except CalledProcessError as e: + if e.stdout and "No space left on device" in e.stdout: + logger.error("The rootfs ran out of space with size=%d", size) + raise # squash the live rootfs and clean up workdir imgutils.mksquashfs(workdir, outfile, compression, compressargs) diff --git a/tests/pylorax/test_imgutils.py b/tests/pylorax/test_imgutils.py index f40f6bd8..56d2dcad 100644 --- a/tests/pylorax/test_imgutils.py +++ b/tests/pylorax/test_imgutils.py @@ -17,6 +17,7 @@ import glob import os import parted +from subprocess import CalledProcessError import tarfile import tempfile import unittest @@ -270,6 +271,22 @@ class ImgUtilsTest(unittest.TestCase): file_details = get_file_magic(disk_img.name) self.assertTrue("ext2 filesystem" in file_details, file_details) + @unittest.skipUnless(os.geteuid() == 0 and not os.path.exists("/.in-container"), "requires root privileges, and no containers") + def test_small_mkext4img(self): + """Test mkext4img error handling""" + with tempfile.TemporaryDirectory(prefix="lorax.test.") as work_dir: + with tempfile.NamedTemporaryFile(prefix="lorax.test.disk.") as disk_img: + mkfakerootdir(work_dir) + # Add a 8MiB file + with open(joinpaths(work_dir, "large-file"), "w") as f: + for _ in range(5): + f.write("A" * 1024**2) + graft = {work_dir+"/etc/yum.repos.d/": "./tests/pylorax/repos/server-2.repo"} + try: + mkext4img(work_dir, disk_img.name, graft=graft, size=5*1024**2) + except CalledProcessError as e: + self.assertTrue(e.stdout and "No space left on device" in e.stdout) + @unittest.skipUnless(os.geteuid() == 0 and not os.path.exists("/.in-container"), "requires root privileges, and no containers") def test_mkbtrfsimg(self): """Test mkbtrfsimg function (requires loop)"""