Skip to content

Commit

Permalink
feat: add interface filesystem_info
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Jan 31, 2025
1 parent 1e27162 commit e28e32f
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 0 deletions.
51 changes: 51 additions & 0 deletions docs/json_schemas/filesystem_info/v0/provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"$defs": {
"BaseModel": {
"properties": {},
"title": "BaseModel",
"type": "object"
},
"ProviderAppData": {
"description": "App databag model for the `filesystem_info` interface.",
"properties": {
"endpoint": {
"description": "Endpoint information to mount the exported filesystem.",
"examples": [
"nfs://(192.168.1.1:65535)/export",
"lustre://(192.168.227.11%40tcp1,192.168.227.12%40tcp1)/export",
"cephfs://fsuser@(192.168.1.1,192.168.1.2,192.168.1.3)/export?fsid=asdf1234&auth=plain%3AQWERTY1234&filesystem=scratch"
],
"title": "Endpoint",
"type": "string"
}
},
"required": [
"endpoint"
],
"title": "ProviderAppData",
"type": "object"
}
},
"description": "Provider schema for filesystem_info.",
"properties": {
"unit": {
"anyOf": [
{
"$ref": "#/$defs/BaseModel"
},
{
"type": "null"
}
],
"default": null
},
"app": {
"$ref": "#/$defs/ProviderAppData"
}
},
"required": [
"app"
],
"title": "ProviderSchema",
"type": "object"
}
36 changes: 36 additions & 0 deletions docs/json_schemas/filesystem_info/v0/requirer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$defs": {
"BaseModel": {
"properties": {},
"title": "BaseModel",
"type": "object"
}
},
"description": "Requirer schema for filesystem_info.",
"properties": {
"unit": {
"anyOf": [
{
"$ref": "#/$defs/BaseModel"
},
{
"type": "null"
}
],
"default": null
},
"app": {
"anyOf": [
{
"$ref": "#/$defs/BaseModel"
},
{
"type": "null"
}
],
"default": null
}
},
"title": "RequirerSchema",
"type": "object"
}
114 changes: 114 additions & 0 deletions interfaces/filesystem_info/v0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# `filesystem_info`

## Usage

This interface defines how a charm that exports a shared filesystem can expose the required mount information
to a client charm that wants to mount the filesystem.

## Direction

The `filesystem_info` interface implements a provider/requirer pattern. The Requirer is a charm that wishes to
mount a shared filesystem, and the Provider is the charm exporting the mount information to do that.

```mermaid
flowchart TD
Requirer --> Provider
Provider -- endpoint --> Requirer
```

## Behavior

The exported endpoint from the Provider needs to adhere to a sublanguage of the URI grammar, which is specified
by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-A). The specific sublanguage is defined
by the following grammar in Augmented Backus–Naur form:

```
key = 1*( unreserved )
value = 1*( unreserved / ":" / "/" / "?" / "#" / "[" / "]" / "@" / "!" / "$"
/ "'" / "(" / ")" / "*" / "+" / "," / ";" )
options = key "=" value ["&" options]
host-port = host [":" port]
hosts = host-port ["," hosts]
authority = [userinfo "@"] "(" hosts ")"
endpoint = scheme "://" authority path-absolute ["?" options]
```

Any unspecified grammar rule is specified by RFC 3986.

Additionally, any string from the language must adhere to a list of additional requirements:

- The `scheme` component must identify the type of filesystem that needs to be mounted by the client e.g. nfs, cephfs, lustre.
- The `userinfo` component may contain a user for authentication purposes, but it must not contain
any password required to authenticate against the filesystem. In other words, the `user:password` syntax is not allowed.
- The `hosts` component must contain the host or list of hosts encompassing the server. The characters
`(` and `)` must encompass an array of values, and the character `,` must delimit each host ip or domain name. If only
a single host is required, the host must still be encompassed by `(` and `)`.
- The `path-absolute` component may be the exported path of the filesystem.
- The `options` component may contain any other required data for the specific filesystem type, including but not limited to:
- Password to authenticate an user (raw or secret based).
- Cluster identifier.
- Filesystem identifier.
- Since each filesystem type will require different data for its options component, and it is unknown if more data will be
required in the future, the scheme component may be used to version different data formats for the same filesystem type,
which will not introduce any breaking changes.
- Any reserved character in the URI according to RFC 3986 must be percent-encoded
e.g. '!' becomes '%21', '#' becomes '%24', etc.

