Skip to content

Commit 5690461

Browse files
lukebaumanncopybara-github
authored andcommitted
Add GCSFuse support to PathwaysJobSet.
PiperOrigin-RevId: 948113751
1 parent 8304999 commit 5690461

2 files changed

Lines changed: 450 additions & 95 deletions

File tree

pathwaysutils/experimental/gke/jobset.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
# limitations under the License.
1212
"""Pathways JobSet generator and builder (with Worker Job Config)."""
1313

14+
import hashlib
1415
import json
1516
import logging
1617
import math
17-
from typing import Any, Mapping
18+
from typing import Any, Mapping, Sequence
1819
from kubernetes import client
1920

2021
# GKE sidecar containers restartPolicy compatibility placeholder.
@@ -530,6 +531,90 @@ def _build_worker_job_template(
530531
)
531532
return worker_job_template
532533

534+
def _filter_matching_containers(
535+
self,
536+
containers_param: str | Sequence[str],
537+
all_containers: list[client.V1Container],
538+
) -> list[client.V1Container]:
539+
"""Filters containers matching the containers_param selection."""
540+
if containers_param == "all":
541+
return all_containers
542+
if containers_param == "worker":
543+
return [c for c in all_containers if c.name == "pathways-worker"]
544+
545+
filter_names = (
546+
[containers_param]
547+
if isinstance(containers_param, str)
548+
else set(containers_param)
549+
)
550+
return [c for c in all_containers if c.name in filter_names]
551+
552+
def _enable_gcsfuse_annotations(
553+
self, job_template: client.V1JobTemplateSpec
554+
) -> None:
555+
"""Enables gke-gcsfuse/volumes annotation on job and pod metadata."""
556+
job_metadata = job_template.metadata or client.V1ObjectMeta()
557+
job_annotations = job_metadata.annotations or {}
558+
job_annotations["gke-gcsfuse/volumes"] = "true"
559+
job_metadata.annotations = job_annotations
560+
job_template.metadata = job_metadata
561+
562+
pod_metadata = job_template.spec.template.metadata or client.V1ObjectMeta()
563+
pod_annotations = pod_metadata.annotations or {}
564+
pod_annotations["gke-gcsfuse/volumes"] = "true"
565+
pod_metadata.annotations = pod_annotations
566+
job_template.spec.template.metadata = pod_metadata
567+
568+
def _add_volume_to_pod_spec(
569+
self, pod_spec: client.V1PodSpec, volume: client.V1Volume
570+
) -> None:
571+
"""Appends volume to pod_spec if not already present."""
572+
volumes = pod_spec.volumes or []
573+
if not any(v.name == volume.name for v in volumes):
574+
volumes.append(volume)
575+
pod_spec.volumes = volumes
576+
577+
def add_gcsfuse(
578+
self,
579+
containers: str | Sequence[str],
580+
mount_path: str,
581+
bucket: str,
582+
read_only: bool = False,
583+
) -> "PathwaysJobSet":
584+
"""Adds GCSFuse mount to specified containers."""
585+
bucket_hash = int(hashlib.md5(bucket.encode()).hexdigest(), 16) % (10**8)
586+
volume_name = f"gcsfuse-{bucket_hash}"
587+
volume = client.V1Volume(
588+
name=volume_name,
589+
csi=client.V1CSIVolumeSource(
590+
driver="gcsfuse.csi.storage.gke.io",
591+
volume_attributes={"bucketName": bucket},
592+
),
593+
)
594+
volume_mount = client.V1VolumeMount(
595+
name=volume_name,
596+
mount_path=mount_path,
597+
read_only=read_only,
598+
)
599+
600+
for job_template in (self._head_job_template, self._worker_job_template):
601+
pod_spec = job_template.spec.template.spec
602+
all_containers = (pod_spec.containers or []) + (pod_spec.init_containers or [])
603+
604+
matching = self._filter_matching_containers(containers, all_containers)
605+
if not matching:
606+
continue
607+
608+
self._enable_gcsfuse_annotations(job_template)
609+
self._add_volume_to_pod_spec(pod_spec, volume)
610+
611+
for container in matching:
612+
volume_mounts = container.volume_mounts or []
613+
volume_mounts.append(volume_mount)
614+
container.volume_mounts = volume_mounts
615+
616+
return self
617+
533618
def _compile_config(self) -> dict[str, Any]:
534619
"""Compiles the JobSet configuration into a dictionary."""
535620
with client.ApiClient() as api_client:

0 commit comments

Comments
 (0)