Storage Class Management
You can either manage storage classes from the CLI or web UI. This document will cover CLI usage. If you have not yet done so you will have to set up a admin context.
The root command is fuzzball admin storage class with the following sub commands:
Usage:
fuzzball admin storage class [command]
Aliases:
class, cl
Available Commands:
create Create a storage class
delete Delete a storage class
describe Describe storage class regarding the most recent install/update operation
disable Disable a storage class
export Export a storage class definition as YAML
info Get information about a storage class
list List storage classes
update Update a storage class definition
Flags:
-h, --help help for class
Global Flags:
-c, --color string Set the color output for fuzzball ($FUZZBALL_COLOR) (default "auto")
--disable-auth Disables auth ($FUZZBALL_DISABLE_AUTH)
--disable-tls Disables tls ($FUZZBALL_DISABLE_TLS)
--insecure Enable insecure connections ($FUZZBALL_INSECURE)
-j, --json Output in json ($FUZZBALL_JSON)
Use "fuzzball admin storage class [command] --help" for more information about a command.
In this example we will create the storage classes for a permanent data class and an ephemeral
scratch class shown in the section on storage class definitions.
For this to work you need access to an NFS server at ${NFS_SERVER_IP} available to the fuzzball
cluster subnet ${FUZZBALL_SUBNET}. If you created a NFS share on
your Orchestrate server during the setup earlier you can add the shares required for this example there with
the following:
# FUZZBALL_SUBNET=...
# NFS_SERVER_IP=...
# mkdir /srv/fuzzball/storage_{data,scratch}
# cat >> /etc/exports <<__EOF__
/srv/fuzzball/storage_data ${FUZZBALL_SUBNET}(rw,sync,no_subtree_check,no_root_squash,crossmnt)
/srv/fuzzball/storage_scratch ${FUZZBALL_SUBNET}(rw,sync,no_subtree_check,no_root_squash,crossmnt)
__EOF__
# exportfs -a
# exportfs
/srv/fuzzball/shared
...subnet...
/srv/fuzzball/storage_data
...subnet...
/srv/fuzzball/storage_scratch
...subnet...
With the NFS storage configured we can create the two storage classes for our organization based on the examples in the previous section:
# cat > persistent_data_class.yaml <<__EOF__
version: v1
name: data
description: Persistent data
driver: nfs.csi.k8s.io
properties:
persistent: true
retainOnDelete: true
parameters:
server: ${NFS_SERVER_IP}
share: /srv/fuzzball/storage_data
capacity:
size: 100
unit: GiB
access:
type: filesystem
mode: multi_node_multi_writer
mount:
options:
- nfsvers=4
user: user
group: user
permissions: 770
scope: user
volumes:
nameArgs:
- USERNAME
nameFormat: "{{username}}"
maxByAccount: 1
__EOF__
# fuzzball admin storage class create --wait persistent_data_class.yaml
Storage class "dc6f6816-158a-3e15-89fd-a1f05e309cf5" created
# cat > ephemeral_scratch_class.yaml <<__EOF__
version: v1
name: scratch
description: Ephemeral Scratch Volumes
driver: nfs.csi.k8s.io
properties:
persistent: false
retainOnDelete: false
parameters:
server: ${NFS_SERVER_ID}
share: /srv/fuzzball/storage_scratch
capacity:
size: 100
unit: GiB
access:
type: filesystem
mode: multi_node_multi_writer
mount:
options:
- nfsvers=4
user: user
group: user
permissions: 770
scope: user
volumes:
nameArgs:
- WORKFLOW_ID
nameFormat: "{{workflow_id}}"
__EOF__
# fuzzball admin storage class create --wait ephemeral_scratch_class.yaml
Storage class "cbe43592-a826-38e3-b744-50d5ee24e2bb" created
The create operation is an asynchronous operation which can take some time depending on the
resources available in your
Fuzzball cluster. The Fuzzball storage
service will create a temporary volume to validate the definition with the CSI driver. This
requires an available Substrate node. The
CLI doesn’t wait for completion
by default, but you can specify that the CLI should wait until the volume has been created and
validated using the --wait argument.
Administrators can view the configured
storage classes with the list subcommand like so:
# fuzzball admin storage class list
ID | NAME | STATUS | CREATED TIME | LAST UPDATED | PERSISTENT | RESTRICTED | CLUSTER
dc6f6816-158a-3e15-89fd-a1f05e309cf5 | data | Ready | 2025-04-14 08:17:05PM | 2025-04-14 08:17:05PM | Yes | No | unset-cluster
cbe43592-a826-38e3-b744-50d5ee24e2bb | scratch | Ready | 2025-04-15 12:01:31AM | 2025-04-15 12:01:31AM | No | No | unset-cluster
More detailed information in machine readable format can be obtained using the --json flag like so:
# fb admin storage class info --json dc6f6816-158a-3e15-89fd-a1f05e309cf5
{
"id": "dc6f6816-158a-3e15-89fd-a1f05e309cf5",
"driver_id": "9c35fed2-26a1-3313-97f6-f25dc2366dd9",
"name": "data",
"create_time": {
"seconds": 1744661825,
"nanos": 292831000
},
"update_time": {
"seconds": 1744661825,
"nanos": 292831000
},
"class": {
"version": "v1",
"name": "data",
"description": "Persistent data",
"driver": "nfs.csi.k8s.io",
"mount": {
"options": [
"nfsvers=4"
],
"user": 2,
"group": 2,
"permissions": "770"
},
"access": {
"type": 1,
"mode": 5
},
"parameters": {
"server": "10.1.96.7",
"share": "/srv/fuzzball/storage_data"
},
"properties": {
"retainOnDelete": true,
"persistent": true
},
"scope": 2,
"capacity": {
"size": 100,
"unit": 2
},
"volumes": {
"nameArgs": [
1
],
"nameFormat": "{{username}}",
"maxByAccount": 1
}
},
"scope": 2,
"status": 2,
"persistent": true,
"retain": true,
"cluster_id": "36ad0001-35f7-c17d-2f75-e910a16292cf"
}
The describe command retrieves the last storage class creation/update state and volume error if any. This command returns a raw JSON output or the last error that occurred.
To describe a class:
# fuzzball admin storage class describe --wait dc6f6816-158a-3e15-89fd-a1f05e309cf5
Administrators can also update a storage class
definition for an
organization. Note the
name field is immutable after the class creation, so changing the class name will return an error
when updating.
To update a class definition with a larger capacity, for example:
# sed 's/size: 100/size: 200/' persistent_data_class.yaml > persistent_data_class_200.yaml
# fuzzball admin storage class update -i dc6f6816-158a-3e15-89fd-a1f05e309cf5 persistent_data_class_200.yaml
Storage class "dc6f6816-158a-3e15-89fd-a1f05e309cf5" updated
# fuzzball admin storage class info --json dc6f6816-158a-3e15-89fd-a1f05e309cf5 | jq '.class.capacity'
{
"size": 200,
"unit": 2
}
Similar to the create command, the update operation is asynchronous. The update command also
accepts the --wait argument to wait for the update completion.
Note that class definition updates done at short interval might return the error:
child workflow execution already started
This signifies that a previous update is still completing. This may be confusing when performing class updates in the web UI.
If you encounter this error, you can use the describe command with --wait argument to wait for
the update to complete.
Storage classes can be disabled preventing users from creating/using storage volumes. This might be useful to migrate users to another storage class or prior to deleting an existing storage class.
The command for disabling and deleting storage classes are shown below. However we will be using both storage classes created earlier in this section in subsequent examples. If you delete either of these volumes for practice please re-create them before continuing.
# fuzzball admin storage class disable cbe43592-a826-38e3-b744-50d5ee24e2bb
Admins can also delete storage classes. Before a storage class can be deleted any storage volumes using the class have to be removed.
# fuzzball admin storage class delete cbe43592-a826-38e3-b744-50d5ee24e2bb
If volumes are still attached to the storage class, an error will be returned:
could not delete storage class cbe43592-a826-38e3-b744-50d5ee24e2bb: volumes still attached to it