From d97ec5afd2a3e68e958a827db430240a8a947d66 Mon Sep 17 00:00:00 2001 From: catborise Date: Thu, 29 Oct 2026 21:02:59 +0300 Subject: [PATCH] fix: a queued job is shown once, in the job panel Queuing a long operation put "... is being ...; follow it in the job panel." above the page, while the job panel on the same page showed the job and its progress. Every such form returns to a page with the job panel for the job's resource (the VM, the compute's VM list, the pool), and the panel shows a job even when it ends before its first poll. The eight messages are removed: migrate, clone, create, volume clone and the snapshot create, revert and delete jobs. Refusals stay messages. --- instances/tests/test_snapshot_views.py | 2 +- instances/views.py | 23 +++++++---------------- storages/views.py | 1 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/instances/tests/test_snapshot_views.py b/instances/tests/test_snapshot_views.py index dc1ff6b4..cf830830 100644 --- a/instances/tests/test_snapshot_views.py +++ b/instances/tests/test_snapshot_views.py @@ -75,7 +75,7 @@ class SnapshotViewsTestCase(TestCase): op = Operation.objects.get() self.assertEqual((op.kind, op.state, op.params), ("snapshot.delete", Operation.QUEUED, {"instance": self.instance.id, "name": "a"})) - self.assertTrue(any("being deleted" in m for m in messages), messages) + self.assertEqual(messages, []) # the job panel shows it proxy.delete_external_snapshot.assert_not_called() def test_a_refused_delete_becomes_a_message_and_queues_nothing(self): diff --git a/instances/views.py b/instances/views.py index bf913dc3..fcaaba39 100755 --- a/instances/views.py +++ b/instances/views.py @@ -861,7 +861,6 @@ def migrate(request, pk): except (jobs.SubmissionConflict, libvirtError) as err: messages.error(request, error_text(request, err)) else: - messages.info(request, _("The VM is being migrated; follow it in the job panel.")) jobs.remember_job(request, op) return get_safe_redirect(request, default=reverse("instances:instance", args=[pk])) @@ -1527,8 +1526,7 @@ def mount_iso(request, pk): @require_POST def snapshot(request, pk): return _snapshot_job(request, pk, "snapshot.create", - {"name": request.POST.get("name", ""), "description": request.POST.get("description", "")}, - _("The snapshot is being taken; follow it in the job panel.")) + {"name": request.POST.get("name", ""), "description": request.POST.get("description", "")}) @require_POST @@ -1548,8 +1546,7 @@ def delete_snapshot(request, pk): @require_POST def revert_snapshot(request, pk): - return _snapshot_job(request, pk, "snapshot.revert", {"name": request.POST.get("name", "")}, - _("The VM is being reverted; follow it in the job panel.")) + return _snapshot_job(request, pk, "snapshot.revert", {"name": request.POST.get("name", "")}) @require_POST @@ -1557,18 +1554,16 @@ def create_external_snapshot(request, pk): return _snapshot_job(request, pk, "snapshot.create", {"name": request.POST.get("name", ""), "description": request.POST.get("description", ""), "external": True, "memory": request.POST.get("memory") == "on", - "quiesce": request.POST.get("quiesce") == "on"}, - _("The snapshot is being taken; follow it in the job panel.")) + "quiesce": request.POST.get("quiesce") == "on"}) @require_POST def revert_external_snapshot(request, pk): - return _snapshot_job(request, pk, "snapshot.revert", {"name": request.POST.get("name", ""), "external": True}, - _("The VM is being reverted; follow it in the job panel.")) + return _snapshot_job(request, pk, "snapshot.revert", {"name": request.POST.get("name", ""), "external": True}) -def _snapshot_job(request, pk, kind, params, queued): - """Queue a snapshot job on the VM; refusals become messages.""" +def _snapshot_job(request, pk, kind, params): + """Queue a snapshot job on the VM: the job panel shows it; refusals become messages.""" get_instance(request.user, pk, perm_type="change") if not request.user.has_perm("instances.snapshot_instances"): raise PermissionDenied @@ -1581,15 +1576,13 @@ def _snapshot_job(request, pk, kind, params, queued): except libvirtError as err: messages.error(request, error_text(request, err)) else: - messages.info(request, queued) jobs.remember_job(request, op) return _back(request, pk, "managesnapshot") @require_POST def delete_external_snapshot(request, pk): - return _snapshot_job(request, pk, "snapshot.delete", {"name": request.POST.get("name", "")}, - _("The snapshot is being deleted; follow it in the job panel.")) + return _snapshot_job(request, pk, "snapshot.delete", {"name": request.POST.get("name", "")}) @require_POST @@ -2103,7 +2096,6 @@ def clone(request, pk): except (jobs.SubmissionConflict, libvirtError, ValueError) as err: messages.error(request, error_text(request, err)) else: - messages.info(request, _("The clone is being made; follow it in the job panel.")) jobs.remember_job(request, op) return redirect(reverse("instances:instance", args=[pk])) @@ -2446,7 +2438,6 @@ def create_instance(request, compute_id, arch, machine): "Changing machine type from '%s' to 'q35' " "which is required for UEFI secure boot." % machine, ) - messages.info(request, _("The VM is being created; follow it in the job panel.")) jobs.remember_job(request, op) return redirect(reverse("instances", args=[compute.id])) conn.close() diff --git a/storages/views.py b/storages/views.py index eef84bbf..c9749b2a 100644 --- a/storages/views.py +++ b/storages/views.py @@ -193,7 +193,6 @@ def storage(request, compute_id, pool): except (jobs.SubmissionConflict, OperationError, libvirtError) as err: messages.error(request, str(err)) else: - messages.info(request, _("The volume is being cloned; follow it in the job panel.")) jobs.remember_job(request, op) else: for msg_err in form.errors.values():