55from datetime import UTC , datetime
66from typing import Any
77
8+ from kubernetes .utils import parse_quantity
9+
810from ..._util import Identifier
911from ...exceptions import VelaKubernetesError
1012from .. import (
1113 _POD_SECURITY_LABELS ,
1214 AUTOSCALER_PVC_SUFFIX ,
1315 AUTOSCALER_WAL_PVC_SUFFIX ,
16+ PITR_WAL_PVC_SIZE ,
1417 get_autoscaler_vm_identity ,
1518 kube_service ,
1619)
3639
3740logger = logging .getLogger (__name__ )
3841
42+ _PITR_WAL_PVC_SIZE_BYTES : int = int (parse_quantity (PITR_WAL_PVC_SIZE ))
43+
3944
4045@dataclass (frozen = True )
4146class CloneTimeouts :
@@ -319,6 +324,7 @@ class _SnapshotRestoreOperation:
319324 storage_class_name : str
320325 target_database_size : int
321326 timeouts : CloneTimeouts
327+ pvc_suffix : str = AUTOSCALER_PVC_SUFFIX
322328 ids : CloneIdentifiers = field (init = False )
323329 created_target_snapshot : bool = field (default = False , init = False )
324330 created_content : bool = field (default = False , init = False )
@@ -327,8 +333,8 @@ def __post_init__(self) -> None:
327333 source_ns = self .snapshot_namespace
328334 _ , source_vm_name = get_autoscaler_vm_identity (self .source_branch_id )
329335 target_ns , target_vm_name = get_autoscaler_vm_identity (self .target_branch_id )
330- pvc_name = f"{ source_vm_name } { AUTOSCALER_PVC_SUFFIX } "
331- target_pvc_name = f"{ target_vm_name } { AUTOSCALER_PVC_SUFFIX } "
336+ pvc_name = f"{ source_vm_name } { self . pvc_suffix } "
337+ target_pvc_name = f"{ target_vm_name } { self . pvc_suffix } "
332338 if target_pvc_name != pvc_name :
333339 raise VelaKubernetesError (
334340 f"Autoscaler PVC name mismatch between source ({ pvc_name } ) and target ({ target_pvc_name } )"
@@ -520,7 +526,7 @@ async def clone_branch_database_volume(
520526 target_branch_id = target_branch_id ,
521527 snapshot_class = snapshot_class ,
522528 storage_class_name = storage_class_name ,
523- target_database_size = database_size ,
529+ target_database_size = _PITR_WAL_PVC_SIZE_BYTES ,
524530 timeouts = timeouts ,
525531 volume_label = "wal" ,
526532 pvc_suffix = AUTOSCALER_WAL_PVC_SUFFIX ,
@@ -563,3 +569,40 @@ async def restore_branch_database_volume_from_snapshot(
563569 ),
564570 )
565571 await operation .run ()
572+
573+
574+ async def restore_branch_wal_volume_from_snapshot (
575+ * ,
576+ source_branch_id : Identifier ,
577+ target_branch_id : Identifier ,
578+ snapshot_namespace : str ,
579+ snapshot_name : str ,
580+ snapshot_class : str ,
581+ storage_class_name : str ,
582+ snapshot_timeout_seconds : float ,
583+ snapshot_poll_interval_seconds : float ,
584+ pvc_timeout_seconds : float ,
585+ pvc_poll_interval_seconds : float ,
586+ ) -> None :
587+ """
588+ Restore the WAL volume for a PITR-enabled branch from an existing VolumeSnapshot.
589+ The WAL PVC is always restored to PITR_WAL_PVC_SIZE (100Gi).
590+ """
591+ operation = _SnapshotRestoreOperation (
592+ source_branch_id = source_branch_id ,
593+ target_branch_id = target_branch_id ,
594+ snapshot_namespace = snapshot_namespace ,
595+ snapshot_name = snapshot_name ,
596+ snapshot_content_name = None ,
597+ snapshot_class = snapshot_class ,
598+ storage_class_name = storage_class_name ,
599+ target_database_size = _PITR_WAL_PVC_SIZE_BYTES ,
600+ pvc_suffix = AUTOSCALER_WAL_PVC_SUFFIX ,
601+ timeouts = CloneTimeouts (
602+ snapshot_ready = snapshot_timeout_seconds ,
603+ snapshot_poll = snapshot_poll_interval_seconds ,
604+ pvc_ready = pvc_timeout_seconds ,
605+ pvc_poll = pvc_poll_interval_seconds ,
606+ ),
607+ )
608+ await operation .run ()
0 commit comments