docs: overhaul documentation

main
svalouch 4 years ago
parent 445a2a90cf
commit 280651a9b2

@ -31,7 +31,7 @@ ZFS
.. autofunction:: simplezfs.zfs.get_zfs .. autofunction:: simplezfs.zfs.get_zfs
.. autoclass:: simplezfs.ZFS .. autoclass:: simplezfs.zfs.ZFS
:members: :members:
ZPool ZPool
@ -39,7 +39,7 @@ ZPool
.. autofunction:: simplezfs.zpool.get_zpool .. autofunction:: simplezfs.zpool.get_zpool
.. autoclass:: simplezfs.ZPool .. autoclass:: simplezfs.zpool.ZPool
:members: :members:
Implementations Implementations

@ -2,7 +2,7 @@
# #
# This file only contains a selection of the most common options. For a full # This file only contains a selection of the most common options. For a full
# list see the documentation: # list see the documentation:
# http://www.sphinx-doc.org/en/master/config # https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup -------------------------------------------------------------- # -- Path setup --------------------------------------------------------------
@ -18,7 +18,7 @@
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'Python-SimpleZFS' project = 'Python-SimpleZFS'
copyright = '2019, Andreas Gonschorek, Stefan Valouch' copyright = '2019-2020, Andreas Gonschorek, Stefan Valouch'
author = 'Andreas Gonschorek, Stefan Valouch' author = 'Andreas Gonschorek, Stefan Valouch'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
@ -32,6 +32,7 @@ release = '0.0.1'
# ones. # ones.
extensions = [ extensions = [
'sphinx.ext.autodoc', 'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx_autodoc_typehints', 'sphinx_autodoc_typehints',
] ]
@ -49,9 +50,15 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'alabaster' import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static'] html_static_path = ['_static']
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

@ -21,12 +21,12 @@ The library makes use of Pythons own `logging` functions. It defines a tree star
* ``simplezfs`` (used as a common root only) * ``simplezfs`` (used as a common root only)
* ``simplezfs.zfs`` used by the :class:`~simplezfs.ZFS` parent class * ``simplezfs.zfs`` used by the :class:`~simplezfs.zfs.ZFS` parent class
* ``simplezfs.zfs.cli`` used by :class:`~simplezfs.zfs_cli.ZFSCli` * ``simplezfs.zfs.cli`` used by :class:`~simplezfs.zfs_cli.ZFSCli`
* ``simplezfs.zfs.native`` used by :class:`~simplezfs.zfs_native.ZFSNative` * ``simplezfs.zfs.native`` used by :class:`~simplezfs.zfs_native.ZFSNative`
* ``simplezfs.zpool`` used by the :class:`~simplezfs.ZPool` parent class * ``simplezfs.zpool`` used by the :class:`~simplezfs.zpool.ZPool` parent class
* ``simplezfs.zpool.cli`` used by :class:`~simplezfs.zpool_cli.ZPoolCli` * ``simplezfs.zpool.cli`` used by :class:`~simplezfs.zpool_cli.ZPoolCli`
* ``simplezfs.zpool.native`` used by :class:`~simplezfs.zpool_native.ZPoolNative` * ``simplezfs.zpool.native`` used by :class:`~simplezfs.zpool_native.ZPoolNative`

@ -1,6 +1,6 @@
################### #########################
Guide to python-zfs Guide to python-simplezfs
################### #########################
Overview Overview
******** ********
@ -12,8 +12,9 @@ collect actions and run them at the end, each action is carried out immediately.
There are, however, two implementations of the functionality, using the ``cli`` tools and another one using the There are, however, two implementations of the functionality, using the ``cli`` tools and another one using the
`libzfs_core` ``native`` library. We'll focus on the ``cli`` version here. `libzfs_core` ``native`` library. We'll focus on the ``cli`` version here.
Most of the functions raise a :class:`:: simplezfs.simplezfs.exceptions.ValidationError` with some helpful text if any of the data turns Most of the functions raise a :class:`simplezfs.exceptions.ValidationError` with some helpful text if any of the data
out not to be valid. For example, including invalid or reserved strings in the dataset name raises this exception. turns out not to be valid. For example, including invalid or reserved strings in the dataset name raises this
exception.
Let's take a look at the two interfaces **ZFS** and **ZPool**... Let's take a look at the two interfaces **ZFS** and **ZPool**...
@ -25,8 +26,8 @@ Let's take a look at the two interfaces **ZFS** and **ZPool**...
The ZFS interface The ZFS interface
***************** *****************
The :class:`:: simplezfs.simplezfs.zfs.ZFS` is the interface that corresponds to the ``zfs(8)`` program. It holds very little state, The :class:`simplezfs.zfs.ZFS` is the interface that corresponds to the ``zfs(8)`` program. It holds very little state,
and it is recommended to get an instance through the function :func:`~zfs.zfs.get_zfs`. It selects the desired and it is recommended to get an instance through the function :func:`~simplezfs.zfs.get_zfs`. It selects the desired
implementation and passes the required parameters. At the very least, it requires the ``api``-parameter, which is a implementation and passes the required parameters. At the very least, it requires the ``api``-parameter, which is a
string that selects the actual implementation, either ``cli`` or ``native``. string that selects the actual implementation, either ``cli`` or ``native``.
@ -40,12 +41,12 @@ All our examples use the ``cli`` implementation for simplicity.
<zfs.zfs_cli.ZFSCli object at 0x7f9f00faa9b0> <zfs.zfs_cli.ZFSCli object at 0x7f9f00faa9b0>
For the remainder of this guide, we're going to assume that the variable ``zfs`` always holds a For the remainder of this guide, we're going to assume that the variable ``zfs`` always holds a
:class:`:: simplezfs.simplezfs.zfs_cli.ZFSCli` object. :class:`simplezfs.zfs_cli.ZFSCli` object.
Viewing data Viewing data
============ ============
To get an overview over the interface, we'll dive in and inspect our running system. Information is returned in the To get an overview over the interface, we'll dive in and inspect our running system. Information is returned in the
form if :class:`:: simplezfs.simplezfs.types.Dataset` instances, which is a named tuple containing a set of fields. For simplicity, form if :class:`simplezfs.types.Dataset` instances, which is a named tuple containing a set of fields. For simplicity,
we'll output only a few of its fields to not clobber the screen, so don't be alarmed if there seems to be information we'll output only a few of its fields to not clobber the screen, so don't be alarmed if there seems to be information
missing: we just omitted the boring parts. missing: we just omitted the boring parts.
@ -85,15 +86,15 @@ Creating something new
There are functions for creating the four different types of datasets with nice interfaces: There are functions for creating the four different types of datasets with nice interfaces:
* :func:`~zfs.ZFS.create_fileset` for ordinary filesets, the most commonly used parameter is ``mountpoint`` for * :func:`~simplezfs.zfs.ZFS.create_fileset` for ordinary filesets, the most commonly used parameter is ``mountpoint``
telling it where it should be mounted. for telling it where it should be mounted.
* :func:`~zfs.ZFS.create_volume` creates volumes, or ZVols, this features a parameter ``thin`` for creating thin- * :func:`~simplezfs.zfs.ZFS.create_volume` creates volumes, or ZVols, this features a parameter ``thin`` for creating
provisioned or sparse volumes. thin-provisioned or sparse volumes.
* :func:`~zfs.ZFS.create_snapshot` creates a snapshot on a volume or fileset. * :func:`~simplezfs.zfs.ZFS.create_snapshot` creates a snapshot on a volume or fileset.
* :func:`~zfs.ZFS.create_bookmark` creates a bookmark (on recent versions of ZFS). * :func:`~simplezfs.zfs.ZFS.create_bookmark` creates a bookmark (on recent versions of ZFS).
These essentially call :func:`~zfs.ZFS.create_dataset`, which can be called directly, but its interface is not as These essentially call :func:`~simplezfs.zfs.ZFS.create_dataset`, which can be called directly, but its interface is
nice as the special purpose create functions. not as nice as the special purpose create functions.
Filesets Filesets
@ -187,16 +188,16 @@ overwritten when working with the get and set functions. It is also possible not
it to the functions every time. it to the functions every time.
When you want to get or set a metadata property, set ``metadata`` to **True** when calling When you want to get or set a metadata property, set ``metadata`` to **True** when calling
:func:`~zfs.ZFS.get_property` or :func:`~zfs.ZFS.set_property`. This will cause it to automatically prepend the :func:`~simplezfs.zfs.ZFS.get_property` or :func:`~simplezfs.zfs.ZFS.set_property`. This will cause it to automatically
namespace given on instantiation or to prepend the one given in the ``overwrite_metadata_namespace`` when calling the prepend the namespace given on instantiation or to prepend the one given in the ``overwrite_metadata_namespace`` when
functions. The name of the property **must not** include the namespace, though it may contain ``:`` characters on its calling the functions. The name of the property **must not** include the namespace, though it may contain ``:``
own, properties of the form ``zfs:is:cool`` are valid afterall. ``:`` characters are never valid in the context of characters on its own, properties of the form ``zfs:is:cool`` are valid afterall. ``:`` characters are never valid in
native properties, and this is the reason why there is a separate switch to turn on metadata properties when using the context of native properties, and this is the reason why there is a separate switch to turn on metadata properties
these functions. when using these functions.
Error handling Error handling
-------------- --------------
If a property name is not valid or the value exceeds certain bounds, a :class:`:: simplezfs.simplezfs.exceptions.ValidationError` is If a property name is not valid or the value exceeds certain bounds, a :class:`simplezfs.exceptions.ValidationError` is
raised. This includes specifying a namespace in the property name if ``metadata`` is **False**, or exceeding the raised. This includes specifying a namespace in the property name if ``metadata`` is **False**, or exceeding the
length allowed for a metadata property (8192 - 1 bytes). length allowed for a metadata property (8192 - 1 bytes).
@ -222,8 +223,8 @@ namespace, it looks like this:
>>> zfs.get_property('tank/system/root', 'do_backup', metdata=True) >>> zfs.get_property('tank/system/root', 'do_backup', metdata=True)
Property(key='do_backup', value='true', source='local', namespace='com.company') Property(key='do_backup', value='true', source='local', namespace='com.company')
If you don't specify a namespace when calling :func:`~zfs.zfs.get_zfs` or if you want to use a different namespace for If you don't specify a namespace when calling :func:`~simplezfs.zfs.get_zfs` or if you want to use a different
one call, specify the desired namespace in ``overwrite_metadata_namespace`` like so: namespace for one call, specify the desired namespace in ``overwrite_metadata_namespace`` like so:
.. code-block:: pycon .. code-block:: pycon
@ -264,10 +265,10 @@ Listing properties
The ZPool interface The ZPool interface
******************* *******************
The :class:`:: simplezfs.simplezfs.zfs.ZPool` is the interface that corresponds to the ``zpool(8)`` program. It holds very little state, The :class:`simplezfs.zfs.ZPool` is the interface that corresponds to the ``zpool(8)`` program. It holds very little
and it is recommended to get an instance through the function :func:`~simplezfs.zpool.get_zpool`. It selects the desired state, and it is recommended to get an instance through the function :func:`~simplezfs.zpool.get_zpool`. It selects the
implementation and passes the required parameters. At the very least, it requires the ``api``-parameter, which is a desired implementation and passes the required parameters. At the very least, it requires the ``api``-parameter, which
string that selects the actual implementation, either ``cli`` or ``native``. is a string that selects the actual implementation, either ``cli`` or ``native``.
All our examples use the ``cli`` implementation for simplicity. All our examples use the ``cli`` implementation for simplicity.
@ -279,21 +280,21 @@ All our examples use the ``cli`` implementation for simplicity.
<zfs.zpool_cli.ZPoolCli object at 0x7f67d5254940> <zfs.zpool_cli.ZPoolCli object at 0x7f67d5254940>
For the remainder of this guide, we're going to assume that the variable ``zpool`` always holds a For the remainder of this guide, we're going to assume that the variable ``zpool`` always holds a
:class:`:: simplezfs.simplezfs.zpool_cli.ZPoolCli` object. :class:`simplezfs.zpool_cli.ZPoolCli` object.
Error handling Error handling
************** **************
We kept the most important part for last: handling errors. The module defines its own hierarchy with We kept the most important part for last: handling errors. The module defines its own hierarchy with
:class:`:: simplezfs.simplezfs.exceptions.ZFSError` as toplevel exception. Various specific exceptions are based on ot. When working :class:`simplezfs.exceptions.ZFSException` as toplevel exception. Various specific exceptions are based on ot. When
with :class:`:: simplezfs.simplezfs.zfs.ZFS`, the three most common ones are: working with :class:`simplezfs.zfs.ZFS`, the three most common ones are:
* :class:`:: simplezfs.simplezfs.exceptions.ValidationError` which indicates that a name (e.g. dataset name) was invalid. * :class:`simplezfs.exceptions.ValidationError` which indicates that a name (e.g. dataset name) was invalid.
* :class:`:: simplezfs.simplezfs.exceptions.DatasetNotFound` is, like FileNotFound in standard python, indicating that the dataset the * :class:`simplezfs.exceptions.DatasetNotFound` is, like FileNotFound in standard python, indicating that the dataset
module was instructed to work on (e.g. get/set properties, destroy) was not present. the module was instructed to work on (e.g. get/set properties, destroy) was not present.
* :class:`:: simplezfs.simplezfs.exceptions.PermissionError` is raised when the current users permissions are not sufficient to perform * :class:`simplezfs.exceptions.PermissionError` is raised when the current users permissions are not sufficient to
the requested operation. While some actions can be delegated using ``zfs allow``, linux, for example, doesn't allow perform the requested operation. While some actions can be delegated using ``zfs allow``, linux, for example, doesn't
non-root users to mount filesystems, which means that a non-root user may create filesets with a valid mountpoint allow non-root users to mount filesystems, which means that a non-root user may create filesets with a valid
property, but it won't be mounted. mountpoint property, but it won't be mounted.
Examples Examples
======== ========

@ -1,2 +1,3 @@
Sphinx>=2.0 Sphinx>=2.0
sphinx-autodoc-typehints sphinx-autodoc-typehints
sphinx-rtd-theme

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from setuptools import setup from setuptools import setup # type: ignore
with open('README.rst', 'r') as fh: with open('README.rst', 'r') as fh:
long_description = fh.read() long_description = fh.read()
@ -10,28 +10,34 @@ setup(
author='Andreas Gonschorek, Stefan Valouch', author='Andreas Gonschorek, Stefan Valouch',
description='Simple, low-level ZFS API', description='Simple, low-level ZFS API',
long_description=long_description, long_description=long_description,
project_urls={
'Documentation': 'https://simplezfs.readthedocs.io/',
'Source': 'https://github.com/svalouch/python-simplezfs/',
'Tracker': 'https://github.com/svalouch/python-simplezfs/issues',
},
packages=['simplezfs'], packages=['simplezfs'],
package_data={'simplezfs': ['py.typed']}, package_data={'simplezfs': ['py.typed']},
package_dir={'': 'src'}, package_dir={'': 'src'},
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
license='BSD-3-Clause', license='BSD-3-Clause',
url='https://github.com/svalouch/python-simplezfs',
platforms='any', platforms='any',
python_requires='>=3.6', python_requires='>=3.6',
install_requires=[ # install_requires=[
'pydantic>=0.32.2', # ],
],
extras_require={ extras_require={
'tests': [ 'tests': [
'flake8',
'mypy', 'mypy',
'pytest', 'pytest',
'pytest-cov', 'pytest-cov',
], ],
'docs': [ 'docs': [
'Sphinx>=2.0', 'Sphinx>=2.0',
'sphinx-autodoc-typehints',
'sphinx-rtd-theme',
], ],
}, },
@ -41,7 +47,9 @@ setup(
'Operating System :: POSIX :: Linux', 'Operating System :: POSIX :: Linux',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
], ],
) )

@ -28,24 +28,26 @@ log = logging.getLogger('simplezfs.zfs')
class ZFS: class ZFS:
''' '''
ZFS interface class. This API generally covers only the zfs(8) tool, for zpool(8) please see :class:`~ZPool`. ZFS interface class. This API generally covers only the zfs(8) tool, for zpool(8) please see
:class:`~simplezfs.zpool.ZPool`.
**ZFS implementation** **ZFS implementation**
There are two ways how the API actually communicates with the ZFS filesystem: There are two ways how the API actually communicates with the ZFS filesystem:
* Using the CLI tools (:class:`~zfs.zfs_cli.ZFSCli`) * Using the CLI tools (:class:`~simplezfs.zfs_cli.ZFSCli`)
* Using the native API (:class:`~zfs.zfs_native.ZFSNative`) * Using the native API (:class:`~simplezfs.zfs_native.ZFSNative`)
You can select the API by either creating an instance of one of them or using :func:`~zfs.zfs.get_zfs`. You can select the API by either creating an instance of one of them or using :func:`~simplezfs.zfs.get_zfs`.
**Properties and Metadata** **Properties and Metadata**
The functions :func:`set_property`, :func:`get_property` and :func:`get_properties` wrap the ZFS get/set The functions :func:`~simplezfs.zfs.ZFS.set_property`, :func:`~simplezfs.zfs.ZFS.get_property` and
functionality. To support so-called `user properties`, which are called `metadata` in this API, a default namespace :func:`~simplezfs.zfs.ZFS.get_properties` wrap the ZFS get/set functionality. To support so-called
can be stored using `metadata_namespace` when instantiating the interface or by calling `user properties`, which are called `metadata` in this API, a default namespace can be stored using
:func:`set_metadata_namespace` at any time. `metadata_namespace` when instantiating the interface or by calling
:func:`~simplezfs.zfs.ZFS.set_metadata_namespace` at any time.
:note: Not setting a metadata namespace means that one can't set or get metadata properties, unless the overwrite :note: Not setting a metadata namespace means that one can't set or get metadata properties, unless the overwrite
parameter for the get/set functions is used. parameter for the get/set functions is used.

Loading…
Cancel
Save