1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 11:46:49 +00:00

fix(instances): a busy host is reported as busy, not as unreachable

A web request refused because this process's requests to the host
(HOST_REQUESTS) all still wait for it raised the same ConnectionFailed as
a host that is down, so the VM page said the host cannot be reached. It
now raises HostBusy; the VM page and the error users who do not see hosts
get say the host is busy and to try again in a moment.
This commit is contained in:
catborise 2026-11-05 15:53:29 +03:00
parent 458074df82
commit f3c44f18c4
9 changed files with 307 additions and 245 deletions

View file

@ -0,0 +1,38 @@
"""A host whose web requests in this process all still wait for it is busy,
not unreachable: users are told to try again."""
from unittest.mock import PropertyMock, patch
from accounts.models import UserInstance
from computes.models import Compute
from django.contrib.auth import get_user_model
from django.contrib.messages import get_messages
from django.test import TestCase
from django.urls import reverse
from instances.models import Instance
from operations.utils import public_error_text
from vrtManager import util
BUSY = "The host of this virtual machine is busy with other requests right now: try again in a moment."
def busy(host="192.0.2.1"):
return util.HostBusy("Connection Failed: %(host)s does not answer: %(requests)s requests still wait for it",
host=host, requests=2)
class HostBusyTests(TestCase):
def test_a_refused_request_tells_users_the_host_is_busy(self):
self.assertEqual(public_error_text(busy()), BUSY)
def test_the_vm_page_of_a_busy_host_says_it_is_busy(self):
compute = Compute.objects.create(name="c", hostname="192.0.2.1", login="u", password="p", type=1)
vm = Instance.objects.create(compute=compute, name="vm", uuid="11111111-1111-1111-1111-111111111111")
owner = get_user_model().objects.create_user("owner", password="pw")
UserInstance.objects.create(user=owner, instance=vm)
self.client.force_login(owner)
with patch.object(Compute, "connection", new_callable=PropertyMock, return_value=busy()):
response = self.client.get(reverse("instances:instance", args=[vm.pk]))
self.assertRedirects(response, reverse("instances:index"), fetch_redirect_response=False)
self.assertEqual([str(m) for m in get_messages(response.wsgi_request)],
[BUSY + " Jobs on it can be followed under Jobs in the menu."])

View file

