Storage Libs

  • HPC Charm Team
Channel Revision Published Runs on
latest/stable 1 04 Apr 2023
Ubuntu 22.04
juju deploy storage-libs
Show information

Platform:

Ubuntu
22.04

charms.storage_libs.v0.nfs_interfaces

Library to manage integrations between NFS share providers and consumers.

This library contains the NFSProvides and NFSRequires classes for managing an integration between an NFS server operator and NFS client operator.

Requires Charm (NFS Client)

This library provides a uniform interface for charms that need to mount, unmount, or request an NFS share, and convenience methods for consuming data sent by an NFS server charm. Here is an example of using a ServerConnectedEvent to request a new NFS share:

from charms.storage_libs.v0.nfs_interfaces import (
    NFSRequires,
    ServerConnectedEvent,
)


class ApplicationCharm(CharmBase):
    # Application charm that needs to mount NFS shares.

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        # Charm events defined in the NFSRequires class.
        self.nfs_share = NFSRequires(self, "nfs-share")
        self.framework.observe(
            self.nfs_share.on.server_connected,
            self._on_server_connected,
        )

    def _on_server_connected(self, event: ServerConnectedEvent) -> None:
        # Handle when new NFS server is connected.
        self._nfs_share.request_share(
            event.relation.id,
            name="/data",
            size=100,
            allowlist="0.0.0.0/0",
        )

        self.unit.status = WaitingStatus("Waiting for NFS share to be created.")

The NFSRequires class provides a few custom events to handle specific situations related to mounting an NFS share. They are all listed below:

  • server_connected: Event emitted when the NFS client is connected to the NFS server. Here is where NFS clients will commonly request the NFS share they need created.
  • mount_share: Event emitted when NFS share is ready to be mounted.
  • umount_share: Event emitted when NFS share is ready or needs to be unmounted.

Note: This charm library only supports one NFS server being integrated with the NFS client at a time. This is to prevent the NFS client from having to manage and request multiple NFS shares, and ensure that NFS clients are creating unique mount points.

Provides Charm (NFS Server)

This library provides a uniform interface for charms that need to process NFS share requests, and convenience methods for consuming data sent by an NFS client charm. Here is an example of using a ShareRequestedEvent to create a new NFS share:

from charms.storage_libs.v0.nfs_interfaces import (
    NFSProvides,
    ShareRequestedEvent,
)


class ApplicationCharm(CharmBase):
    # Application charm that exports mountable NFS shares.

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        # Charm events defined in the NFSProvides class.
        self.nfs_share = NFSProvides(self, "nfs-share")
        self.framework.observe(
            self.nfs_share.on.share_requested,
            self._on_share_requested,
        )

    def _on_share_requested(self, event: ShareRequestedEvent) -> None:
        # Handle when NFS client requests NFS share.
        if not self.unit.is_leader():
            return

        share = pathlib.Path(f"/var/local/{event.name}")
        if not share.exists()
            storage = pathlib.Path(f"/var/local/storage/{event.name}")
            storage.touch()
            subprocess.run(["truncate", "-s", f"{event.size}G", share])
            subprocess.run(["mke2fs", "-t", "ext4", "-F", share])
            share.mkdir()
            subprocess.run(["mount", storage, share])
            with open("/etc/exports", "at") as fout:
                fout.write(f"{share} *(rw,sync,no_subtree_check,no_root_squash)")
            subprocess.run(["exportfs", "-a"])
            systemd.service_restart("nfs-kernel-server")

        hostname = subprocess.run(["hostname", "-I"], text=True).stdout
        self.nfs_share.set_endpoint(event.relation.id, f"{hostname}:{share}")
        self.unit.status = ActiveStatus("Exporting shares")

The NFSProvides class only provides one custom event:

  • share_requested: Event emitted when NFS client requests an NFS share.

Note: It is the responsibility of the NFS Provider charm to provide the implementation for creating a new NFS share. NFSProvides just provides the interface for the integration.


class ServerConnectedEvent

Description

Emit when an NFS server is integrated with NFS client. None

class MountShareEvent

Description

Emit when NFS share is ready to be mounted. None

class UmountShareEvent

Description

Emit when NFS share needs to be unmounted. None

class ShareRequestedEvent

Description

Emit when a consumer requests a new NFS share be created by the provider. None

Methods

ShareRequestedEvent. name( self )

Description

Get name of requested NFS share. None

ShareRequestedEvent. allowlist( self )

Description

Comma-separated list of addresses grant access to NFS share. None

ShareRequestedEvent. size( self )

Size in gigabytes of the NFS share.

Description

If unset, the NFS share will not be restricted in size.

class NFSRequires

Description

Consumer-side interface of NFS share integrations. None

Methods

NFSRequires. __init__( self , charm: CharmBase , integration_name: str )

NFSRequires. request_share( self , integration_id: int , name: str , allowlist , size )

Request access to an NFS share.

Arguments

integration_id

Identifier for specific integration.

name

Name of NFS share.

allowlist

List of IP address to grant r/w access to on NFS share.

size

Size, in gigabytes, of NFS share.

class NFSProvides

Description

Provider-side interface of NFS share integrations. None

Methods

NFSProvides. __init__( self , charm: CharmBase , integration_name: str )

NFSProvides. set_endpoint( self , integration_id: int , endpoint: str )

Set endpoint for mounting NFS share.

Arguments

integration_id

Identifier for specific integration.

endpoint

NFS share endpoint.