feat: implement QEMU clone and local migration
This commit is contained in:
@@ -262,3 +262,52 @@ async def test_qemu_snapshot_handlers(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
assert (await rollback(http_request, common)).startswith("UPID:pve1:")
|
||||
assert (await delete(http_request, common)).startswith("UPID:pve1:")
|
||||
assert tasks == ["qemu-snapshot-create", "qemu-snapshot-rollback", "qemu-snapshot-delete"]
|
||||
|
||||
|
||||
async def test_qemu_clone_and_migrate_handlers(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
tasks: list[dict[str, Any]] = []
|
||||
|
||||
class FakeTaskRepository:
|
||||
def __init__(self, pool: object) -> None:
|
||||
del pool
|
||||
|
||||
async def create(self, **kwargs: Any) -> Task:
|
||||
tasks.append(kwargs)
|
||||
return Task(
|
||||
uuid.uuid4(),
|
||||
str(kwargs["upid"]),
|
||||
str(kwargs["task_type"]),
|
||||
"queued",
|
||||
{},
|
||||
0,
|
||||
False,
|
||||
0,
|
||||
)
|
||||
|
||||
monkeypatch.setattr("app.handlers.qemu.TaskRepository", FakeTaskRepository)
|
||||
registry = HandlerRegistry()
|
||||
register_qemu_handlers(registry)
|
||||
pool = QemuPool()
|
||||
http_request = request(pool)
|
||||
clone = registry.get("/nodes/{node}/qemu/{vmid}/clone", "POST")
|
||||
migrate_get = registry.get("/nodes/{node}/qemu/{vmid}/migrate", "GET")
|
||||
migrate = registry.get("/nodes/{node}/qemu/{vmid}/migrate", "POST")
|
||||
assert clone and migrate_get and migrate
|
||||
|
||||
clone_upid = await clone(
|
||||
http_request, inputs(node="pve1", vmid=150, newid=151, name="clone", full=True)
|
||||
)
|
||||
assert clone_upid.startswith("UPID:pve1:")
|
||||
assert tasks[-1]["task_type"] == "qemu-clone"
|
||||
assert (await migrate_get(http_request, inputs(node="pve1", vmid=150, target="pve2")))[
|
||||
"local_disks"
|
||||
] == []
|
||||
migrate_upid = await migrate(
|
||||
http_request, inputs(node="pve1", vmid=150, target="pve2", online=False)
|
||||
)
|
||||
assert migrate_upid.startswith("UPID:pve1:")
|
||||
assert tasks[-1]["task_type"] == "qemu-migrate"
|
||||
|
||||
with pytest.raises(ApiError) as same_node:
|
||||
await migrate(http_request, inputs(node="pve1", vmid=150, target="pve1"))
|
||||
assert same_node.value.status_code == 400
|
||||
|
||||
@@ -82,6 +82,8 @@ class CrudConnection:
|
||||
return {"id": uuid.uuid4(), "cluster_id": uuid.uuid4()}
|
||||
if "JOIN virtual_machines" in sql:
|
||||
return {"state": '{"status":"stopped","name":"old"}', "config": '{"name":"old"}'}
|
||||
if "SELECT state FROM resources" in sql:
|
||||
return {"state": '{"status":"stopped","name":"old"}'}
|
||||
if "FROM snapshots" in sql:
|
||||
return {
|
||||
"state": (
|
||||
@@ -217,3 +219,45 @@ async def test_qemu_worker_snapshot_create_rollback_and_delete_are_persistent()
|
||||
assert any("INSERT INTO snapshots" in command for command in commands)
|
||||
assert any("UPDATE virtual_machines" in command for command in commands)
|
||||
assert any("DELETE FROM snapshots" in command for command in commands)
|
||||
|
||||
|
||||
async def test_qemu_worker_clone_and_migrate_are_persistent() -> None:
|
||||
repository = CrudRepository()
|
||||
handler = qemu_handler(cast(TaskRepository, repository), cast(Clock, ImmediateClock()))
|
||||
resource_id = uuid.uuid4()
|
||||
|
||||
cloned = await handler(
|
||||
Task(
|
||||
uuid.uuid4(),
|
||||
"UPID:clone",
|
||||
"qemu-clone",
|
||||
"running",
|
||||
{
|
||||
"source_resource_id": str(resource_id),
|
||||
"node": "pve1",
|
||||
"vmid": 151,
|
||||
"name": "clone",
|
||||
},
|
||||
0,
|
||||
False,
|
||||
1,
|
||||
)
|
||||
)
|
||||
migrated = await handler(
|
||||
Task(
|
||||
uuid.uuid4(),
|
||||
"UPID:migrate",
|
||||
"qemu-migrate",
|
||||
"running",
|
||||
{"resource_id": str(resource_id), "target": "pve2"},
|
||||
0,
|
||||
False,
|
||||
1,
|
||||
)
|
||||
)
|
||||
|
||||
assert cloned == {"vmid": 151, "node": "pve1"}
|
||||
assert migrated == {"node": "pve2", "status": "stopped"}
|
||||
commands = repository.connection.commands
|
||||
assert any("INSERT INTO resources" in command for command in commands)
|
||||
assert any("node_id=$2" in command for command in commands)
|
||||
|
||||
Reference in New Issue
Block a user