#### Examples

The following examples show some URIs adhering to the defined grammar, and their equivalent components.

- nfs://(192.168.1.1:65535)/export
- scheme: nfs
- userinfo: None
- hosts: 192.168.1.1:65535
- path-absolute: /export
- options: None

- lustre://(192.168.227.11%40tcp1,192.168.227.12%40tcp1)/export
- scheme: lustre
- userinfo: None
- hosts: 192.168.227.11@tcp1 192.168.227.12@tcp1
- path-absolute: /export
- options: None

- cephfs://fsuser@(192.168.1.1,192.168.1.2,192.168.1.3)/export?fsid=asdf1234&auth=plain%3AQWERTY1234&filesystem=scratch
- scheme: cephfs
- userinfo: fsuser
- hosts: 192.168.1.1 192.168.1.2 192.168.1.3
- path-absolute: /export
- options:
- fsid: asdf1234
- auth: plain:QWERTY1234
- filesystem: scratch

### Provider

- Is expected to adhere to both the defined grammar and the additional requirements specified here.
- Is expected to export mount information for a valid and accessible shared filesystem.

### Requirer

- Is expected to be able to parse the exported endpoint from the provider according to the defined grammar.
- Is expected to either have support for mounting the provider's exported filesystem, or gracefully
handle when it cannot mount it.

## Relation Data

Only the provider must export relation data.

[\[Pydantic Schema\]](./schema.py)

#### Example
```yaml
provider:
app: {
"endpoint": "lustre://(192.168.227.11%40tcp1,192.168.227.12%40tcp1)/export"
}
unit: {}
requirer:
app: {}
unit: {}
```
17 changes: 17 additions & 0 deletions interfaces/filesystem_info/v0/interface.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: filesystem_info
version: 0
status: draft

# TODO: the charms live in a monorepo which needs additional setup steps to be able to run tests.

providers:
- name: nfs-server-proxy
url: https://github.com/charmed-hpc/filesystem-charms
- name: cephfs-server-proxy
url: https://github.com/charmed-hpc/filesystem-charms

requirers:
- name: filesystem-client
url: https://github.com/charmed-hpc/filesystem-charms

maintainer: hpc-team
39 changes: 39 additions & 0 deletions interfaces/filesystem_info/v0/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""This file defines the schemas for the provider and requirer sides of the filesystem_info interface.
It exposes two interfaces.schema_base.DataBagSchema subclasses called:
- ProviderSchema
- RequirerSchema
Examples:
ProviderSchema:
app: {
"endpoint": "nfs://(192.168.1.1:65535)/export"
}
unit: <empty>
RequirerSchema:
unit: <empty>
app: <empty>
"""
from interface_tester.schema_base import DataBagSchema
from pydantic import BaseModel, Field


class ProviderAppData(BaseModel):
"""App databag model for the `filesystem_info` interface."""

endpoint: str = Field(
description="Endpoint information to mount the exported filesystem.",
examples=[
"nfs://(192.168.1.1:65535)/export",
"lustre://(192.168.227.11%40tcp1,192.168.227.12%40tcp1)/export",
"cephfs://fsuser@(192.168.1.1,192.168.1.2,192.168.1.3)/export?fsid=asdf1234&auth=plain%3AQWERTY1234&filesystem=scratch"
]
)


class ProviderSchema(DataBagSchema):
"""Provider schema for filesystem_info."""

app: ProviderAppData


class RequirerSchema(DataBagSchema):
"""Requirer schema for filesystem_info."""

0 comments on commit e28e32f

Please sign in to comment.