1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

fix(logs): a row says what happened: a recovered migration, a failed clone step, a device not there

- A migration whose libvirt call failed but which recovery finds moved (or
  cannot tell) gets a row of that end; only a failure already logged by
  migrate_instance is not logged twice.
- A clone made with its resize or start failed, and a recovered migration
  whose autostart or NVRAM step failed, write a failed row of that step, as
  migrate_instance does for its later steps.
- Setting the link state of an interface or the video model of a VM that
  has none is refused: it changed nothing and was logged as done.
- The rows of a removed VM record (deleted or expired) name its host, VM
  and UUID, so the VM's history has them.
This commit is contained in:
catborise 2026-11-07 14:22:47 +03:00
parent 470cc9860e
commit 528b4492f6
14 changed files with 390 additions and 304 deletions

View file

@ -8,6 +8,7 @@ from django.urls import reverse
from django.utils import timezone
from instances.models import InstanceTombstone
from logs.models import Logs
UUID = "00000000-0000-4000-8000-000000000001"
@ -57,3 +58,6 @@ class TombstoneTests(TestCase):
self.assertRedirects(response, reverse("admin:tombstone_list"))
self.assertContains(response, "Removed VM ts-vm deleted")
self.assertFalse(InstanceTombstone.objects.exists())
# the VM's history (found by UUID) has it
self.assertEqual(list(Logs.objects.filter(message__startswith="Removed VM").values_list("host", "instance", "instance_uuid")),
[("ts-host", "ts-vm", UUID)])

View file

@ -343,7 +343,8 @@ def tombstone_list(request):
def tombstone_delete(request, pk):
tombstone = get_object_or_404(InstanceTombstone, pk=pk)
if request.method == "POST":
with audit(request, None, f"Removed VM {tombstone.name} ({tombstone.uuid})", "delete"):
with audit(request, tombstone.host or None, f"Removed VM {tombstone.name} ({tombstone.uuid})", "delete",
instance=tombstone.name, uuid=tombstone.uuid):
tombstone.delete()
messages.success(request, _("Removed VM %(name)s deleted") % {"name": tombstone.name})
return redirect("admin:tombstone_list")

View file

@ -109,7 +109,7 @@ class OwnershipTestCase(TestCase):
self.assertEqual(self.ownership(self.host_a), (False, []))
self.assertFalse(InstanceTombstone.objects.exists())
self.assertIn(("-", "-", f"VM vm ({UUID}): removed record expired"), self.rows())
self.assertIn(("-", "host-a", f"VM vm ({UUID}): removed record expired"), self.rows())
@override_settings(INSTANCE_OWNERSHIP_RETENTION_DAYS=30)
def test_a_removed_record_expires_while_nothing_changes(self):
@ -120,7 +120,9 @@ class OwnershipTestCase(TestCase):
refresh_instance_database(self.host_b) # its VMs match the database
self.assertFalse(InstanceTombstone.objects.exists())
self.assertIn(("-", "-", f"VM vm ({UUID}): removed record expired"), self.rows())
# the VM's history (found by UUID) has it
self.assertTrue(Logs.objects.filter(instance_uuid=UUID, instance="vm", message__endswith="expired").exists())
self.assertIn(("-", "host-a", f"VM vm ({UUID}): removed record expired"), self.rows())
def test_deleted_users_are_skipped(self):
self.owned_vm(self.host_a)

View file

@ -212,7 +212,7 @@ def refresh_instance_database(compute):
# ownership is restored.
expired = InstanceTombstone.objects.filter(removed__lt=cutoff)
for t in expired:
write("-", "-", "", f"VM {t.name} ({t.uuid}): removed record expired", True)
write("-", t.host or "-", t.name, f"VM {t.name} ({t.uuid}): removed record expired", True, uuid=t.uuid)
expired.delete()
for uuid, name in host_domains.items():
if uuid not in db_uuids:

View file

