diff --git a/instances/tests/test_host_busy.py b/instances/tests/test_host_busy.py new file mode 100644 index 00000000..1c7e1cf2 --- /dev/null +++ b/instances/tests/test_host_busy.py @@ -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."]) diff --git a/instances/views.py b/instances/views.py index 319bf07a..b843fe0a 100755 --- a/instances/views.py +++ b/instances/views.py @@ -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, diff --git a/locale/tr/LC_MESSAGES/django.mo b/locale/tr/LC_MESSAGES/django.mo index d42e8243..13c2b904 100644 Binary files a/locale/tr/LC_MESSAGES/django.mo and b/locale/tr/LC_MESSAGES/django.mo differ diff --git a/locale/tr/LC_MESSAGES/django.po b/locale/tr/LC_MESSAGES/django.po index 0634a4f8..0481f342 100644 --- a/locale/tr/LC_MESSAGES/django.po +++ b/locale/tr/LC_MESSAGES/django.po @@ -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 , 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" diff --git a/locale/zh/LC_MESSAGES/django.mo b/locale/zh/LC_MESSAGES/django.mo index 2b9314be..48c08d03 100644 Binary files a/locale/zh/LC_MESSAGES/django.mo and b/locale/zh/LC_MESSAGES/django.mo differ diff --git a/locale/zh/LC_MESSAGES/django.po b/locale/zh/LC_MESSAGES/django.po index f844f414..97a5f4c8 100644 --- a/locale/zh/LC_MESSAGES/django.po +++ b/locale/zh/LC_MESSAGES/django.po @@ -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 "所有接口" diff --git a/operations/utils.py b/operations/utils.py index d0321949..a8486e20 100644 --- a/operations/utils.py +++ b/operations/utils.py @@ -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) diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 7f19059c..398f3a42 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -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 diff --git a/vrtManager/util.py b/vrtManager/util.py index eda7ae6a..8fd232d4 100644 --- a/vrtManager/util.py +++ b/vrtManager/util.py @@ -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