Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion lib/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging
import os
import re
import subprocess
import tempfile
import uuid
Expand All @@ -12,6 +13,7 @@
import lib.efi as efi
from lib.basevm import BaseVM
from lib.common import (
KiB,
PackageManagerEnum,
expand_scope_relative_nodeid,
parse_xe_dict,
Expand All @@ -27,7 +29,7 @@
from lib.vdi import VDI
from lib.vif import VIF

from typing import TYPE_CHECKING, Iterable, List, Literal, overload
from typing import TYPE_CHECKING, Iterable, List, Literal, assert_never, overload

if TYPE_CHECKING:
from lib.host import Host
Expand Down Expand Up @@ -523,6 +525,36 @@ def detect_package_manager(self) -> PackageManagerEnum:
return PackageManagerEnum.ZYPPER
return PackageManagerEnum.UNKNOWN

def grow_root_partition(self) -> int | None:
pkg_manager = self.detect_package_manager()
match pkg_manager:
case PackageManagerEnum.APK:
self.ssh('apk add util-linux e2fsprogs-extra')
case PackageManagerEnum.APT_GET:
self.ssh('apt-get update && apt-get install -y -qq util-linux e2fsprogs')
case PackageManagerEnum.DNF:
self.ssh('dnf install -y util-linux e2fsprogs')
case PackageManagerEnum.YUM:
self.ssh('yum install -y util-linux e2fsprogs')
case PackageManagerEnum.ZYPPER:
self.ssh('zypper --non-interactive install util-linux e2fsprogs')
case PackageManagerEnum.UNKNOWN:
return None
case _:
assert_never(pkg_manager)
mount_output = self.ssh('mount').strip()
root_match = re.search(r'/dev/(\w+?)(p?)(\d+) on / type (\w+)', mount_output)
Comment thread
glehmann marked this conversation as resolved.
assert root_match is not None
disk, p, partition, fs_type = root_match.groups()
if not fs_type.startswith('ext'):
logging.debug(f"Unsupported filesystem: {fs_type}")
return None
self.ssh(f'echo ", +" | sfdisk --no-reread --force -N {partition} /dev/{disk}')
self.ssh(f'partx -u -n {partition}:{partition} /dev/{disk}')
self.ssh(f'resize2fs /dev/{disk}{p}{partition}')
Comment thread
glehmann marked this conversation as resolved.
df_output = self.ssh('df /')
return int(df_output.splitlines()[-1].split()[3]) * KiB

def insert_cd(self, vdi_name: str) -> None:
logging.info("Insert CD %r in VM %s", vdi_name, self.uuid)
self.host.xe('vm-cd-insert', {'uuid': self.uuid, 'cd-name': vdi_name})
Expand Down
14 changes: 3 additions & 11 deletions tests/storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,9 @@ def xva_export_import(source_vm: VM, compression: XVACompression, temp_large_dir
vm.wait_for_vm_running_and_ssh_up()
install_randstream(vm)

if vm.detect_package_manager() == PackageManagerEnum.APK:
# growpart is not available in alpine 3.12
# vm.ssh('apk add cloud-utils-growpart e2fsprogs-extra')
vm.ssh('apk add gawk util-linux e2fsprogs-extra')
vm.ssh('wget https://raw.githubusercontent.com/canonical/cloud-utils/main/bin/growpart -O /usr/bin/growpart')
vm.ssh('chmod +x /usr/bin/growpart')
# TODO: maybe use `findmnt -no SOURCE /` from util-linux to get the blockdevice mounted on /
growpart_returncode = vm.ssh_with_result('growpart /dev/xvda 3').returncode
assert growpart_returncode in [0, 1] # growpart returns 1 if the size is already the expected one
vm.ssh('resize2fs /dev/xvda3')
stream_size = min(volume_size // 2, config.write_volume_cap)
root_partition_size = vm.grow_root_partition()
if root_partition_size is not None:
stream_size = min(root_partition_size // 2, config.write_volume_cap)
else:
stream_size = 500 * MiB

Expand Down
Loading