@ -225,6 +225,8 @@ def _finish_clone(op, clone, warning):
proxy.start()
except libvirtError as err:
notes += say(_("The clone is made, but not as asked: %(error)s"), error=err)
write(op.username, c.name, op.intent["name"], f"VM {op.intent['name']}: resize or start the clone: "
f"{safe_text(err)}", False, uuid=op.intent["uuid"])
return {"warning": notes} if notes else {}
@ -966,17 +968,25 @@ def _moved(op, dest):
stopped before it: autostart is per host, and the source keeps the
NVRAM file. The job's result, with a warning for a step that failed."""
notes = []
source, _sep, name = op.resource_label.rpartition("/")
target = Compute.objects.get(pk=op.params["target"]).name
def failed(action, err): # as migrate_instance logs its later steps
write(op.username, source, name, f"VM {name}: {action}: {safe_text(err)}", False, uuid=op.intent["uuid"])
if op.intent.get("autostart"):
try:
dest.setAutostart(1)
except libvirtError as err:
notes += say(_("The VM migrated, but autostart could not be set on the destination: %(error)s"),
error=err)
failed(f"restore autostart on {target}", err)
if nvram := op.intent.get("nvram"):
try:
_connect(op.intent["compute"]).remove_nvram(nvram, _connect(op.params["target"]))
except libvirtError as err:
notes += say(_("The VM migrated, but its NVRAM file stays on the source: %(error)s"), error=err)
failed(f"remove NVRAM file {nvram} on the source", err)
return {"warning": notes} if notes else {}
@ -1034,8 +1044,13 @@ class MigrateInstance(Kind):
try:
utils.migrate_instance(Compute.objects.get(pk=p["target"]), instance, op.user,
disk_pools=p["disk_pools"],
on_moved=lambda: ctx.record_intent(outcome_logged=True),
**{k: p[k] for k in MIGRATE_OPTIONS})
except libvirtError as err:
except Exception as err:
# migrate_instance wrote the error's Logs row; recovery may still find the VM moved
ctx.record_intent(failure_logged=True)
if not isinstance(err, libvirtError):
raise
op.refresh_from_db(fields=["cancel_requested"])
if op.cancel_requested:
raise Cancelled from None
@ -1045,15 +1060,13 @@ class MigrateInstance(Kind):
if isinstance(err, util.OperationError):
raise
raise util.OperationError(str(err)) from err
finally:
# migrate_instance wrote the outcome's Logs row (log_entry)
ctx.record_intent(outcome_logged=True)
return {}
def log_entry(self, op, state):
"""A row for an end migrate_instance did not log: refused before it
ran, cancelled while queued, or ended by recovery."""
if op.intent.get("outcome_logged"):
ran, cancelled while queued, or ended by recovery other than the
failure migrate_instance logged."""
if op.intent.get("outcome_logged") or (op.intent.get("failure_logged") and state == Operation.FAILED):
return None
target = Compute.objects.filter(pk=op.params["target"]).values_list("name", flat=True).first()
return _log(op, state, f"migrate to {target}")

View file

@ -17,6 +17,7 @@ from appsettings.settings import get_settings
from computes.models import Compute
from instances.jobs import CloneInstance
from instances.models import Instance
from logs.models import Logs
from operations.utils import words
from operations.jobs import Cancelled, Context
from vrtManager.util import ConnectionFailed, OperationError
@ -148,6 +149,9 @@ class CloneJobTestCase(TransactionTestCase):
op, result = self.clone_with(**{"clone-start": "true"})
self.assertTrue(Instance.objects.filter(uuid=op.intent["uuid"]).exists())
self.assertIn("The clone is made, but not as asked", words(result["warning"]))
# the job succeeded: Logs has the step that failed too
self.assertTrue(Logs.objects.filter(instance_uuid=op.intent["uuid"], success=False,
message="VM copy: resize or start the clone: no memory").exists())
def queued(self):
self.client.post(reverse("instances:clone", args=[self.source.pk]),

View file

@ -11,6 +11,7 @@ from appsettings.settings import get_settings
from computes.models import Compute
from instances.jobs import MigrateInstance
from instances.models import Instance
from logs.models import Logs
from libvirt import VIR_DOMAIN_XML_INACTIVE, VIR_ERR_SYSTEM_ERROR, VIR_FROM_RPC, libvirtError
from operations.jobs import Cancelled, Context, get_kind
from operations.models import Claim, Operation, acquire
@ -124,6 +125,8 @@ class MigrateJobTestCase(TransactionTestCase):
outcome = MigrateInstance().reconcile(op)
self.assertEqual(outcome.state, Operation.SUCCEEDED)
self.assertIn("autostart could not be set", outcome.result["warning"][0]["text"])
self.assertTrue(Logs.objects.filter(instance_uuid=UUID, success=False,
message="VM mig-vm: restore autostart on mig-dst: refused").exists())
def test_a_copy_claims_its_volume_on_both_computes(self):
Instance.proxy.get_disk_devices.return_value = [
@ -261,8 +264,6 @@ class MigrateJobTestCase(TransactionTestCase):
proxy.return_value.instance.abortJob.assert_not_called()
def test_each_end_of_a_migration_leaves_one_logs_row(self):
from logs.models import Logs
op = self.queue(live_migrate="true")
ctx = self.start(op)
get_kind(op.kind).run(op, ctx) # migrate_instance writes its row
@ -275,6 +276,29 @@ class MigrateJobTestCase(TransactionTestCase):
self.assertEqual(MigrateInstance().log_entry(queued, Operation.CANCELLED),
("mig-src", "mig-vm", UUID, "VM mig-vm: migrate to mig-dst (cancelled)"))
def test_a_failed_migration_recovery_finds_moved_has_a_row_of_that_end(self):
op = self.queue(live_migrate="true")
ctx = self.start(op)
self.dest_conn.moveto.side_effect = libvirtError("connection reset while migrating")
with self.assertRaises(Exception):
get_kind(op.kind).run(op, ctx) # migrate_instance writes the failed row
op.refresh_from_db()
self.assertIsNone(MigrateInstance().log_entry(op, Operation.FAILED)) # that row is the end
for state, message in ((Operation.SUCCEEDED, "VM mig-vm: migrate to mig-dst"),
(Operation.UNCERTAIN, "VM mig-vm: migrate to mig-dst (uncertain)")):
with self.subTest(state):
self.assertEqual(MigrateInstance().log_entry(op, state)[3], message)
def test_a_migration_moved_then_failed_to_record_has_its_row_once(self):
op = self.queue(live_migrate="true")
ctx = self.start(op)
with patch("instances.utils.record_migration", side_effect=RuntimeError("database locked")), \
self.assertRaises(RuntimeError):
get_kind(op.kind).run(op, ctx) # the migration's row, then the failed record's
op.refresh_from_db()
self.assertIsNone(MigrateInstance().log_entry(op, Operation.SUCCEEDED)) # recovery finds it moved
self.assertEqual(Logs.objects.filter(instance_uuid=UUID, message__startswith="VM mig-vm: migrate (").count(), 1)
def test_recording_a_migration_holds_the_ownership_lock(self):
# a sync of a third compute must not move the owners at the same time
from instances import utils

View file

@ -214,13 +214,14 @@ def migrate_instance(
compress=False,
delete_source=False,
disk_pools=None,
on_moved=None,
):
"""Migrates instance to new_compute and logs the outcome (the mode
used, or the error), then each later step that failed in a row of its
own. disk_pools: {target: pool} of the disks copied into pools of
new_compute (moveto's pools); their source files go with delete_source
unless another VM or volume uses them, and are named in the log
otherwise. Returns the mode."""
own; on_moved is called once the outcome's row is written. disk_pools:
{target: pool} of the disks copied into pools of new_compute (moveto's
pools); their source files go with delete_source unless another VM or
volume uses them, and are named in the log otherwise. Returns the mode."""
source, target = instance.compute, migration_target(new_compute)
def log(action, error=None):
@ -259,6 +260,8 @@ def migrate_instance(
# The VM runs on new_compute now: what follows must not stop it
# from being recorded there.
log(f"migrate ({mode}) to {target}")
if on_moved is not None: # its row is written: a later step that raises does not undo it
on_moved()
if autostart:
conn_new = None
try:

Binary file not shown.

View file

@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-11-06 21:10+0000\n"
"POT-Creation-Date: 2026-11-07 11:22+0000\n"
"PO-Revision-Date: 2020-11-04 12:00+0000\n"
"Last-Translator: catborise <muhammetalisag@gmail.com>, 2020\n"
"Language-Team: Turkish (https://www.transifex.com/catborise/teams/110663/tr/)\n"
@ -21,7 +21,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: accounts/auth.py:22
#: accounts/auth.py:22 accounts/middleware.py:28
msgid "Change your password before using the API."
msgstr "API'yi kullanmadan önce parolanızı değiştirin."
@ -1157,12 +1157,12 @@ msgstr ""
msgid "deleted user"
msgstr "silinmiş kullanıcı"
#: admin/views.py:348
#: admin/views.py:349
#, python-format
msgid "Removed VM %(name)s deleted"
msgstr "Kaldırılan sanal makine %(name)s silindi"
#: admin/views.py:355
#: admin/views.py:356
msgid "Its owners no longer get the VM back if its UUID shows up again."
msgstr ""
"UUID'si yeniden görünse bile sahipleri sanal makineyi artık geri almaz."
@ -2750,7 +2750,7 @@ msgstr "Klonun adını boş adlar listesinden seçin"
msgid "%(quota)s: cannot create '%(clone_name)s'."
msgstr "%(quota)s: '%(clone_name)s' oluşturulamıyor."
#: instances/jobs.py:200 instances/jobs.py:552
#: instances/jobs.py:200 instances/jobs.py:554
#, python-format
msgid "Instance '%(clone_name)s' already exists!"
msgstr "'%(clone_name)s' sanal makinesi zaten mevcut!"
@ -2775,11 +2775,11 @@ msgstr "Disk adı '%(disk_name)s' geçersiz karakterler içeriyor!"
msgid "The clone is made, but not as asked: %(error)s"
msgstr "Klon oluşturuldu, ama istendiği gibi değil: %(error)s"
#: instances/jobs.py:283
#: instances/jobs.py:285
msgid "The VM was not defined and no volume of it was left."
msgstr "Sanal makine tanımlanmadı ve ondan geriye birim kalmadı."
#: instances/jobs.py:285
#: instances/jobs.py:287
#, python-format
msgid ""
"The VM was not defined; check these volumes, then resolve this job: "
@ -2788,28 +2788,28 @@ msgstr ""
"Sanal makine tanımlanmadı; şu birimleri kontrol edin, sonra bu işi çözün: "
"%(volumes)s"
#: instances/jobs.py:306
#: instances/jobs.py:308
msgid "Delete snapshot"
msgstr "Anlık görüntüyü sil"
#: instances/jobs.py:316 vrtManager/instance.py:2287
#: instances/jobs.py:318 vrtManager/instance.py:2288
#, python-format
msgid "The VM has no external snapshot named %(name)s"
msgstr "Sanal makinede %(name)s adında harici anlık görüntü yok"
#: instances/jobs.py:329
#: instances/jobs.py:331
msgid "Merging the snapshot"
msgstr "Anlık görüntü birleştiriliyor"
#: instances/jobs.py:348
#: instances/jobs.py:350
msgid "The VM is no longer on its compute"
msgstr "Sanal makine artık kendi sunucusunda değil"
#: instances/jobs.py:351
#: instances/jobs.py:353
msgid "libvirt is still merging the snapshot"
msgstr "libvirt anlık görüntüyü hâlâ birleştiriyor"
#: instances/jobs.py:359
#: instances/jobs.py:361
msgid ""
"The snapshot is still listed and no merge runs. It cannot be told whether the"
" disks changed; check the VM before deleting the snapshot again or reverting "
@ -2819,44 +2819,44 @@ msgstr ""
"değişmediği bilinemiyor; anlık görüntüyü yeniden silmeden ya da ona dönmeden "
"önce sanal makineyi kontrol edin."
#: instances/jobs.py:366
#: instances/jobs.py:368
msgid "The VM is no longer on the compute the job ran on"
msgstr "Sanal makine artık işin çalıştığı sunucuda değil"
#: instances/jobs.py:372
#: instances/jobs.py:374
msgid "Take snapshot"
msgstr "Anlık görüntü al"
#: instances/jobs.py:384 instances/jobs.py:393 vrtManager/instance.py:1883
#: instances/jobs.py:386 instances/jobs.py:395 vrtManager/instance.py:1884
#, python-format
msgid "A snapshot named %(name)s already exists"
msgstr "%(name)s adında bir anlık görüntü zaten var"
#: instances/jobs.py:399
#: instances/jobs.py:401
msgid "Taking the snapshot"
msgstr "Anlık görüntü alınıyor"
#: instances/jobs.py:412
#: instances/jobs.py:414
msgid "libvirt is still taking the snapshot"
msgstr "libvirt anlık görüntüyü hâlâ alıyor"
#: instances/jobs.py:415
#: instances/jobs.py:417
msgid "The snapshot was not taken"
msgstr "Anlık görüntü alınmadı"
#: instances/jobs.py:438
#: instances/jobs.py:440
msgid "Revert snapshot"
msgstr "Snapshota dön"
#: instances/jobs.py:469
#: instances/jobs.py:471
msgid "Reverting the VM"
msgstr "Sanal makine geri döndürülüyor"
#: instances/jobs.py:480
#: instances/jobs.py:482
msgid "libvirt is still reverting the VM"
msgstr "libvirt sanal makineyi hâlâ geri döndürüyor"
#: instances/jobs.py:484
#: instances/jobs.py:486
msgid ""
"It cannot be told whether the VM was reverted; check it, then revert again or"
" resolve this job."
@ -2864,12 +2864,12 @@ msgstr ""
"Sanal makinenin geri döndürülüp döndürülmediği bilinemiyor; kontrol edin, "
"sonra yeniden geri döndürün ya da bu işi çözün."
#: instances/jobs.py:501
#: instances/jobs.py:503
msgid "The VM must be running, paused or shut off to be cloned"
msgstr ""
"Klonlanmak için sanal makine çalışıyor, duraklatılmış ya da kapalı olmalı"
#: instances/jobs.py:502
#: instances/jobs.py:504
#, python-format
msgid ""
"The guest's file systems could not be thawed (%(error)s); thaw them with: "
@ -2878,19 +2878,19 @@ msgstr ""
"Konuğun dosya sistemleri çözülemedi (%(error)s); şununla çözün: virsh "
"domfsthaw %(vm)s"
#: instances/jobs.py:521
#: instances/jobs.py:523
msgid "Clone VM"
msgstr "Sanal makineyi klonla"
#: instances/jobs.py:562 instances/jobs.py:569 instances/jobs.py:847
#: instances/jobs.py:564 instances/jobs.py:571 instances/jobs.py:849
msgid "Copying disks"
msgstr "Diskler kopyalanıyor"
#: instances/jobs.py:621
#: instances/jobs.py:623
msgid "libvirt has no result of the copy"
msgstr "libvirt'te kopyanın sonucu yok"
#: instances/jobs.py:632
#: instances/jobs.py:634
#, python-format
msgid ""
"The copy failed: %(error)s. The guest's file systems could not be thawed "
@ -2899,11 +2899,11 @@ msgstr ""
"Kopyalama başarısız oldu: %(error)s. Konuğun dosya sistemleri çözülemedi "
"(%(thaw)s); şununla çözün: virsh domfsthaw %(vm)s"
#: instances/jobs.py:635 instances/jobs.py:722
#: instances/jobs.py:637 instances/jobs.py:724
msgid "The copy failed"
msgstr "Kopyalama başarısız oldu"
#: instances/jobs.py:660
#: instances/jobs.py:662
#, python-format
msgid ""
"The VM is no longer on the compute the job ran on; check these volumes, then "
@ -2912,7 +2912,7 @@ msgstr ""
"Sanal makine artık işin çalıştığı sunucuda değil; şu birimleri kontrol edin, "
"sonra bu işi çözün: %(volumes)s"
#: instances/jobs.py:698
#: instances/jobs.py:700
#, python-format
msgid ""
"A volume of the clone was being created; check these volumes, then resolve "
@ -2921,15 +2921,15 @@ msgstr ""
"Klonun bir birimi oluşturuluyordu; şu birimleri kontrol edin, sonra bu işi "
"çözün: %(volumes)s"
#: instances/jobs.py:702
#: instances/jobs.py:704
msgid "The job stopped before the copy started"
msgstr "İş, kopyalama başlamadan durdu"
#: instances/jobs.py:709
#: instances/jobs.py:711
msgid "libvirt is still copying the disks"
msgstr "libvirt diskleri hâlâ kopyalıyor"
#: instances/jobs.py:712
#: instances/jobs.py:714
#, python-format
msgid ""
"Another backup runs on the VM; check these volumes, then resolve this job: "
@ -2938,7 +2938,7 @@ msgstr ""
"Sanal makinede başka bir yedekleme çalışıyor; şu birimleri kontrol edin, "
"sonra bu işi çözün: %(volumes)s"
#: instances/jobs.py:717
#: instances/jobs.py:719
#, python-format
msgid ""
"libvirt has no result of the copy; check these volumes, then resolve this "
@ -2947,7 +2947,7 @@ msgstr ""
"libvirt'te kopyanın sonucu yok; şu birimleri kontrol edin, sonra bu işi "
"çözün: %(volumes)s"
#: instances/jobs.py:729
#: instances/jobs.py:731
#, python-format
msgid ""
"The disks were copied, but the clone could not be defined: %(error)s; check "
@ -2956,74 +2956,74 @@ msgstr ""
"Diskler kopyalandı, ancak klon tanımlanamadı: %(error)s; şu birimleri kontrol"
" edin, sonra bu işi çözün: %(volumes)s"
#: instances/jobs.py:752 instances/templates/create_instance_w1.html:60
#: instances/jobs.py:754 instances/templates/create_instance_w1.html:60
#: instances/templates/create_instance_w2.html:356
msgid "Create VM"
msgstr "Sanal makine oluştur"
#: instances/jobs.py:776 instances/jobs.py:821 instances/views.py:2463
#: instances/jobs.py:778 instances/jobs.py:823 instances/views.py:2463
msgid "A virtual machine with this name already exists"
msgstr "Bu isimde bir sanal makine mevcut"
#: instances/jobs.py:778 instances/jobs.py:818
#: instances/jobs.py:780 instances/jobs.py:820
msgid "There is an instance with same name. Remove it and try again!"
msgstr "Aynı isimde başka bir sanal makine var. Onu silip yeniden deneyin!"
#: instances/jobs.py:781
#: instances/jobs.py:783
msgid "First you need to create or select an image"
msgstr "Öncelikle bir imaj oluşturun ya da mevcut bir imajı seçin"
#: instances/jobs.py:783
#: instances/jobs.py:785
msgid "Choose one disk source: a new disk, existing volumes or a template"
msgstr ""
"Tek bir disk kaynağı seçin: yeni bir disk, mevcut birimler ya da bir şablon"
#: instances/jobs.py:785
#: instances/jobs.py:787
msgid "Image has already exist. Please check volumes or change instance name"
msgstr ""
"İmaj zaten mevcut. Lütfen ya makine adını değişin ya da disk alanlarını "
"kontrol edin"
#: instances/jobs.py:787
#: instances/jobs.py:789
msgid "Invalid cache mode"
msgstr "Geçersiz önbellek modu"
#: instances/jobs.py:789
#: instances/jobs.py:791
#, python-format
msgid "This host offers no CPU mode or model %(mode)s"
msgstr "Bu sunucu %(mode)s CPU modunu veya modelini sunmuyor"
#: instances/jobs.py:791
#: instances/jobs.py:793
#, python-format
msgid "A CD-ROM cannot use the %(bus)s bus"
msgstr "CD-ROM %(bus)s veri yolunu kullanamaz"
#: instances/jobs.py:794
#: instances/jobs.py:796
msgid "The cloud-init seed is read from a CD-ROM: choose its bus"
msgstr "cloud-init tohumu bir CD-ROM'dan okunur: veri yolunu seçin"
#: instances/jobs.py:797
#: instances/jobs.py:799
msgid "The cloud-init seed needs a directory storage pool for the disk"
msgstr "cloud-init tohumu, disk için bir dizin depolama havuzu gerektirir"
#: instances/jobs.py:803
#: instances/jobs.py:805
#, python-format
msgid "This host offers no firmware %(firmware)s"
msgstr "Bu sunucu %(firmware)s firmware'ini sunmuyor"
#: instances/jobs.py:805 vrtManager/instance.py:3015
#: instances/jobs.py:807 vrtManager/instance.py:3020
msgid "This host offers no TPM 2.0: install swtpm on it"
msgstr "Bu sunucu TPM 2.0 sunmuyor: üzerine swtpm kurun"
#: instances/jobs.py:866
#: instances/jobs.py:868
msgid "Writing the cloud-init seed"
msgstr "cloud-init tohumu yazılıyor"
#: instances/jobs.py:873
#: instances/jobs.py:875
msgid "Defining the VM"
msgstr "Sanal makine tanımlanıyor"
#: instances/jobs.py:906
#: instances/jobs.py:908
#, python-format
msgid ""
"The panel failed unexpectedly; its log has the details. Remove these volumes "
@ -3032,114 +3032,114 @@ msgstr ""
"Panel beklenmedik bir hatayla karşılaştı; ayrıntılar panelin günlüğünde. Bu "
"birimleri elle kaldırın: %(volumes)s"
#: instances/jobs.py:910
#: instances/jobs.py:912
#, python-format
msgid "%(error)s. Remove these volumes by hand: %(volumes)s"
msgstr "%(error)s. Şu birimleri elle silin: %(volumes)s"
#: instances/jobs.py:935
#: instances/jobs.py:937
#, python-format
msgid "The instance is already on %(compute)s"
msgstr "Sanal makine zaten %(compute)s üzerinde"
#: instances/jobs.py:937
#: instances/jobs.py:939
#, python-format
msgid "%(compute)s is not reachable"
msgstr "%(compute)s sunucusuna ulaşılamıyor"
#: instances/jobs.py:939
#: instances/jobs.py:941
#, python-format
msgid "%(compute)s is the VM's own host under another name"
msgstr "%(compute)s, sanal makinenin kendi sunucusunun başka bir adı"
#: instances/jobs.py:973
#: instances/jobs.py:981
#, python-format
msgid ""
"The VM migrated, but autostart could not be set on the destination: %(error)s"
msgstr ""
"Sanal makine taşındı, ancak hedefte otomatik başlatma ayarlanamadı: %(error)s"
#: instances/jobs.py:979
#: instances/jobs.py:988
#, python-format
msgid "The VM migrated, but its NVRAM file stays on the source: %(error)s"
msgstr "Sanal makine taşındı, ancak NVRAM dosyası kaynakta kaldı: %(error)s"
#: instances/jobs.py:986
#: instances/jobs.py:996
msgid "Migrate VM"
msgstr "Sanal makineyi taşı"
#: instances/jobs.py:1033
#: instances/jobs.py:1043
msgid "Migrating the VM"
msgstr "Sanal makine taşınıyor"
#: instances/jobs.py:1080
#: instances/jobs.py:1094
msgid "libvirt is still migrating the VM"
msgstr "libvirt sanal makineyi hâlâ taşıyor"
#: instances/jobs.py:1091
#: instances/jobs.py:1105
msgid "The VM stayed on the source host"
msgstr "Sanal makine kaynak sunucuda kaldı"
#: instances/jobs.py:1093
#: instances/jobs.py:1107
msgid ""
"The VM is on both computes or on neither; check them, then resolve this job."
msgstr ""
"Sanal makine ya iki sunucuda da var ya da hiçbirinde yok; kontrol edin, sonra"
" bu işi çözün."
#: instances/jobs.py:1141
#: instances/jobs.py:1155
msgid "Move disk"
msgstr "Diski taşı"
#: instances/jobs.py:1148
#: instances/jobs.py:1162
msgid "Choose a disk of the VM"
msgstr "Sanal makinenin bir diskini seçin"
#: instances/jobs.py:1172
#: instances/jobs.py:1186
msgid "Copying the disk"
msgstr "Disk kopyalanıyor"
#: instances/jobs.py:1215
#: instances/jobs.py:1229
#, python-format
msgid "Another block job runs on %(dev)s; check the VM"
msgstr ""
"%(dev)s üzerinde başka bir blok işi çalışıyor; sanal makineyi kontrol edin"
#: instances/jobs.py:1221
#: instances/jobs.py:1235
#, python-format
msgid "The disk stayed in %(path)s; remove %(dest)s if it is there"
msgstr "Disk %(path)s içinde kaldı; varsa %(dest)s dosyasını silin"
#: instances/jobs.py:1223
#: instances/jobs.py:1237
#, python-format
msgid "The definitions of %(dev)s name %(paths)s; check the VM"
msgstr "%(dev)s tanımları %(paths)s gösteriyor; sanal makineyi kontrol edin"
#: instances/jobs.py:1230
#: instances/jobs.py:1244
#, python-format
msgid "Disk %(path)s was kept: a disk file that stays needs it"
msgstr "%(path)s diski korundu: kalan bir disk dosyası ona ihtiyaç duyuyor"
#: instances/jobs.py:1231
#: instances/jobs.py:1245
#, python-format
msgid "The VM is removed, but disk %(path)s was not deleted: %(err)s"
msgstr "Sanal makine kaldırıldı, ancak %(path)s diski silinmedi: %(err)s"
#: instances/jobs.py:1232
#: instances/jobs.py:1246
#, python-format
msgid "Disk %(path)s is used by another VM and was kept"
msgstr ""
"%(path)s diski başka bir sanal makine tarafından kullanılıyor ve korundu"
#: instances/jobs.py:1286
#: instances/jobs.py:1300
msgid "Delete VM"
msgstr "Sanal makineyi sil"
#: instances/jobs.py:1316
#: instances/jobs.py:1330
msgid "Deleting the VM"
msgstr "Sanal makine siliniyor"
#: instances/jobs.py:1328
#: instances/jobs.py:1342
msgid "The VM was not deleted; it may have been shut off"
msgstr "Sanal makine silinmedi; kapatılmış olabilir"
@ -6351,7 +6351,7 @@ msgstr "%(quota)s: '%(instance_name)s' şablon olarak kalıyor."
msgid "The XML has no name"
msgstr "XML'de ad yok"
#: instances/views.py:2475 webvirtcloud/middleware.py:126
#: instances/views.py:2475 webvirtcloud/middleware.py:151
#, python-format
msgid "libvirt Error - %(exception)s"
msgstr "libvirt Hatası - %(exception)s"
@ -7937,7 +7937,8 @@ msgstr ""
msgid "The worker stopped before the job changed anything"
msgstr "Worker, iş herhangi bir şeyi değiştirmeden önce durdu"
#: storages/api/viewsets.py:203 storages/api/viewsets.py:224
#: storages/api/viewsets.py:147 storages/api/viewsets.py:164
#: storages/api/viewsets.py:202 storages/api/viewsets.py:223
msgid "Pool is not active"
msgstr "Havuz etkin değil"
@ -8883,7 +8884,6 @@ msgstr "Bağlantı başarısız: %(host)s bağlı değil"
#: vrtManager/connection.py:502
#, python-format
#| msgid "This host has no secrets."
msgid "This host has no architecture %(arch)s"
msgstr "Bu sunucuda %(arch)s mimarisi yok"
@ -9108,56 +9108,60 @@ msgid "Please shutdown the instance then try to enable vCPU hotplug"
msgstr ""
"vCPU hotplug özelliğini etkinleştirmek için önce sanal makineyi kapatın"
#: vrtManager/instance.py:1842
#: vrtManager/instance.py:1669
msgid "The VM has no video card"
msgstr "Sanal makinede ekran kartı yok"
#: vrtManager/instance.py:1843
msgid ""
"The VM has external snapshots; internal snapshots cannot be mixed with them"
msgstr ""
"Sanal makinenin harici anlık görüntüleri var; dahili anlık görüntüler "
"bunlarla karıştırılamaz"
#: vrtManager/instance.py:1874
#: vrtManager/instance.py:1875
msgid "A snapshot with memory is not quiesced; it keeps the whole guest state"
msgstr ""
"Bellekli bir anlık görüntüde dosya sistemleri dondurulmaz; tüm konuk durumunu"
" saklar"
#: vrtManager/instance.py:1876
#: vrtManager/instance.py:1877
msgid "Only a running VM's file systems can be frozen"
msgstr "Yalnızca çalışan bir sanal makinenin dosya sistemleri dondurulabilir"
#: vrtManager/instance.py:1878
#: vrtManager/instance.py:1879
msgid "The QEMU guest agent is not connected; it freezes the file systems"
msgstr "QEMU konuk aracısı bağlı değil; dosya sistemlerini o dondurur"
#: vrtManager/instance.py:1881
#: vrtManager/instance.py:1882
msgid ""
"The VM has internal snapshots; external snapshots cannot be mixed with them"
msgstr ""
"Sanal makinenin dahili anlık görüntüleri var; harici anlık görüntüler "
"bunlarla karıştırılamaz"
#: vrtManager/instance.py:1886
#: vrtManager/instance.py:1887
msgid "Newer snapshots exist after the last revert; delete them first"
msgstr ""
"Son geri dönüşten sonra daha yeni anlık görüntüler var; önce onları silin"
#: vrtManager/instance.py:1889
#: vrtManager/instance.py:1890
msgid "No snapshot is current; revert to a snapshot first"
msgstr "Geçerli anlık görüntü yok; önce bir anlık görüntüye geri dönün"
#: vrtManager/instance.py:1895
#: vrtManager/instance.py:1896
#, python-format
msgid "Eject the media from %(dev)s first"
msgstr "Önce %(dev)s içindeki ortamı çıkarın"
#: vrtManager/instance.py:1897
#: vrtManager/instance.py:1898
#, python-format
msgid "Disk %(dev)s is not a file; external snapshots need file disks"
msgstr ""
"Disk %(dev)s bir dosya değil; harici anlık görüntüler dosya diskleri "
"gerektirir"
#: vrtManager/instance.py:1905
#: vrtManager/instance.py:1906
#, python-format
msgid ""
"The storage pools could not be refreshed, so their free space is unknown: "
@ -9165,21 +9169,21 @@ msgid ""
msgstr ""
"Depolama havuzları yenilenemedi, bu yüzden boş alanları bilinmiyor: %(err)s"
#: vrtManager/instance.py:1926
#: vrtManager/instance.py:1927
msgid "Memory is saved only from a running VM"
msgstr "Bellek yalnızca çalışan bir sanal makineden kaydedilir"
#: vrtManager/instance.py:1928
#: vrtManager/instance.py:1929
msgid "The VM has no disk to keep its memory next to"
msgstr "Sanal makinenin, belleğinin yanına kaydedileceği bir diski yok"
#: vrtManager/instance.py:1932
#: vrtManager/instance.py:1933
#, python-format
msgid "%(disk)s is not in a storage pool; memory is saved only into one"
msgstr ""
"%(disk)s bir depolama havuzunda değil; bellek yalnızca bir havuza kaydedilir"
#: vrtManager/instance.py:1963
#: vrtManager/instance.py:1964
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the snapshot needs %(size).1f "
@ -9190,7 +9194,7 @@ msgstr ""
"%(size).1f GiB gerektiriyor (sanal makinenin oradaki disklerinin "
"%%%(percent)g kadarı, en az %(minimum)g GiB, ve kaydediliyorsa bellek)"
#: vrtManager/instance.py:1981
#: vrtManager/instance.py:1982
msgid ""
"This snapshot was taken by an older version on a UEFI VM and cannot be "
"reverted; delete it instead"
@ -9198,7 +9202,7 @@ msgstr ""
"Bu anlık görüntü UEFI bir sanal makinede eski bir sürümle alındı ve geri "
"dönülemez; bunun yerine silin"
#: vrtManager/instance.py:2011
#: vrtManager/instance.py:2012
#, python-format
msgid ""
"The revert failed twice; try again in a moment (%(error)s). The VM is "
@ -9207,7 +9211,7 @@ msgstr ""
"Geri dönüş iki kez başarısız oldu; biraz sonra tekrar deneyin (%(error)s). "
"Sanal makine çalışıyor."
#: vrtManager/instance.py:2013
#: vrtManager/instance.py:2014
#, python-format
msgid ""
"The revert failed twice; try again in a moment (%(error)s). The VM is shut "
@ -9216,13 +9220,13 @@ msgstr ""
"Geri dönüş iki kez başarısız oldu; biraz sonra tekrar deneyin (%(error)s). "
"Sanal makine kapalı."
#: vrtManager/instance.py:2176
#: vrtManager/instance.py:2177
msgid "A disk moves when its VM is defined and running, paused or shut off"
msgstr ""
"Bir disk, sanal makinesi tanımlıyken ve çalışırken, duraklatılmışken veya "
"kapalıyken taşınır"
#: vrtManager/instance.py:2178
#: vrtManager/instance.py:2179
msgid ""
"A disk of a VM with snapshots, a saved state or a running block job does not "
"move"
@ -9230,7 +9234,7 @@ msgstr ""
"Anlık görüntüleri, kaydedilmiş durumu veya çalışan bir blok işi olan sanal "
"makinenin diski taşınmaz"
#: vrtManager/instance.py:2186
#: vrtManager/instance.py:2187
#, python-format
msgid ""
"%(dev)s is not a disk file of the VM, the same in its running and next "
@ -9239,132 +9243,132 @@ msgstr ""
"%(dev)s, sanal makinenin çalışan ve sonraki başlatma tanımlarında aynı olan "
"bir disk dosyası değil"
#: vrtManager/instance.py:2191
#: vrtManager/instance.py:2192
#, python-format
msgid "%(dev)s does not move: only writable raw and qcow2 disks do"
msgstr "%(dev)s taşınmaz: yalnızca yazılabilir raw ve qcow2 diskler taşınır"
#: vrtManager/instance.py:2198
#: vrtManager/instance.py:2199
#, python-format
msgid "%(dev)s does not move: no storage pool has %(path)s"
msgstr "%(dev)s taşınmaz: hiçbir depolama havuzunda %(path)s yok"
#: vrtManager/instance.py:2200
#: vrtManager/instance.py:2201
#, python-format
msgid "%(dev)s does not move: it has a backing file"
msgstr "%(dev)s taşınmaz: temel (backing) dosyası var"
#: vrtManager/instance.py:2203
#: vrtManager/instance.py:2204
#, python-format
msgid "%(pool_name)s is not an active pool of disk files of this host"
msgstr "%(pool_name)s bu sunucunun etkin bir disk dosyası havuzu değil"
#: vrtManager/instance.py:2206
#: vrtManager/instance.py:2207
#, python-format
msgid "%(dev)s is in pool %(pool_name)s already"
msgstr "%(dev)s zaten %(pool_name)s havuzunda"
#: vrtManager/instance.py:2210
#: vrtManager/instance.py:2211
#, python-format
msgid "Pool %(pool_name)s already has a file %(name)s"
msgstr "%(pool_name)s havuzunda zaten %(name)s dosyası var"
#: vrtManager/instance.py:2234
#: vrtManager/instance.py:2235
#, python-format
msgid "The copy of %(dev)s ended before it was complete"
msgstr "%(dev)s kopyası tamamlanmadan sona erdi"
#: vrtManager/instance.py:2279
#: vrtManager/instance.py:2280
#, python-format
msgid "%(error)s; remove %(dest)s if it is there: %(cleanup_error)s"
msgstr "%(error)s; varsa %(dest)s dosyasını kaldırın: %(cleanup_error)s"
#: vrtManager/instance.py:2281
#: vrtManager/instance.py:2282
#, python-format
msgid "%(error)s; the VM may use %(dest)s now: check its disk %(dev)s"
msgstr ""
"%(error)s; sanal makine şu anda %(dest)s dosyasını kullanıyor olabilir: "
"%(dev)s diskini kontrol edin"
#: vrtManager/instance.py:2288
#: vrtManager/instance.py:2289
#, python-format
msgid "The VM has no internal snapshot named %(name)s"
msgstr "Sanal makinenin %(name)s adlı dahili anlık görüntüsü yok"
#: vrtManager/instance.py:2297
#: vrtManager/instance.py:2298
msgid "The VM has a saved state; start it or remove the saved state first"
msgstr ""
"Sanal makinenin kaydedilmiş durumu var; önce başlatın veya kaydedilmiş durumu"
" kaldırın"
#: vrtManager/instance.py:2299
#: vrtManager/instance.py:2300
msgid "A snapshot job is still running on this VM; try again when it ends"
msgstr ""
"Bu sanal makinede hâlâ bir anlık görüntü işi çalışıyor; bittiğinde tekrar "
"deneyin"
#: vrtManager/instance.py:2309
#: vrtManager/instance.py:2310
msgid "Shut the VM down to revert to an internal snapshot"
msgstr "Dahili bir anlık görüntüye geri dönmek için sanal makineyi kapatın"
#: vrtManager/instance.py:2407
#: vrtManager/instance.py:2408
msgid "Cannot clone a VM whose NVRAM is not a file"
msgstr "NVRAM'i dosya olmayan bir sanal makine klonlanamaz"
#: vrtManager/instance.py:2475
#: vrtManager/instance.py:2476
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(path)s"
msgstr ""
"Klonlama başarısız oldu (%(err)s); bu kopyaları elle kaldırın: %(path)s"
#: vrtManager/instance.py:2485
#: vrtManager/instance.py:2486
msgid "Shut the VM down before cloning it"
msgstr "Klonlamadan önce sanal makineyi kapatın"
#: vrtManager/instance.py:2539
#: vrtManager/instance.py:2540
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(leftovers)s"
msgstr ""
"Klonlama başarısız oldu (%(err)s); bu kopyaları elle kaldırın: %(leftovers)s"
#: vrtManager/instance.py:2550
#: vrtManager/instance.py:2551
msgid "Live clone needs libvirt 11.10 or later; shut the VM down to clone it"
msgstr ""
"Canlı klonlama libvirt 11.10 veya sonrasını gerektirir; klonlamak için sanal "
"makineyi kapatın"
#: vrtManager/instance.py:2553
#: vrtManager/instance.py:2554
msgid "A VM with a TPM is cloned only shut down"
msgstr "TPM'i olan bir sanal makine yalnızca kapalıyken klonlanır"
#: vrtManager/instance.py:2556
#: vrtManager/instance.py:2557
#, python-format
msgid "Disk %(dev)s is not a local file; shut the VM down to clone it"
msgstr ""
"Disk %(dev)s yerel bir dosya değil; klonlamak için sanal makineyi kapatın"
#: vrtManager/instance.py:2558
#: vrtManager/instance.py:2559
#, python-format
msgid "Disk %(dev)s is shareable; shut the VM down to clone it"
msgstr "Disk %(dev)s paylaşılabilir; klonlamak için sanal makineyi kapatın"
#: vrtManager/instance.py:2563
#: vrtManager/instance.py:2564
#, python-format
msgid "Disk %(dev)s changes at the next start; shut the VM down to clone it"
msgstr ""
"Disk %(dev)s sonraki başlatmada değişiyor; klonlamak için sanal makineyi "
"kapatın"
#: vrtManager/instance.py:2565
#: vrtManager/instance.py:2566
msgid "Another job is running on the VM; clone it when that ends"
msgstr "Sanal makinede başka bir iş çalışıyor; o bittiğinde klonlayın"
#: vrtManager/instance.py:2578
#: vrtManager/instance.py:2579
#, python-format
msgid "Volume %(name)s already exists in storage pool %(pool)s"
msgstr "%(name)s birimi %(pool)s depolama havuzunda zaten var"
#: vrtManager/instance.py:2597
#: vrtManager/instance.py:2598
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the clone needs %(size).1f GiB"
@ -9374,20 +9378,20 @@ msgstr ""
"gerektiriyor (kopyalanan diskler, artı bunların %%%(percent)g kadarı, en az "
"%(minimum)g GiB)"
#: vrtManager/instance.py:2736
#: vrtManager/instance.py:2737
msgid "A network interface that is a host device is removed in the XML editor"
msgstr "Sunucu aygıtı olan bir ağ arabirimi XML düzenleyicide kaldırılır"
#: vrtManager/instance.py:2752
#: vrtManager/instance.py:2753
#, python-format
msgid "No network interface with MAC %(old_mac)s"
msgstr "MAC adresi %(old_mac)s olan ağ arabirimi yok"
#: vrtManager/instance.py:2755
#: vrtManager/instance.py:2756
msgid "A network interface that is a host device is changed in the XML editor"
msgstr "Sunucu aygıtı olan bir ağ arabirimi XML düzenleyicide değiştirilir"
#: vrtManager/instance.py:2846
#: vrtManager/instance.py:2847
msgid ""
"A VM changes its PCI devices while it runs, or is shut off without a saved "
"state"
@ -9395,14 +9399,14 @@ msgstr ""
"Sanal makine PCI aygıtlarını çalışırken veya kaydedilmiş durumu olmadan "
"kapalıyken değiştirir"
#: vrtManager/instance.py:2858
#: vrtManager/instance.py:2859
#, python-format
msgid "%(err)s; whether the VM has PCI device %(address)s now is not known"
msgstr ""
"%(err)s; sanal makinede şu anda %(address)s PCI aygıtının olup olmadığı "
"bilinmiyor"
#: vrtManager/instance.py:2860
#: vrtManager/instance.py:2861
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start has it"
@ -9410,7 +9414,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: sanal makine çalışmıyor, sonraki başlatmada "
"var"
#: vrtManager/instance.py:2862
#: vrtManager/instance.py:2863
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start does "
@ -9419,7 +9423,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: sanal makine çalışmıyor, sonraki başlatmada "
"yok"
#: vrtManager/instance.py:2863
#: vrtManager/instance.py:2864
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start has it"
@ -9427,7 +9431,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede var, sonraki "
"başlatmada var"
#: vrtManager/instance.py:2865
#: vrtManager/instance.py:2866
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start does "
@ -9436,7 +9440,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede var, sonraki "
"başlatmada yok"
#: vrtManager/instance.py:2867
#: vrtManager/instance.py:2868
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
@ -9445,7 +9449,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede yok, sonraki "
"başlatmada var"
#: vrtManager/instance.py:2869
#: vrtManager/instance.py:2870
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
@ -9454,29 +9458,34 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede yok, sonraki "
"başlatmada yok"
#: vrtManager/instance.py:2903
#: vrtManager/instance.py:2904
#, python-format
msgid "The VM has no PCI device %(address)s"
msgstr "Sanal makinede %(address)s PCI aygıtı yok"
#: vrtManager/instance.py:2921
#: vrtManager/instance.py:2922
msgid "The VM has no USB controller"
msgstr "Sanal makinede USB denetleyicisi yok"
#: vrtManager/instance.py:2940
#: vrtManager/instance.py:2941
msgid "The VM has no such USB device"
msgstr "Sanal makinede böyle bir USB aygıtı yok"
#: vrtManager/instance.py:2981
#: vrtManager/instance.py:2955
#, python-format
msgid "The VM has no network interface %(mac)s"
msgstr "Sanal makinede %(mac)s ağ arabirimi yok"
#: vrtManager/instance.py:2986
msgid "The VM has its own RNG device: change it in the XML editor"
msgstr ""
"Sanal makinenin kendi RNG aygıtı var: bunu XML düzenleyicide değiştirin"
#: vrtManager/instance.py:3008
#: vrtManager/instance.py:3013
msgid "The VM has its own TPM: change it in the XML editor"
msgstr "Sanal makinenin kendi TPM'i var: bunu XML düzenleyicide değiştirin"
#: vrtManager/instance.py:3027
#: vrtManager/instance.py:3032
#, python-format
msgid "Unknown crash action %(action)s"
msgstr "Bilinmeyen çökme eylemi %(action)s"
@ -9877,16 +9886,16 @@ msgstr ""
"%(name)s birimi kullanımda: bir sanal makinenin diski, bir temel (backing) "
"dosya ya da bir anlık görüntünün dosyası"
#: vrtManager/util.py:95
#: vrtManager/util.py:99
#, python-format
msgid "The XML is not valid: %(err)s"
msgstr "XML geçerli değil: %(err)s"
#: vrtManager/util.py:97
#: vrtManager/util.py:101
msgid "The XML may not declare a DTD"
msgstr "XML bir DTD bildiremez"
#: vrtManager/util.py:143
#: vrtManager/util.py:147
#, python-format
msgid "MAC address must be of the format AA:BB:CC:DD:EE:FF, was %(mac)s"
msgstr "MAC adresi AA:BB:CC:DD:EE:FF biçiminde olmalı; girilen: %(mac)s"

Binary file not shown.

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-11-06 21:10+0000\n"
"POT-Creation-Date: 2026-11-07 11:22+0000\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@ -18,7 +18,7 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.0.1\n"
#: accounts/auth.py:22
#: accounts/auth.py:22 accounts/middleware.py:28
msgid "Change your password before using the API."
msgstr "使用 API 前请先修改密码。"
@ -1128,12 +1128,12 @@ msgstr "其对虚拟机、SSH 密钥和设置的访问将被移除;虚拟机
msgid "deleted user"
msgstr "已删除的用户"
#: admin/views.py:348
#: admin/views.py:349
#, python-format
msgid "Removed VM %(name)s deleted"
msgstr "已删除已移除的虚拟机 %(name)s"
#: admin/views.py:355
#: admin/views.py:356
msgid "Its owners no longer get the VM back if its UUID shows up again."
msgstr "若其 UUID 再次出现,其所有者将不再恢复对该虚拟机的所有权。"
@ -2653,7 +2653,7 @@ msgstr "请从可用名称列表中选择克隆的名称"
msgid "%(quota)s: cannot create '%(clone_name)s'."
msgstr "%(quota)s:无法创建“%(clone_name)s”。"
#: instances/jobs.py:200 instances/jobs.py:552
#: instances/jobs.py:200 instances/jobs.py:554
#, python-format
msgid "Instance '%(clone_name)s' already exists!"
msgstr "虚拟机 '%(clone_name)s' 已存在!"
@ -2678,339 +2678,339 @@ msgstr "磁盘名称 '%(disk_name)s' 包含无效字符!"
msgid "The clone is made, but not as asked: %(error)s"
msgstr "克隆已创建,但与要求不符:%(error)s"
#: instances/jobs.py:283
#: instances/jobs.py:285
msgid "The VM was not defined and no volume of it was left."
msgstr "虚拟机未定义,也没有留下它的卷。"
#: instances/jobs.py:285
#: instances/jobs.py:287
#, python-format
msgid ""
"The VM was not defined; check these volumes, then resolve this job: "
"%(volumes)s"
msgstr "虚拟机未定义;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:306
#: instances/jobs.py:308
msgid "Delete snapshot"
msgstr "删除快照"
#: instances/jobs.py:316 vrtManager/instance.py:2287
#: instances/jobs.py:318 vrtManager/instance.py:2288
#, python-format
msgid "The VM has no external snapshot named %(name)s"
msgstr "虚拟机没有名为 %(name)s 的外部快照"
#: instances/jobs.py:329
#: instances/jobs.py:331
msgid "Merging the snapshot"
msgstr "正在合并快照"
#: instances/jobs.py:348
#: instances/jobs.py:350
msgid "The VM is no longer on its compute"
msgstr "虚拟机已不在其计算节点上"
#: instances/jobs.py:351
#: instances/jobs.py:353
msgid "libvirt is still merging the snapshot"
msgstr "libvirt 仍在合并快照"
#: instances/jobs.py:359
#: instances/jobs.py:361
msgid ""
"The snapshot is still listed and no merge runs. It cannot be told whether the"
" disks changed; check the VM before deleting the snapshot again or reverting "
"to it."
msgstr "快照仍在列表中,且没有正在运行的合并。无法判断磁盘是否已更改;再次删除该快照或恢复到它之前,请检查虚拟机。"
#: instances/jobs.py:366
#: instances/jobs.py:368
msgid "The VM is no longer on the compute the job ran on"
msgstr "虚拟机已不在运行该任务的计算节点上"
#: instances/jobs.py:372
#: instances/jobs.py:374
msgid "Take snapshot"
msgstr "创建快照"
#: instances/jobs.py:384 instances/jobs.py:393 vrtManager/instance.py:1883
#: instances/jobs.py:386 instances/jobs.py:395 vrtManager/instance.py:1884
#, python-format
msgid "A snapshot named %(name)s already exists"
msgstr "名为 %(name)s 的快照已存在"
#: instances/jobs.py:399
#: instances/jobs.py:401
msgid "Taking the snapshot"
msgstr "正在创建快照"
#: instances/jobs.py:412
#: instances/jobs.py:414
msgid "libvirt is still taking the snapshot"
msgstr "libvirt 仍在创建快照"
#: instances/jobs.py:415
#: instances/jobs.py:417
msgid "The snapshot was not taken"
msgstr "未创建快照"
#: instances/jobs.py:438
#: instances/jobs.py:440
msgid "Revert snapshot"
msgstr "恢复快照"
#: instances/jobs.py:469
#: instances/jobs.py:471
msgid "Reverting the VM"
msgstr "正在恢复虚拟机"
#: instances/jobs.py:480
#: instances/jobs.py:482
msgid "libvirt is still reverting the VM"
msgstr "libvirt 仍在恢复虚拟机"
#: instances/jobs.py:484
#: instances/jobs.py:486
msgid ""
"It cannot be told whether the VM was reverted; check it, then revert again or"
" resolve this job."
msgstr "无法判断虚拟机是否已恢复;请检查后再次恢复,或处理此任务。"
#: instances/jobs.py:501
#: instances/jobs.py:503
msgid "The VM must be running, paused or shut off to be cloned"
msgstr "虚拟机必须处于运行、暂停或关机状态才能克隆"
#: instances/jobs.py:502
#: instances/jobs.py:504
#, python-format
msgid ""
"The guest's file systems could not be thawed (%(error)s); thaw them with: "
"virsh domfsthaw %(vm)s"
msgstr "无法解冻客户机的文件系统(%(error)s);请用以下命令解冻:virsh domfsthaw %(vm)s"
#: instances/jobs.py:521
#: instances/jobs.py:523
msgid "Clone VM"
msgstr "克隆虚拟机"
#: instances/jobs.py:562 instances/jobs.py:569 instances/jobs.py:847
#: instances/jobs.py:564 instances/jobs.py:571 instances/jobs.py:849
msgid "Copying disks"
msgstr "正在复制磁盘"
#: instances/jobs.py:621
#: instances/jobs.py:623
msgid "libvirt has no result of the copy"
msgstr "libvirt 没有复制的结果"
#: instances/jobs.py:632
#: instances/jobs.py:634
#, python-format
msgid ""
"The copy failed: %(error)s. The guest's file systems could not be thawed "
"(%(thaw)s); thaw them with: virsh domfsthaw %(vm)s"
msgstr "复制失败:%(error)s。无法解冻客户机的文件系统(%(thaw)s);请用以下命令解冻:virsh domfsthaw %(vm)s"
#: instances/jobs.py:635 instances/jobs.py:722
#: instances/jobs.py:637 instances/jobs.py:724
msgid "The copy failed"
msgstr "复制失败"
#: instances/jobs.py:660
#: instances/jobs.py:662
#, python-format
msgid ""
"The VM is no longer on the compute the job ran on; check these volumes, then "
"resolve this job: %(volumes)s"
msgstr "虚拟机已不在运行该任务的计算节点上;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:698
#: instances/jobs.py:700
#, python-format
msgid ""
"A volume of the clone was being created; check these volumes, then resolve "
"this job: %(volumes)s"
msgstr "克隆的一个卷正在创建中;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:702
#: instances/jobs.py:704
msgid "The job stopped before the copy started"
msgstr "任务在复制开始前停止"
#: instances/jobs.py:709
#: instances/jobs.py:711
msgid "libvirt is still copying the disks"
msgstr "libvirt 仍在复制磁盘"
#: instances/jobs.py:712
#: instances/jobs.py:714
#, python-format
msgid ""
"Another backup runs on the VM; check these volumes, then resolve this job: "
"%(volumes)s"
msgstr "虚拟机上正在运行另一个备份;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:717
#: instances/jobs.py:719
#, python-format
msgid ""
"libvirt has no result of the copy; check these volumes, then resolve this "
"job: %(volumes)s"
msgstr "libvirt 没有复制的结果;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:729
#: instances/jobs.py:731
#, python-format
msgid ""
"The disks were copied, but the clone could not be defined: %(error)s; check "
"these volumes, then resolve this job: %(volumes)s"
msgstr "磁盘已复制,但无法定义克隆:%(error)s;请检查这些卷,然后处理此任务:%(volumes)s"
#: instances/jobs.py:752 instances/templates/create_instance_w1.html:60
#: instances/jobs.py:754 instances/templates/create_instance_w1.html:60
#: instances/templates/create_instance_w2.html:356
msgid "Create VM"
msgstr "创建虚拟机"
#: instances/jobs.py:776 instances/jobs.py:821 instances/views.py:2463
#: instances/jobs.py:778 instances/jobs.py:823 instances/views.py:2463
msgid "A virtual machine with this name already exists"
msgstr "同名虚拟机已存在"
#: instances/jobs.py:778 instances/jobs.py:818
#: instances/jobs.py:780 instances/jobs.py:820
msgid "There is an instance with same name. Remove it and try again!"
msgstr "已存在同名虚拟机。请删除后重试!"
#: instances/jobs.py:781
#: instances/jobs.py:783
msgid "First you need to create or select an image"
msgstr "请先创建或选择一个镜像"
#: instances/jobs.py:783
#: instances/jobs.py:785
msgid "Choose one disk source: a new disk, existing volumes or a template"
msgstr "请选择一种磁盘来源:新磁盘、现有卷或模板"
#: instances/jobs.py:785
#: instances/jobs.py:787
msgid "Image has already exist. Please check volumes or change instance name"
msgstr "镜像已存在。请检查卷或更改虚拟机名称"
#: instances/jobs.py:787
#: instances/jobs.py:789
msgid "Invalid cache mode"
msgstr "无效的缓存模式"
#: instances/jobs.py:789
#: instances/jobs.py:791
#, python-format
msgid "This host offers no CPU mode or model %(mode)s"
msgstr "此主机不提供 CPU 模式或型号 %(mode)s"
#: instances/jobs.py:791
#: instances/jobs.py:793
#, python-format
msgid "A CD-ROM cannot use the %(bus)s bus"
msgstr "CD-ROM 不能使用 %(bus)s 总线"
#: instances/jobs.py:794
#: instances/jobs.py:796
msgid "The cloud-init seed is read from a CD-ROM: choose its bus"
msgstr "cloud-init 种子从 CD-ROM 读取:请选择其总线"
#: instances/jobs.py:797
#: instances/jobs.py:799
msgid "The cloud-init seed needs a directory storage pool for the disk"
msgstr "cloud-init 种子需要为磁盘使用目录类型的存储池"
#: instances/jobs.py:803
#: instances/jobs.py:805
#, python-format
msgid "This host offers no firmware %(firmware)s"
msgstr "此主机不提供固件 %(firmware)s"
#: instances/jobs.py:805 vrtManager/instance.py:3015
#: instances/jobs.py:807 vrtManager/instance.py:3020
msgid "This host offers no TPM 2.0: install swtpm on it"
msgstr "此主机不提供 TPM 2.0:请在主机上安装 swtpm"
#: instances/jobs.py:866
#: instances/jobs.py:868
msgid "Writing the cloud-init seed"
msgstr "正在写入 cloud-init 种子"
#: instances/jobs.py:873
#: instances/jobs.py:875
msgid "Defining the VM"
msgstr "正在定义虚拟机"
#: instances/jobs.py:906
#: instances/jobs.py:908
#, python-format
msgid ""
"The panel failed unexpectedly; its log has the details. Remove these volumes "
"by hand: %(volumes)s"
msgstr "面板发生意外错误;详细信息见面板日志。请手动删除这些卷:%(volumes)s"
#: instances/jobs.py:910
#: instances/jobs.py:912
#, python-format
msgid "%(error)s. Remove these volumes by hand: %(volumes)s"
msgstr "%(error)s。请手动删除这些卷:%(volumes)s"
#: instances/jobs.py:935
#: instances/jobs.py:937
#, python-format
msgid "The instance is already on %(compute)s"
msgstr "虚拟机已在 %(compute)s 上"
#: instances/jobs.py:937
#: instances/jobs.py:939
#, python-format
msgid "%(compute)s is not reachable"
msgstr "无法连接 %(compute)s"
#: instances/jobs.py:939
#: instances/jobs.py:941
#, python-format
msgid "%(compute)s is the VM's own host under another name"
msgstr "%(compute)s 是该虚拟机所在主机的另一个名称"
#: instances/jobs.py:973
#: instances/jobs.py:981
#, python-format
msgid ""
"The VM migrated, but autostart could not be set on the destination: %(error)s"
msgstr "虚拟机已迁移,但无法在目标主机上设置自动启动:%(error)s"
#: instances/jobs.py:979
#: instances/jobs.py:988
#, python-format
msgid "The VM migrated, but its NVRAM file stays on the source: %(error)s"
msgstr "虚拟机已迁移,但其 NVRAM 文件仍留在源主机上:%(error)s"
#: instances/jobs.py:986
#: instances/jobs.py:996
msgid "Migrate VM"
msgstr "迁移虚拟机"
#: instances/jobs.py:1033
#: instances/jobs.py:1043
msgid "Migrating the VM"
msgstr "正在迁移虚拟机"
#: instances/jobs.py:1080
#: instances/jobs.py:1094
msgid "libvirt is still migrating the VM"
msgstr "libvirt 仍在迁移虚拟机"
#: instances/jobs.py:1091
#: instances/jobs.py:1105
msgid "The VM stayed on the source host"
msgstr "虚拟机留在了源主机上"
#: instances/jobs.py:1093
#: instances/jobs.py:1107
msgid ""
"The VM is on both computes or on neither; check them, then resolve this job."
msgstr "虚拟机同时位于两个计算节点上,或都不在;请检查后处理此任务。"
#: instances/jobs.py:1141
#: instances/jobs.py:1155
msgid "Move disk"
msgstr "移动磁盘"
#: instances/jobs.py:1148
#: instances/jobs.py:1162
msgid "Choose a disk of the VM"
msgstr "请选择虚拟机的一个磁盘"
#: instances/jobs.py:1172
#: instances/jobs.py:1186
msgid "Copying the disk"
msgstr "正在复制磁盘"
#: instances/jobs.py:1215
#: instances/jobs.py:1229
#, python-format
msgid "Another block job runs on %(dev)s; check the VM"
msgstr "%(dev)s 上正在运行另一个块任务;请检查虚拟机"
#: instances/jobs.py:1221
#: instances/jobs.py:1235
#, python-format
msgid "The disk stayed in %(path)s; remove %(dest)s if it is there"
msgstr "磁盘仍在 %(path)s;如果 %(dest)s 存在,请将其删除"
#: instances/jobs.py:1223
#: instances/jobs.py:1237
#, python-format
msgid "The definitions of %(dev)s name %(paths)s; check the VM"
msgstr "%(dev)s 的定义指向 %(paths)s;请检查虚拟机"
#: instances/jobs.py:1230
#: instances/jobs.py:1244
#, python-format
msgid "Disk %(path)s was kept: a disk file that stays needs it"
msgstr "磁盘 %(path)s 已保留:某个保留的磁盘文件依赖它"
#: instances/jobs.py:1231
#: instances/jobs.py:1245
#, python-format
msgid "The VM is removed, but disk %(path)s was not deleted: %(err)s"
msgstr "虚拟机已删除,但磁盘 %(path)s 未被删除:%(err)s"
#: instances/jobs.py:1232
#: instances/jobs.py:1246
#, python-format
msgid "Disk %(path)s is used by another VM and was kept"
msgstr "磁盘 %(path)s 正被另一台虚拟机使用,已保留"
#: instances/jobs.py:1286
#: instances/jobs.py:1300
msgid "Delete VM"
msgstr "删除虚拟机"
#: instances/jobs.py:1316
#: instances/jobs.py:1330
msgid "Deleting the VM"
msgstr "正在删除虚拟机"
#: instances/jobs.py:1328
#: instances/jobs.py:1342
msgid "The VM was not deleted; it may have been shut off"
msgstr "虚拟机未被删除;它可能已被关闭"
@ -6014,7 +6014,7 @@ msgstr "%(quota)s:“%(instance_name)s”仍为模板。"
msgid "The XML has no name"
msgstr "XML 中没有名称"
#: instances/views.py:2475 webvirtcloud/middleware.py:126
#: instances/views.py:2475 webvirtcloud/middleware.py:151
#, python-format
msgid "libvirt Error - %(exception)s"
msgstr "libvirt 错误 - %(exception)s"
@ -7517,7 +7517,8 @@ msgstr "恢复在一小时内无法读取任务状态;请检查虚拟机,然
msgid "The worker stopped before the job changed anything"
msgstr "工作进程在任务做出任何更改之前停止"
#: storages/api/viewsets.py:203 storages/api/viewsets.py:224
#: storages/api/viewsets.py:147 storages/api/viewsets.py:164
#: storages/api/viewsets.py:202 storages/api/viewsets.py:223
msgid "Pool is not active"
msgstr "存储池未激活"
@ -8421,7 +8422,6 @@ msgstr "连接失败:%(host)s 未连接"
#: vrtManager/connection.py:502
#, python-format
#| msgid "This host has no secrets."
msgid "This host has no architecture %(arch)s"
msgstr "此主机没有 %(arch)s 架构"
@ -8628,67 +8628,71 @@ msgstr "磁盘 %(target_dev)s 不在虚拟机的定义中"
msgid "Please shutdown the instance then try to enable vCPU hotplug"
msgstr "请先关闭虚拟机,再启用 vCPU 热插拔"
#: vrtManager/instance.py:1842
#: vrtManager/instance.py:1669
msgid "The VM has no video card"
msgstr "虚拟机没有显卡"
#: vrtManager/instance.py:1843
msgid ""
"The VM has external snapshots; internal snapshots cannot be mixed with them"
msgstr "虚拟机有外部快照;内部快照不能与其混用"
#: vrtManager/instance.py:1874
#: vrtManager/instance.py:1875
msgid "A snapshot with memory is not quiesced; it keeps the whole guest state"
msgstr "含内存的快照不会静默文件系统;它保存整个客户机状态"
#: vrtManager/instance.py:1876
#: vrtManager/instance.py:1877
msgid "Only a running VM's file systems can be frozen"
msgstr "只有运行中的虚拟机的文件系统可以冻结"
#: vrtManager/instance.py:1878
#: vrtManager/instance.py:1879
msgid "The QEMU guest agent is not connected; it freezes the file systems"
msgstr "QEMU 客户机代理未连接;文件系统由它冻结"
#: vrtManager/instance.py:1881
#: vrtManager/instance.py:1882
msgid ""
"The VM has internal snapshots; external snapshots cannot be mixed with them"
msgstr "虚拟机有内部快照;外部快照不能与其混用"
#: vrtManager/instance.py:1886
#: vrtManager/instance.py:1887
msgid "Newer snapshots exist after the last revert; delete them first"
msgstr "上次还原后存在更新的快照;请先删除它们"
#: vrtManager/instance.py:1889
#: vrtManager/instance.py:1890
msgid "No snapshot is current; revert to a snapshot first"
msgstr "没有当前快照;请先还原到某个快照"
#: vrtManager/instance.py:1895
#: vrtManager/instance.py:1896
#, python-format
msgid "Eject the media from %(dev)s first"
msgstr "请先弹出 %(dev)s 中的介质"
#: vrtManager/instance.py:1897
#: vrtManager/instance.py:1898
#, python-format
msgid "Disk %(dev)s is not a file; external snapshots need file disks"
msgstr "磁盘 %(dev)s 不是文件;外部快照需要文件磁盘"
#: vrtManager/instance.py:1905
#: vrtManager/instance.py:1906
#, python-format
msgid ""
"The storage pools could not be refreshed, so their free space is unknown: "
"%(err)s"
msgstr "无法刷新存储池,其可用空间未知:%(err)s"
#: vrtManager/instance.py:1926
#: vrtManager/instance.py:1927
msgid "Memory is saved only from a running VM"
msgstr "只能保存运行中的虚拟机的内存"
#: vrtManager/instance.py:1928
#: vrtManager/instance.py:1929
msgid "The VM has no disk to keep its memory next to"
msgstr "虚拟机没有可存放其内存的磁盘"
#: vrtManager/instance.py:1932
#: vrtManager/instance.py:1933
#, python-format
msgid "%(disk)s is not in a storage pool; memory is saved only into one"
msgstr "%(disk)s 不在存储池中;内存只能保存到存储池中"
#: vrtManager/instance.py:1963
#: vrtManager/instance.py:1964
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the snapshot needs %(size).1f "
@ -8698,156 +8702,156 @@ msgstr ""
"存储池 %(pool)s 可用 %(free).1f GiB;快照需要 %(size).1f GiB(其中虚拟机磁盘的 %(percent)g%%,至少 "
"%(minimum)g GiB,若保存内存则另加内存)"
#: vrtManager/instance.py:1981
#: vrtManager/instance.py:1982
msgid ""
"This snapshot was taken by an older version on a UEFI VM and cannot be "
"reverted; delete it instead"
msgstr "此快照由旧版本在 UEFI 虚拟机上创建,无法还原;请将其删除"
#: vrtManager/instance.py:2011
#: vrtManager/instance.py:2012
#, python-format
msgid ""
"The revert failed twice; try again in a moment (%(error)s). The VM is "
"running."
msgstr "还原两次失败;请稍后重试(%(error)s)。虚拟机正在运行。"
#: vrtManager/instance.py:2013
#: vrtManager/instance.py:2014
#, python-format
msgid ""
"The revert failed twice; try again in a moment (%(error)s). The VM is shut "
"off."
msgstr "还原两次失败;请稍后重试(%(error)s)。虚拟机已关机。"
#: vrtManager/instance.py:2176
#: vrtManager/instance.py:2177
msgid "A disk moves when its VM is defined and running, paused or shut off"
msgstr "仅当虚拟机已定义且处于运行、暂停或关机状态时才能移动磁盘"
#: vrtManager/instance.py:2178
#: vrtManager/instance.py:2179
msgid ""
"A disk of a VM with snapshots, a saved state or a running block job does not "
"move"
msgstr "有快照、保存的状态或正在运行块任务的虚拟机的磁盘不能移动"
#: vrtManager/instance.py:2186
#: vrtManager/instance.py:2187
#, python-format
msgid ""
"%(dev)s is not a disk file of the VM, the same in its running and next "
"start's definition"
msgstr "%(dev)s 不是该虚拟机在运行中的定义和下次启动定义中相同的磁盘文件"
#: vrtManager/instance.py:2191
#: vrtManager/instance.py:2192
#, python-format
msgid "%(dev)s does not move: only writable raw and qcow2 disks do"
msgstr "%(dev)s 不能移动:只能移动可写的 raw 和 qcow2 磁盘"
#: vrtManager/instance.py:2198
#: vrtManager/instance.py:2199
#, python-format
msgid "%(dev)s does not move: no storage pool has %(path)s"
msgstr "%(dev)s 不能移动:没有存储池包含 %(path)s"
#: vrtManager/instance.py:2200
#: vrtManager/instance.py:2201
#, python-format
msgid "%(dev)s does not move: it has a backing file"
msgstr "%(dev)s 不能移动:它有后备文件"
#: vrtManager/instance.py:2203
#: vrtManager/instance.py:2204
#, python-format
msgid "%(pool_name)s is not an active pool of disk files of this host"
msgstr "%(pool_name)s 不是此主机上活动的磁盘文件存储池"
#: vrtManager/instance.py:2206
#: vrtManager/instance.py:2207
#, python-format
msgid "%(dev)s is in pool %(pool_name)s already"
msgstr "%(dev)s 已在存储池 %(pool_name)s 中"
#: vrtManager/instance.py:2210
#: vrtManager/instance.py:2211
#, python-format
msgid "Pool %(pool_name)s already has a file %(name)s"
msgstr "存储池 %(pool_name)s 中已有文件 %(name)s"
#: vrtManager/instance.py:2234
#: vrtManager/instance.py:2235
#, python-format
msgid "The copy of %(dev)s ended before it was complete"
msgstr "%(dev)s 的复制在完成前结束"
#: vrtManager/instance.py:2279
#: vrtManager/instance.py:2280
#, python-format
msgid "%(error)s; remove %(dest)s if it is there: %(cleanup_error)s"
msgstr "%(error)s;如果 %(dest)s 存在请将其删除:%(cleanup_error)s"
#: vrtManager/instance.py:2281
#: vrtManager/instance.py:2282
#, python-format
msgid "%(error)s; the VM may use %(dest)s now: check its disk %(dev)s"
msgstr "%(error)s;虚拟机现在可能在使用 %(dest)s:请检查其磁盘 %(dev)s"
#: vrtManager/instance.py:2288
#: vrtManager/instance.py:2289
#, python-format
msgid "The VM has no internal snapshot named %(name)s"
msgstr "虚拟机没有名为 %(name)s 的内部快照"
#: vrtManager/instance.py:2297
#: vrtManager/instance.py:2298
msgid "The VM has a saved state; start it or remove the saved state first"
msgstr "虚拟机有保存的状态;请先启动它或删除保存的状态"
#: vrtManager/instance.py:2299
#: vrtManager/instance.py:2300
msgid "A snapshot job is still running on this VM; try again when it ends"
msgstr "此虚拟机上仍有快照任务在运行;请在其结束后重试"
#: vrtManager/instance.py:2309
#: vrtManager/instance.py:2310
msgid "Shut the VM down to revert to an internal snapshot"
msgstr "请关闭虚拟机后再还原到内部快照"
#: vrtManager/instance.py:2407
#: vrtManager/instance.py:2408
msgid "Cannot clone a VM whose NVRAM is not a file"
msgstr "NVRAM 不是文件的虚拟机无法克隆"
#: vrtManager/instance.py:2475
#: vrtManager/instance.py:2476
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(path)s"
msgstr "克隆失败(%(err)s);请手动删除这些副本:%(path)s"
#: vrtManager/instance.py:2485
#: vrtManager/instance.py:2486
msgid "Shut the VM down before cloning it"
msgstr "请先关闭虚拟机再克隆"
#: vrtManager/instance.py:2539
#: vrtManager/instance.py:2540
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(leftovers)s"
msgstr "克隆失败(%(err)s);请手动删除这些副本:%(leftovers)s"
#: vrtManager/instance.py:2550
#: vrtManager/instance.py:2551
msgid "Live clone needs libvirt 11.10 or later; shut the VM down to clone it"
msgstr "在线克隆需要 libvirt 11.10 或更高版本;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2553
#: vrtManager/instance.py:2554
msgid "A VM with a TPM is cloned only shut down"
msgstr "带 TPM 的虚拟机只能在关机时克隆"
#: vrtManager/instance.py:2556
#: vrtManager/instance.py:2557
#, python-format
msgid "Disk %(dev)s is not a local file; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 不是本地文件;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2558
#: vrtManager/instance.py:2559
#, python-format
msgid "Disk %(dev)s is shareable; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 是可共享的;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2563
#: vrtManager/instance.py:2564
#, python-format
msgid "Disk %(dev)s changes at the next start; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 在下次启动时会改变;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2565
#: vrtManager/instance.py:2566
msgid "Another job is running on the VM; clone it when that ends"
msgstr "虚拟机上有另一个任务正在运行;请在其结束后再克隆"
#: vrtManager/instance.py:2578
#: vrtManager/instance.py:2579
#, python-format
msgid "Volume %(name)s already exists in storage pool %(pool)s"
msgstr "卷 %(name)s 已存在于存储池 %(pool)s 中"
#: vrtManager/instance.py:2597
#: vrtManager/instance.py:2598
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the clone needs %(size).1f GiB"
@ -8856,92 +8860,97 @@ msgstr ""
"存储池 %(pool)s 可用 %(free).1f GiB;克隆需要 %(size).1f GiB(复制的磁盘,再加其 %(percent)g%%,至少"
" %(minimum)g GiB)"
#: vrtManager/instance.py:2736
#: vrtManager/instance.py:2737
msgid "A network interface that is a host device is removed in the XML editor"
msgstr "作为主机设备的网络接口需在 XML 编辑器中删除"
#: vrtManager/instance.py:2752
#: vrtManager/instance.py:2753
#, python-format
msgid "No network interface with MAC %(old_mac)s"
msgstr "没有 MAC 为 %(old_mac)s 的网络接口"
#: vrtManager/instance.py:2755
#: vrtManager/instance.py:2756
msgid "A network interface that is a host device is changed in the XML editor"
msgstr "作为主机设备的网络接口需在 XML 编辑器中修改"
#: vrtManager/instance.py:2846
#: vrtManager/instance.py:2847
msgid ""
"A VM changes its PCI devices while it runs, or is shut off without a saved "
"state"
msgstr "虚拟机只能在运行时或无保存的状态的关机时更改其 PCI 设备"
#: vrtManager/instance.py:2858
#: vrtManager/instance.py:2859
#, python-format
msgid "%(err)s; whether the VM has PCI device %(address)s now is not known"
msgstr "%(err)s;虚拟机现在是否有 PCI 设备 %(address)s 未知"
#: vrtManager/instance.py:2860
#: vrtManager/instance.py:2861
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start has it"
msgstr "%(err)s;PCI 设备 %(address)s:虚拟机未运行,下次启动时有它"
#: vrtManager/instance.py:2862
#: vrtManager/instance.py:2863
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start does "
"not have it"
msgstr "%(err)s;PCI 设备 %(address)s:虚拟机未运行,下次启动时没有它"
#: vrtManager/instance.py:2863
#: vrtManager/instance.py:2864
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start has it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机有它,下次启动时有它"
#: vrtManager/instance.py:2865
#: vrtManager/instance.py:2866
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start does "
"not have it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机有它,下次启动时没有它"
#: vrtManager/instance.py:2867
#: vrtManager/instance.py:2868
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
"start has it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机没有它,下次启动时有它"
#: vrtManager/instance.py:2869
#: vrtManager/instance.py:2870
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
"start does not have it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机没有它,下次启动时没有它"
#: vrtManager/instance.py:2903
#: vrtManager/instance.py:2904
#, python-format
msgid "The VM has no PCI device %(address)s"
msgstr "虚拟机没有 PCI 设备 %(address)s"
#: vrtManager/instance.py:2921
#: vrtManager/instance.py:2922
msgid "The VM has no USB controller"
msgstr "虚拟机没有 USB 控制器"
#: vrtManager/instance.py:2940
#: vrtManager/instance.py:2941
msgid "The VM has no such USB device"
msgstr "虚拟机没有此 USB 设备"
#: vrtManager/instance.py:2981
#: vrtManager/instance.py:2955
#, python-format
msgid "The VM has no network interface %(mac)s"
msgstr "虚拟机没有网络接口 %(mac)s"
#: vrtManager/instance.py:2986
msgid "The VM has its own RNG device: change it in the XML editor"
msgstr "虚拟机有自己的 RNG 设备:请在 XML 编辑器中修改"
#: vrtManager/instance.py:3008
#: vrtManager/instance.py:3013
msgid "The VM has its own TPM: change it in the XML editor"
msgstr "虚拟机有自己的 TPM:请在 XML 编辑器中修改"
#: vrtManager/instance.py:3027
#: vrtManager/instance.py:3032
#, python-format
msgid "Unknown crash action %(action)s"
msgstr "未知的崩溃操作 %(action)s"
@ -9314,16 +9323,16 @@ msgid ""
"Volume %(name)s is in use: a VM's disk, a backing file or a snapshot's file"
msgstr "卷 %(name)s 正在使用中:它是虚拟机的磁盘、后备文件或快照文件"
#: vrtManager/util.py:95
#: vrtManager/util.py:99
#, python-format
msgid "The XML is not valid: %(err)s"
msgstr "XML 无效:%(err)s"
#: vrtManager/util.py:97
#: vrtManager/util.py:101
msgid "The XML may not declare a DTD"
msgstr "XML 不能声明 DTD"
#: vrtManager/util.py:143
#: vrtManager/util.py:147
#, python-format
msgid "MAC address must be of the format AA:BB:CC:DD:EE:FF, was %(mac)s"
msgstr "MAC 地址的格式必须为 AA:BB:CC:DD:EE:FF,实际为 %(mac)s"

View file

@ -1666,6 +1666,7 @@ class wvmInstance(wvmConnect):
new_model.set("primary", video_model.get("primary"))
self._defineXML(etree.tostring(tree).decode())
return
raise util.OperationError(gettext_noop("The VM has no video card"))
def resize_cpu(self, cur_vcpu, vcpu):
"""
@ -2940,14 +2941,18 @@ class wvmInstance(wvmConnect):
raise util.OperationError(gettext_noop("The VM has no such USB device"))
def set_link_state(self, mac_address, state):
found = False
for xml_flags, affect in self._definitions():
nic = self._nic(xml_flags, mac_address)
if nic is None:
continue
found = True
for link in nic.findall("link"):
nic.remove(link)
etree.SubElement(nic, "link", state=state)
self.instance.updateDeviceFlags(etree.tostring(nic).decode(), affect)
if not found:
raise util.OperationError(gettext_noop("The VM has no network interface %(mac)s"), mac=mac_address)
def _set_options(self, tree, options):
for o in ["title", "description"]:

View file

@ -110,6 +110,18 @@ class DeviceEditsTestCase(unittest.TestCase):
self.assertEqual(model.attrib, {"type": "vga' heads='9"})
p._defineXML.assert_called_once()
def test_a_device_the_vm_does_not_have_is_refused(self):
# a stale form: no change, and the audit row says it failed
p = proxy()
p._definitions = lambda: [(PERSISTENT_XML, VIR_DOMAIN_AFFECT_CONFIG)]
with self.assertRaisesRegex(util.OperationError, "no network interface 52:54:10:00:00:09"):
p.set_link_state("52:54:10:00:00:09", "down")
p._XMLDesc = lambda flags: PERSISTENT.replace("<video><model type='vga'/></video>", "")
with self.assertRaisesRegex(util.OperationError, "no video card"):
p.set_video_model("virtio")
p.instance.updateDeviceFlags.assert_not_called()
p._defineXML.assert_not_called()
def test_qos_changes_go_through_define_xml(self):
for change in (
lambda p: p.set_qos("52:54:10:00:00:01", "outbound", 1, 2, 3),