ZPool: adapt to new structure

main
svalouch 3 years ago
parent 89a7a98470
commit 83fcbb1053

@ -30,8 +30,9 @@ class ZFSCli(ZFS):
If ``zfs_exe`` is supplied, it is assumed that it points to the path of the ``zfs(8)`` executable. If ``zfs_exe`` is supplied, it is assumed that it points to the path of the ``zfs(8)`` executable.
''' '''
def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[PEHelperBase] = None, def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[PEHelperBase] = None,
use_pe_helper: bool = False, zfs_exe: Optional[str] = None, **kwargs) -> None: pe_helper_mode: PEHelperMode = PEHelperMode.DO_NOT_USE, zfs_exe: Optional[str] = None,
super().__init__(metadata_namespace=metadata_namespace, pe_helper=pe_helper, use_pe_helper=use_pe_helper, **kwargs) -> None:
super().__init__(metadata_namespace=metadata_namespace, pe_helper=pe_helper, pe_helper_mode=pe_helper_mode,
**kwargs) **kwargs)
self.find_executable(path=zfs_exe) self.find_executable(path=zfs_exe)

@ -1,9 +1,15 @@
'''
ZPOOL frontend API
'''
import logging import logging
import os import os
import stat import stat
from typing import Optional from typing import Optional
from .pe_helper import PEHelperBase
from .types import PEHelperMode
log = logging.getLogger('simplezfs.zpool') log = logging.getLogger('simplezfs.zpool')
@ -20,12 +26,25 @@ class ZPool:
* Using the native API * Using the native API
When creating an instance of this class, select one or the other as the ``api`` argument. When creating an instance of this class, select one or the other as the ``api`` argument.
**Properties and Metadata**
Please see the documentation for :class:`~simplezfs.zfs.ZFS` for native and metadata properties.
:param metadata_namespace: Default namespace
:param pe_helper: Privilege escalation (PE) helper to use for actions that require elevated privileges (root).
:param pe_helper_mode: How and when to use the PEHelper. Defaults to not using it at all.
:param kwargs: Extra arguments, ignored
''' '''
def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[str] = None, def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[PEHelperBase] = None,
use_pe_helper: bool = False, **kwargs) -> None: pe_helper_mode: PEHelperMode = PEHelperMode.DO_NOT_USE, **kwargs) -> None:
self.metadata_namespace = metadata_namespace self.metadata_namespace = metadata_namespace
self.pe_helper = pe_helper self.pe_helper = pe_helper
self.use_pe_helper = use_pe_helper self.pe_helper_mode = pe_helper_mode
def __repr__(self) -> str:
return f'<ZPool(pe_helper="{self._pe_helper}", pe_helper_mode="{self._pe_helper_mode}")>'
@property @property
def metadata_namespace(self) -> Optional[str]: def metadata_namespace(self) -> Optional[str]:
@ -44,36 +63,37 @@ class ZPool:
self._metadata_namespace = namespace self._metadata_namespace = namespace
@property @property
def pe_helper(self) -> Optional[str]: def pe_helper(self) -> Optional[PEHelperBase]:
''' '''
Returns the pe_helper, which may be None if not set. Returns the pe_helper, which may be None if not set.
''' '''
return self._pe_helper return self._pe_helper
@pe_helper.setter @pe_helper.setter
def pe_helper(self, helper: Optional[str]) -> None: def pe_helper(self, helper: Optional[PEHelperBase]) -> None:
''' '''
Sets the privilege escalation (PE) helper. Some basic checks for existance and executability are performed, Sets the privilege escalation (PE) helper. Supply ``None`` to unset it.
but these are not sufficient for secure operation and are provided to aid the user in configuring the library.
:note: This method does not follow symlinks.
:raises FileNotFoundError: if the helper can't be found or is not executable.
''' '''
if helper is None: if helper is None:
log.debug('PE helper is None') log.debug('PE helper is None')
self._pe_helper = None self._pe_helper = helper
else:
candidate = helper.strip()
mode = os.lstat(candidate).st_mode
if not stat.S_ISREG(mode):
raise FileNotFoundError('PE helper must be a file')
if not os.access(candidate, os.X_OK):
raise FileNotFoundError('PE helper must be executable')
log.debug(f'Setting privilege escalation helper to "{candidate}"')
self._pe_helper = candidate
@property
def pe_helper_mode(self) -> PEHelperMode:
'''
Returns whether the privilege escalation (PE) helper should be used and when. If the helper has not been set,
this property evaluates to ``False``.
'''
if self._pe_helper is None:
return PEHelperMode.DO_NOT_USE
return self._pe_helper_mode
@pe_helper_mode.setter
def pe_helper_mode(self, mode: PEHelperMode) -> None:
'''
Sets the privilege escalation (PE) helper mode.
'''
self._pe_helper_mode = mode
def get_zpool(api: str = 'cli', metadata_namespace: Optional[str] = None, **kwargs) -> ZPool: def get_zpool(api: str = 'cli', metadata_namespace: Optional[str] = None, **kwargs) -> ZPool:
''' '''