@ -51,7 +51,7 @@ from libvirt import (VIR_DOMAIN_PAUSED,
from logs.audit import audit, audit_vm, changed_fields, failed_vm
from logs.audit import snapshot as audit_snapshot
from operations import claims, jobs
from operations.utils import busy_message, summary
from operations.utils import HOST_BUSY, busy_message, summary
from webvirtcloud.middleware import error_text, same_origin_referer
from vrtManager import util
from vrtManager.connection import CONNECT_TIMEOUT
@ -253,7 +253,9 @@ def instance(request, pk):
# the page reads the VM from libvirt throughout; without the host it would
# be the error page, with a connection error that names the host
if compute.status is not True:
if request.user.is_superuser or request.user.has_perm("instances.view_instances"):
if isinstance(compute.connection, util.HostBusy):
msg = _(HOST_BUSY)
elif request.user.is_superuser or request.user.has_perm("instances.view_instances"):
msg = _("The host %(host)s of '%(name)s' cannot be reached: %(error)s") % {
"host": compute.name,
"name": instance.name,

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-05 08:41+0000\n"
"POT-Creation-Date: 2026-11-05 12:53+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"
@ -2922,7 +2922,7 @@ msgstr ""
msgid "Create VM"
msgstr "Sanal makine oluştur"
#: instances/jobs.py:756 instances/views.py:2480
#: instances/jobs.py:756 instances/views.py:2482
msgid "A virtual machine with this name already exists"
msgstr "Bu isimde bir sanal makine mevcut"
@ -3282,7 +3282,7 @@ msgid "Disk source"
msgstr "Disk kaynağı"
#: instances/templates/add_instance_volume.html:21
#: instances/templates/create_instance_w2.html:134 instances/views.py:2499
#: instances/templates/create_instance_w2.html:134 instances/views.py:2501
msgid "New disk"
msgstr "Yeni disk"
@ -3654,7 +3654,7 @@ msgstr "Özel CPU modelleri"
msgid "Size (GiB)"
msgstr "Boyut (GiB)"
#: instances/templates/create_instance_w2.html:161 instances/views.py:2500
#: instances/templates/create_instance_w2.html:161 instances/views.py:2502
msgid "Existing volumes"
msgstr "Mevcut birimler"
@ -3690,7 +3690,7 @@ msgstr "Aygıt"
msgid "Remove"
msgstr "Kaldır"
#: instances/templates/create_instance_w2.html:194 instances/views.py:2501
#: instances/templates/create_instance_w2.html:194 instances/views.py:2503
msgid "Clone from template"
msgstr "Şablondan klonla"
@ -5861,30 +5861,30 @@ msgstr "Bir IP adresi, 192.0.2.0/24 gibi bir ağ ya da bir MAC adresi girin."
msgid "Too many searches are still running; try again shortly."
msgstr "Çok fazla arama hâlâ çalışıyor; birazdan yeniden deneyin."
#: instances/views.py:257
#: instances/views.py:259
#, python-format
msgid "The host %(host)s of '%(name)s' cannot be reached: %(error)s"
msgstr "'%(name)s' sanal makinesinin sunucusu %(host)s erişilemiyor: %(error)s"
#: instances/views.py:263
#: instances/views.py:265
#, python-format
msgid "The host of '%(name)s' cannot be reached right now."
msgstr "'%(name)s' sanal makinesinin sunucusuna şu anda erişilemiyor."
#: instances/views.py:264
#: instances/views.py:266
msgid " Jobs on it can be followed under Jobs in the menu."
msgstr " Üzerindeki işler menüdeki İşler bölümünden izlenebilir."
#: instances/views.py:366
#: instances/views.py:368
msgid "There is no other host to migrate to."
msgstr "Taşınacak başka bir sunucu yok."
#: instances/views.py:368
#: instances/views.py:370
msgid "A VM migrates when it is running, paused or shut off."
msgstr ""
"Sanal makine çalışırken, duraklatılmışken ya da kapalıyken taşınabilir."
#: instances/views.py:370
#: instances/views.py:372
msgid ""
"A VM with snapshots cannot be migrated: its snapshots stay on this host. "
"Delete them first."
@ -5892,7 +5892,7 @@ msgstr ""
"Anlık görüntüsü olan bir sanal makine taşınamaz: anlık görüntüleri bu "
"sunucuda kalır. Önce onları silin."
#: instances/views.py:372
#: instances/views.py:374
msgid ""
"A VM with host devices cannot be migrated: the destination may not have them."
" Remove them first."
@ -5900,11 +5900,11 @@ msgstr ""
"Sunucu aygıtları olan bir sanal makine taşınamaz: hedefte bu aygıtlar "
"olmayabilir. Önce onları kaldırın."
#: instances/views.py:634
#: instances/views.py:636
msgid "The VM was moved meanwhile; try again."
msgstr "Sanal makine bu arada taşındı; yeniden deneyin."
#: instances/views.py:746
#: instances/views.py:748
msgid ""
"The running VM has no free PCI slot for another disk on this bus: choose the "
"scsi bus if the VM has a SCSI controller, or shut the VM down and add the "
@ -5917,7 +5917,7 @@ msgstr ""
"yuvaları ekle, sonraki başlatmadan itibaren ona boş yuvalar verir. Yeni bir "
"birim havuzunda kalır, mevcut birim olarak eklenebilir."
#: instances/views.py:750
#: instances/views.py:752
msgid ""
"The running VM has no free PCI slot for the SCSI controller the disk needs: "
"shut the VM down and add the disk then; Add PCIe slots on the Disks tab gives"
@ -5929,191 +5929,191 @@ msgstr ""
"PCIe yuvaları ekle, sonraki başlatmadan itibaren ona boş yuvalar verir. Yeni "
"bir birim havuzunda kalır, mevcut birim olarak eklenebilir."
#: instances/views.py:768
#: instances/views.py:770
#, python-format
msgid "Invalid disk options: %(options)s"
msgstr "Geçersiz disk seçenekleri: %(options)s"
#: instances/views.py:778 instances/views.py:793
#: instances/views.py:780 instances/views.py:795
msgid "Templates cannot be started."
msgstr "Şablon makineler başlatılamaz."
#: instances/views.py:889
#: instances/views.py:891
#, 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/views.py:895
#: instances/views.py:897
#, 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/views.py:904
#: instances/views.py:906
#, 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/views.py:1026
#: instances/views.py:1028
#, python-format
msgid "Set the gstfsd key of %(compute)s first (Computes, edit the host)"
msgstr ""
"Önce %(compute)s sunucusunun gstfsd anahtarını ayarlayın (Sunucular, sunucuyu"
" düzenle)"
#: instances/views.py:1033 instances/views.py:1048 instances/views.py:1057
#: instances/views.py:1035 instances/views.py:1050 instances/views.py:1059
#, python-format
msgid "gstfsd error: %(err)s"
msgstr "gstfsd hatası: %(err)s"
#: instances/views.py:1058
#: instances/views.py:1060
msgid "the reply is not signed with the key"
msgstr "yanıt anahtarla imzalanmamış"
#: instances/views.py:1066
#: instances/views.py:1068
msgid "Shut the VM down, or start its QEMU guest agent, and try again"
msgstr ""
"Sanal makineyi kapatın ya da QEMU konuk ajanını başlatın ve yeniden deneyin"
#: instances/views.py:1079
#: instances/views.py:1081
msgid "The change may still be made when the agent answers again."
msgstr "Ajan yeniden yanıt verdiğinde değişiklik yine de yapılabilir."
#: instances/views.py:1106
#: instances/views.py:1108
msgid "Reset root password"
msgstr "Root parolasını sıfırla"
#: instances/views.py:1110
#: instances/views.py:1112
msgid "Enter a password"
msgstr "Bir parola girin"
#: instances/views.py:1124
#: instances/views.py:1126
msgid "Select an SSH public key"
msgstr "Bir SSH açık anahtarı seçin"
#: instances/views.py:1146
#: instances/views.py:1148
#, python-format
msgid "Installed new SSH public key %(keyname)s"
msgstr "Yeni %(keyname)s SSH açık anahtarı yüklendi"
#: instances/views.py:1166
#: instances/views.py:1168
msgid "Enter a whole number of vCPUs"
msgstr "vCPU sayısı için bir tam sayı girin"
#: instances/views.py:1170
#: instances/views.py:1172
msgid "Shut off the VM to change its vCPUs"
msgstr "vCPU'larını değiştirmek için sanal makineyi kapatın"
#: instances/views.py:1173
#: instances/views.py:1175
msgid "The current vCPUs cannot be more than the maximum"
msgstr "Geçerli vCPU sayısı en fazla değerden büyük olamaz"
#: instances/views.py:1180
#: instances/views.py:1182
#, python-format
msgid "%(quota)s: cannot resize the CPU of '%(instance_name)s'."
msgstr "%(quota)s: '%(instance_name)s' CPU'su yeniden boyutlandırılamıyor."
#: instances/views.py:1188
#: instances/views.py:1190
#, python-format
msgid "vCPUs set to %(cur)s (maximum %(max)s)"
msgstr "vCPU sayısı %(cur)s olarak ayarlandı (en fazla %(max)s)"
#: instances/views.py:1207
#: instances/views.py:1209
msgid "Enter a whole number for memory"
msgstr "Bellek için bir tam sayı girin"
#: instances/views.py:1210
#: instances/views.py:1212
msgid "The current memory cannot be more than the maximum"
msgstr "Geçerli bellek en fazla değerden büyük olamaz"
#: instances/views.py:1214
#: instances/views.py:1216
#, python-format
msgid "%(quota)s: cannot resize the memory of '%(instance_name)s'."
msgstr "%(quota)s: '%(instance_name)s' belleği yeniden boyutlandırılamıyor."
#: instances/views.py:1220
#: instances/views.py:1222
#, python-format
msgid "Memory set to %(cur)s MiB (maximum %(max)s MiB)"
msgstr "Bellek %(cur)s MiB olarak ayarlandı (en fazla %(max)s MiB)"
#: instances/views.py:1240
#: instances/views.py:1242
msgid "Enter disk sizes as whole GiB"
msgstr "Disk boyutlarını tam GiB olarak girin"
#: instances/views.py:1244
#: instances/views.py:1246
#, python-format
msgid "%(dev)s is %(size)s: a disk cannot shrink"
msgstr "%(dev)s boyutu %(size)s: disk küçültülemez"
#: instances/views.py:1252
#: instances/views.py:1254
msgid "No disks were selected or valid for resizing."
msgstr "Boyutlandırma için seçilmiş ya da geçerli disk yok."
#: instances/views.py:1261
#: instances/views.py:1263
#, python-format
msgid "%(quota)s: cannot resize the disks of '%(instance_name)s'."
msgstr "%(quota)s: '%(instance_name)s' diskleri yeniden boyutlandırılamıyor."
#: instances/views.py:1273
#: instances/views.py:1275
#, python-format
msgid "The storage pool of %(dev)s cannot resize its volumes"
msgstr "%(dev)s diskinin depolama havuzu birimlerini boyutlandıramaz"
#: instances/views.py:1275
#: instances/views.py:1277
#, python-format
msgid "Disk is resized: %(dev)s"
msgstr "Disk boyutu değiştirildi: %(dev)s"
#: instances/views.py:1369
#: instances/views.py:1371
msgid "The VM's machine has no PCIe slots to add"
msgstr "Sanal makinenin makine tipinde eklenecek PCIe yuvası yok"
#: instances/views.py:1374
#: instances/views.py:1376
#, python-format
msgid "%(count)s PCIe slots added"
msgstr "%(count)s PCIe yuvası eklendi"
#: instances/views.py:1376
#: instances/views.py:1378
#, python-format
msgid "%(count)s PCIe slots added: the VM gets them at its next start"
msgstr ""
"%(count)s PCIe yuvası eklendi: sanal makine bunları sonraki başlatmasında "
"alır"
#: instances/views.py:1422
#: instances/views.py:1424
#, python-format
msgid "%(volume)s is already a disk of this VM"
msgstr "%(volume)s zaten bu sanal makinenin bir diski"
#: instances/views.py:1512
#: instances/views.py:1514
msgid "Volume changes are applied. But it will be activated after shutdown"
msgstr ""
"Birim değişiklikleri uygulandı. Ama yeniden başlatıldıktan sonra uygulanacak"
#: instances/views.py:1517
#: instances/views.py:1519
msgid "Volume is changed successfully."
msgstr "Birim başarıyla değiştirildi."
#: instances/views.py:1535
#: instances/views.py:1537
#, python-format
msgid "Disk %(dev)s is not a storage volume of this instance"
msgstr "%(dev)s diski bu sanal makinenin bir depolama birimi değil"
#: instances/views.py:1542
#: instances/views.py:1544
#, python-format
msgid "Disk %(dev)s has a pending change; delete it once the VM is shut down"
msgstr ""
"%(dev)s diskinin bekleyen bir değişikliği var; sanal makine kapatıldığında "
"silin"
#: instances/views.py:1557
#: instances/views.py:1559
#, python-format
msgid "Volume %(vol)s is used by another VM; detach it instead"
msgstr ""
"%(vol)s birimi başka bir sanal makine tarafından kullanılıyor; onun yerine "
"ayırın"
#: instances/views.py:1569
#: instances/views.py:1571
#, python-format
msgid ""
"The guest has not released disk %(dev)s yet; volume %(vol)s was kept. Delete "
@ -6122,57 +6122,57 @@ msgstr ""
"Konuk sistem %(dev)s diskini henüz bırakmadı; %(vol)s birimi korundu. Sanal "
"makine kapatıldığında depolama havuzundan silin."
#: instances/views.py:1580
#: instances/views.py:1582
#, python-format
msgid "Disk %(dev)s was detached, but its volume was kept: %(err)s"
msgstr "%(dev)s diski ayrıldı, ancak birimi korundu: %(err)s"
#: instances/views.py:1606
#: instances/views.py:1608
#, python-format
msgid "This VM cannot take a CD-ROM on the %(bus)s bus now"
msgstr "Bu sanal makineye şu anda %(bus)s veri yolunda CD-ROM eklenemez"
#: instances/views.py:1609
#: instances/views.py:1611
msgid "A USB CD-ROM needs an ISO image: libvirt has no empty USB drive"
msgstr "USB CD-ROM bir ISO imajı ister: libvirt boş USB sürücü desteklemiyor"
#: instances/views.py:1690
#: instances/views.py:1692
#, python-format
msgid "Pool %(pool)s was not read again: %(err)s"
msgstr "%(pool)s havuzu yeniden okunamadı: %(err)s"
#: instances/views.py:1711
#: instances/views.py:1713
#, python-format
msgid "Snapshot was not deleted: %(err)s"
msgstr "Anlık görüntü silinmedi: %(err)s"
#: instances/views.py:1826
#: instances/views.py:1828
msgid "Add at least one device to the boot order."
msgstr "Ön yükleme sırasına en az bir aygıt ekleyin."
#: instances/views.py:1840
#: instances/views.py:1842
msgid "Boot order changed. It applies at the next start."
msgstr "Ön yükleme sırası değiştirildi. Sonraki başlatmada uygulanır."
#: instances/views.py:1842
#: instances/views.py:1844
msgid "Boot order changed successfully."
msgstr "Ön yükleme sırası başarıyla değiştirildi."
#: instances/views.py:1862
#: instances/views.py:1864
msgid "The XML is empty"
msgstr "XML boş"
#: instances/views.py:1866 instances/views.py:2490
#: instances/views.py:1868 instances/views.py:2492
#, python-format
msgid "The XML is not well-formed: %(error)s"
msgstr "XML düzgün biçimlendirilmemiş: %(error)s"
#: instances/views.py:1868
#: instances/views.py:1870
#, python-format
msgid "The XML must keep the VM's UUID %(uuid)s."
msgstr "XML, sanal makinenin %(uuid)s UUID'sini korumalıdır."
#: instances/views.py:1872
#: instances/views.py:1874
msgid ""
"The definition has changed since the editor was opened. Reload the page to "
"edit the current one."
@ -6180,40 +6180,40 @@ msgstr ""
"Düzenleyici açıldığından beri tanım değişti. Geçerli tanımı düzenlemek için "
"sayfayı yeniden yükleyin."
#: instances/views.py:1884
#: instances/views.py:1886
msgid "The XML definition was saved."
msgstr "XML tanımı kaydedildi."
#: instances/views.py:1886
#: instances/views.py:1888
msgid "The XML definition was saved; the VM uses it from its next start."
msgstr ""
"XML tanımı kaydedildi; sanal makine onu sonraki başlatmasından itibaren "
"kullanır."
#: instances/views.py:1967
#: instances/views.py:1969
msgid "Select one network interface to change"
msgstr "Değiştirilecek bir ağ arabirimi seçin"
#: instances/views.py:2005
#: instances/views.py:2007
msgid "Network Device Config is changed. Please shutdown instance to activate."
msgstr ""
"Ağ aygıtı yapılandırması değiştirildi. Aktifleştirmek için lütfen sanal "
"makineyi kapatın."
#: instances/views.py:2007
#: instances/views.py:2009
msgid "Network device changed"
msgstr "Ağ aygıtı değiştirildi"
#: instances/views.py:2019
#: instances/views.py:2021
msgid "No network selected"
msgstr "Ağ seçilmedi"
#: instances/views.py:2024
#: instances/views.py:2026
#, python-format
msgid "The VM already has a network device with MAC %(mac)s"
msgstr "Sanal makinede %(mac)s MAC adresli bir ağ aygıtı zaten var"
#: instances/views.py:2043
#: instances/views.py:2045
msgid ""
"The running VM has no free PCI slot for another network device: shut it down "
"and add the device then; Add PCIe slots on the Disks tab gives it free ones "
@ -6223,21 +6223,21 @@ msgstr ""
"aygıtı sonra ekleyin; Diskler sekmesindeki PCIe yuvaları ekle, sonraki "
"başlatmadan itibaren ona boş yuvalar verir."
#: instances/views.py:2084 instances/views.py:2090
#: instances/views.py:2086 instances/views.py:2092
msgid "The VM has it"
msgstr "Sanal makinede var"
#: instances/views.py:2121
#: instances/views.py:2123
#, python-format
msgid "The host has no USB device %(device)s"
msgstr "Sunucuda %(device)s USB aygıtı yok"
#: instances/views.py:2142
#: instances/views.py:2144
#, python-format
msgid "The host has no PCI device %(device)s"
msgstr "Sunucuda %(device)s PCI aygıtı yok"
#: instances/views.py:2160
#: instances/views.py:2162
#, python-format
msgid ""
"Removal of PCI device %(address)s requested: the guest has not let it go yet;"
@ -6247,20 +6247,20 @@ msgstr ""
"bırakmadı; bırakana ya da sanal makine durana kadar çalışan sanal makinede "
"kalır."
#: instances/views.py:2205 instances/views.py:2235
#: instances/views.py:2207 instances/views.py:2237
msgid "Select a network interface and a QoS direction"
msgstr "Bir ağ arabirimi ve bir QoS yönü seçin"
#: instances/views.py:2208 vrtManager/network.py:459
#: instances/views.py:2210 vrtManager/network.py:459
msgid "QoS rates must be whole numbers"
msgstr "QoS hızları tam sayı olmalıdır"
#: instances/views.py:2215 networks/views.py:229
#: instances/views.py:2217 networks/views.py:229
#, python-format
msgid "%(qos_dir)s QoS is set"
msgstr "%(qos_dir)s QoS ayarlandı"
#: instances/views.py:2220
#: instances/views.py:2222
#, python-format
msgid ""
"%(qos_dir)s QoS is set. A running VM gets it after it is powered off and on."
@ -6268,12 +6268,12 @@ msgstr ""
"%(qos_dir)s QoS ayarlandı. Çalışan bir sanal makine, kapatılıp açıldıktan "
"sonra bunu alır."
#: instances/views.py:2242 networks/views.py:255
#: instances/views.py:2244 networks/views.py:255
#, python-format
msgid "%(qos_dir)s QoS is deleted"
msgstr "%(qos_dir)s QoS silindi"
#: instances/views.py:2247
#: instances/views.py:2249
#, python-format
msgid ""
"%(qos_dir)s QoS is deleted. A running VM keeps the old limit until it is "
@ -6282,21 +6282,21 @@ msgstr ""
"%(qos_dir)s QoS silindi. Çalışan bir sanal makine, kapatılıp açılana kadar "
"eski sınırı korur."
#: instances/views.py:2275
#: instances/views.py:2277
msgid "Only one owner is allowed and the one already added"
msgstr "Sadece bir sahibe izin verilmiştir ve bir sahip zaten eklenmiş"
#: instances/views.py:2277
#: instances/views.py:2279
#, python-format
msgid "%(user)s is already an owner"
msgstr "%(user)s zaten bir sahip"
#: instances/views.py:2321
#: instances/views.py:2323
#, python-format
msgid "Console settings were not saved: %(errors)s"
msgstr "Konsol ayarları kaydedilmedi: %(errors)s"
#: instances/views.py:2343
#: instances/views.py:2345
msgid ""
"Error setting console password. You should check that your instance have an "
"graphic device."
@ -6304,65 +6304,65 @@ msgstr ""
"Konsol parolası ayarlanırken hata oluştu. Sanal makinenin bir grafik aygıtına"
" sahip olduğundan emin olunuz."
#: instances/views.py:2390
#: instances/views.py:2392
msgid "Shut the VM down to change whether it is a template."
msgstr "Şablon olup olmadığını değiştirmek için sanal makineyi kapatın."
#: instances/views.py:2396
#: instances/views.py:2398
#, python-format
msgid "%(quota)s: '%(instance_name)s' stays a template."
msgstr "%(quota)s: '%(instance_name)s' şablon olarak kalıyor."
#: instances/views.py:2478
#: instances/views.py:2480
msgid "The XML has no name"
msgstr "XML'de ad yok"
#: instances/views.py:2492 webvirtcloud/middleware.py:79
#: instances/views.py:2494 webvirtcloud/middleware.py:126
#, python-format
msgid "libvirt Error - %(exception)s"
msgstr "libvirt Hatası - %(exception)s"
#: instances/views.py:2499
#: instances/views.py:2501
msgid "An empty disk of the size you set"
msgstr "Belirlediğiniz boyutta boş bir disk"
#: instances/views.py:2500
#: instances/views.py:2502
msgid "Volumes already in a pool"
msgstr "Bir havuzda zaten bulunan birimler"
#: instances/views.py:2501
#: instances/views.py:2503
msgid "A copy of a template volume"
msgstr "Bir şablon biriminin kopyası"
#: instances/views.py:2590
#: instances/views.py:2592
msgid "You haven't defined any storage pools"
msgstr "Hiç bir depolama havuzu tanımlamadınız"
#: instances/views.py:2592
#: instances/views.py:2594
msgid "You haven't defined any network pools"
msgstr "Hiç bir ağ havuzu tanımlamadınız"
#: instances/views.py:2655
#: instances/views.py:2657
msgid "Flavor Created"
msgstr "Flavor Oluşturuldu"
#: instances/views.py:2663
#: instances/views.py:2665
msgid "Create Flavor"
msgstr "Kullanıcı Oluştur"
#: instances/views.py:2678
#: instances/views.py:2680
msgid "Flavor Updated"
msgstr "Flavor Güncellendi"
#: instances/views.py:2684
#: instances/views.py:2686
msgid "Update Flavor"
msgstr "Flavor Güncelle"
#: instances/views.py:2696
#: instances/views.py:2698
msgid "Flavor Deleted"
msgstr "Flavor Silindi"
#: instances/views.py:2702
#: instances/views.py:2704
msgid "Only the size template goes; VMs made from it keep their size."
msgstr ""
"Yalnızca boyut şablonu silinir; ondan oluşturulan sanal makineler boyutlarını"
@ -7854,12 +7854,20 @@ msgstr "İptal edilemedi: sunucuya ulaşılamadı."
msgid "The host of this virtual machine cannot be reached right now."
msgstr "Bu sanal makinenin sunucusuna şu anda ulaşılamıyor."
#: operations/utils.py:157
#: operations/utils.py:53
msgid ""
"The host of this virtual machine is busy with other requests right now: try "
"again in a moment."
msgstr ""
"Bu sanal makinenin sunucusu şu anda başka isteklerle meşgul: biraz sonra "
"yeniden deneyin."
#: operations/utils.py:160
msgid ""
"A short operation is in progress on this resource; try again in a moment."
msgstr "Bu kaynakta kısa bir işlem sürüyor; birazdan yeniden deneyin."
#: operations/utils.py:160
#: operations/utils.py:163
#, python-format
msgid ""
"%(label)s is %(state)s on this resource (started by %(user)s, %(since)s ago);"
@ -7868,7 +7876,7 @@ msgstr ""
"%(label)s bu kaynakta %(state)s (%(user)s başlattı, %(since)s önce); İşler "
"sayfasına bakın."
#: operations/utils.py:162
#: operations/utils.py:165
#, python-format
msgid "%(label)s is %(state)s on this resource (since %(since)s)."
msgstr "%(label)s bu kaynakta %(state)s (%(since)s beri)."
@ -8809,23 +8817,23 @@ msgstr ""
"Eski değerin yerini hemen alır; bir parolanın şifrelediği veriler yeniden "
"şifrelenmez."
#: vrtManager/connection.py:50
#: vrtManager/connection.py:51
msgid "Connection closed (error)"
msgstr "Bağlantı kapandı (hata)"
#: vrtManager/connection.py:51
#: vrtManager/connection.py:52
msgid "Connection closed (end of file)"
msgstr "Bağlantı kapandı (dosya sonu)"
#: vrtManager/connection.py:52
#: vrtManager/connection.py:53
msgid "Connection closed (keepalive timeout)"
msgstr "Bağlantı kapandı (canlı tutma zaman aşımı)"
#: vrtManager/connection.py:53
#: vrtManager/connection.py:54
msgid "Connection closed (client closed)"
msgstr "Bağlantı kapandı (istemci kapattı)"
#: vrtManager/connection.py:139
#: vrtManager/connection.py:147
#, python-format
msgid ""
"Connection Failed: %(host)s does not answer: %(requests)s requests still wait"
@ -8834,26 +8842,26 @@ msgstr ""
"Bağlantı başarısız: %(host)s yanıt vermiyor: %(requests)s istek hâlâ onu "
"bekliyor"
#: vrtManager/connection.py:210
#: vrtManager/connection.py:219
#, python-format
msgid "Connection Failed: %(host)s did not answer within %(seconds)s s"
msgstr "Bağlantı başarısız: %(host)s %(seconds)s sn içinde yanıt vermedi"
#: vrtManager/connection.py:220
#: vrtManager/connection.py:230
msgid "the connection closed right after opening"
msgstr "bağlantı açıldıktan hemen sonra kapandı"
#: vrtManager/connection.py:233
#: vrtManager/connection.py:243
#, python-format
msgid "Connection Failed: %(error)s"
msgstr "Bağlantı başarısız: %(error)s"
#: vrtManager/connection.py:293
#: vrtManager/connection.py:312
#, python-format
msgid "Connection closed (%(reason)s)"
msgstr "Bağlantı kapandı (%(reason)s)"
#: vrtManager/connection.py:435
#: vrtManager/connection.py:455
#, python-format
msgid "Connection Failed: %(host)s is not connected"
msgstr "Bağlantı başarısız: %(host)s bağlı değil"
@ -9848,12 +9856,12 @@ 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:140
#: vrtManager/util.py:145
#, python-format
msgid "The XML is not valid: %(err)s"
msgstr "XML geçerli değil: %(err)s"
#: vrtManager/util.py:142
#: vrtManager/util.py:147
msgid "The XML may not declare a DTD"
msgstr "XML bir DTD bildiremez"
@ -9878,10 +9886,10 @@ msgid "Secret %(uuid)s is used by %(named)s; remove it from them first"
msgstr ""
"%(uuid)s parolası %(named)s tarafından kullanılıyor; önce onlardan kaldırın"
#: webvirtcloud/settings.py:327
#: webvirtcloud/settings.py:332
msgid "Localhost"
msgstr "Yerel sunucu"
#: webvirtcloud/settings.py:328
#: webvirtcloud/settings.py:333
msgid "All interfaces"
msgstr "Tüm arabirimler"

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-05 08:41+0000\n"
"POT-Creation-Date: 2026-11-05 12:53+0000\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@ -2807,7 +2807,7 @@ msgstr "libvirt 没有复制的结果;请检查这些卷,然后处理此任
msgid "Create VM"
msgstr "创建虚拟机"
#: instances/jobs.py:756 instances/views.py:2480
#: instances/jobs.py:756 instances/views.py:2482
msgid "A virtual machine with this name already exists"
msgstr "同名虚拟机已存在"
@ -3157,7 +3157,7 @@ msgid "Disk source"
msgstr "磁盘来源"
#: instances/templates/add_instance_volume.html:21
#: instances/templates/create_instance_w2.html:134 instances/views.py:2499
#: instances/templates/create_instance_w2.html:134 instances/views.py:2501
msgid "New disk"
msgstr "新磁盘"
@ -3521,7 +3521,7 @@ msgstr "自定义 CPU 型号"
msgid "Size (GiB)"
msgstr "大小(GiB)"
#: instances/templates/create_instance_w2.html:161 instances/views.py:2500
#: instances/templates/create_instance_w2.html:161 instances/views.py:2502
msgid "Existing volumes"
msgstr "已有卷"
@ -3557,7 +3557,7 @@ msgstr "设备"
msgid "Remove"
msgstr "移除"
#: instances/templates/create_instance_w2.html:194 instances/views.py:2501
#: instances/templates/create_instance_w2.html:194 instances/views.py:2503
msgid "Clone from template"
msgstr "从模板克隆"
@ -5571,45 +5571,45 @@ msgstr "请输入 IP 地址、网络(如 192.0.2.0/24)或 MAC 地址。"
msgid "Too many searches are still running; try again shortly."
msgstr "仍在运行的搜索过多;请稍后再试。"
#: instances/views.py:257
#: instances/views.py:259
#, python-format
msgid "The host %(host)s of '%(name)s' cannot be reached: %(error)s"
msgstr "无法连接“%(name)s”所在的主机 %(host)s:%(error)s"
#: instances/views.py:263
#: instances/views.py:265
#, python-format
msgid "The host of '%(name)s' cannot be reached right now."
msgstr "目前无法连接“%(name)s”所在的主机。"
#: instances/views.py:264
#: instances/views.py:266
msgid " Jobs on it can be followed under Jobs in the menu."
msgstr " 其上的任务可在菜单的“任务”中跟踪。"
#: instances/views.py:366
#: instances/views.py:368
msgid "There is no other host to migrate to."
msgstr "没有其他可迁移到的主机。"
#: instances/views.py:368
#: instances/views.py:370
msgid "A VM migrates when it is running, paused or shut off."
msgstr "虚拟机在运行、暂停或关机状态下均可迁移。"
#: instances/views.py:370
#: instances/views.py:372
msgid ""
"A VM with snapshots cannot be migrated: its snapshots stay on this host. "
"Delete them first."
msgstr "有快照的虚拟机无法迁移:其快照保留在本主机上。请先删除快照。"
#: instances/views.py:372
#: instances/views.py:374
msgid ""
"A VM with host devices cannot be migrated: the destination may not have them."
" Remove them first."
msgstr "有主机设备的虚拟机无法迁移:目标主机可能没有这些设备。请先移除它们。"
#: instances/views.py:634
#: instances/views.py:636
msgid "The VM was moved meanwhile; try again."
msgstr "该虚拟机在此期间已被移动;请重试。"
#: instances/views.py:746
#: instances/views.py:748
msgid ""
"The running VM has no free PCI slot for another disk on this bus: choose the "
"scsi bus if the VM has a SCSI controller, or shut the VM down and add the "
@ -5619,7 +5619,7 @@ msgstr ""
"运行中的虚拟机在此总线上没有可用 PCI 插槽来添加磁盘:如果虚拟机有 SCSI 控制器,请选择 scsi "
"总线;或关闭虚拟机后再添加磁盘。“磁盘”选项卡上的“添加 PCIe 插槽”可使其从下次启动起获得可用插槽。新卷会保留在其存储池中,可作为现有卷挂载。"
#: instances/views.py:750
#: instances/views.py:752
msgid ""
"The running VM has no free PCI slot for the SCSI controller the disk needs: "
"shut the VM down and add the disk then; Add PCIe slots on the Disks tab gives"
@ -5629,272 +5629,272 @@ msgstr ""
"运行中的虚拟机没有可用 PCI 插槽来添加磁盘所需的 SCSI 控制器:请关闭虚拟机后再添加磁盘。“磁盘”选项卡上的“添加 PCIe "
"插槽”可使其从下次启动起获得可用插槽。新卷会保留在其存储池中,可作为现有卷挂载。"
#: instances/views.py:768
#: instances/views.py:770
#, python-format
msgid "Invalid disk options: %(options)s"
msgstr "无效的磁盘选项:%(options)s"
#: instances/views.py:778 instances/views.py:793
#: instances/views.py:780 instances/views.py:795
msgid "Templates cannot be started."
msgstr "模板无法启动。"
#: instances/views.py:889
#: instances/views.py:891
#, python-format
msgid "Disk %(path)s was kept: a disk file that stays needs it"
msgstr "磁盘 %(path)s 已保留:某个保留的磁盘文件依赖它"
#: instances/views.py:895
#: instances/views.py:897
#, python-format
msgid "The VM is removed, but disk %(path)s was not deleted: %(err)s"
msgstr "虚拟机已删除,但磁盘 %(path)s 未被删除:%(err)s"
#: instances/views.py:904
#: instances/views.py:906
#, python-format
msgid "Disk %(path)s is used by another VM and was kept"
msgstr "磁盘 %(path)s 正被另一台虚拟机使用,已保留"
#: instances/views.py:1026
#: instances/views.py:1028
#, python-format
msgid "Set the gstfsd key of %(compute)s first (Computes, edit the host)"
msgstr "请先设置 %(compute)s 的 gstfsd 密钥(计算节点,编辑该主机)"
#: instances/views.py:1033 instances/views.py:1048 instances/views.py:1057
#: instances/views.py:1035 instances/views.py:1050 instances/views.py:1059
#, python-format
msgid "gstfsd error: %(err)s"
msgstr "gstfsd 错误:%(err)s"
#: instances/views.py:1058
#: instances/views.py:1060
msgid "the reply is not signed with the key"
msgstr "回复未使用该密钥签名"
#: instances/views.py:1066
#: instances/views.py:1068
msgid "Shut the VM down, or start its QEMU guest agent, and try again"
msgstr "请关闭虚拟机,或启动其 QEMU 客户机代理,然后重试"
#: instances/views.py:1079
#: instances/views.py:1081
msgid "The change may still be made when the agent answers again."
msgstr "当代理再次响应时,此更改仍可能生效。"
#: instances/views.py:1106
#: instances/views.py:1108
msgid "Reset root password"
msgstr "重置 root 密码"
#: instances/views.py:1110
#: instances/views.py:1112
msgid "Enter a password"
msgstr "请输入密码"
#: instances/views.py:1124
#: instances/views.py:1126
msgid "Select an SSH public key"
msgstr "请选择 SSH 公钥"
#: instances/views.py:1146
#: instances/views.py:1148
#, python-format
msgid "Installed new SSH public key %(keyname)s"
msgstr "已安装新的 SSH 公钥 %(keyname)s"
#: instances/views.py:1166
#: instances/views.py:1168
msgid "Enter a whole number of vCPUs"
msgstr "请输入整数个 vCPU"
#: instances/views.py:1170
#: instances/views.py:1172
msgid "Shut off the VM to change its vCPUs"
msgstr "请关闭虚拟机以更改其 vCPU"
#: instances/views.py:1173
#: instances/views.py:1175
msgid "The current vCPUs cannot be more than the maximum"
msgstr "当前 vCPU 数不能超过最大值"
#: instances/views.py:1180
#: instances/views.py:1182
#, python-format
msgid "%(quota)s: cannot resize the CPU of '%(instance_name)s'."
msgstr "%(quota)s:无法调整“%(instance_name)s”的 CPU。"
#: instances/views.py:1188
#: instances/views.py:1190
#, python-format
msgid "vCPUs set to %(cur)s (maximum %(max)s)"
msgstr "vCPU 已设为 %(cur)s(最大 %(max)s)"
#: instances/views.py:1207
#: instances/views.py:1209
msgid "Enter a whole number for memory"
msgstr "请输入整数内存值"
#: instances/views.py:1210
#: instances/views.py:1212
msgid "The current memory cannot be more than the maximum"
msgstr "当前内存不能超过最大值"
#: instances/views.py:1214
#: instances/views.py:1216
#, python-format
msgid "%(quota)s: cannot resize the memory of '%(instance_name)s'."
msgstr "%(quota)s:无法调整“%(instance_name)s”的内存。"
#: instances/views.py:1220
#: instances/views.py:1222
#, python-format
msgid "Memory set to %(cur)s MiB (maximum %(max)s MiB)"
msgstr "内存已设为 %(cur)s MiB(最大 %(max)s MiB)"
#: instances/views.py:1240
#: instances/views.py:1242
msgid "Enter disk sizes as whole GiB"
msgstr "请以整数 GiB 输入磁盘大小"
#: instances/views.py:1244
#: instances/views.py:1246
#, python-format
msgid "%(dev)s is %(size)s: a disk cannot shrink"
msgstr "%(dev)s 为 %(size)s:磁盘不能缩小"
#: instances/views.py:1252
#: instances/views.py:1254
msgid "No disks were selected or valid for resizing."
msgstr "未选择磁盘或没有可调整大小的有效磁盘。"
#: instances/views.py:1261
#: instances/views.py:1263
#, python-format
msgid "%(quota)s: cannot resize the disks of '%(instance_name)s'."
msgstr "%(quota)s:无法调整“%(instance_name)s”的磁盘。"
#: instances/views.py:1273
#: instances/views.py:1275
#, python-format
msgid "The storage pool of %(dev)s cannot resize its volumes"
msgstr "%(dev)s 所在的存储池无法调整其卷的大小"
#: instances/views.py:1275
#: instances/views.py:1277
#, python-format
msgid "Disk is resized: %(dev)s"
msgstr "磁盘已调整大小:%(dev)s"
#: instances/views.py:1369
#: instances/views.py:1371
msgid "The VM's machine has no PCIe slots to add"
msgstr "该虚拟机的机器类型没有可添加的 PCIe 插槽"
#: instances/views.py:1374
#: instances/views.py:1376
#, python-format
msgid "%(count)s PCIe slots added"
msgstr "已添加 %(count)s 个 PCIe 插槽"
#: instances/views.py:1376
#: instances/views.py:1378
#, python-format
msgid "%(count)s PCIe slots added: the VM gets them at its next start"
msgstr "已添加 %(count)s 个 PCIe 插槽:虚拟机在下次启动时获得它们"
#: instances/views.py:1422
#: instances/views.py:1424
#, python-format
msgid "%(volume)s is already a disk of this VM"
msgstr "%(volume)s 已是此虚拟机的磁盘"
#: instances/views.py:1512
#: instances/views.py:1514
msgid "Volume changes are applied. But it will be activated after shutdown"
msgstr "卷更改已应用,但将在关机后生效"
#: instances/views.py:1517
#: instances/views.py:1519
msgid "Volume is changed successfully."
msgstr "卷已成功更改。"
#: instances/views.py:1535
#: instances/views.py:1537
#, python-format
msgid "Disk %(dev)s is not a storage volume of this instance"
msgstr "磁盘 %(dev)s 不是此虚拟机的存储卷"
#: instances/views.py:1542
#: instances/views.py:1544
#, python-format
msgid "Disk %(dev)s has a pending change; delete it once the VM is shut down"
msgstr "磁盘 %(dev)s 有待生效的更改;请在虚拟机关机后删除它"
#: instances/views.py:1557
#: instances/views.py:1559
#, python-format
msgid "Volume %(vol)s is used by another VM; detach it instead"
msgstr "卷 %(vol)s 正被另一台虚拟机使用;请改为分离它"
#: instances/views.py:1569
#: instances/views.py:1571
#, python-format
msgid ""
"The guest has not released disk %(dev)s yet; volume %(vol)s was kept. Delete "
"it from the storage pool once the VM is shut down."
msgstr "客户机尚未释放磁盘 %(dev)s;卷 %(vol)s 已保留。请在虚拟机关机后从存储池中删除它。"
#: instances/views.py:1580
#: instances/views.py:1582
#, python-format
msgid "Disk %(dev)s was detached, but its volume was kept: %(err)s"
msgstr "磁盘 %(dev)s 已分离,但其卷已保留:%(err)s"
#: instances/views.py:1606
#: instances/views.py:1608
#, python-format
msgid "This VM cannot take a CD-ROM on the %(bus)s bus now"
msgstr "该虚拟机现在无法在 %(bus)s 总线上添加 CD-ROM"
#: instances/views.py:1609
#: instances/views.py:1611
msgid "A USB CD-ROM needs an ISO image: libvirt has no empty USB drive"
msgstr "USB CD-ROM 需要 ISO 镜像:libvirt 不支持空的 USB 驱动器"
#: instances/views.py:1690
#: instances/views.py:1692
#, python-format
msgid "Pool %(pool)s was not read again: %(err)s"
msgstr "未重新读取存储池 %(pool)s:%(err)s"
#: instances/views.py:1711
#: instances/views.py:1713
#, python-format
msgid "Snapshot was not deleted: %(err)s"
msgstr "快照未删除:%(err)s"
#: instances/views.py:1826
#: instances/views.py:1828
msgid "Add at least one device to the boot order."
msgstr "请至少向启动顺序中添加一个设备。"
#: instances/views.py:1840
#: instances/views.py:1842
msgid "Boot order changed. It applies at the next start."
msgstr "启动顺序已更改,将在下次启动时生效。"
#: instances/views.py:1842
#: instances/views.py:1844
msgid "Boot order changed successfully."
msgstr "启动顺序已成功更改。"
#: instances/views.py:1862
#: instances/views.py:1864
msgid "The XML is empty"
msgstr "XML 为空"
#: instances/views.py:1866 instances/views.py:2490
#: instances/views.py:1868 instances/views.py:2492
#, python-format
msgid "The XML is not well-formed: %(error)s"
msgstr "XML 格式不正确:%(error)s"
#: instances/views.py:1868
#: instances/views.py:1870
#, python-format
msgid "The XML must keep the VM's UUID %(uuid)s."
msgstr "XML 必须保留虚拟机的 UUID %(uuid)s。"
#: instances/views.py:1872
#: instances/views.py:1874
msgid ""
"The definition has changed since the editor was opened. Reload the page to "
"edit the current one."
msgstr "自打开编辑器以来定义已被更改。请重新加载页面以编辑当前定义。"
#: instances/views.py:1884
#: instances/views.py:1886
msgid "The XML definition was saved."
msgstr "XML 定义已保存。"
#: instances/views.py:1886
#: instances/views.py:1888
msgid "The XML definition was saved; the VM uses it from its next start."
msgstr "XML 定义已保存;虚拟机从下次启动起使用它。"
#: instances/views.py:1967
#: instances/views.py:1969
msgid "Select one network interface to change"
msgstr "请选择一个要更改的网络接口"
#: instances/views.py:2005
#: instances/views.py:2007
msgid "Network Device Config is changed. Please shutdown instance to activate."
msgstr "网络设备配置已更改。请关闭虚拟机以使其生效。"
#: instances/views.py:2007
#: instances/views.py:2009
msgid "Network device changed"
msgstr "网络设备已更改"
#: instances/views.py:2019
#: instances/views.py:2021
msgid "No network selected"
msgstr "未选择网络"
#: instances/views.py:2024
#: instances/views.py:2026
#, python-format
msgid "The VM already has a network device with MAC %(mac)s"
msgstr "虚拟机已有 MAC 地址为 %(mac)s 的网络设备"
#: instances/views.py:2043
#: instances/views.py:2045
msgid ""
"The running VM has no free PCI slot for another network device: shut it down "
"and add the device then; Add PCIe slots on the Disks tab gives it free ones "
@ -5902,137 +5902,137 @@ msgid ""
msgstr ""
"运行中的虚拟机没有可用 PCI 插槽来添加网络设备:请关机后再添加设备。“磁盘”选项卡上的“添加 PCIe 插槽”可使其从下次启动起获得可用插槽。"
#: instances/views.py:2084 instances/views.py:2090
#: instances/views.py:2086 instances/views.py:2092
msgid "The VM has it"
msgstr "虚拟机已有此设备"
#: instances/views.py:2121
#: instances/views.py:2123
#, python-format
msgid "The host has no USB device %(device)s"
msgstr "主机上没有 USB 设备 %(device)s"
#: instances/views.py:2142
#: instances/views.py:2144
#, python-format
msgid "The host has no PCI device %(device)s"
msgstr "主机上没有 PCI 设备 %(device)s"
#: instances/views.py:2160
#: instances/views.py:2162
#, python-format
msgid ""
"Removal of PCI device %(address)s requested: the guest has not let it go yet;"
" it stays in the running VM until it does or the VM stops."
msgstr "已请求移除 PCI 设备 %(address)s:客户机尚未释放它;在客户机释放或虚拟机停止之前,它仍保留在运行中的虚拟机中。"
#: instances/views.py:2205 instances/views.py:2235
#: instances/views.py:2207 instances/views.py:2237
msgid "Select a network interface and a QoS direction"
msgstr "请选择网络接口和 QoS 方向"
#: instances/views.py:2208 vrtManager/network.py:459
#: instances/views.py:2210 vrtManager/network.py:459
msgid "QoS rates must be whole numbers"
msgstr "QoS 速率必须为整数"
#: instances/views.py:2215 networks/views.py:229
#: instances/views.py:2217 networks/views.py:229
#, python-format
msgid "%(qos_dir)s QoS is set"
msgstr "%(qos_dir)s QoS 已设置"
#: instances/views.py:2220
#: instances/views.py:2222
#, python-format
msgid ""
"%(qos_dir)s QoS is set. A running VM gets it after it is powered off and on."
msgstr "%(qos_dir)s QoS 已设置。运行中的虚拟机需关机再开机后才能生效。"
#: instances/views.py:2242 networks/views.py:255
#: instances/views.py:2244 networks/views.py:255
#, python-format
msgid "%(qos_dir)s QoS is deleted"
msgstr "%(qos_dir)s QoS 已删除"
#: instances/views.py:2247
#: instances/views.py:2249
#, python-format
msgid ""
"%(qos_dir)s QoS is deleted. A running VM keeps the old limit until it is "
"powered off and on."
msgstr "%(qos_dir)s QoS 已删除。运行中的虚拟机在关机再开机之前保留旧的限制。"
#: instances/views.py:2275
#: instances/views.py:2277
msgid "Only one owner is allowed and the one already added"
msgstr "只允许一个所有者,且已添加"
#: instances/views.py:2277
#: instances/views.py:2279
#, python-format
msgid "%(user)s is already an owner"
msgstr "%(user)s 已是所有者"
#: instances/views.py:2321
#: instances/views.py:2323
#, python-format
msgid "Console settings were not saved: %(errors)s"
msgstr "控制台设置未保存:%(errors)s"
#: instances/views.py:2343
#: instances/views.py:2345
msgid ""
"Error setting console password. You should check that your instance have an "
"graphic device."
msgstr "设置控制台密码出错。请检查虚拟机是否有图形设备。"
#: instances/views.py:2390
#: instances/views.py:2392
msgid "Shut the VM down to change whether it is a template."
msgstr "请关闭虚拟机以更改其是否为模板。"
#: instances/views.py:2396
#: instances/views.py:2398
#, python-format
msgid "%(quota)s: '%(instance_name)s' stays a template."
msgstr "%(quota)s:“%(instance_name)s”仍为模板。"
#: instances/views.py:2478
#: instances/views.py:2480
msgid "The XML has no name"
msgstr "XML 中没有名称"
#: instances/views.py:2492 webvirtcloud/middleware.py:79
#: instances/views.py:2494 webvirtcloud/middleware.py:126
#, python-format
msgid "libvirt Error - %(exception)s"
msgstr "libvirt 错误 - %(exception)s"
#: instances/views.py:2499
#: instances/views.py:2501
msgid "An empty disk of the size you set"
msgstr "按设定大小创建的空磁盘"
#: instances/views.py:2500
#: instances/views.py:2502
msgid "Volumes already in a pool"
msgstr "存储池中已有的卷"
#: instances/views.py:2501
#: instances/views.py:2503
msgid "A copy of a template volume"
msgstr "模板卷的副本"
#: instances/views.py:2590
#: instances/views.py:2592
msgid "You haven't defined any storage pools"
msgstr "您尚未定义任何存储池"
#: instances/views.py:2592
#: instances/views.py:2594
msgid "You haven't defined any network pools"
msgstr "您尚未定义任何网络池"
#: instances/views.py:2655
#: instances/views.py:2657
msgid "Flavor Created"
msgstr "规格已创建"
#: instances/views.py:2663
#: instances/views.py:2665
msgid "Create Flavor"
msgstr "创建规格"
#: instances/views.py:2678
#: instances/views.py:2680
msgid "Flavor Updated"
msgstr "规格已更新"
#: instances/views.py:2684
#: instances/views.py:2686
msgid "Update Flavor"
msgstr "更新规格"
#: instances/views.py:2696
#: instances/views.py:2698
msgid "Flavor Deleted"
msgstr "规格已删除"
#: instances/views.py:2702
#: instances/views.py:2704
msgid "Only the size template goes; VMs made from it keep their size."
msgstr "仅删除此规格;由它创建的虚拟机保持其大小。"
@ -7454,19 +7454,25 @@ msgstr "取消失败:无法连接到服务器。"
msgid "The host of this virtual machine cannot be reached right now."
msgstr "当前无法连接此虚拟机所在的主机。"
#: operations/utils.py:157
#: operations/utils.py:53
msgid ""
"The host of this virtual machine is busy with other requests right now: try "
"again in a moment."
msgstr "此虚拟机所在的主机正忙于处理其他请求:请稍后重试。"
#: operations/utils.py:160
msgid ""
"A short operation is in progress on this resource; try again in a moment."
msgstr "此资源上正在进行一项短时操作,请稍后重试。"
#: operations/utils.py:160
#: operations/utils.py:163
#, python-format
msgid ""
"%(label)s is %(state)s on this resource (started by %(user)s, %(since)s ago);"
" see the Jobs page."
msgstr "此资源上的%(label)s%(state)s(由 %(user)s 于 %(since)s前发起),请查看任务页面。"
#: operations/utils.py:162
#: operations/utils.py:165
#, python-format
msgid "%(label)s is %(state)s on this resource (since %(since)s)."
msgstr "此资源上的%(label)s%(state)s(自 %(since)s起)。"
@ -8362,49 +8368,49 @@ msgid ""
"encrypted anew."
msgstr "新值会立即替换旧值;之前用口令加密的内容不会重新加密。"
#: vrtManager/connection.py:50
#: vrtManager/connection.py:51
msgid "Connection closed (error)"
msgstr "连接已关闭(错误)"
#: vrtManager/connection.py:51
#: vrtManager/connection.py:52
msgid "Connection closed (end of file)"
msgstr "连接已关闭(文件结束)"
#: vrtManager/connection.py:52
#: vrtManager/connection.py:53
msgid "Connection closed (keepalive timeout)"
msgstr "连接已关闭(保活超时)"
#: vrtManager/connection.py:53
#: vrtManager/connection.py:54
msgid "Connection closed (client closed)"
msgstr "连接已关闭(客户端已关闭)"
#: vrtManager/connection.py:139
#: vrtManager/connection.py:147
#, python-format
msgid ""
"Connection Failed: %(host)s does not answer: %(requests)s requests still wait"
" for it"
msgstr "连接失败:%(host)s 无响应:仍有 %(requests)s 个请求在等待它"
#: vrtManager/connection.py:210
#: vrtManager/connection.py:219
#, python-format
msgid "Connection Failed: %(host)s did not answer within %(seconds)s s"
msgstr "连接失败:%(host)s 在 %(seconds)s 秒内未响应"
#: vrtManager/connection.py:220
#: vrtManager/connection.py:230
msgid "the connection closed right after opening"
msgstr "连接在打开后立即关闭"
#: vrtManager/connection.py:233
#: vrtManager/connection.py:243
#, python-format
msgid "Connection Failed: %(error)s"
msgstr "连接失败:%(error)s"
#: vrtManager/connection.py:293
#: vrtManager/connection.py:312
#, python-format
msgid "Connection closed (%(reason)s)"
msgstr "连接已关闭(%(reason)s)"
#: vrtManager/connection.py:435
#: vrtManager/connection.py:455
#, python-format
msgid "Connection Failed: %(host)s is not connected"
msgstr "连接失败:%(host)s 未连接"
@ -9298,12 +9304,12 @@ 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:140
#: vrtManager/util.py:145
#, python-format
msgid "The XML is not valid: %(err)s"
msgstr "XML 无效:%(err)s"
#: vrtManager/util.py:142
#: vrtManager/util.py:147
msgid "The XML may not declare a DTD"
msgstr "XML 不能声明 DTD"
@ -9326,10 +9332,10 @@ msgstr "存储池 %(names)s"
msgid "Secret %(uuid)s is used by %(named)s; remove it from them first"
msgstr "机密 %(uuid)s 正被 %(named)s 使用;请先从中移除它"
#: webvirtcloud/settings.py:327
#: webvirtcloud/settings.py:332
msgid "Localhost"
msgstr "本机"
#: webvirtcloud/settings.py:328
#: webvirtcloud/settings.py:333
msgid "All interfaces"
msgstr "所有接口"

View file

@ -19,7 +19,7 @@ from libvirt import libvirtError
from accounts.models import UserInstance
from appsettings.models import AppSettings
from instances.models import Instance
from vrtManager.util import ConnectionFailed, OperationError, render
from vrtManager.util import ConnectionFailed, HostBusy, OperationError, render
from . import jobs
@ -50,6 +50,7 @@ TRANSPORT_ERROR_CODES = {
libvirt.VIR_ERR_LIBSSH,
}
UNREACHABLE = gettext_noop("The host of this virtual machine cannot be reached right now.")
HOST_BUSY = gettext_noop("The host of this virtual machine is busy with other requests right now: try again in a moment.")
BOUNDS = {"WORKER_CONCURRENCY": (1, 16, 4), "JOB_RETENTION_DAYS": (1, 3650, 30), "LOG_RETENTION_DAYS": (1, 3650, 365)}
@ -102,6 +103,8 @@ def public_error(exception):
and exception.get_error_domain() in TRANSPORT_ERROR_DOMAINS
and exception.get_error_code() in TRANSPORT_ERROR_CODES
)
if isinstance(exception, HostBusy):
return say(HOST_BUSY)
return say(UNREACHABLE) if connection_error else said(exception)

View file

@ -144,8 +144,8 @@ def _count_on(connection):
_leave_host()
if not connection.requests.acquire(timeout=CONNECT_TIMEOUT):
logger.warning("%s: request refused, %s requests still wait for the host", connection.host, HOST_REQUESTS)
raise util.ConnectionFailed(gettext_noop("Connection Failed: %(host)s does not answer: %(requests)s requests still wait for it"),
host=connection.host, requests=HOST_REQUESTS)
raise util.HostBusy(gettext_noop("Connection Failed: %(host)s does not answer: %(requests)s requests still wait for it"),
host=connection.host, requests=HOST_REQUESTS)
_request.held = connection

View file

@ -56,6 +56,11 @@ class ConnectionFailed(OperationError):
is reached."""
class HostBusy(ConnectionFailed):
"""The host is connected, but this process's web requests to it
(HOST_REQUESTS) still wait for its answers."""
def is_kvm_available(xml):
kvm_domains = get_xml_path(xml, "//domain/@type='kvm'")
return kvm_domains > 0