Skip to content

Add --mount-options parameter to xpk storage attach/create #450

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 9 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/reusable_storage_tests_by_type.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ jobs:
if: inputs.storage-command == 'attach' && inputs.storage-type == 'gcsfuse'
run: |
python3 xpk.py storage attach ${{secrets.STORAGE_NAME}} --cluster=${{inputs.cluster-name}} --zone=${{inputs.zone}} --type=${{inputs.storage-type}} \
--auto-mount=true --mount-point='/${{inputs.storage-type}}-test-mount-point' --readonly=false --size=1 --bucket=${{secrets.BUCKET_NAME}}
--auto-mount=true --mount-point='/${{inputs.storage-type}}-test-mount-point' --readonly=false --size=1 --bucket=${{secrets.BUCKET_NAME}} --mount-options rename-dir-limit=10000
- name: Create auto-mount GCP Filestore Storage instance
if: inputs.storage-command == 'create' && inputs.storage-type == 'gcpfilestore'
run: |
Expand All @@ -128,6 +128,9 @@ jobs:
run: python3 xpk.py storage list --cluster ${{inputs.cluster-name}} --zone=${{inputs.zone}} | tee output.txt | grep ${{secrets.STORAGE_NAME}} || (echo 'No storage found' && exit 143)
- name: Verify VolumeBundle created
run: kubectl get volumebundle ${{secrets.STORAGE_NAME}} -o jsonpath='{.spec.containerVolumeMounts[0].mountPath}' | grep '/${{inputs.storage-type}}-test-mount-point'
- name: Verify Persistent Volume mount options
if: inputs.storage-command == 'attach' && inputs.storage-type == 'gcsfuse'
run: kubectl get pv ${{secrets.STORAGE_NAME}}-pv -oyaml | grep rename-dir-limit=10000 || (echo 'Invalid storage mount options' && exit 143)
- name: Run workload to write file on filestore
run: python3 xpk.py workload create --workload $FS_WRITE_WORKLOAD --num-slices=1 --docker-image='marketplace.gcr.io/google/ubuntu2004' --command "mkdir /${{inputs.storage-type}}-test-mount-point/$RANDOM_SEED/ && echo 'Test text message' > /${{inputs.storage-type}}-test-mount-point/$RANDOM_SEED/test.txt || (echo 'Writing to filestore failed' && exit 143)" --cluster ${{inputs.cluster-name}} --tpu-type=${{inputs.tpu-type}} --zone ${{inputs.zone}}
- name: Wait for writer workload completion and confirm it succeeded
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ Parameters:
- `--readonly` - if set to true, workload can only read from storage.
- `--size` - size of the storage in Gb.
- `--bucket` - name of the storage bucket. If not set then the name of the storage is used as a bucket name.
- `--mount-options` - comma-separated list of additional mount options for PersistentVolume ([reference](https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-storage-fuse-csi-driver-perf#mount-options)).
- `--manifest` - path to the manifest file containing PersistentVolume and PresistentVolumeClaim definitions. If set, then values from manifest override the following parameters: `--size` and `--bucket`.

### Filestore
Expand Down
14 changes: 11 additions & 3 deletions src/xpk/commands/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ def storage_create(args: Namespace) -> None:
manifest = list(yaml.safe_load_all(f))
else:
manifest = filestore_client.manifest(
args.name, args.vol, args.access_mode, filestore_network
args.name,
args.vol,
args.access_mode,
filestore_network,
args.mount_options,
)

k8s_api_client = setup_k8s_env(args)
Expand Down Expand Up @@ -154,7 +158,11 @@ def storage_attach(args: Namespace) -> None:
else:
filestore_network = get_cluster_network(args)
manifest = filestore_client.manifest(
args.name, args.vol, args.access_mode, filestore_network
args.name,
args.vol,
args.access_mode,
filestore_network,
args.mount_options,
)

elif args.type == GCS_FUSE_TYPE:
Expand All @@ -170,7 +178,7 @@ def storage_attach(args: Namespace) -> None:
manifest = list(yaml.safe_load_all(f))
else:
manifest = gcsfuse.manifest(
name=args.name, bucket=args.bucket, size=args.size
args.name, args.bucket, args.size, args.mount_options
)

elif args.type in [PARALLELSTORE_TYPE, GCE_PD_TYPE]:
Expand Down
14 changes: 11 additions & 3 deletions src/xpk/core/filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ def create_sc(self, name: str, network: str) -> dict:
] = f"projects/{self.project}/global/networks/{network}"
return data

def create_pv(self, name: str, vol: str, access_mode: str) -> dict:
def create_pv(
self, name: str, vol: str, access_mode: str, mount_options: str
) -> dict:
"""Create a yaml representing filestore PersistentVolume."""
data = templates.load(FS_PV_PATH)
data["metadata"]["name"] = get_pv_name(name)
Expand All @@ -215,6 +217,7 @@ def create_pv(self, name: str, vol: str, access_mode: str) -> dict:
0
].ip_addresses[0]
data["spec"]["csi"]["volumeAttributes"]["volume"] = vol
data["spec"]["mountOptions"] = mount_options.split(",")
return data