@ -7,7 +7,9 @@ import logging
import shutil import shutil
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from .types import ZPoolHealth
from .pe_helper import PEHelperBase
from .types import PEHelperMode, ZPoolHealth
from .zpool import ZPool from .zpool import ZPool
log = logging.getLogger('simplezfs.zpool_cli') log = logging.getLogger('simplezfs.zpool_cli')
@ -21,18 +23,23 @@ class ZPoolCli(ZPool):
If ``zpool_exe`` is supplied, it is assumed that it points to the path to the ``zpool(8)`` executable. If ``zpool_exe`` is supplied, it is assumed that it points to the path to the ``zpool(8)`` executable.
''' '''
def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[str] = None, def __init__(self, *, metadata_namespace: Optional[str] = None, pe_helper: Optional[PEHelperBase] = None,
use_pe_helper: bool = False, zpool_exe: Optional[str] = None, **kwargs) -> None: pe_helper_mode: PEHelperMode = PEHelperMode.DO_NOT_USE, zpool_exe: Optional[str] = None,
super().__init__(metadata_namespace=metadata_namespace, pe_helper=pe_helper, use_pe_helper=use_pe_helper) **kwargs) -> None:
super().__init__(metadata_namespace=metadata_namespace, pe_helper=pe_helper, pe_helper_mode=pe_helper_mode,
**kwargs)
self.find_executable(path=zpool_exe) self.find_executable(path=zpool_exe)
def __repr__(self) -> str:
return f'<ZPoolCLI(exe="{self.__exe}", pe_helper="{self._pe_helper}", pe_helper_mode="{self._pe_helper_mode}")>'
def find_executable(self, path: str = None) -> None: def find_executable(self, path: str = None) -> None:
''' '''
Tries to find the executable ``zpool``. If ``path`` points to an executable, it is used instead of relying on Tries to find the executable ``zpool``. If ``path`` points to an executable, it is used instead of relying on
the PATH to find it. It does not fall back to searching in PATH if ``path`` does not point to an exeuctable. the PATH to find it. It does not fall back to searching in PATH if ``path`` does not point to an exeuctable.
An exception is raised if no executable could be found. An exception is raised if no executable could be found.
:param path: Path to an executable to use instead of searching through $PATH. :param path: Path to the executable, used blindly if supplied.
:raises OSError: If the executable could not be found. :raises OSError: If the executable could not be found.
''' '''
exe_path = path exe_path = path
@ -40,14 +47,14 @@ class ZPoolCli(ZPool):
exe_path = shutil.which('zpool') exe_path = shutil.which('zpool')
if not exe_path: if not exe_path:
raise OSError('Could not find the executable') raise OSError('Could not find executable')
self.__exe = exe_path self.__exe = exe_path
@property @property
def executable(self) -> str: def executable(self) -> str:
''' '''
Returns the executable found by find_executable. Returns the zpool executable that was found by find_executable.
''' '''
return self.__exe return self.__exe

@ -39,7 +39,7 @@ class TestZPoolCli:
with pytest.raises(OSError) as excinfo: with pytest.raises(OSError) as excinfo:
ZPoolCli() ZPoolCli()
assert 'not find the executable' in str(excinfo.value) assert 'not find executable' in str(excinfo.value)
########################################################################## ##########################################################################

Loading…
Cancel
Save