summaryrefslogtreecommitdiff
path: root/morphlib/builder2.py
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-10-08 16:25:35 +0000
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-10-08 16:50:45 +0000
commita60bf07b33bda4df9defe20489707f61341e3685 (patch)
treef4c8347f6ba37abea039771674a1afea0d58b87e /morphlib/builder2.py
parenta04884d9a79c296023a555279f727a4dc17b5523 (diff)
downloadmorph-a60bf07b33bda4df9defe20489707f61341e3685.tar.gz
Compress system disk images
Since tarball rootfs images are compressed with gzip -1, we should do the same for disk images. This means they'll need decompressing before they can be used as disk images, but it means we'll be shunting around something closer to their true data size rather than the disk image size. For example, a 2G development system image compresses down to around 380M which is a lot faster to transfer and doesn't risk de-sparseification.
Diffstat (limited to 'morphlib/builder2.py')
-rw-r--r--morphlib/builder2.py74
1 files changed, 45 insertions, 29 deletions
diff --git a/morphlib/builder2.py b/morphlib/builder2.py
index 72165ce7..81ee5692 100644
--- a/morphlib/builder2.py
+++ b/morphlib/builder2.py
@@ -23,6 +23,8 @@ from collections import defaultdict
import tarfile
import traceback
import subprocess
+import tempfile
+import gzip
import cliapp
@@ -663,40 +665,54 @@ class DiskImageBuilder(SystemKindBuilder): # pragma: no cover
rootfs_artifact = self.new_artifact(
self.artifact.source.morphology['name'] + '-rootfs')
handle = self.local_artifact_cache.put(rootfs_artifact)
- image_name = handle.name
-
- self._create_image(image_name)
- self._partition_image(image_name)
- self._install_mbr(arch, image_name)
- partition = self._setup_device_mapping(image_name)
-
- mount_point = None
+ (image_file_fd, image_name) = \
+ tempfile.mkstemp(dir=self.app.settings['tempdir'])
try:
- self._create_fs(partition)
- mount_point = self.staging_area.destdir(self.artifact.source)
- self._mount(partition, mount_point)
- factory_path = os.path.join(mount_point, 'factory')
- self._create_subvolume(factory_path)
- self.unpack_strata(factory_path)
- self.create_fstab(factory_path)
- self._create_bootloader_config(factory_path)
- self._create_subvolume_snapshot(
- mount_point, 'factory', 'factory-run')
- factory_run_path = os.path.join(mount_point, 'factory-run')
- self._install_boot_files(arch, factory_run_path, mount_point)
- self._install_bootloader(mount_point)
- self.copy_kernel_into_artifact_cache(factory_path)
- self._unmount(mount_point)
- except BaseException, e:
- logging.error(traceback.format_exc())
- self.app.status(msg='Error while building system',
- error=True)
- self._unmount(mount_point)
+ self._create_image(image_name)
+ self._partition_image(image_name)
+ self._install_mbr(arch, image_name)
+ partition = self._setup_device_mapping(image_name)
+
+ mount_point = None
+ try:
+ self._create_fs(partition)
+ mount_point = self.staging_area.destdir(self.artifact.source)
+ self._mount(partition, mount_point)
+ factory_path = os.path.join(mount_point, 'factory')
+ self._create_subvolume(factory_path)
+ self.unpack_strata(factory_path)
+ self.create_fstab(factory_path)
+ self._create_bootloader_config(factory_path)
+ self._create_subvolume_snapshot(
+ mount_point, 'factory', 'factory-run')
+ factory_run_path = os.path.join(mount_point, 'factory-run')
+ self._install_boot_files(arch, factory_run_path, mount_point)
+ self._install_bootloader(mount_point)
+ self.copy_kernel_into_artifact_cache(factory_path)
+ self._unmount(mount_point)
+ except BaseException, e:
+ logging.error(traceback.format_exc())
+ self.app.status(msg='Error while building system',
+ error=True)
+ self._unmount(mount_point)
+ self._undo_device_mapping(image_name)
+ raise
+
self._undo_device_mapping(image_name)
+
+ self.app.status(msg='Compressing disk image',
+ chatty=True)
+ with os.fdopen(image_file_fd, "rb") as ifh:
+ with gzip.GzipFile(fileobj=handle, mode="wb",
+ compresslevel=1) as ofh:
+ shutil.copyfileobj(ifh, ofh, 1024 * 1024)
+
+ except:
+ os.remove(image_name)
handle.abort()
raise
- self._undo_device_mapping(image_name)
+ os.remove(image_name)
handle.close()
self.save_build_times()