Add compression to /etc/fstab for btrfs subvolumes (#1473)

* Adding a btrfs compression plugin to genfstab

* Allowing the genfstab plugin to break on success
This commit is contained in:
Anton Hvornum 2022-09-19 23:42:08 +02:00 committed by GitHub
parent e83a41f3f5
commit c1f21e7ca4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 5 deletions

View File

@ -54,7 +54,3 @@ def create_subvolume(installation: Installer, subvolume_location :Union[pathlib.
log(f"Creating a subvolume on {target}", level=logging.INFO) log(f"Creating a subvolume on {target}", level=logging.INFO)
if (cmd := SysCommand(f"btrfs subvolume create {target}")).exit_code != 0: if (cmd := SysCommand(f"btrfs subvolume create {target}")).exit_code != 0:
raise DiskError(f"Could not create a subvolume at {target}: {cmd}") raise DiskError(f"Could not create a subvolume at {target}: {cmd}")
def manage_btrfs_subvolumes(installation :Installer, partition :Dict[str, str]) -> list:
raise Deprecated("Use setup_subvolumes() instead.")

View File

@ -1,4 +1,5 @@
import logging import logging
import re
from pathlib import Path from pathlib import Path
from typing import Optional, Dict, Any, TYPE_CHECKING from typing import Optional, Dict, Any, TYPE_CHECKING
@ -6,6 +7,7 @@ from ...models.subvolume import Subvolume
from ...exceptions import SysCallError, DiskError from ...exceptions import SysCallError, DiskError
from ...general import SysCommand from ...general import SysCommand
from ...output import log from ...output import log
from ...plugins import plugins
from ..helpers import get_mount_info from ..helpers import get_mount_info
from .btrfssubvolumeinfo import BtrfsSubvolumeInfo from .btrfssubvolumeinfo import BtrfsSubvolumeInfo
@ -14,6 +16,35 @@ if TYPE_CHECKING:
from ...installer import Installer from ...installer import Installer
class fstab_btrfs_compression_plugin():
def __init__(self, partition_dict):
self.partition_dict = partition_dict
def on_genfstab(self, installation):
with open(f"{installation.target}/etc/fstab", 'r') as fh:
fstab = fh.read()
# Replace the {installation}/etc/fstab with entries
# using the compress=zstd where the mountpoint has compression set.
with open(f"{installation.target}/etc/fstab", 'w') as fh:
for line in fstab.split('\n'):
# So first we grab the mount options by using subvol=.*? as a locator.
# And we also grab the mountpoint for the entry, for instance /var/log
if (subvoldef := re.findall(',.*?subvol=.*?[\t ]', line)) and (mountpoint := re.findall('[\t ]/.*?[\t ]', line)):
for subvolume in self.partition_dict.get('btrfs', {}).get('subvolumes', []):
# We then locate the correct subvolume and check if it's compressed
if subvolume.compress and subvolume.mountpoint == mountpoint[0].strip():
# We then sneak in the compress=zstd option if it doesn't already exist:
# We skip entries where compression is already defined
if ',compress=zstd,' not in line:
line = line.replace(subvoldef[0], f",compress=zstd{subvoldef[0]}")
break
fh.write(f"{line}\n")
return True
def mount_subvolume(installation: 'Installer', device: 'BTRFSPartition', subvolume: Subvolume): def mount_subvolume(installation: 'Installer', device: 'BTRFSPartition', subvolume: Subvolume):
# we normalize the subvolume name (getting rid of slash at the start if exists. # we normalize the subvolume name (getting rid of slash at the start if exists.
# In our implementation has no semantic load. # In our implementation has no semantic load.
@ -61,6 +92,9 @@ def setup_subvolumes(installation: 'Installer', partition_dict: Dict[str, Any]):
if (cmd := SysCommand(f"chattr +c {installation.target}/{name}")).exit_code != 0: if (cmd := SysCommand(f"chattr +c {installation.target}/{name}")).exit_code != 0:
raise DiskError(f"Could not set compress attribute at {installation.target}/{name}: {cmd}") raise DiskError(f"Could not set compress attribute at {installation.target}/{name}: {cmd}")
if 'fstab_btrfs_compression_plugin' not in plugins:
plugins['fstab_btrfs_compression_plugin'] = fstab_btrfs_compression_plugin(partition_dict)
def subvolume_info_from_path(path: Path) -> Optional[BtrfsSubvolumeInfo]: def subvolume_info_from_path(path: Path) -> Optional[BtrfsSubvolumeInfo]:
try: try:

View File

@ -432,7 +432,8 @@ class Installer:
for plugin in plugins.values(): for plugin in plugins.values():
if hasattr(plugin, 'on_genfstab'): if hasattr(plugin, 'on_genfstab'):
plugin.on_genfstab(self) if plugin.on_genfstab(self) is True:
break
return True return True