Add initial implementation of snapshot export

This commit is contained in:
2024-08-19 18:46:07 -04:00
parent 9a435fe2ae
commit d060787503
6 changed files with 395 additions and 0 deletions

View File

@ -1870,6 +1870,45 @@ def cli_vm_snapshot_rollback(domain, snapshot_name):
finish(retcode, retmsg)
###############################################################################
# > pvc vm snapshot export
###############################################################################
@click.command(
name="export", short_help="Export a snapshot of a virtual machine to files."
)
@connection_req
@click.argument("domain")
@click.argument("snapshot_name")
@click.argument("export_path")
@click.option(
"-i",
"--incremental",
"incremental_parent",
default=None,
help="Perform an incremental volume backup from this parent snapshot.",
)
def cli_vm_snapshot_export(domain, snapshot_name, export_path, incremental_parent):
"""
Export the (existing) snapshot SNAPSHOT_NAME of virtual machine DOMAIN to the absolute path
EXPORT_PATH on the current PVC primary coordinator. DOMAIN may be a UUID or name.
"""
primary_node = pvc.lib.cluster.get_primary_node(CLI_CONFIG)
echo(
CLI_CONFIG,
f'Exporting snapshot "{snapshot_name}" of VM "{domain}" to "{export_path}" on "{primary_node}"...',
newline=False,
)
retcode, retmsg = pvc.lib.vm.vm_export_snapshot(
CLI_CONFIG, domain, snapshot_name, export_path, incremental_parent
)
if retcode:
echo(CLI_CONFIG, "done.")
else:
echo(CLI_CONFIG, "failed.")
finish(retcode, retmsg)
###############################################################################
# > pvc vm backup
###############################################################################
@ -6410,6 +6449,7 @@ cli_vm.add_command(cli_vm_flush_locks)
cli_vm_snapshot.add_command(cli_vm_snapshot_create)
cli_vm_snapshot.add_command(cli_vm_snapshot_remove)
cli_vm_snapshot.add_command(cli_vm_snapshot_rollback)
cli_vm_snapshot.add_command(cli_vm_snapshot_export)
cli_vm.add_command(cli_vm_snapshot)
cli_vm_backup.add_command(cli_vm_backup_create)
cli_vm_backup.add_command(cli_vm_backup_restore)

View File

@ -21,6 +21,8 @@
import json
from time import sleep
from pvc.lib.common import call_api
@ -114,3 +116,22 @@ def get_info(config):
return True, response.json()
else:
return False, response.json().get("message", "")
def get_primary_node(config):
"""
Get the current primary node of the PVC cluster
API endpoint: GET /api/v1/status/primary_node
API arguments:
API schema: {json_data_object}
"""
while True:
response = call_api(config, "get", "/status/primary_node")
resp_code = response.status_code
if resp_code == 200:
break
else:
sleep(1)
return True, response.json()["primary_node"]

View File

@ -557,6 +557,32 @@ def vm_rollback_snapshot(config, vm, snapshot_name):
return True, response.json().get("message", "")
def vm_export_snapshot(config, vm, snapshot_name, export_path, incremental_parent):
"""
Export an (existing) snapshot of a VM's disks and configuration to export_path, optionally
incremental with incremental_parent
API endpoint: POST /vm/{vm}/snapshot/export
API arguments: snapshot_name=snapshot_name, export_path=export_path, incremental_parent=incremental_parent
API schema: {"message":"{data}"}
"""
params = {
"snapshot_name": snapshot_name,
"export_path": export_path,
}
if incremental_parent is not None:
params["incremental_parent"] = incremental_parent
response = call_api(
config, "post", "/vm/{vm}/snapshot/export".format(vm=vm), params=params
)
if response.status_code != 200:
return False, response.json().get("message", "")
else:
return True, response.json().get("message", "")
def vm_vcpus_set(config, vm, vcpus, topology, restart):
"""
Set the vCPU count of the VM with topology