Source code for btrsync.btrfs.cmd

#!/usr/bin/env python

# Copyright © 2023 Andrei Tatar <andrei.ttr@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later


"""
Programmatically generate ``btrfs`` subcommand invocations.
"""

import itertools

from .. import util


[docs]def list(path, *, list_all=False, readonly=False, fields='pcguqR'): """ Generate a ``btrfs subvolume list`` command. :param path: the target path to list :param list_all: if :const:`True`, list all subvolumes in the filesystem (btrfs option ``-a``), otherwise only direct descendants of `path` (btrfs option ``-o``) :param readonly: if :const:`True`, list only readonly subvolumes (btrfs option ``-r``) :param fields: flags selecting the subvolume fields to print (see ``btrfs-subvolume(8)``); default is all supported :returns: :class:`btrsync.util.Cmd` instance of the desired btrfs list command :raises ValueError: if unsupported fields are supplied """ FIELDS = 'pcguqR' for f in fields: if f not in FIELDS: raise ValueError(f"Unknown field `{f}'; allowed fields are: {', '.join(FIELDS)}") args = ['subvolume', 'list', '-t'] args.append('-a' if list_all else '-o') if readonly: args.append('-r') if fields: args.append('-' + fields) args.append(path) return util.Cmd('btrfs', args)
[docs]def send(*paths, parent=None, clones=[], keep_compressed=False): """ Generate a ``btrfs send`` command. :param paths: the target paths to send :param parent: path of the parent volume for incremental sends (btrfs-send option ``-p``) :param clones: sequence of paths of clone subvolumes (btrfs-send option ``-c``) :param keep_compressed: if :const:`True` instruct btrfs-send to output compressed blocks unchanged (btrfs-send option ``--compressed-data``) :returns: :class:`btrsync.util.Cmd` instance of the desired btrfs send command :raises ValueError: if no paths are given """ if not paths: raise ValueError('Must specify at least one path to send') args = ['send'] if keep_compressed: args.append('--compressed-data') if parent is not None: args.extend(('-p', parent)) if clones: args.extend(itertools.chain.from_iterable(('-c', cl) for cl in clones)) args.extend(paths) return util.Cmd('btrfs', args)
[docs]def receive(path, *, force_decompress=False): """ Generate a ``btrfs receive`` command. :param path: the path to receive into :param force_decompress: if :const:`True`, force the decompression of any compressed blocks in the stream (btrfs-receive option ``--force-decompress``) :returns: :class:`btrsync.util.Cmd` instance of the desired btrfs receive command """ args = ['receive'] if force_decompress: args.append('--force-decompress') args.append(path) return util.Cmd('btrfs', args)
[docs]def show(path, *, uuid=None, rootid=None): """ Generate a ``btrfs subvolume show`` command. :param path: path of the target subvolume or filesystem :param uuid: show information about subvolume with specified UUID; cannot be used together with `rootid` :param rootid: show information about subvolume with specified root ID; cannot be used together with `uuid` :returns: :class:`btrsync.util.Cmd` instance of the desired btrfs show command :raises ValueError: if both `uuid` and `rootid` are specified """ if uuid is not None and rootid is not None: raise ValueError("At most one of `uuid' and `rootid' may be specified") args = ['subvolume', 'show'] if uuid is not None: args.extend(('-u', uuid)) elif rootid is not None: args.extend(('-r', rootid)) args.append(path) return util.Cmd('btrfs', args)