From b2deb042e8193e0c0321f65e8e0c642da95a9fc1 Mon Sep 17 00:00:00 2001 From: catborise Date: Thu, 5 Nov 2026 09:40:44 +0300 Subject: [PATCH] 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. --- .../migrations/0024_log_retention_setting.py | 30 +++ appsettings/tests/test_migrations.py | 2 +- appsettings/views.py | 3 +- locale/tr/LC_MESSAGES/django.mo | Bin 191566 -> 191753 bytes locale/tr/LC_MESSAGES/django.po | 178 +++++++++--------- locale/zh/LC_MESSAGES/django.mo | Bin 179127 -> 179286 bytes locale/zh/LC_MESSAGES/django.po | 178 +++++++++--------- operations/tests/test_worker.py | 14 ++ operations/utils.py | 6 +- operations/worker.py | 5 + 10 files changed, 243 insertions(+), 173 deletions(-) create mode 100644 appsettings/migrations/0024_log_retention_setting.py diff --git a/appsettings/migrations/0024_log_retention_setting.py b/appsettings/migrations/0024_log_retention_setting.py new file mode 100644 index 00000000..e2b69f95 --- /dev/null +++ b/appsettings/migrations/0024_log_retention_setting.py @@ -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)] diff --git a/appsettings/tests/test_migrations.py b/appsettings/tests/test_migrations.py index c2325d21..1ecda31b 100644 --- a/appsettings/tests/test_migrations.py +++ b/appsettings/tests/test_migrations.py @@ -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 diff --git a/appsettings/views.py b/appsettings/views.py index 8e5173aa..ebfa215f 100644 --- a/appsettings/views.py +++ b/appsettings/views.py @@ -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"]), ] diff --git a/locale/tr/LC_MESSAGES/django.mo b/locale/tr/LC_MESSAGES/django.mo index 9898a879ab481f0b622a3adc37a5b5a54df704d8..c0e036c5362389feedbff18616057d88f9988500 100644 GIT binary patch delta 42540 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 delta 42385 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®~^5I#jML6W-Wc$G%YXgKPHR@=r~qxMS2 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 diff --git a/locale/tr/LC_MESSAGES/django.po b/locale/tr/LC_MESSAGES/django.po index 833340c1..a60d2057 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-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 , 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" diff --git a/locale/zh/LC_MESSAGES/django.mo b/locale/zh/LC_MESSAGES/django.mo index 3571f7a0f1f83f5c6b7e35a354ac10420b8676d4..06b5670b69c38ef272977d5df0a53da5223a349c 100644 GIT binary patch delta 42521 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

1p! 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 delta 42385 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 a4;z*G@Pzr|b8Obky{02FX*T@MwfsLWAS=uO diff --git a/locale/zh/LC_MESSAGES/django.po b/locale/zh/LC_MESSAGES/django.po index f0a72a4d..9a7cf0a1 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-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 "所有接口" diff --git a/operations/tests/test_worker.py b/operations/tests/test_worker.py index 12c1411c..9b9f0991 100644 --- a/operations/tests/test_worker.py +++ b/operations/tests/test_worker.py @@ -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") diff --git a/operations/utils.py b/operations/utils.py index 4a950703..d0321949 100644 --- a/operations/utils.py +++ b/operations/utils.py @@ -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") diff --git a/operations/worker.py b/operations/worker.py index d7c17562..8f1851f9 100644 --- a/operations/worker.py +++ b/operations/worker.py @@ -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: