Filesystems =========== Creating a Filesystem --------------------- Creating filesystems is done with the ``create`` method: .. code-block:: python >>> from capacity import GiB, GB >>> my_fs = system.filesystems.create(pool=pool, name='my_fs', size=GiB) .. note:: When a size is not explicitly stated, a default of 1 GiB is used. You can also provide the size explicitly: .. code-block:: python >>> fs = system.filesystems.create(pool=pool, size=1*GiB) You can optionally specify the ``security_style`` in the ``create`` method: .. code-block:: python >>> fs = system.filesystems.create(pool=pool, security_style="WINDOWS") It is also possible to create multiple filesystems with a single line, by calling :meth:`.create_many <.DatasetTypeBinder.create_many>`: .. code-block:: python >>> filesystems = system.filesystems.create_many(pool=pool, name='fs', count=5) >>> len(filesystems) 5 >>> for fs in filesystems: ... print(fs.get_name()) fs_1 fs_2 fs_3 fs_4 fs_5 We can now access various attributes of the filesystem: .. code-block:: python >>> print(my_fs.get_name()) my_fs >>> my_fs.get_size() 1*GiB Moving Between Pools -------------------- Use :meth:`.Filesystem.move_pool` to move a filesystem between pools: .. code-block:: python >>> new_pool = system.pools.create() >>> fs.move_pool(new_pool) Resizing Filesystems -------------------- Use :meth:`.Filesystem.resize` to resize the filesystem by the given delta: .. code-block:: python >>> fs.resize(delta=2*GB) Deleting Filesystems -------------------- Deleting a filesystem is done with :meth:`.Filesystem.delete`: .. code-block:: python >>> fs.delete() Example: Deleting All Filesystems with Specific Name Prefix ----------------------------------------------------------- .. code-block:: python >>> for fs in system.filesystems: ... if fs.get_name(from_cache=True).startswith('prefix'): ... fs.delete() .. seealso:: :mod:`Filesystem API documentation ` NFS Exports ============ Creating a Filesystem Export ---------------------------- A filesystem export is created with default settings and advanced setting. For a detailed documentation of these settings, Read more `Here `_. >>> export = fs.add_export() We can now access and modify various attributes of the export: .. code-block:: python >>> from capacity import MiB >>> export.get_max_read() 1*MiB >>> export.update_max_read(2*MiB) >>> export.get_max_read() 2*MiB Disabling an Export ------------------- Following this operation, the filesystem is not accessible by the user. The export path is not deleted, and can be enabled. .. code-block:: python >>> export.disable() >>> export.is_enabled() False Enabling an Export ------------------ .. code-block:: python >>> export.enable() >>> export.is_enabled() True Querying for Filesystem Exports ------------------------------- Like other InfiniBox collections, InfiniSDK provides iteration and filtering abilty for exports. .. code-block:: python >>> system.exports.count() 1 Export Permissions -------------------- | Export permissions can be modified with ``.Export.update_permissions``. | This method overrides current permissions. | | To preserve current permission settings, first use ``.Export.get_permissions``, then update accordingly. .. code-block:: python >>> from munch import Munch >>> permissions = export.get_permissions() >>> permissions[0] == Munch({'access': 'RW', 'no_root_squash': True, 'client': '*'}) True >>> export.update_permissions(permissions + ... [{'access': 'RO', 'client': '1.1.1.1', 'no_root_squash': True}]) >>> permissions = export.get_permissions() >>> permissions[0] == Munch({'access': 'RW', 'no_root_squash': True, 'client': '*'}) True >>> permissions[1] == Munch({'access': 'RO', 'no_root_squash': True, 'client': '1.1.1.1'}) True >>> export.update_permissions([{'access': 'RW', 'client': '2.2.2.2', 'no_root_squash': True}]) >>> permissions = export.get_permissions() >>> permissions[0] == Munch({'access': 'RW', 'no_root_squash': True, 'client': '2.2.2.2'}) True Deleting an Export -------------------- Deleting an export is done with :func:`.Export.delete `: .. code-block:: python >>> export.delete() Tree Quotas ------------ Each filesystem has a ``treeqs`` member, which is a collection of its TreeQ's: .. code-block:: python >>> fs.treeqs.to_list() [] >>> treeq1 = fs.treeqs.create(path='/path1', soft_capacity=GB, hard_inodes=200) >>> print(treeq1.get_capacity_state()) BELOW_SOFT TreeQ's can be queried, filtered and sorted: .. code-block:: python >>> treeq2 = fs.treeqs.create(path='/path2', soft_capacity=GB, hard_inodes=300) >>> treeq3 = fs.treeqs.create(path='/path3', soft_capacity=GB, hard_inodes=400) >>> from infinisdk import Q >>> for treeq in fs.treeqs.find(Q.hard_inodes>200).sort(-fs.treeqs.fields.hard_inodes): ... print(treeq.get_path()) /path3 /path2 When creating a snapshot, all TreeQ's are copied to the child dataset. The new TreeQ's are separate and distinct objects: .. code-block:: python >>> fs2 = fs.create_snapshot() >>> for treeq in fs2.treeqs: ... print(treeq.get_path()) /path1 /path2 /path3 >>> fs.treeqs.get(path='/path1') == fs2.treeqs.get(path='/path1') False A single update request can modify either TreeQ limits or its name: .. code-block:: python >>> treeq1.update_fields(soft_inodes=5, soft_capacity=GB) >>> treeq1.update_fields(name='path1') >>> treeq1.update_fields(soft_inodes=5, name='path1') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... APICommandFailed: ... Refreshing a snapshot or restoring a filesystem from a snapshot modifies its TreeQ's accordingly: .. code-block:: python >>> treeq1.delete() >>> print(fs.treeqs.count()) 2 >>> fs.restore(fs2) >>> print(fs.treeqs.count()) 3 >>> print(fs2.treeqs.count()) 3 >>> fs.treeqs.choose().delete() >>> fs2.refresh_snapshot() >>> print(fs2.treeqs.count()) 2 SMB Shares ==================== Creating a Share ---------------- Create a share using the ``add_share`` method on the :class:`infinisdk.infinibox.filesystem.Filesystem` object: .. code-block:: python >>> fs = system.filesystems.create( ... pool=pool, ... security_style="WINDOWS" ... ) >>> share = fs.add_share() >>> share in fs.get_shares() True Share Permissions ------------------------- Permissions can be accessed with the ``permissions`` field: .. code-block:: python >>> perm = share.permissions.create(sid="S-1-1-1", access="NONE") # doctest: +SKIP >>> perm.update_access("FULLCONTROL") # doctest: +SKIP >>> perm.get_access() # doctest: +SKIP FULLCONTROL >>> share.permissions.get(sid="S-1-1-1") == perm # doctest: +SKIP True >>> perm in share.permissions.to_list() # doctest: +SKIP True >>> perm.delete() # doctest: +SKIP >>> perm in share.permissions.to_list() # doctest: +SKIP False