def create_pvc(self, name: str, access_mode: str) -> dict:
Expand All @@ -230,10 +233,15 @@ def create_pvc(self, name: str, access_mode: str) -> dict:
return data

def manifest(
self, name: str, vol: str, access_mode: str, network: str
self,
name: str,
vol: str,
access_mode: str,
network: str,
mount_options: str,
) -> list[dict]:
self.load_instance()
pv = self.create_pv(name, vol, access_mode)
pv = self.create_pv(name, vol, access_mode, mount_options)
pvc = self.create_pvc(name, access_mode)
sc = self.create_sc(name, network)
return [pv, pvc, sc]
Expand Down
13 changes: 8 additions & 5 deletions src/xpk/core/gcsfuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
FUSE_PVC_PATH = "/../templates/fuse-pvc.yaml"


def create_pv(name: str, size: int, bucket: str) -> dict:
def create_pv(name: str, size: int, bucket: str, mount_options: str) -> dict:
data = templates.load(FUSE_PV_PATH)
data["metadata"]["name"] = f"{name}-pv"
data["spec"]["capacity"]["storage"] = f"{size}Gi"
data["spec"]["csi"]["volumeHandle"] = bucket
data["spec"]["mountOptions"] = mount_options.split(",")
return data


Expand All @@ -36,15 +37,17 @@ def create_pvc(name: str, size: int) -> dict:
return data


def manifest(name: str, bucket: str, size: int) -> list[dict]:
def manifest(
name: str, bucket: str, size: int, mount_options: str
) -> list[dict]:
"""Creates GCS FUSE manifest file.

Args:
path (str): path to the file where the manifest will be created
name (str): base name of the volumes
bucket (str): name of the storage bucket
size (str): size of the storage
size (str): size of the storage (in GB)
mount_options (str): comma-separated list of mountOptions for PersistentVolume
"""
pv = create_pv(name, size, bucket)
pv = create_pv(name, size, bucket, mount_options)
pvc = create_pvc(name, size)
return [pv, pvc]
14 changes: 13 additions & 1 deletion src/xpk/parser/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,19 @@ def add_storage_attach_parser(

opt_args = storage_attach_parser.add_argument_group(
'Optional Arguments',
'Optional arguments for storage create.',
'Optional arguments for storage attach.',
)
opt_args.add_argument(
'--manifest',
type=str,
help='Path to manifest file containing volume definitions',
)
opt_args.add_argument(
'--mount-options',
type=str,
help='Comma-separated list of mountOptions for PersistentVolume',
default='implicit-dirs',
)
add_kind_cluster_arguments(opt_args)


Expand Down Expand Up @@ -248,6 +254,12 @@ def add_storage_create_parser(
type=str,
help='Path to manifest file containing volume definitions',
)
opt_args.add_argument(
'--mount-options',
type=str,
help='Comma-separated list of mountOptions for PersistentVolume',
default='',
)

add_kind_cluster_arguments(opt_args)

Expand Down
Loading