diff options
Diffstat (limited to 'extensions/writeexts.py')
-rw-r--r-- | extensions/writeexts.py | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/extensions/writeexts.py b/extensions/writeexts.py index 647f3742..f60458ce 100644 --- a/extensions/writeexts.py +++ b/extensions/writeexts.py @@ -302,8 +302,7 @@ class WriteExtension(Extension): def create_system(self, temp_root, raw_disk): with self.mount(raw_disk) as mp: try: - self.create_btrfs_system_layout( - mp, version_label='factory') + self.create_versioned_layout(mp, version_label='factory') self.create_btrfs_system_rootfs( temp_root, mp, version_label='factory', rootfs_uuid=self.get_uuid(raw_disk)) @@ -436,8 +435,25 @@ class WriteExtension(Extension): subprocess.check_call(['umount', mount_point]) os.rmdir(mount_point) - def create_btrfs_system_layout(self, mountpoint, version_label): - '''Create the btrfs folder layout required for baserock + def create_versioned_layout(self, mountpoint, version_label): + '''Create a versioned directory structure within a partition. + + The Baserock project has defined a 'reference upgrade mechanism'. This + mandates a specific directory layout. It consists of a toplevel + '/systems' directory, containing subdirectories named with a 'version + label'. These subdirectories contain the actual OS content. + + For the root file system, a Btrfs partition must be used. For each + version, two subvolumes are created: 'orig' and 'run'. This is handled + in create_btrfs_system_rootfs(). + + Other partitions (e.g. /boot) can also follow the same layout. In the + case of /boot, content goes directly in the version directory. That + means there are no 'orig' and 'run' subvolumes, which avoids the + need to use Btrfs. + + The `system-version-manager` tool from tbdiff.git is responsible for + deploying live upgrades, and it understands this layout. ''' version_root = os.path.join(mountpoint, 'systems', version_label) @@ -492,8 +508,6 @@ class WriteExtension(Extension): root_guid = device.get_partition_uuid(root_part) self.generate_bootloader_config(mountpoint, root_guid=root_guid) - if self.get_bootloader_install() == 'extlinux': - self.install_syslinux_blob(device, system_dir) else: # Unpartitioned and no initramfs - cannot boot with a UUID self.generate_bootloader_config(mountpoint) @@ -938,6 +952,7 @@ class WriteExtension(Extension): dev = partitioning.do_partitioning(location, disk_size, temp_root, part_spec) + boot_partition_available = dev.get_partition_by_mountpoint('/boot') for part in dev.partitionlist: if not hasattr(part, 'mountpoint'): @@ -957,13 +972,23 @@ class WriteExtension(Extension): # Install root filesystem rfs_uuid = self.get_uuid(location, part.extent.start * dev.sector_size) - self.create_btrfs_system_layout(part_mount_dir, 'factory') + self.create_versioned_layout(part_mount_dir, 'factory') self.create_btrfs_system_rootfs(temp_root, part_mount_dir, 'factory', rfs_uuid, dev) - if self.bootloader_config_is_wanted(): - self.create_bootloader_config(temp_root, part_mount_dir, - 'factory', rfs_uuid, dev) + # If there's no /boot partition, but we do need to generate + # a bootloader configuration file, then it needs to go in + # the root partition. + if (boot_partition_available is False + and self.bootloader_config_is_wanted()): + self.create_bootloader_config( + temp_root, part_mount_dir, 'factory', rfs_uuid, + dev) + + if self.get_bootloader_install() == 'extlinux': + # The extlinux/syslinux MBR blob always needs to be + # installed in the root partition. + self.install_syslinux_blob(dev, temp_root) else: # Copy files to partition from unpacked rootfs src_dir = os.path.join(temp_root, @@ -972,6 +997,16 @@ class WriteExtension(Extension): part.mountpoint) self.copy_dir_contents(src_dir, part_mount_dir) + if (part.mountpoint == '/boot' and + self.bootloader_config_is_wanted()): + # We need to mirror the layout of the root partition in the + # /boot partition. Each kernel lives in its own + # systems/$version_label/ directory within the /boot + # partition. + self.create_versioned_layout(part_mount_dir, 'factory') + self.create_bootloader_config(temp_root, part_mount_dir, + 'factory', None, dev) + # Write raw files to disk with dd partitioning.process_raw_files(dev, temp_root) |