==================== Updating the objects ==================== .. warning:: Unfortunately, Minikube cannot handle the PVC/PV resizing, as it uses the HostPath provider internally. You can either skip this step of the tutorial, or you can use an external Kubernetes cluster with real dynamically sized volumes. Previously (:doc:`creation`), we have implemented a handler for the creation of an ``EphemeralVolumeClaim`` (EVC), and created the corresponding ``PersistentVolumeClaim`` (PVC). What happens if we change the size of the EVC after it already exists? The PVC must be updated accordingly to match its parent EVC. First, we have to remember the name of the created PVC. Let us extend the creation handler we already have from the previous step with one additional line: .. code-block:: python :caption: ephemeral.py :emphasize-lines: 21 @kopf.on.create('ephemeralvolumeclaims') def create_fn(spec: kopf.Spec, name: str, namespace: str | None, logger: kopf.Logger, **_: Any) -> dict[str, str]: size = spec.get('size') if not size: raise kopf.PermanentError(f"Size must be set. Got {size!r}.") path = os.path.join(os.path.dirname(__file__), 'pvc.yaml') tmpl = open(path, 'rt').read() text = tmpl.format(size=size, name=name) data = yaml.safe_load(text) api = kubernetes.client.CoreV1Api() obj = api.create_namespaced_persistent_volume_claim( namespace=namespace, body=data, ) logger.info(f"PVC child is created: {obj}") return {'pvc-name': obj.metadata.name} Whatever is returned from any handler is stored in the object's status under that handler ID (which is the function name by default). We can see that with kubectl: .. code-block:: bash kubectl get -o yaml evc my-claim .. code-block:: yaml spec: size: 1G status: create_fn: pvc-name: my-claim kopf: {} .. note:: If the above change causes ``Patching failed with inconsistencies`` debug warnings and/or your EVC YAML does not show a ``.status`` field, make sure you have set the ``x-kubernetes-preserve-unknown-fields: true`` field in your CRD on either the entire object or just the ``.status`` field, as detailed in :doc:`resources`. Without setting this field, Kubernetes will prune the ``.status`` field when Kopf tries to update it. For more information on field pruning, see `the Kubernetes docs `_. Let us add yet another handler, but for the "update" cause. This handler gets this stored PVC name from the creation handler, and patches the PVC with the new size from the EVC: .. code-block:: python import kopf from typing import Any @kopf.on.update('ephemeralvolumeclaims') def update_fn(spec: kopf.Spec, status: kopf.Status, namespace: str | None, logger: kopf.Logger, **_: Any) -> None: size = spec.get('size', None) if not size: raise kopf.PermanentError(f"Size must be set. Got {size!r}.") pvc_name = status['create_fn']['pvc-name'] pvc_patch = {'spec': {'resources': {'requests': {'storage': size}}}} api = kubernetes.client.CoreV1Api() obj = api.patch_namespaced_persistent_volume_claim( namespace=namespace, name=pvc_name, body=pvc_patch, ) logger.info(f"PVC child is updated: {obj}") Now, let us change the EVC's size: .. code-block:: bash kubectl edit evc my-claim Or by patching it: .. code-block:: bash kubectl patch evc my-claim --type merge -p '{"spec": {"size": "2G"}}' Keep in mind the PVC size can only be increased, never decreased. Give the operator a few seconds to handle the change. Check the size of the actual PV behind the PVC, which is now increased: .. code-block:: bash kubectl get pv .. code-block:: none NAME CAPACITY ACCESS MODES ... pvc-a37b65bd-8384-11e9-b857-42010a800265 2Gi RWO ... .. warning:: Kubernetes & ``kubectl`` incorrectly show the capacity of PVCs: it remains the same (1G) even after the change. What matters is the size of the actual PV (Persistent Volume) behind each PVC. This is a Kubernetes issue unrelated to Kopf, so we work around it.