mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
container: Update FSID inside the image file to keep it bootable
- When fsid of the btrfs filesystem is updated, grub needs to updated too. Otherwise, the image can't be booted into using a virtual machine. - When fsid of the btrfs filesystem is updated, /etc/fstab needs to updated too. Otherwise, the root file system can't be remounted as read-write. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
parent
4f9e5e9e14
commit
6f6e2bc876
43
container
43
container
@ -591,7 +591,9 @@ def _resize_disk_image(image_file: pathlib.Path, new_size: str):
|
||||
check=True)
|
||||
last_line = process.stdout.decode().splitlines()[-1]
|
||||
partition = '/dev/mapper/' + last_line.split()[2]
|
||||
old_fsid = _get_fsid(partition)
|
||||
subprocess.run(['sudo', 'btrfstune', '-uf', partition], check=True)
|
||||
new_fsid = _get_fsid(partition)
|
||||
|
||||
with tempfile.TemporaryDirectory(
|
||||
dir=_get_work_directory().resolve()) as mount_point:
|
||||
@ -599,6 +601,7 @@ def _resize_disk_image(image_file: pathlib.Path, new_size: str):
|
||||
subprocess.run(
|
||||
['sudo', 'btrfs', 'filesystem', 'resize', 'max', mount_point],
|
||||
check=True, stdout=subprocess.DEVNULL)
|
||||
_update_fsid(mount_point, partition, old_fsid, new_fsid)
|
||||
subprocess.run(['sudo', 'umount', mount_point], check=True)
|
||||
|
||||
subprocess.run(
|
||||
@ -606,6 +609,46 @@ def _resize_disk_image(image_file: pathlib.Path, new_size: str):
|
||||
stderr=subprocess.DEVNULL)
|
||||
|
||||
|
||||
def _get_fsid(partition: str) -> str:
|
||||
"""Return the btrfs filesystem ID for a device."""
|
||||
# Find the new FSID
|
||||
process = subprocess.run(
|
||||
['sudo', 'btrfs', 'filesystem', 'show', partition], check=True,
|
||||
stdout=subprocess.PIPE)
|
||||
return process.stdout.decode().splitlines()[0].rpartition(' ')[2]
|
||||
|
||||
|
||||
def _update_fsid(mount_point: str, partition: str, old_fsid: str,
|
||||
new_fsid: str):
|
||||
"""After changing btrfs fsid, run grub-install to keep image bootable."""
|
||||
# Guess the loopback device for the filesystem
|
||||
matches = re.match(r'^/dev/mapper/loop(\d+)p\d+$', partition)
|
||||
assert matches
|
||||
loop_device = f'/dev/loop{matches[1]}'
|
||||
|
||||
# Mount /dev, /proc and run grub commands in chroot
|
||||
grub_args = []
|
||||
if platform.machine() in ('aarch64', 'arm64'):
|
||||
grub_args += ['--no-nvram']
|
||||
|
||||
subprocess.run(
|
||||
['sudo', 'mount', '-o', 'bind', '/dev/', f'{mount_point}/dev'],
|
||||
check=True)
|
||||
subprocess.run(
|
||||
['sudo', 'mount', '-o', 'bind', '/proc/', f'{mount_point}/proc'],
|
||||
check=True)
|
||||
subprocess.run(['sudo', 'chroot', mount_point, 'update-grub'], check=True)
|
||||
subprocess.run(
|
||||
['sudo', 'chroot', mount_point, 'grub-install', loop_device] +
|
||||
grub_args, check=True)
|
||||
subprocess.run([
|
||||
'sudo', 'chroot', mount_point, 'sed', '-ie',
|
||||
f's|UUID={old_fsid}|UUID={new_fsid}|', '/etc/fstab'
|
||||
], check=True)
|
||||
subprocess.run(['sudo', 'umount', f'{mount_point}/proc'], check=True)
|
||||
subprocess.run(['sudo', 'umount', f'{mount_point}/dev'], check=True)
|
||||
|
||||
|
||||
def _runc(image_file: pathlib.Path, command: list[str], **kwargs):
|
||||
"""Run a command inside the container."""
|
||||
subprocess.run([
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user