fix: resolve datastore URL encoding errors and improve snapshot removal reliability with fresh object lookups
This commit is contained in:
parent
2b5514f4c2
commit
9621175a76
@ -139,14 +139,17 @@ def find_datacenter_for_datastore(content, datastore_name):
|
|||||||
def download_datastore_file(host, dc_name, datastore_name, ds_path, local_path,
|
def download_datastore_file(host, dc_name, datastore_name, ds_path, local_path,
|
||||||
session_cookie, verify_ssl=True, progress_cb=None):
|
session_cookie, verify_ssl=True, progress_cb=None):
|
||||||
"""Download a file from a vSphere datastore. progress_cb(bytes_done, bytes_total) is optional."""
|
"""Download a file from a vSphere datastore. progress_cb(bytes_done, bytes_total) is optional."""
|
||||||
encoded_path = urllib.parse.quote(ds_path, safe='')
|
# Keep slashes unencoded (safe='/') — vCenter's /folder/ API requires them in the URL path.
|
||||||
|
encoded_path = urllib.parse.quote(ds_path, safe='/')
|
||||||
url = (f"https://{host}/folder/{encoded_path}"
|
url = (f"https://{host}/folder/{encoded_path}"
|
||||||
f"?dcPath={urllib.parse.quote(dc_name)}&dsName={urllib.parse.quote(datastore_name)}")
|
f"?dcPath={urllib.parse.quote(dc_name)}&dsName={urllib.parse.quote(datastore_name)}")
|
||||||
headers = {"Cookie": f"vmware_soap_session={session_cookie}"}
|
headers = {"Cookie": f"vmware_soap_session={session_cookie}"}
|
||||||
print(f"Downloading {ds_path} from datastore {datastore_name} to {local_path}")
|
print(f"Downloading {ds_path} from datastore {datastore_name} to {local_path}")
|
||||||
|
print(f" URL: {url}")
|
||||||
with requests.get(url, headers=headers, stream=True, verify=verify_ssl, proxies={"http": None, "https": None}) as r:
|
with requests.get(url, headers=headers, stream=True, verify=verify_ssl, proxies={"http": None, "https": None}) as r:
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
total_bytes = int(r.headers.get('Content-Length', 0))
|
total_bytes = int(r.headers.get('Content-Length', 0))
|
||||||
|
print(f" HTTP {r.status_code}, Content-Length: {total_bytes} bytes")
|
||||||
done_bytes = 0
|
done_bytes = 0
|
||||||
os.makedirs(os.path.dirname(local_path), exist_ok=True)
|
os.makedirs(os.path.dirname(local_path), exist_ok=True)
|
||||||
with open(local_path, 'wb') as f:
|
with open(local_path, 'wb') as f:
|
||||||
@ -406,16 +409,28 @@ def _run_backup_impl(host, user, password, vm_name, dest, compress, no_verify_ss
|
|||||||
print('Backup completed successfully')
|
print('Backup completed successfully')
|
||||||
finally:
|
finally:
|
||||||
if created_snapshot:
|
if created_snapshot:
|
||||||
snap_root = getattr(vm, 'snapshot', None)
|
try:
|
||||||
if snap_root and snap_root.rootSnapshotList:
|
# Re-fetch vm snapshot state to avoid stale object references
|
||||||
snap_obj = find_snapshot_by_name(snap_root.rootSnapshotList, snap_name)
|
content.rootFolder # touch to keep session alive
|
||||||
if snap_obj:
|
vm_fresh = None
|
||||||
try:
|
obj_view2 = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
|
||||||
|
for v in obj_view2.view:
|
||||||
|
if v.name == vm_name:
|
||||||
|
vm_fresh = v
|
||||||
|
break
|
||||||
|
obj_view2.Destroy()
|
||||||
|
target_vm = vm_fresh or vm
|
||||||
|
snap_root = getattr(target_vm, 'snapshot', None)
|
||||||
|
if snap_root and snap_root.rootSnapshotList:
|
||||||
|
snap_obj = find_snapshot_by_name(snap_root.rootSnapshotList, snap_name)
|
||||||
|
if snap_obj:
|
||||||
remove_snapshot(snap_obj)
|
remove_snapshot(snap_obj)
|
||||||
except Exception as e:
|
else:
|
||||||
print(f'Failed to remove snapshot: {e}', file=sys.stderr)
|
print('Snapshot already removed or not found in tree')
|
||||||
else:
|
else:
|
||||||
print('Snapshot object not found in tree; may have been removed already')
|
print('No snapshots found on VM — may have already been removed')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Failed to remove snapshot: {e}', file=sys.stderr)
|
||||||
_prog('done', 100, 'Backup finished successfully')
|
_prog('done', 100, 'Backup finished successfully')
|
||||||
finally:
|
finally:
|
||||||
if si:
|
if si:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user