Skip to main content

Understanding volumes

CGC's Volume SDK provides functionality to create, manage, and mount persistent storage volumes to your compute resources.

Volumes persist data beyond the lifecycle of individual containers and can be shared between multiple resources.

Individual access rights may need to be adjusted for folders, files, sub-folders to get the most of that feature and not get impacted by privilege errors.

Quick example

import cgc.sdk.volume as volume
import cgc.sdk.resource as resource

# Create a volume
response = volume.volume_create("my-data", size=10)
if response['code'] == 200:
print("Volume created successfully")

# Wait for volume to be ready
if volume.volume_ready("my-data"):
print("Volume is ready for use")

# Mount to a compute resource (requires app reload)
volume.volume_mount("my-data", "my-compute")

# Use the volume in your workload...

# Cleanup
volume.volume_umount("my-data") # will reload the app
volume.volume_delete("my-data")

Volume operations

Create persistent storage volumes with specific size and storage class:

import cgc.sdk.volume as volume

# Create with default storage class
response = volume.volume_create("my-volume", size=20)

# Create with specific storage class
response = volume.volume_create(
name="fast-storage",
size=50,
storage_class="ssd-rwx-ec"
)

# Check response
if response['code'] == 200:
print("Volume created successfully")
else:
print(f"Failed to create volume: {response.get('message')}")

Listing volumes

Get information about all volumes in your namespace:

response = volume.volume_list()

if response['code'] == 200:
volumes = response['details']['volume_list']
for vol in volumes:
# Note: size comes with 'Gi' suffix (e.g., '10Gi')
size = vol['size'].replace('Gi', '')
print(f"Volume: {vol['name']}, Size: {size}GB, Status: {vol['status']}")
print(f" Storage Type: {vol['disks_type']}, Mounted to: {vol['mounted_to']}")

Checking volume status

Check if a volume is ready for use:

# Simple boolean check
if volume.volume_ready("my-volume"):
print("Volume is ready to mount")
else:
print("Volume is still provisioning")

# Wait for volume with timeout
import time

def wait_for_volume(name, timeout=60):
start_time = time.time()
while time.time() - start_time < timeout:
if volume.volume_ready(name):
return True
time.sleep(2)
return False

if wait_for_volume("my-volume"):
print("Volume is ready!")
else:
print("Timeout waiting for volume")

Deleting volumes

Remove volumes when no longer needed:

# Delete unmounted volume
response = volume.volume_delete("my-volume")

# Force delete even if mounted (dangerous)
response = volume.volume_delete("my-volume", force=True)

if response['code'] == 200:
print("Volume deleted successfully")

Storage classes

Storage classes define the type and performance characteristics of volumes.

Available storage classes

# Get all available storage classes
storage_classes = volume.get_available_storage_classes()
print("Available storage classes:", storage_classes)

# Get default storage class
default_class = volume.get_default_storage_class()
print("Default storage class:", default_class)

# Get details about a specific storage class
response = volume.volume_storage_class_details("ssd-rwx-ecd")
if response['code'] == 200:
details = response['details']
print(f"Storage class details: {details}")

Mounting and unmounting

It's essential for compute and job resources, to use persistent storage, whenever required. Volumes must be attached during resource creation or after with set of commands.

Mounting volumes

Attach volumes to compute resources to access stored data:

# Mount with default path
response = volume.volume_mount("my-volume", "my-compute")

# Mount with custom start path
response = volume.volume_mount(
name="my-volume",
target="my-compute",
start_mount_path="data" # will be used, instead of the "volume name"
)

# Mount with full custom path (advanced - use carefully)
response = volume.volume_mount(
name="my-volume",
target="my-compute",
full_mount_path="/custom/mount/point"
)

if response['code'] == 200:
print("Volume mount initiated successfully")
warning

Important: Mount Delays: Volume mounting triggers a compute resource reload/restart, which takes time

  • Mount operation returns success immediately but takes time to complete
  • Compute resource will restart to apply the volume mount
  • Volume status may show as "Not mounted" initially
  • Wait 15-30 seconds before checking mount status
import time

# Mount volume
response = volume.volume_mount("my-volume", "my-compute")
if response['code'] == 200:
print("Mount initiated, waiting for completion...")

# Wait for mount to complete
time.sleep(30) # Allow time for resource reload

# Verify mount completed
response = volume.volume_list()
for vol in response['details']['volume_list']:
if vol['name'] == 'my-volume':
if vol['mounted_to']:
print("✓ Volume is now mounted!")
else:
print("⏳ Mount still in progress...")

Unmounting volumes

Detach volumes from compute resources:

# Unmount from all resources
response = volume.volume_umount("my-volume")

# Unmount from specific resources
response = volume.volume_umount("my-volume", ["compute1", "compute2"])

# Force unmount even if resources are not responding
response = volume.volume_umount("my-volume", force=True)

if response['code'] == 200:
print("Volume unmount initiated successfully")
warning

Important: Unmount Delays: Similar to mounting, unmounting also triggers resource reloads

  • Unmount operation returns success immediately but takes time to complete
  • Compute resource will restart to remove the volume mount
  • Volume status may still show as "Mounted" initially
  • Wait 15-30 seconds before checking unmount status
import time

# Unmount volume
response = volume.volume_umount("my-volume")
if response['code'] == 200:
print("Unmount initiated, waiting for completion...")

# Wait for unmount to complete
time.sleep(20) # Allow time for resource reload

# Verify unmount completed
response = volume.volume_list()
for vol in response['details']['volume_list']:
if vol['name'] == 'my-volume':
if not vol['mounted_to']:
print("✓ Volume is now unmounted!")
else:
print("⏳ Unmount still in progress...")