mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
feat(operations): the Logs page's rows and expired sessions are removed
Nothing removed the Logs page's rows, which every action and every failed login adds, or the database sessions past their expiry. The job worker's housekeeping now deletes the rows older than Log Retention Days, a new setting under Lists and pages (1-3650, 365 by default), and the expired sessions.
This commit is contained in:
parent
93b420ae81
commit
b2deb042e8
10 changed files with 243 additions and 173 deletions
30
appsettings/migrations/0024_log_retention_setting.py
Normal file
30
appsettings/migrations/0024_log_retention_setting.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from django.core.management.color import no_style
|
||||
from django.db import migrations
|
||||
from django.utils.translation import gettext_noop as _
|
||||
|
||||
|
||||
SETTING = (_("Log Retention Days"), "LOG_RETENTION_DAYS", "365", _("Days the Logs page keeps its rows (1-3650)"))
|
||||
|
||||
|
||||
def add_setting(apps, schema_editor):
|
||||
setting = apps.get_model("appsettings", "AppSettings")
|
||||
db_alias = schema_editor.connection.alias
|
||||
# see 0014: move a PostgreSQL id sequence past the fixed ids first
|
||||
with schema_editor.connection.cursor() as cursor:
|
||||
for sql in schema_editor.connection.ops.sequence_reset_sql(no_style(), [setting]):
|
||||
cursor.execute(sql)
|
||||
name, key, value, description = SETTING
|
||||
setting.objects.using(db_alias).get_or_create(
|
||||
key=key, defaults={"name": name, "value": value, "choices": "", "description": description}
|
||||
)
|
||||
|
||||
|
||||
def del_setting(apps, schema_editor):
|
||||
apps.get_model("appsettings", "AppSettings").objects.using(schema_editor.connection.alias).filter(
|
||||
key=SETTING[1]).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [("appsettings", "0023_remove_bottom_bar")]
|
||||
|
||||
operations = [migrations.RunPython(add_setting, del_setting)]
|
||||
|
|
@ -55,7 +55,7 @@ class SnapshotFreeSpaceSettingsTestCase(TestCase):
|
|||
|
||||
class WorkerSettingsTestCase(TestCase):
|
||||
def test_the_rows_fit_their_columns(self):
|
||||
for key in ("WORKER_CONCURRENCY", "JOB_RETENTION_DAYS"):
|
||||
for key in ("WORKER_CONCURRENCY", "JOB_RETENTION_DAYS", "LOG_RETENTION_DAYS"):
|
||||
setting = AppSettings.objects.get(key=key)
|
||||
for field in ("name", "key", "value", "description"):
|
||||
limit = AppSettings._meta.get_field(field).max_length
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ GROUPS = [
|
|||
(gettext_noop("Snapshots and jobs"), ["SNAPSHOT_FREE_SPACE_PERCENT", "SNAPSHOT_FREE_SPACE_MIN_GIB",
|
||||
"WORKER_CONCURRENCY", "JOB_RETENTION_DAYS"]),
|
||||
(gettext_noop("Login"), ["LOGIN_FAILURE_LIMIT", "LOGIN_LOCKOUT_MINUTES"]),
|
||||
(gettext_noop("Lists and pages"), ["VIEW_INSTANCES_LIST_STYLE", "VM_DRBD_STATUS", "LOGS_PER_PAGE"]),
|
||||
(gettext_noop("Lists and pages"), ["VIEW_INSTANCES_LIST_STYLE", "VM_DRBD_STATUS", "LOGS_PER_PAGE",
|
||||
"LOG_RETENTION_DAYS"]),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -11,7 +11,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-11-04 19:51+0000\n"
|
||||
"POT-Creation-Date: 2026-11-05 06:39+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"
|
||||
|
|
@ -1636,6 +1636,14 @@ msgstr "Sanal Makineler sayfası her sanal makinenin DRBD durumunu gösterir"
|
|||
msgid "Rows per page on the Logs page"
|
||||
msgstr "Loglar sayfasında sayfa başına satır"
|
||||
|
||||
#: appsettings/migrations/0024_log_retention_setting.py:6
|
||||
msgid "Log Retention Days"
|
||||
msgstr "Log saklama süresi (gün)"
|
||||
|
||||
#: appsettings/migrations/0024_log_retention_setting.py:6
|
||||
msgid "Days the Logs page keeps its rows (1-3650)"
|
||||
msgstr "Logs sayfasının satırları sakladığı gün sayısı (1-3650)"
|
||||
|
||||
#: appsettings/models.py:10
|
||||
msgid "key"
|
||||
msgstr "anahtar"
|
||||
|
|
@ -1729,41 +1737,41 @@ msgstr "Oturum açma"
|
|||
msgid "Lists and pages"
|
||||
msgstr "Listeler ve sayfalar"
|
||||
|
||||
#: appsettings/views.py:58
|
||||
#: appsettings/views.py:59
|
||||
#, python-format
|
||||
msgid "%(setting)s takes at most %(length)s characters"
|
||||
msgstr "%(setting)s en fazla %(length)s karakter alır"
|
||||
|
||||
#: appsettings/views.py:63
|
||||
#: appsettings/views.py:64
|
||||
#, python-format
|
||||
msgid "%(setting)s must be a whole number between %(low)s and %(high)s"
|
||||
msgstr "%(setting)s, %(low)s ile %(high)s arasında bir tam sayı olmalıdır"
|
||||
|
||||
#: appsettings/views.py:66
|
||||
#: appsettings/views.py:67
|
||||
#, python-format
|
||||
msgid "%(setting)s must be one of %(choices)s"
|
||||
msgstr "%(setting)s şunlardan biri olmalıdır: %(choices)s"
|
||||
|
||||
#: appsettings/views.py:84
|
||||
#: appsettings/views.py:85
|
||||
#, python-format
|
||||
msgid "Unknown theme: %(theme)s"
|
||||
msgstr "Bilinmeyen tema: %(theme)s"
|
||||
|
||||
#: appsettings/views.py:90
|
||||
#: appsettings/views.py:91
|
||||
#, python-format
|
||||
msgid "Theme is changed. Now: %(theme)s"
|
||||
msgstr "Tema değiştirildi. Şimdi: %(theme)s"
|
||||
|
||||
#: appsettings/views.py:113
|
||||
#: appsettings/views.py:114
|
||||
#, python-format
|
||||
msgid "Saved: %(settings)s"
|
||||
msgstr "Kaydedildi: %(settings)s"
|
||||
|
||||
#: appsettings/views.py:115
|
||||
#: appsettings/views.py:116
|
||||
msgid "Nothing changed"
|
||||
msgstr "Hiçbir şey değişmedi"
|
||||
|
||||
#: appsettings/views.py:122 vrtManager/nodedevs.py:219
|
||||
#: appsettings/views.py:123 vrtManager/nodedevs.py:219
|
||||
#: vrtManager/nodedevs.py:258
|
||||
msgid "Other"
|
||||
msgstr "Diğer"
|
||||
|
|
@ -2707,7 +2715,7 @@ msgstr "Klonun adını boş adlar listesinden seçin"
|
|||
msgid "%(quota)s: cannot create '%(clone_name)s'."
|
||||
msgstr "%(quota)s: '%(clone_name)s' oluşturulamıyor."
|
||||
|
||||
#: instances/jobs.py:196 instances/jobs.py:533
|
||||
#: instances/jobs.py:196 instances/jobs.py:543
|
||||
#, python-format
|
||||
msgid "Instance '%(clone_name)s' already exists!"
|
||||
msgstr "'%(clone_name)s' sanal makinesi zaten mevcut!"
|
||||
|
|
@ -2732,11 +2740,11 @@ msgstr "Disk adı '%(disk_name)s' geçersiz karakterler içeriyor!"
|
|||
msgid "The clone is made, but not as asked: %(error)s"
|
||||
msgstr "Klon oluşturuldu, ama istendiği gibi değil: %(error)s"
|
||||
|
||||
#: instances/jobs.py:271
|
||||
#: instances/jobs.py:279
|
||||
msgid "The VM was not defined and no volume of it was left."
|
||||
msgstr "Sanal makine tanımlanmadı ve ondan geriye birim kalmadı."
|
||||
|
||||
#: instances/jobs.py:273
|
||||
#: instances/jobs.py:281
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The VM was not defined; check these volumes, then resolve this job: "
|
||||
|
|
@ -2745,28 +2753,28 @@ msgstr ""
|
|||
"Sanal makine tanımlanmadı; şu birimleri kontrol edin, sonra bu işi çözün: "
|
||||
"%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:294
|
||||
#: instances/jobs.py:302
|
||||
msgid "Delete snapshot"
|
||||
msgstr "Anlık görüntüyü sil"
|
||||
|
||||
#: instances/jobs.py:304 vrtManager/instance.py:2286
|
||||
#: instances/jobs.py:312 vrtManager/instance.py:2286
|
||||
#, python-format
|
||||
msgid "The VM has no external snapshot named %(name)s"
|
||||
msgstr "Sanal makinede %(name)s adında harici anlık görüntü yok"
|
||||
|
||||
#: instances/jobs.py:317
|
||||
#: instances/jobs.py:325
|
||||
msgid "Merging the snapshot"
|
||||
msgstr "Anlık görüntü birleştiriliyor"
|
||||
|
||||
#: instances/jobs.py:336
|
||||
#: instances/jobs.py:344
|
||||
msgid "The VM is no longer on its compute"
|
||||
msgstr "Sanal makine artık kendi sunucusunda değil"
|
||||
|
||||
#: instances/jobs.py:339
|
||||
#: instances/jobs.py:347
|
||||
msgid "libvirt is still merging the snapshot"
|
||||
msgstr "libvirt anlık görüntüyü hâlâ birleştiriyor"
|
||||
|
||||
#: instances/jobs.py:347
|
||||
#: instances/jobs.py:355
|
||||
msgid ""
|
||||
"The snapshot is still listed and no merge runs. It cannot be told whether the"
|
||||
" disks changed; check the VM before deleting the snapshot again or reverting "
|
||||
|
|
@ -2776,44 +2784,44 @@ msgstr ""
|
|||
"değişmediği bilinemiyor; anlık görüntüyü yeniden silmeden ya da ona dönmeden "
|
||||
"önce sanal makineyi kontrol edin."
|
||||
|
||||
#: instances/jobs.py:354
|
||||
#: instances/jobs.py:362
|
||||
msgid "The VM is no longer on the compute the job ran on"
|
||||
msgstr "Sanal makine artık işin çalıştığı sunucuda değil"
|
||||
|
||||
#: instances/jobs.py:360
|
||||
#: instances/jobs.py:368
|
||||
msgid "Take snapshot"
|
||||
msgstr "Anlık görüntü al"
|
||||
|
||||
#: instances/jobs.py:372 vrtManager/instance.py:1882
|
||||
#: instances/jobs.py:380 vrtManager/instance.py:1882
|
||||
#, python-format
|
||||
msgid "A snapshot named %(name)s already exists"
|
||||
msgstr "%(name)s adında bir anlık görüntü zaten var"
|
||||
|
||||
#: instances/jobs.py:384
|
||||
#: instances/jobs.py:392
|
||||
msgid "Taking the snapshot"
|
||||
msgstr "Anlık görüntü alınıyor"
|
||||
|
||||
#: instances/jobs.py:397
|
||||
#: instances/jobs.py:405
|
||||
msgid "libvirt is still taking the snapshot"
|
||||
msgstr "libvirt anlık görüntüyü hâlâ alıyor"
|
||||
|
||||
#: instances/jobs.py:400
|
||||
#: instances/jobs.py:408
|
||||
msgid "The snapshot was not taken"
|
||||
msgstr "Anlık görüntü alınmadı"
|
||||
|
||||
#: instances/jobs.py:423
|
||||
#: instances/jobs.py:431
|
||||
msgid "Revert snapshot"
|
||||
msgstr "Snapshota dön"
|
||||
|
||||
#: instances/jobs.py:452
|
||||
#: instances/jobs.py:460
|
||||
msgid "Reverting the VM"
|
||||
msgstr "Sanal makine geri döndürülüyor"
|
||||
|
||||
#: instances/jobs.py:463
|
||||
#: instances/jobs.py:471
|
||||
msgid "libvirt is still reverting the VM"
|
||||
msgstr "libvirt sanal makineyi hâlâ geri döndürüyor"
|
||||
|
||||
#: instances/jobs.py:467
|
||||
#: instances/jobs.py:475
|
||||
msgid ""
|
||||
"It cannot be told whether the VM was reverted; check it, then revert again or"
|
||||
" resolve this job."
|
||||
|
|
@ -2821,12 +2829,12 @@ msgstr ""
|
|||
"Sanal makinenin geri döndürülüp döndürülmediği bilinemiyor; kontrol edin, "
|
||||
"sonra yeniden geri döndürün ya da bu işi çözün."
|
||||
|
||||
#: instances/jobs.py:484
|
||||
#: instances/jobs.py:492
|
||||
msgid "The VM must be running, paused or shut off to be cloned"
|
||||
msgstr ""
|
||||
"Klonlanmak için sanal makine çalışıyor, duraklatılmış ya da kapalı olmalı"
|
||||
|
||||
#: instances/jobs.py:485
|
||||
#: instances/jobs.py:493
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The guest's file systems could not be thawed (%(error)s); thaw them with: "
|
||||
|
|
@ -2835,19 +2843,19 @@ msgstr ""
|
|||
"Konuğun dosya sistemleri çözülemedi (%(error)s); şununla çözün: virsh "
|
||||
"domfsthaw %(vm)s"
|
||||
|
||||
#: instances/jobs.py:504
|
||||
#: instances/jobs.py:512
|
||||
msgid "Clone VM"
|
||||
msgstr "Sanal makineyi klonla"
|
||||
|
||||
#: instances/jobs.py:543 instances/jobs.py:550 instances/jobs.py:807
|
||||
#: instances/jobs.py:553 instances/jobs.py:560 instances/jobs.py:817
|
||||
msgid "Copying disks"
|
||||
msgstr "Diskler kopyalanıyor"
|
||||
|
||||
#: instances/jobs.py:602
|
||||
#: instances/jobs.py:612
|
||||
msgid "libvirt has no result of the copy"
|
||||
msgstr "libvirt'te kopyanın sonucu yok"
|
||||
|
||||
#: instances/jobs.py:613
|
||||
#: instances/jobs.py:623
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The copy failed: %(error)s. The guest's file systems could not be thawed "
|
||||
|
|
@ -2856,11 +2864,11 @@ msgstr ""
|
|||
"Kopyalama başarısız oldu: %(error)s. Konuğun dosya sistemleri çözülemedi "
|
||||
"(%(thaw)s); şununla çözün: virsh domfsthaw %(vm)s"
|
||||
|
||||
#: instances/jobs.py:616 instances/jobs.py:700
|
||||
#: instances/jobs.py:626 instances/jobs.py:710
|
||||
msgid "The copy failed"
|
||||
msgstr "Kopyalama başarısız oldu"
|
||||
|
||||
#: instances/jobs.py:641
|
||||
#: instances/jobs.py:651
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The VM is no longer on the compute the job ran on; check these volumes, then "
|
||||
|
|
@ -2869,7 +2877,7 @@ msgstr ""
|
|||
"Sanal makine artık işin çalıştığı sunucuda değil; şu birimleri kontrol edin, "
|
||||
"sonra bu işi çözün: %(volumes)s"
|
||||
|
||||
#: instances/jobs.py:676
|
||||
#: instances/jobs.py:686
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A volume of the clone was being created; check these volumes, then resolve "
|
||||
|
|
@ -2878,15 +2886,15 @@ msgstr ""
|
|||
"Klonun bir birimi oluşturuluyordu; şu birimleri kontrol edin, sonra bu işi "
|
||||
"çözün: %(volumes)s"
|
||||
|
||||
#: instances/jobs.py:680
|
||||
#: instances/jobs.py:690
|
||||
msgid "The job stopped before the copy started"
|
||||
msgstr "İş, kopyalama başlamadan durdu"
|
||||
|
||||
#: instances/jobs.py:687
|
||||
#: instances/jobs.py:697
|
||||
msgid "libvirt is still copying the disks"
|
||||
msgstr "libvirt diskleri hâlâ kopyalıyor"
|
||||
|
||||
#: instances/jobs.py:690
|
||||
#: instances/jobs.py:700
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Another backup runs on the VM; check these volumes, then resolve this job: "
|
||||
|
|
@ -2895,7 +2903,7 @@ msgstr ""
|
|||
"Sanal makinede başka bir yedekleme çalışıyor; şu birimleri kontrol edin, "
|
||||
"sonra bu işi çözün: %(volumes)s"
|
||||
|
||||
#: instances/jobs.py:695
|
||||
#: instances/jobs.py:705
|
||||
#, python-format
|
||||
msgid ""
|
||||
"libvirt has no result of the copy; check these volumes, then resolve this "
|
||||
|
|
@ -2904,140 +2912,140 @@ msgstr ""
|
|||
"libvirt'te kopyanın sonucu yok; şu birimleri kontrol edin, sonra bu işi "
|
||||
"çözün: %(volumes)s"
|
||||
|
||||
#: instances/jobs.py:723 instances/templates/create_instance_w1.html:60
|
||||
#: instances/jobs.py:733 instances/templates/create_instance_w1.html:60
|
||||
#: instances/templates/create_instance_w2.html:356
|
||||
msgid "Create VM"
|
||||
msgstr "Sanal makine oluştur"
|
||||
|
||||
#: instances/jobs.py:746 instances/views.py:2468
|
||||
#: instances/jobs.py:756 instances/views.py:2468
|
||||
msgid "A virtual machine with this name already exists"
|
||||
msgstr "Bu isimde bir sanal makine mevcut"
|
||||
|
||||
#: instances/jobs.py:748
|
||||
#: instances/jobs.py:758
|
||||
msgid "There is an instance with same name. Remove it and try again!"
|
||||
msgstr "Aynı isimde başka bir sanal makine var. Onu silip yeniden deneyin!"
|
||||
|
||||
#: instances/jobs.py:751
|
||||
#: instances/jobs.py:761
|
||||
msgid "First you need to create or select an image"
|
||||
msgstr "Öncelikle bir imaj oluşturun ya da mevcut bir imajı seçin"
|
||||
|
||||
#: instances/jobs.py:753
|
||||
#: instances/jobs.py:763
|
||||
msgid "Choose one disk source: a new disk, existing volumes or a template"
|
||||
msgstr ""
|
||||
"Tek bir disk kaynağı seçin: yeni bir disk, mevcut birimler ya da bir şablon"
|
||||
|
||||
#: instances/jobs.py:755
|
||||
#: instances/jobs.py:765
|
||||
msgid "Image has already exist. Please check volumes or change instance name"
|
||||
msgstr ""
|
||||
"İmaj zaten mevcut. Lütfen ya makine adını değişin ya da disk alanlarını "
|
||||
"kontrol edin"
|
||||
|
||||
#: instances/jobs.py:757
|
||||
#: instances/jobs.py:767
|
||||
msgid "Invalid cache mode"
|
||||
msgstr "Geçersiz önbellek modu"
|
||||
|
||||
#: instances/jobs.py:759
|
||||
#: instances/jobs.py:769
|
||||
#, python-format
|
||||
msgid "This host offers no CPU mode or model %(mode)s"
|
||||
msgstr "Bu sunucu %(mode)s CPU modunu veya modelini sunmuyor"
|
||||
|
||||
#: instances/jobs.py:761
|
||||
#: instances/jobs.py:771
|
||||
#, python-format
|
||||
msgid "A CD-ROM cannot use the %(bus)s bus"
|
||||
msgstr "CD-ROM %(bus)s veri yolunu kullanamaz"
|
||||
|
||||
#: instances/jobs.py:764
|
||||
#: instances/jobs.py:774
|
||||
msgid "The cloud-init seed is read from a CD-ROM: choose its bus"
|
||||
msgstr "cloud-init tohumu bir CD-ROM'dan okunur: veri yolunu seçin"
|
||||
|
||||
#: instances/jobs.py:767
|
||||
#: instances/jobs.py:777
|
||||
msgid "The cloud-init seed needs a directory storage pool for the disk"
|
||||
msgstr "cloud-init tohumu, disk için bir dizin depolama havuzu gerektirir"
|
||||
|
||||
#: instances/jobs.py:773
|
||||
#: instances/jobs.py:783
|
||||
#, python-format
|
||||
msgid "This host offers no firmware %(firmware)s"
|
||||
msgstr "Bu sunucu %(firmware)s firmware'ini sunmuyor"
|
||||
|
||||
#: instances/jobs.py:775 vrtManager/instance.py:3005
|
||||
#: instances/jobs.py:785 vrtManager/instance.py:3005
|
||||
msgid "This host offers no TPM 2.0: install swtpm on it"
|
||||
msgstr "Bu sunucu TPM 2.0 sunmuyor: üzerine swtpm kurun"
|
||||
|
||||
#: instances/jobs.py:826
|
||||
#: instances/jobs.py:836
|
||||
msgid "Writing the cloud-init seed"
|
||||
msgstr "cloud-init tohumu yazılıyor"
|
||||
|
||||
#: instances/jobs.py:833
|
||||
#: instances/jobs.py:843
|
||||
msgid "Defining the VM"
|
||||
msgstr "Sanal makine tanımlanıyor"
|
||||
|
||||
#: instances/jobs.py:866
|
||||
#: instances/jobs.py:876
|
||||
#, python-format
|
||||
msgid "%(error)s. Remove these volumes by hand: %(volumes)s"
|
||||
msgstr "%(error)s. Şu birimleri elle silin: %(volumes)s"
|
||||
|
||||
#: instances/jobs.py:891
|
||||
#: instances/jobs.py:901
|
||||
#, python-format
|
||||
msgid "The instance is already on %(compute)s"
|
||||
msgstr "Sanal makine zaten %(compute)s üzerinde"
|
||||
|
||||
#: instances/jobs.py:893
|
||||
#: instances/jobs.py:903
|
||||
#, python-format
|
||||
msgid "%(compute)s is not reachable"
|
||||
msgstr "%(compute)s sunucusuna ulaşılamıyor"
|
||||
|
||||
#: instances/jobs.py:895
|
||||
#: instances/jobs.py:905
|
||||
#, python-format
|
||||
msgid "%(compute)s is the VM's own host under another name"
|
||||
msgstr "%(compute)s, sanal makinenin kendi sunucusunun başka bir adı"
|
||||
|
||||
#: instances/jobs.py:913
|
||||
#: instances/jobs.py:923
|
||||
msgid "Migrate VM"
|
||||
msgstr "Sanal makineyi taşı"
|
||||
|
||||
#: instances/jobs.py:957
|
||||
#: instances/jobs.py:967
|
||||
msgid "Migrating the VM"
|
||||
msgstr "Sanal makine taşınıyor"
|
||||
|
||||
#: instances/jobs.py:994
|
||||
#: instances/jobs.py:1004
|
||||
msgid "libvirt is still migrating the VM"
|
||||
msgstr "libvirt sanal makineyi hâlâ taşıyor"
|
||||
|
||||
#: instances/jobs.py:1001
|
||||
#: instances/jobs.py:1011
|
||||
msgid "The VM stayed on the source host"
|
||||
msgstr "Sanal makine kaynak sunucuda kaldı"
|
||||
|
||||
#: instances/jobs.py:1003
|
||||
#: instances/jobs.py:1013
|
||||
msgid ""
|
||||
"The VM is on both computes or on neither; check them, then resolve this job."
|
||||
msgstr ""
|
||||
"Sanal makine ya iki sunucuda da var ya da hiçbirinde yok; kontrol edin, sonra"
|
||||
" bu işi çözün."
|
||||
|
||||
#: instances/jobs.py:1035
|
||||
#: instances/jobs.py:1045
|
||||
msgid "Move disk"
|
||||
msgstr "Diski taşı"
|
||||
|
||||
#: instances/jobs.py:1042
|
||||
#: instances/jobs.py:1052
|
||||
msgid "Choose a disk of the VM"
|
||||
msgstr "Sanal makinenin bir diskini seçin"
|
||||
|
||||
#: instances/jobs.py:1066
|
||||
#: instances/jobs.py:1076
|
||||
msgid "Copying the disk"
|
||||
msgstr "Disk kopyalanıyor"
|
||||
|
||||
#: instances/jobs.py:1109
|
||||
#: instances/jobs.py:1119
|
||||
#, python-format
|
||||
msgid "Another block job runs on %(dev)s; check the VM"
|
||||
msgstr ""
|
||||
"%(dev)s üzerinde başka bir blok işi çalışıyor; sanal makineyi kontrol edin"
|
||||
|
||||
#: instances/jobs.py:1115
|
||||
#: instances/jobs.py:1125
|
||||
#, python-format
|
||||
msgid "The disk stayed in %(path)s; remove %(dest)s if it is there"
|
||||
msgstr "Disk %(path)s içinde kaldı; varsa %(dest)s dosyasını silin"
|
||||
|
||||
#: instances/jobs.py:1117
|
||||
#: instances/jobs.py:1127
|
||||
#, python-format
|
||||
msgid "The definitions of %(dev)s name %(paths)s; check the VM"
|
||||
msgstr "%(dev)s tanımları %(paths)s gösteriyor; sanal makineyi kontrol edin"
|
||||
|
|
@ -5827,16 +5835,16 @@ msgstr "%(quota)s (%(total)s > %(limit)s)"
|
|||
msgid "None available device name"
|
||||
msgstr "Hiçbiri uygun aygıt adı değil"
|
||||
|
||||
#: instances/utils.py:392
|
||||
#: instances/utils.py:394
|
||||
#, python-format
|
||||
msgid "%(hostname)s via %(address)s"
|
||||
msgstr "%(address)s üzerinden %(hostname)s"
|
||||
|
||||
#: instances/utils.py:431
|
||||
#: instances/utils.py:433
|
||||
msgid "Invalid MAC address"
|
||||
msgstr "Geçersiz MAC adresi"
|
||||
|
||||
#: instances/utils.py:433
|
||||
#: instances/utils.py:435
|
||||
msgid "More MAC addresses than networks"
|
||||
msgstr "Ağlardan daha fazla MAC adresi"
|
||||
|
||||
|
|
@ -7850,7 +7858,7 @@ msgstr ""
|
|||
msgid "%(label)s is %(state)s on this resource (since %(since)s)."
|
||||
msgstr "%(label)s bu kaynakta %(state)s (%(since)s beri)."
|
||||
|
||||
#: operations/worker.py:40
|
||||
#: operations/worker.py:42
|
||||
msgid ""
|
||||
"libvirt's merge finished copying but never completed (for example after a "
|
||||
"libvirtd restart); check the VM before resolving"
|
||||
|
|
@ -7859,7 +7867,7 @@ msgstr ""
|
|||
"libvirtd yeniden başlatıldıktan sonra); çözmeden önce sanal makineyi kontrol "
|
||||
"edin"
|
||||
|
||||
#: operations/worker.py:42
|
||||
#: operations/worker.py:44
|
||||
msgid ""
|
||||
"The worker that ran this job stopped responding; an administrator must make "
|
||||
"sure it is no longer running, then resolve this job"
|
||||
|
|
@ -7867,11 +7875,11 @@ msgstr ""
|
|||
"Bu işi çalıştıran worker yanıt vermeyi bıraktı; bir yönetici artık "
|
||||
"çalışmadığından emin olmalı, sonra bu işi çözmeli"
|
||||
|
||||
#: operations/worker.py:44
|
||||
#: operations/worker.py:46
|
||||
msgid "Waiting for recovery"
|
||||
msgstr "Kurtarma bekleniyor"
|
||||
|
||||
#: operations/worker.py:455
|
||||
#: operations/worker.py:460
|
||||
msgid "The worker stopped before the job changed anything"
|
||||
msgstr "Worker, iş herhangi bir şeyi değiştirmeden önce durdu"
|
||||
|
||||
|
|
@ -8811,26 +8819,26 @@ msgstr ""
|
|||
"Bağlantı başarısız: %(host)s yanıt vermiyor: %(requests)s istek hâlâ onu "
|
||||
"bekliyor"
|
||||
|
||||
#: vrtManager/connection.py:208
|
||||
#: vrtManager/connection.py:210
|
||||
#, 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:218
|
||||
#: vrtManager/connection.py:220
|
||||
msgid "the connection closed right after opening"
|
||||
msgstr "bağlantı açıldıktan hemen sonra kapandı"
|
||||
|
||||
#: vrtManager/connection.py:231
|
||||
#: vrtManager/connection.py:233
|
||||
#, python-format
|
||||
msgid "Connection Failed: %(error)s"
|
||||
msgstr "Bağlantı başarısız: %(error)s"
|
||||
|
||||
#: vrtManager/connection.py:291
|
||||
#: vrtManager/connection.py:293
|
||||
#, python-format
|
||||
msgid "Connection closed (%(reason)s)"
|
||||
msgstr "Bağlantı kapandı (%(reason)s)"
|
||||
|
||||
#: vrtManager/connection.py:433
|
||||
#: vrtManager/connection.py:435
|
||||
#, python-format
|
||||
msgid "Connection Failed: %(host)s is not connected"
|
||||
msgstr "Bağlantı başarısız: %(host)s bağlı değil"
|
||||
|
|
@ -9855,10 +9863,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:325
|
||||
#: webvirtcloud/settings.py:326
|
||||
msgid "Localhost"
|
||||
msgstr "Yerel sunucu"
|
||||
|
||||
#: webvirtcloud/settings.py:326
|
||||
#: webvirtcloud/settings.py:327
|
||||
msgid "All interfaces"
|
||||
msgstr "Tüm arabirimler"
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-11-04 19:51+0000\n"
|
||||
"POT-Creation-Date: 2026-11-05 06:39+0000\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -1582,6 +1582,14 @@ msgstr "虚拟机页面显示每台虚拟机的 DRBD 状态"
|
|||
msgid "Rows per page on the Logs page"
|
||||
msgstr "日志页面每页行数"
|
||||
|
||||
#: appsettings/migrations/0024_log_retention_setting.py:6
|
||||
msgid "Log Retention Days"
|
||||
msgstr "日志保留天数"
|
||||
|
||||
#: appsettings/migrations/0024_log_retention_setting.py:6
|
||||
msgid "Days the Logs page keeps its rows (1-3650)"
|
||||
msgstr "日志页面保留记录的天数(1-3650)"
|
||||
|
||||
#: appsettings/models.py:10
|
||||
msgid "key"
|
||||
msgstr "键"
|
||||
|
|
@ -1675,41 +1683,41 @@ msgstr "登录"
|
|||
msgid "Lists and pages"
|
||||
msgstr "列表与页面"
|
||||
|
||||
#: appsettings/views.py:58
|
||||
#: appsettings/views.py:59
|
||||
#, python-format
|
||||
msgid "%(setting)s takes at most %(length)s characters"
|
||||
msgstr "%(setting)s 最多 %(length)s 个字符"
|
||||
|
||||
#: appsettings/views.py:63
|
||||
#: appsettings/views.py:64
|
||||
#, python-format
|
||||
msgid "%(setting)s must be a whole number between %(low)s and %(high)s"
|
||||
msgstr "%(setting)s 必须是 %(low)s 到 %(high)s 之间的整数"
|
||||
|
||||
#: appsettings/views.py:66
|
||||
#: appsettings/views.py:67
|
||||
#, python-format
|
||||
msgid "%(setting)s must be one of %(choices)s"
|
||||
msgstr "%(setting)s 必须是以下之一:%(choices)s"
|
||||
|
||||
#: appsettings/views.py:84
|
||||
#: appsettings/views.py:85
|
||||
#, python-format
|
||||
msgid "Unknown theme: %(theme)s"
|
||||
msgstr "未知主题:%(theme)s"
|
||||
|
||||
#: appsettings/views.py:90
|
||||
#: appsettings/views.py:91
|
||||
#, python-format
|
||||
msgid "Theme is changed. Now: %(theme)s"
|
||||
msgstr "主题已更改。当前:%(theme)s"
|
||||
|
||||
#: appsettings/views.py:113
|
||||
#: appsettings/views.py:114
|
||||
#, python-format
|
||||
msgid "Saved: %(settings)s"
|
||||
msgstr "已保存:%(settings)s"
|
||||
|
||||
#: appsettings/views.py:115
|
||||
#: appsettings/views.py:116
|
||||
msgid "Nothing changed"
|
||||
msgstr "没有任何更改"
|
||||
|
||||
#: appsettings/views.py:122 vrtManager/nodedevs.py:219
|
||||
#: appsettings/views.py:123 vrtManager/nodedevs.py:219
|
||||
#: vrtManager/nodedevs.py:258
|
||||
msgid "Other"
|
||||
msgstr "其他"
|
||||
|
|
@ -2612,7 +2620,7 @@ msgstr "请从可用名称列表中选择克隆的名称"
|
|||
msgid "%(quota)s: cannot create '%(clone_name)s'."
|
||||
msgstr "%(quota)s:无法创建“%(clone_name)s”。"
|
||||
|
||||
#: instances/jobs.py:196 instances/jobs.py:533
|
||||
#: instances/jobs.py:196 instances/jobs.py:543
|
||||
#, python-format
|
||||
msgid "Instance '%(clone_name)s' already exists!"
|
||||
msgstr "虚拟机 '%(clone_name)s' 已存在!"
|
||||
|
|
@ -2637,286 +2645,286 @@ msgstr "磁盘名称 '%(disk_name)s' 包含无效字符!"
|
|||
msgid "The clone is made, but not as asked: %(error)s"
|
||||
msgstr "克隆已创建,但与要求不符:%(error)s"
|
||||
|
||||
#: instances/jobs.py:271
|
||||
#: instances/jobs.py:279
|
||||
msgid "The VM was not defined and no volume of it was left."
|
||||
msgstr "虚拟机未定义,也没有留下它的卷。"
|
||||
|
||||
#: instances/jobs.py:273
|
||||
#: instances/jobs.py:281
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The VM was not defined; check these volumes, then resolve this job: "
|
||||
"%(volumes)s"
|
||||
msgstr "虚拟机未定义;请检查这些卷,然后处理此任务:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:294
|
||||
#: instances/jobs.py:302
|
||||
msgid "Delete snapshot"
|
||||
msgstr "删除快照"
|
||||
|
||||
#: instances/jobs.py:304 vrtManager/instance.py:2286
|
||||
#: instances/jobs.py:312 vrtManager/instance.py:2286
|
||||
#, python-format
|
||||
msgid "The VM has no external snapshot named %(name)s"
|
||||
msgstr "虚拟机没有名为 %(name)s 的外部快照"
|
||||
|
||||
#: instances/jobs.py:317
|
||||
#: instances/jobs.py:325
|
||||
msgid "Merging the snapshot"
|
||||
msgstr "正在合并快照"
|
||||
|
||||
#: instances/jobs.py:336
|
||||
#: instances/jobs.py:344
|
||||
msgid "The VM is no longer on its compute"
|
||||
msgstr "虚拟机已不在其计算节点上"
|
||||
|
||||
#: instances/jobs.py:339
|
||||
#: instances/jobs.py:347
|
||||
msgid "libvirt is still merging the snapshot"
|
||||
msgstr "libvirt 仍在合并快照"
|
||||
|
||||
#: instances/jobs.py:347
|
||||
#: instances/jobs.py:355
|
||||
msgid ""
|
||||
"The snapshot is still listed and no merge runs. It cannot be told whether the"
|
||||
" disks changed; check the VM before deleting the snapshot again or reverting "
|
||||
"to it."
|
||||
msgstr "快照仍在列表中,且没有正在运行的合并。无法判断磁盘是否已更改;再次删除该快照或恢复到它之前,请检查虚拟机。"
|
||||
|
||||
#: instances/jobs.py:354
|
||||
#: instances/jobs.py:362
|
||||
msgid "The VM is no longer on the compute the job ran on"
|
||||
msgstr "虚拟机已不在运行该任务的计算节点上"
|
||||
|
||||
#: instances/jobs.py:360
|
||||
#: instances/jobs.py:368
|
||||
msgid "Take snapshot"
|
||||
msgstr "创建快照"
|
||||
|
||||
#: instances/jobs.py:372 vrtManager/instance.py:1882
|
||||
#: instances/jobs.py:380 vrtManager/instance.py:1882
|
||||
#, python-format
|
||||
msgid "A snapshot named %(name)s already exists"
|
||||
msgstr "名为 %(name)s 的快照已存在"
|
||||
|
||||
#: instances/jobs.py:384
|
||||
#: instances/jobs.py:392
|
||||
msgid "Taking the snapshot"
|
||||
msgstr "正在创建快照"
|
||||
|
||||
#: instances/jobs.py:397
|
||||
#: instances/jobs.py:405
|
||||
msgid "libvirt is still taking the snapshot"
|
||||
msgstr "libvirt 仍在创建快照"
|
||||
|
||||
#: instances/jobs.py:400
|
||||
#: instances/jobs.py:408
|
||||
msgid "The snapshot was not taken"
|
||||
msgstr "未创建快照"
|
||||
|
||||
#: instances/jobs.py:423
|
||||
#: instances/jobs.py:431
|
||||
msgid "Revert snapshot"
|
||||
msgstr "恢复快照"
|
||||
|
||||
#: instances/jobs.py:452
|
||||
#: instances/jobs.py:460
|
||||
msgid "Reverting the VM"
|
||||
msgstr "正在恢复虚拟机"
|
||||
|
||||
#: instances/jobs.py:463
|
||||
#: instances/jobs.py:471
|
||||
msgid "libvirt is still reverting the VM"
|
||||
msgstr "libvirt 仍在恢复虚拟机"
|
||||
|
||||
#: instances/jobs.py:467
|
||||
#: instances/jobs.py:475
|
||||
msgid ""
|
||||
"It cannot be told whether the VM was reverted; check it, then revert again or"
|
||||
" resolve this job."
|
||||
msgstr "无法判断虚拟机是否已恢复;请检查后再次恢复,或处理此任务。"
|
||||
|
||||
#: instances/jobs.py:484
|
||||
#: instances/jobs.py:492
|
||||
msgid "The VM must be running, paused or shut off to be cloned"
|
||||
msgstr "虚拟机必须处于运行、暂停或关机状态才能克隆"
|
||||
|
||||
#: instances/jobs.py:485
|
||||
#: instances/jobs.py:493
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The guest's file systems could not be thawed (%(error)s); thaw them with: "
|
||||
"virsh domfsthaw %(vm)s"
|
||||
msgstr "无法解冻客户机的文件系统(%(error)s);请用以下命令解冻:virsh domfsthaw %(vm)s"
|
||||
|
||||
#: instances/jobs.py:504
|
||||
#: instances/jobs.py:512
|
||||
msgid "Clone VM"
|
||||
msgstr "克隆虚拟机"
|
||||
|
||||
#: instances/jobs.py:543 instances/jobs.py:550 instances/jobs.py:807
|
||||
#: instances/jobs.py:553 instances/jobs.py:560 instances/jobs.py:817
|
||||
msgid "Copying disks"
|
||||
msgstr "正在复制磁盘"
|
||||
|
||||
#: instances/jobs.py:602
|
||||
#: instances/jobs.py:612
|
||||
msgid "libvirt has no result of the copy"
|
||||
msgstr "libvirt 没有复制的结果"
|
||||
|
||||
#: instances/jobs.py:613
|
||||
#: instances/jobs.py:623
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The copy failed: %(error)s. The guest's file systems could not be thawed "
|
||||
"(%(thaw)s); thaw them with: virsh domfsthaw %(vm)s"
|
||||
msgstr "复制失败:%(error)s。无法解冻客户机的文件系统(%(thaw)s);请用以下命令解冻:virsh domfsthaw %(vm)s"
|
||||
|
||||
#: instances/jobs.py:616 instances/jobs.py:700
|
||||
#: instances/jobs.py:626 instances/jobs.py:710
|
||||
msgid "The copy failed"
|
||||
msgstr "复制失败"
|
||||
|
||||
#: instances/jobs.py:641
|
||||
#: instances/jobs.py:651
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The VM is no longer on the compute the job ran on; check these volumes, then "
|
||||
"resolve this job: %(volumes)s"
|
||||
msgstr "虚拟机已不在运行该任务的计算节点上;请检查这些卷,然后处理此任务:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:676
|
||||
#: instances/jobs.py:686
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A volume of the clone was being created; check these volumes, then resolve "
|
||||
"this job: %(volumes)s"
|
||||
msgstr "克隆的一个卷正在创建中;请检查这些卷,然后处理此任务:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:680
|
||||
#: instances/jobs.py:690
|
||||
msgid "The job stopped before the copy started"
|
||||
msgstr "任务在复制开始前停止"
|
||||
|
||||
#: instances/jobs.py:687
|
||||
#: instances/jobs.py:697
|
||||
msgid "libvirt is still copying the disks"
|
||||
msgstr "libvirt 仍在复制磁盘"
|
||||
|
||||
#: instances/jobs.py:690
|
||||
#: instances/jobs.py:700
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Another backup runs on the VM; check these volumes, then resolve this job: "
|
||||
"%(volumes)s"
|
||||
msgstr "虚拟机上正在运行另一个备份;请检查这些卷,然后处理此任务:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:695
|
||||
#: instances/jobs.py:705
|
||||
#, python-format
|
||||
msgid ""
|
||||
"libvirt has no result of the copy; check these volumes, then resolve this "
|
||||
"job: %(volumes)s"
|
||||
msgstr "libvirt 没有复制的结果;请检查这些卷,然后处理此任务:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:723 instances/templates/create_instance_w1.html:60
|
||||
#: instances/jobs.py:733 instances/templates/create_instance_w1.html:60
|
||||
#: instances/templates/create_instance_w2.html:356
|
||||
msgid "Create VM"
|
||||
msgstr "创建虚拟机"
|
||||
|
||||
#: instances/jobs.py:746 instances/views.py:2468
|
||||
#: instances/jobs.py:756 instances/views.py:2468
|
||||
msgid "A virtual machine with this name already exists"
|
||||
msgstr "同名虚拟机已存在"
|
||||
|
||||
#: instances/jobs.py:748
|
||||
#: instances/jobs.py:758
|
||||
msgid "There is an instance with same name. Remove it and try again!"
|
||||
msgstr "已存在同名虚拟机。请删除后重试!"
|
||||
|
||||
#: instances/jobs.py:751
|
||||
#: instances/jobs.py:761
|
||||
msgid "First you need to create or select an image"
|
||||
msgstr "请先创建或选择一个镜像"
|
||||
|
||||
#: instances/jobs.py:753
|
||||
#: instances/jobs.py:763
|
||||
msgid "Choose one disk source: a new disk, existing volumes or a template"
|
||||
msgstr "请选择一种磁盘来源:新磁盘、现有卷或模板"
|
||||
|
||||
#: instances/jobs.py:755
|
||||
#: instances/jobs.py:765
|
||||
msgid "Image has already exist. Please check volumes or change instance name"
|
||||
msgstr "镜像已存在。请检查卷或更改虚拟机名称"
|
||||
|
||||
#: instances/jobs.py:757
|
||||
#: instances/jobs.py:767
|
||||
msgid "Invalid cache mode"
|
||||
msgstr "无效的缓存模式"
|
||||
|
||||
#: instances/jobs.py:759
|
||||
#: instances/jobs.py:769
|
||||
#, python-format
|
||||
msgid "This host offers no CPU mode or model %(mode)s"
|
||||
msgstr "此主机不提供 CPU 模式或型号 %(mode)s"
|
||||
|
||||
#: instances/jobs.py:761
|
||||
#: instances/jobs.py:771
|
||||
#, python-format
|
||||
msgid "A CD-ROM cannot use the %(bus)s bus"
|
||||
msgstr "CD-ROM 不能使用 %(bus)s 总线"
|
||||
|
||||
#: instances/jobs.py:764
|
||||
#: instances/jobs.py:774
|
||||
msgid "The cloud-init seed is read from a CD-ROM: choose its bus"
|
||||
msgstr "cloud-init 种子从 CD-ROM 读取:请选择其总线"
|
||||
|
||||
#: instances/jobs.py:767
|
||||
#: instances/jobs.py:777
|
||||
msgid "The cloud-init seed needs a directory storage pool for the disk"
|
||||
msgstr "cloud-init 种子需要为磁盘使用目录类型的存储池"
|
||||
|
||||
#: instances/jobs.py:773
|
||||
#: instances/jobs.py:783
|
||||
#, python-format
|
||||
msgid "This host offers no firmware %(firmware)s"
|
||||
msgstr "此主机不提供固件 %(firmware)s"
|
||||
|
||||
#: instances/jobs.py:775 vrtManager/instance.py:3005
|
||||
#: instances/jobs.py:785 vrtManager/instance.py:3005
|
||||
msgid "This host offers no TPM 2.0: install swtpm on it"
|
||||
msgstr "此主机不提供 TPM 2.0:请在主机上安装 swtpm"
|
||||
|
||||
#: instances/jobs.py:826
|
||||
#: instances/jobs.py:836
|
||||
msgid "Writing the cloud-init seed"
|
||||
msgstr "正在写入 cloud-init 种子"
|
||||
|
||||
#: instances/jobs.py:833
|
||||
#: instances/jobs.py:843
|
||||
msgid "Defining the VM"
|
||||
msgstr "正在定义虚拟机"
|
||||
|
||||
#: instances/jobs.py:866
|
||||
#: instances/jobs.py:876
|
||||
#, python-format
|
||||
msgid "%(error)s. Remove these volumes by hand: %(volumes)s"
|
||||
msgstr "%(error)s。请手动删除这些卷:%(volumes)s"
|
||||
|
||||
#: instances/jobs.py:891
|
||||
#: instances/jobs.py:901
|
||||
#, python-format
|
||||
msgid "The instance is already on %(compute)s"
|
||||
msgstr "虚拟机已在 %(compute)s 上"
|
||||
|
||||
#: instances/jobs.py:893
|
||||
#: instances/jobs.py:903
|
||||
#, python-format
|
||||
msgid "%(compute)s is not reachable"
|
||||
msgstr "无法连接 %(compute)s"
|
||||
|
||||
#: instances/jobs.py:895
|
||||
#: instances/jobs.py:905
|
||||
#, python-format
|
||||
msgid "%(compute)s is the VM's own host under another name"
|
||||
msgstr "%(compute)s 是该虚拟机所在主机的另一个名称"
|
||||
|
||||
#: instances/jobs.py:913
|
||||
#: instances/jobs.py:923
|
||||
msgid "Migrate VM"
|
||||
msgstr "迁移虚拟机"
|
||||
|
||||
#: instances/jobs.py:957
|
||||
#: instances/jobs.py:967
|
||||
msgid "Migrating the VM"
|
||||
msgstr "正在迁移虚拟机"
|
||||
|
||||
#: instances/jobs.py:994
|
||||
#: instances/jobs.py:1004
|
||||
msgid "libvirt is still migrating the VM"
|
||||
msgstr "libvirt 仍在迁移虚拟机"
|
||||
|
||||
#: instances/jobs.py:1001
|
||||
#: instances/jobs.py:1011
|
||||
msgid "The VM stayed on the source host"
|
||||
msgstr "虚拟机留在了源主机上"
|
||||
|
||||
#: instances/jobs.py:1003
|
||||
#: instances/jobs.py:1013
|
||||
msgid ""
|
||||
"The VM is on both computes or on neither; check them, then resolve this job."
|
||||
msgstr "虚拟机同时位于两个计算节点上,或都不在;请检查后处理此任务。"
|
||||
|
||||
#: instances/jobs.py:1035
|
||||
#: instances/jobs.py:1045
|
||||
msgid "Move disk"
|
||||
msgstr "移动磁盘"
|
||||
|
||||
#: instances/jobs.py:1042
|
||||
#: instances/jobs.py:1052
|
||||
msgid "Choose a disk of the VM"
|
||||
msgstr "请选择虚拟机的一个磁盘"
|
||||
|
||||
#: instances/jobs.py:1066
|
||||
#: instances/jobs.py:1076
|
||||
msgid "Copying the disk"
|
||||
msgstr "正在复制磁盘"
|
||||
|
||||
#: instances/jobs.py:1109
|
||||
#: instances/jobs.py:1119
|
||||
#, python-format
|
||||
msgid "Another block job runs on %(dev)s; check the VM"
|
||||
msgstr "%(dev)s 上正在运行另一个块任务;请检查虚拟机"
|
||||
|
||||
#: instances/jobs.py:1115
|
||||
#: instances/jobs.py:1125
|
||||
#, python-format
|
||||
msgid "The disk stayed in %(path)s; remove %(dest)s if it is there"
|
||||
msgstr "磁盘仍在 %(path)s;如果 %(dest)s 存在,请将其删除"
|
||||
|
||||
#: instances/jobs.py:1117
|
||||
#: instances/jobs.py:1127
|
||||
#, python-format
|
||||
msgid "The definitions of %(dev)s name %(paths)s; check the VM"
|
||||
msgstr "%(dev)s 的定义指向 %(paths)s;请检查虚拟机"
|
||||
|
|
@ -5537,16 +5545,16 @@ msgstr "%(quota)s(%(total)s > %(limit)s)"
|
|||
msgid "None available device name"
|
||||
msgstr "没有可用的设备名称"
|
||||
|
||||
#: instances/utils.py:392
|
||||
#: instances/utils.py:394
|
||||
#, python-format
|
||||
msgid "%(hostname)s via %(address)s"
|
||||
msgstr "%(hostname)s,经由 %(address)s"
|
||||
|
||||
#: instances/utils.py:431
|
||||
#: instances/utils.py:433
|
||||
msgid "Invalid MAC address"
|
||||
msgstr "无效的 MAC 地址"
|
||||
|
||||
#: instances/utils.py:433
|
||||
#: instances/utils.py:435
|
||||
msgid "More MAC addresses than networks"
|
||||
msgstr "MAC 地址数量多于网络数量"
|
||||
|
||||
|
|
@ -7448,23 +7456,23 @@ msgstr "此资源上的%(label)s%(state)s(由 %(user)s 于 %(since)s前发起
|
|||
msgid "%(label)s is %(state)s on this resource (since %(since)s)."
|
||||
msgstr "此资源上的%(label)s%(state)s(自 %(since)s起)。"
|
||||
|
||||
#: operations/worker.py:40
|
||||
#: operations/worker.py:42
|
||||
msgid ""
|
||||
"libvirt's merge finished copying but never completed (for example after a "
|
||||
"libvirtd restart); check the VM before resolving"
|
||||
msgstr "libvirt 的合并已完成复制但从未结束(例如 libvirtd 重启后);处理前请检查虚拟机"
|
||||
|
||||
#: operations/worker.py:42
|
||||
#: operations/worker.py:44
|
||||
msgid ""
|
||||
"The worker that ran this job stopped responding; an administrator must make "
|
||||
"sure it is no longer running, then resolve this job"
|
||||
msgstr "运行此任务的工作进程已停止响应;管理员必须确认它已不再运行,然后处理此任务"
|
||||
|
||||
#: operations/worker.py:44
|
||||
#: operations/worker.py:46
|
||||
msgid "Waiting for recovery"
|
||||
msgstr "等待恢复"
|
||||
|
||||
#: operations/worker.py:455
|
||||
#: operations/worker.py:460
|
||||
msgid "The worker stopped before the job changed anything"
|
||||
msgstr "工作进程在任务做出任何更改之前停止"
|
||||
|
||||
|
|
@ -8362,26 +8370,26 @@ msgid ""
|
|||
" for it"
|
||||
msgstr "连接失败:%(host)s 无响应:仍有 %(requests)s 个请求在等待它"
|
||||
|
||||
#: vrtManager/connection.py:208
|
||||
#: vrtManager/connection.py:210
|
||||
#, python-format
|
||||
msgid "Connection Failed: %(host)s did not answer within %(seconds)s s"
|
||||
msgstr "连接失败:%(host)s 在 %(seconds)s 秒内未响应"
|
||||
|
||||
#: vrtManager/connection.py:218
|
||||
#: vrtManager/connection.py:220
|
||||
msgid "the connection closed right after opening"
|
||||
msgstr "连接在打开后立即关闭"
|
||||
|
||||
#: vrtManager/connection.py:231
|
||||
#: vrtManager/connection.py:233
|
||||
#, python-format
|
||||
msgid "Connection Failed: %(error)s"
|
||||
msgstr "连接失败:%(error)s"
|
||||
|
||||
#: vrtManager/connection.py:291
|
||||
#: vrtManager/connection.py:293
|
||||
#, python-format
|
||||
msgid "Connection closed (%(reason)s)"
|
||||
msgstr "连接已关闭(%(reason)s)"
|
||||
|
||||
#: vrtManager/connection.py:433
|
||||
#: vrtManager/connection.py:435
|
||||
#, python-format
|
||||
msgid "Connection Failed: %(host)s is not connected"
|
||||
msgstr "连接失败:%(host)s 未连接"
|
||||
|
|
@ -9303,10 +9311,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:325
|
||||
#: webvirtcloud/settings.py:326
|
||||
msgid "Localhost"
|
||||
msgstr "本机"
|
||||
|
||||
#: webvirtcloud/settings.py:326
|
||||
#: webvirtcloud/settings.py:327
|
||||
msgid "All interfaces"
|
||||
msgstr "所有接口"
|
||||
|
|
|
|||
|
|
@ -302,6 +302,20 @@ class RequestJobTestCase(TransactionTestCase):
|
|||
self.assertEqual(fakes.EXPIRED, [str(idle.pk)])
|
||||
self.assertNotIn(str(fresh.pk), fakes.EXPIRED)
|
||||
|
||||
def test_housekeeping_removes_old_log_rows_and_expired_sessions(self):
|
||||
from django.contrib.sessions.models import Session
|
||||
from logs.models import Logs
|
||||
|
||||
AppSettings.objects.update_or_create(key="LOG_RETENTION_DAYS", defaults={"name": "t", "value": "10", "choices": ""})
|
||||
old, kept = (Logs.objects.create(user="u", host="h", instance="vm", message=m) for m in ("old", "kept"))
|
||||
Logs.objects.filter(pk=old.pk).update(date=timezone.now() - timedelta(days=11))
|
||||
Logs.objects.filter(pk=kept.pk).update(date=timezone.now() - timedelta(days=9))
|
||||
Session.objects.create(session_key="expired-session", session_data="", expire_date=timezone.now() - timedelta(1))
|
||||
Session.objects.create(session_key="current-session", session_data="", expire_date=timezone.now() + timedelta(1))
|
||||
housekeeping()
|
||||
self.assertEqual(list(Logs.objects.values_list("message", flat=True)), ["kept"])
|
||||
self.assertEqual(list(Session.objects.values_list("session_key", flat=True)), ["current-session"])
|
||||
|
||||
def test_one_failing_expire_does_not_stop_the_others(self):
|
||||
self.request_job("key-00000001", 61, uuid="u1", fail_expire=True)
|
||||
other = self.request_job("key-00000002", 61, uuid="u2")
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ TRANSPORT_ERROR_CODES = {
|
|||
}
|
||||
UNREACHABLE = gettext_noop("The host of this virtual machine cannot be reached right now.")
|
||||
|
||||
BOUNDS = {"WORKER_CONCURRENCY": (1, 16, 4), "JOB_RETENTION_DAYS": (1, 3650, 30)}
|
||||
BOUNDS = {"WORKER_CONCURRENCY": (1, 16, 4), "JOB_RETENTION_DAYS": (1, 3650, 30), "LOG_RETENTION_DAYS": (1, 3650, 365)}
|
||||
|
||||
|
||||
def safe_text(text):
|
||||
|
|
@ -177,3 +177,7 @@ def concurrency():
|
|||
|
||||
def retention_days():
|
||||
return _value("JOB_RETENTION_DAYS")
|
||||
|
||||
|
||||
def log_retention_days():
|
||||
return _value("LOG_RETENTION_DAYS")
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import uuid
|
|||
from collections import Counter
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import timedelta
|
||||
from importlib import import_module
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
|
|
@ -23,6 +24,7 @@ from django.utils import timezone
|
|||
from django.utils.translation import gettext_noop
|
||||
|
||||
from appsettings.settings import get_settings
|
||||
from logs.models import Logs
|
||||
|
||||
from . import claims, jobs, utils
|
||||
from .models import Claim, LeaseLost, Operation, acquire, fenced, renew
|
||||
|
|
@ -367,6 +369,9 @@ def housekeeping():
|
|||
)
|
||||
Operation.objects.filter(pk__in=old).delete()
|
||||
Claim.objects.filter(operation__isnull=True, expires_at__lt=timezone.now()).delete()
|
||||
# nothing else removes the Logs page's rows or the expired sessions
|
||||
Logs.objects.filter(date__lt=timezone.now() - timedelta(days=utils.log_retention_days())).delete()
|
||||
import_module(settings.SESSION_ENGINE).SessionStore.clear_expired()
|
||||
# each kind ends its idle jobs; HOUSEKEEPING_EVERY bounds how late an idle request job ends
|
||||
for op in Operation.objects.filter(state__in=ACTIVE, worker=Operation.REQUEST):
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue