def list_volumes(): """List the currently mounted volumes.""" client = k8sutils.get_v1_client() namespace = get_namespace() pod_name = get_pod_name() container_name = get_container_name() return _list_volumes(client, namespace, pod_name, container_name)
def get_pod(name, namespace): """Get a pod. This function seems redundant but it can save a few repeated lines of code. """ k8s_client = k8sutils.get_v1_client() return k8s_client.read_namespaced_pod(name, namespace)
def get_workflow_name(pod_name, namespace): """Get the workflow name associated to a pod (pipeline step).""" v1_client = k8sutils.get_v1_client() pod = v1_client.read_namespaced_pod(pod_name, namespace) # Obtain the workflow name labels = pod.metadata.labels workflow_name = labels.get("workflows.argoproj.io/workflow", None) if workflow_name is None: msg = ("Could not retrieve workflow name from pod" "{}/{}".format(namespace, pod_name)) raise RuntimeError(msg) return workflow_name
def get_docker_base_image(): """Get the current container's docker image. Raises: ConfigException when initializing the client FileNotFoundError when attempting to find the namespace ApiException when getting the container name or reading the pod """ client = k8sutils.get_v1_client() namespace = get_namespace() pod_name = get_pod_name() container_name = get_container_name() pod = client.read_namespaced_pod(pod_name, namespace) container = _get_pod_container(pod, container_name) return container.image
def _add_owner_references(infs_name: str, pvc_name: str): # add owner reference to the PVC log.info("Adding owner references to PVC '%s' for InferenceService '%s'", pvc_name, infs_name) client = k8sutils.get_v1_client() infs = get_inference_service(infs_name) pvc = client.read_namespaced_persistent_volume_claim( pvc_name, podutils.get_namespace()) ref = kubernetes.client.V1OwnerReference(api_version=API_VERSION, kind="InferenceService", name=infs_name, uid=infs["metadata"]["uid"]) if not pvc.metadata.owner_references: pvc.metadata.owner_references = [ref] else: pvc.metadata.owner_references.append(ref) client.patch_namespaced_persistent_volume_claim( name=pvc_name, namespace=podutils.get_namespace(), body=pvc)
def _get_output_rok_artifacts(pod_names): # We return early if there are no RokSnapshot artifacts in the db try: rok_snapshot_type_id = self.store.get_artifact_type( type_name=ROK_SNAPSHOT_ARTIFACT_TYPE_NAME).id except Exception: return [] output_artifact_ids = [] annotation = METADATA_OUTPUT_ARTIFACT_IDS_ANNOTATION_KEY k8s_client = k8sutils.get_v1_client() for name in pod_names: pod = k8s_client.read_namespaced_pod(name, self.pod_namespace) ids = json.loads(pod.metadata.annotations.get( annotation, "[]")) output_artifact_ids.extend(ids) return [ a for a in self.store.get_artifacts_by_id(output_artifact_ids) if a.type_id == rok_snapshot_type_id ]
def hydrate_pvc_from_snapshot(obj, version, new_pvc_name, bucket=DEFAULT_BUCKET): """Create a new PVC out of a Rok snapshot.""" log.info("Creating new PVC '%s' from Rok version %s ..." % (new_pvc_name, version)) rok = get_client() version_info = rok.version_info(bucket, obj, version) # size of the snapshot size = int(version_info['content_length']) units = ["", "Ki", "Mi", "Gi"] unit = 0 while size > 1024 and unit < 3: size = math.ceil(size / 1024) unit += 1 size_repr = "%s%s" % (size, units[unit]) rok_url = version_info['rok_url'] log.info("Using Rok url: %s" % rok_url) # todo: kubernetes python client v11 have a # kubernetes.utils.create_from_dict that would make it much more nicer # here. (KFP support kubernetes <= 10) pvc = kubernetes.client.V1PersistentVolumeClaim( api_version="v1", metadata=kubernetes.client.V1ObjectMeta( annotations={"rok/origin": rok_url}, name=new_pvc_name ), spec=kubernetes.client.V1PersistentVolumeClaimSpec( storage_class_name="rok", access_modes=["ReadWriteOnce"], resources=kubernetes.client.V1ResourceRequirements( requests={"storage": size_repr} ) ) ) k8s_client = k8sutils.get_v1_client() ns = podutils.get_namespace() ns_pvc = k8s_client.create_namespaced_persistent_volume_claim(ns, pvc) log.info("Successfully submitted PVC.") return {"name": ns_pvc.metadata.name}
def get_docker_base_image(): """Get the current container's docker image. Just reading the Pod spec's container image is not enough to have a reproducible reference to the current image, because an image tag can be re-assigned to newer builds, in the future (e.g. when using the `latest` tag). The only way to have reproducible reference is by using the image manifest's `sha`. Kubernetes exposes this in the Pod's `status`, under `containerStatuses` [1], in the field `imageID`. In the case this field is empty (this could happen when the image was built locally), then fallback to reading the Pod's container `image` field. [1] https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#containerstatus-v1-core # noqa: 501 Raises: ConfigException when initializing the client FileNotFoundError when attempting to find the namespace ApiException when getting the container name or reading the pod """ log.info("Getting the base image of container...") client = k8sutils.get_v1_client() pod = client.read_namespaced_pod(get_pod_name(), get_namespace()) container_name = get_container_name() image = None try: image = _get_container_image_sha(pod, container_name) except RuntimeError as e: log.warning("Could not retrieve the container image sha: %s", str(e)) log.warning("Using its tag instead. The pipeline won't be reproducible" " if a new image is pushed with the same tag.") image = _get_pod_container(pod, container_name).image log.info("Retrieved image: %s", image) return image
def patch_pod(name, namespace, patch): """Patch a pod.""" k8s_client = k8sutils.get_v1_client() k8s_client.patch_namespaced_pod(name=name, namespace=namespace, body=patch)