From 764cbb3c4309d76538e06791b828014a9ecbcf51 Mon Sep 17 00:00:00 2001 From: catborise Date: Fri, 6 Nov 2026 10:53:37 +0300 Subject: [PATCH] chore: remove code nothing uses Each was checked with git grep across every tracked file (templates, JS, shell, unit files and the extensionless console daemons) and for dynamic use (URL names, template names, registries): - vrtManager: host_is_up, is_kvm_supported, get_emulators, get_file_extensions, both get_network_forward, get_snapshots, get_storages_images, get_os_type, get_host_arch, the get_pretty_* trio and, in util, is_kvm_available, randomMAC, get_max_vcpus, compareMAC, pretty_mem, pretty_bytes and validate_uuid; with them the port constants only host_is_up read. Some were reached only by their tests, which go too. - The flavor edit page: nothing linked to it; flavors are created and deleted on the Flavors page and edited through the API. - computes.validate_name, UserForm.identity_has_errors, the has_perm template tag, the ALLOW_EMPTY_PASSWORD setting nothing reads, hidePleaseWaitDialog, default_app_config (ignored since Django 4.1) and the Python < 3.6 lines of secret_generator.py. --- accounts/__init__.py | 1 - admin/__init__.py | 1 - admin/forms.py | 4 - computes/tests/test_validators.py | 7 +- computes/validators.py | 6 - conf/runit/secret_generator.py | 12 +- instances/__init__.py | 1 - instances/tests/test_audit_rows.py | 4 +- instances/tests/test_views.py | 15 -- instances/urls.py | 1 - instances/views.py | 24 +- locale/tr/LC_MESSAGES/django.mo | Bin 193911 -> 193678 bytes locale/tr/LC_MESSAGES/django.po | 314 ++++++++++++------------- locale/zh/LC_MESSAGES/django.mo | Bin 181348 -> 181132 bytes locale/zh/LC_MESSAGES/django.po | 314 ++++++++++++------------- networks/tests/test_network_changes.py | 2 +- static/js/please_wait.js | 7 - vrtManager/connection.py | 81 ------- vrtManager/create.py | 21 -- vrtManager/network.py | 5 - vrtManager/storage.py | 9 - vrtManager/tests/test_connection.py | 24 -- vrtManager/tests/test_util.py | 55 ----- vrtManager/util.py | 85 ------- webvirtcloud/common_tags.py | 3 - webvirtcloud/settings.py.template | 1 - 26 files changed, 307 insertions(+), 690 deletions(-) diff --git a/accounts/__init__.py b/accounts/__init__.py index 83198231..e69de29b 100644 --- a/accounts/__init__.py +++ b/accounts/__init__.py @@ -1 +0,0 @@ -default_app_config = 'accounts.apps.AccountsConfig' diff --git a/admin/__init__.py b/admin/__init__.py index 052dc420..e69de29b 100644 --- a/admin/__init__.py +++ b/admin/__init__.py @@ -1 +0,0 @@ -default_app_config = 'admin.apps.AdminConfig' diff --git a/admin/forms.py b/admin/forms.py index 331a181d..1c526c3c 100644 --- a/admin/forms.py +++ b/admin/forms.py @@ -119,10 +119,6 @@ class UserForm(UniqueEmailMixin, forms.ModelForm): def permission_rows(self): return permission_rows(self["user_permissions"]) - def identity_has_errors(self): - return any(self.has_error(name) for name in ("username", "password", "first_name", "last_name", "email")) - - class UserCreateForm(UserForm): password = forms.CharField(widget=forms.PasswordInput) diff --git a/computes/tests/test_validators.py b/computes/tests/test_validators.py index 178fcc8e..17b97610 100644 --- a/computes/tests/test_validators.py +++ b/computes/tests/test_validators.py @@ -6,7 +6,7 @@ import unittest from django.core.exceptions import ValidationError -from computes.validators import validate_hostname, validate_login, validate_name +from computes.validators import validate_hostname, validate_login class HostnameValidatorTestCase(unittest.TestCase): @@ -46,8 +46,3 @@ class LoginValidatorTestCase(unittest.TestCase): validate_login(value) -class NameValidatorTestCase(unittest.TestCase): - def test_checks_the_value(self): - validate_name("good-name_1.2") - with self.assertRaises(ValidationError): - validate_name("bad name!") diff --git a/computes/validators.py b/computes/validators.py index 4e3620f5..d4fedc15 100644 --- a/computes/validators.py +++ b/computes/validators.py @@ -7,7 +7,6 @@ from django.utils.translation import gettext_lazy as _ # one or more dot-separated RFC 1123 labels, optional trailing dot _hostname = re.compile(r"[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\.?") _login = re.compile(r"[A-Za-z0-9._][A-Za-z0-9._-]*") -_name = re.compile(r"[A-Za-z0-9._-]+") def validate_hostname(value): @@ -37,11 +36,6 @@ def validate_login(value): ) -def validate_name(value): - if not _name.fullmatch(value): - raise ValidationError(_("The name must not contain any special characters")) - - def validate_migration_address(value): """An IP address (no IPv6 scope) or a host name: no scheme, port or brackets.""" try: diff --git a/conf/runit/secret_generator.py b/conf/runit/secret_generator.py index 70ee032c..3183ffaf 100644 --- a/conf/runit/secret_generator.py +++ b/conf/runit/secret_generator.py @@ -1,13 +1,3 @@ import secrets -generated_key = secrets.token_urlsafe(50) - -print(''.join(generated_key)) - - -### Use for old python versions < 3.6 -##import random -##import string -# -##haystack = string.ascii_letters + string.digits + string.punctuation -##print(''.join([random.SystemRandom().choice(haystack.replace('/', '').replace('\'', '').replace('\"', '')) for _ in range(50)])) +print(secrets.token_urlsafe(50)) diff --git a/instances/__init__.py b/instances/__init__.py index bf9df051..e69de29b 100644 --- a/instances/__init__.py +++ b/instances/__init__.py @@ -1 +0,0 @@ -default_app_config = 'instances.apps.InstancesConfig' diff --git a/instances/tests/test_audit_rows.py b/instances/tests/test_audit_rows.py index 94eebe22..b7783965 100644 --- a/instances/tests/test_audit_rows.py +++ b/instances/tests/test_audit_rows.py @@ -54,8 +54,6 @@ class FlavorRowTests(TestCase): data = {"label": "tiny-a", "memory": 512, "vcpu": 1, "disk": 10} self.client.post(reverse("instances:flavor_create"), data) flavor = Flavor.objects.get(label="tiny-a") - self.client.post(reverse("instances:flavor_update", args=[flavor.pk]), {**data, "vcpu": 2}) - self.client.post(reverse("instances:flavor_update", args=[flavor.pk]), {**data, "vcpu": 2}) # no change self.client.post(reverse("instances:flavor_delete", args=[flavor.pk])) self.assertFalse(Flavor.objects.filter(label="tiny-a").exists()) @@ -71,6 +69,6 @@ class FlavorRowTests(TestCase): self.assertFalse(Flavor.objects.filter(label="huge-a").exists()) self.assertEqual([m for m, _ in rows()], [ - "Flavor tiny-a: add", "Flavor tiny-a: change vcpu", "Flavor tiny-a: delete", + "Flavor tiny-a: add", "Flavor tiny-a: delete", "Flavor huge-a: add", "Flavor huge-a: change vcpu", "Flavor huge-a: change memory", "Flavor huge-a: delete", ]) diff --git a/instances/tests/test_views.py b/instances/tests/test_views.py index 03d71f9c..b6ee2531 100644 --- a/instances/tests/test_views.py +++ b/instances/tests/test_views.py @@ -1080,21 +1080,6 @@ class InstancesTestCase(TestCase): id = Flavor.objects.last().id - response = self.client.get(reverse("instances:flavor_update", args=[id])) - self.assertEqual(response.status_code, 200) - - response = self.client.post( - reverse("instances:flavor_update", args=[id]), - { - "label": "test_flavor_", - "memory": 256, - "vcpu": 1, - "disk": 10, - }, - HTTP_REFERER=reverse("index"), - ) - self.assertEqual(response.status_code, 302) - response = self.client.get(reverse("instances:flavor_delete", args=[id])) self.assertEqual(response.status_code, 200) diff --git a/instances/urls.py b/instances/urls.py index ffd35068..ac26173c 100755 --- a/instances/urls.py +++ b/instances/urls.py @@ -10,7 +10,6 @@ urlpatterns = [ path("find_address/", views.find_address, name="find_address"), path("report.xlsx", views.vm_report, name="vm_report"), path("flavor/create/", views.flavor_create, name="flavor_create"), - path("flavor//update/", views.flavor_update, name="flavor_update"), path("flavor//delete/", views.flavor_delete, name="flavor_delete"), path("/", views.instance, name="instance"), path("/poweron/", views.poweron, name="poweron"), diff --git a/instances/views.py b/instances/views.py index 9a6b1bc7..199401bf 100755 --- a/instances/views.py +++ b/instances/views.py @@ -46,8 +46,7 @@ from libvirt import (VIR_DOMAIN_PAUSED, VIR_ERR_NO_DOMAIN, VIR_ERR_NO_SUPPORT, libvirtError) -from logs.audit import audit, audit_vm, changed_fields, failed_vm -from logs.audit import snapshot as audit_snapshot +from logs.audit import audit, audit_vm, failed_vm from operations import claims, jobs from operations.utils import HOST_BUSY, busy_message, summary from webvirtcloud.middleware import error_text, same_origin_referer @@ -2643,27 +2642,6 @@ def flavor_create(request): ) -@superuser_only -def flavor_update(request, pk): - flavor = get_object_or_404(Flavor, pk=pk) - subject, before = f"Flavor {flavor.label}", audit_snapshot(flavor) - form = FlavorForm(request.POST or None, instance=flavor) - if form.is_valid(): - with audit(request, None, subject, "change") as entry: - form.save() - fields = changed_fields(before, audit_snapshot(flavor)) - entry.action = "change " + ", ".join(fields) - entry.skip = not fields - messages.success(request, _("Flavor Updated")) - return get_safe_redirect(request, default=reverse("instances:index")) - - return render( - request, - "common/form.html", - {"form": form, "title": _("Update Flavor")}, - ) - - @superuser_only def flavor_delete(request, pk): flavor = get_object_or_404(Flavor, pk=pk) diff --git a/locale/tr/LC_MESSAGES/django.mo b/locale/tr/LC_MESSAGES/django.mo index 4bf1a92528b1fa0ca8b78917ff05d63e84327c2f..9db11eb6c33b7576a658314cd1be9f85ee4e6766 100644 GIT binary patch delta 43097 zcmZtP1#}h11Ml%ofZz}`c!EoUClG=K4HDd);8xsiarffxP$&}I-QC^Y{uF3|0)@Ws z@6K>u&pU6=*?wkb$7SzLpzY^Z@h82E@7_xqbB4opDYoOJ!{19dPM3I&Q*4k@9p~?r zjuVDoupkDna-1sI4g+u-=D_P1gwAS{o*RRSRz*J?j;enis-7K~$#Gog4S^gaB>v5D z(qJgk2d5U2!I_4+a4TlO2bc~2MKzdhjpO9RTBv-3P~}#mI(`~eug_Y?NsSp%<%(iK z+IQL!C`!V7R7E#X9rFI&aT;JCCcu%X=hHAH?!jbu8P&1p=#M_@949?y!?IWwRnJ)L zjE}Jj)?Dv6b!p#OOh6TW#&Aru!Ex$gHB`n`7=<5gdcBS2`3BVU*wK#D2J2uM+=H5W zXA{c^Ay^H&qw*iZrs%tw`L9Kw3js~}VN8hLTg+7XqSh=I24VziN_${)T#xxN@m90u zrBLNtpq8jBCc#;l7=N?zov4{Qy_NY_f!8Fc179!!hHf)!Rt_5zZ;qOQy_gdHw>wTG z7DA;D$Bg(C^I_~AW-o+dDDjr4j?YIe^>xgS$#ydTSqK!}Y1XniYK?nhNnD5;$vw=A zv38k)A*gaqP@8TTYKqsPHs5zFf&sf7r#?2shPWA(FVP-zDw?_kG_}1k0GFa>N<(`nSmWb)#rNecbw`3a$yJ# zK<)l$)W~jObBuMsY^FA-8Ciyn@D!?nYzG}DE4IK4I0n`6Rp^IDZ2BFnNc(dacW=dxRXXrL3km!Qr#KSJA^V;7!0ey%sw64H}#DB-wxXY#= zvhkCswZ4eS@g-_6{6Ou6^cT(2hM_<4x))i0J?Kq>cKffW_&U^XK85PQ1B`*sQ5}7a ziSZLALZ3^<6sV46!T15>I;ByvVX*D&hrDQ(qZ#;{a6o-&_J}XfvweJ*b9`qegZfmGPd9 zzd+^xjIGhRVrHfds-X_n;i&TSQRUa7W^^m6ozs{e-D?EW5cmsoV&bdj#Zd&46K{fg z-W|1O6H%LV9Tvdz7=Yf_%(2XD?S*woKaLuChU@0ERK+61XJKZY|BD3F^N*;WCAwjz zE;VYZvSAjijoKUiFc!|l6gVGa;wID*Znqvqb@Vc720mgE{MW{l+|*37{%HwlGiAoM zSP)g=JWPg*QER*fmG1y*>Mo!!zD2zO|3!7I=q`eP=v@ z0Gx^Wal4Jb#9YMV-R5f)hM)?Lz)Uy^wVR_+9p8cKXuuuQ@gUS*3P*LM0_u5H)M;vn zZUO>L31}o8Q5_hFnyU4v1`eRs`Z#JWzoMo(*IiRlC~E17VOoqpZPJ#gj&?#V)nrVC zD^MNUcbEBB!6PL2;dx|JIL}d2AOD^iu|KLKIWYk9p*m6nwIo9^9ZtnST#xF&E$d^{ zK;NKd@C#}tV%%r`HS)yw&4U0`&vKzE&W9RlII4qHF#y}3Mm8FiZ;f@A^%N@qE!2oV zpgJ7?f$2z5)Y4XP2^1&L1Iu7EYN|e3<3BXVFe9qLLe>VTh6kb=nt<7HIjX~FP&0T7 zOXFM2iuoUz<6I955_h{3@F%bmH8sbq7f>&dTd2M85=-MZR0m5uHgCGxsB&#lGuO@9 z2ekx)P~}FU26_^;6tSOpI_Nsd31}^Hp!PyA*1(dej8jo-zYsIx3RFYKQ8REBwdw9+ zdi;XwxZhJV1KCg=2}9Li21{X8jIZ-Q#b%gqGps-zn~kWE?LbZOAOGMmcZIL7=!RKW%0hotP5Oqt^BrYDxY= zjnwCb*~BSOyFVLh=4xU!Y=+uw8&Dm+g(~+M-3A1FUYcFq9M!;3)Tx+^`ZQaNYH%}Z z365f1e2%g4J^J7mRC(u>=|CdX(xydymSjhjD`wNnzheH?lbR%Gw??5V=!F`=aMbac zg6hz3sQkN7`A?!6xQiXHx>+hH2~1>@rw zjEB>0`XbawcVS&Th;=a48&keBYNS0-$7>Ac!ab;^d~TnA$85xty8kn4UIgQiP!ZKY zP1G)JV4u%Jjc6@q#zUwXd4`^~L`|*FTQeYEOh`NvYV+npb+`hm+#+0v?nVL$2vqyS zRMZ%Y5bubZi4_!|72C=0qKva16uds5PC3zPJpvR9jFpxF5AykD>CtKy~09 zR>mLbqw`)q`;|E=6^uz(+IH6;a2w7ODgNZ2CA%LVP-Q$CX$G zQ-3n`wnfc&7mU#PA4otwKVl!8M{UMCSQZ~*In4Ii{FL0ux)wu7e}#oH;BWIqq(16R zI34rhCe-uCm><)AG3`}BSDUWBO^Cvz#5VqEJ97?a?FC;P$RpITH`OMQ=%Vt zf}u33Tp!c`2BOw{EUJUEtgBF`W&1bgKN*38B&5cxs1g5RGkilmkM)oF_)U!(K`~SX zrBNM>L=B)RYDT-E_C$YFhsL8e;}n~|3ALFIy95dlc#IlZ%J1eK9*o6^H^=h00L$VN zOpiH#nBy6Nn(`K?r5S*Ya2#ripV{;us25Sfe@(|jQ5|$k6HvxlsDd3)BRG!j@B)Tm z5y#8(Ew?9X1~#ImbQ`LoW2mLPZoQ8Y#Gj*ioL|G53@$`>K7ro|sE6g_n5C$SnTSWB8Xke!a50X;<5&=@#x)%phMJMFsJ$}Trk_Hc z`-`XsU!d~+Y2#nwdbyq+#f<0WdG-3Dj$t;`l!jv@R!6Pz0@MhiQERvt)xa^-p1F(K z%ui4w{>SPS-<0#QCPlp;GQ@YyS_P7zO&Eq+f-0yrtcP0THa6Z9(-9wz>fmBjM>e8H zwiETr-H+W+Ft4n)0(qEVaNy-Yw2y+Q4T&)5Q|Co;SKGwRr6PVD9Ru&Ioi zx}jJOCt+^9f*OdouNgo*RKp3e4*H=w_6sUsZ)C<@XD|V+?NrpRU4d%gDC&K133FhQ zB&LEe%tE{j=EQawgws%KzaRBNx{g|c7pP8xh{k{o}Doq$6+2kjoNfyQ4Rked zHT9JU=ta^Lm9Z=4$6lyYu*$j(Rq;{O)Sg6*O}m#FgZQ29RE=U-4W>7B~%3DoZQ zOU3yQAW(+{73_`L)dNt+Yc!U{S*Xu|JD3ZTr}pyv2}Vf_CB6`|;C0k-{RdTFyfh}B z7`4RdQT1j=?XkjXIRDy>Wl7L3jL0{DQpMYv`DQYCEPz`KFP3eBrCOeFp(z~b`dtsmd zh3dfHs0N*MW?%_X=|wRcmO+(wI}lJ0dtn|NfhxEeRp5a21gb+9Fa+`3rwx~VP1yx^f)C*|1jqgD6yUtMp+SQj)J^O%~iPRa)Cd-R?iI+#cv3jF+{bba+ zUW=ZNT2G)xb^-MsxQ*J}Z%}Lh12bbHf0g6>6(FFs2*UsjNA)-gHPxN%^D(H3C!v;T z4l3V5REO50@*hVn*+WzZU!w-(1Q=7ImNE##bpG?%gpR09)CJX0UmG8eYH$K-il^c- zT!b27nT%eZ?}W8c4R%M($Y>0}$*39Li286kkD37|6X(AjW+6};Ct?IXLalAC%;uF^ z2+I?%iWP7M>cw&o^&WVSn%X#7OnNHRo(e>zhoP3Bl6~G7HFI6EaQ-#ofh1@NM%oAC zQ3YqCHqmMu-+;=$A2mZKP*Z&wRpDLK61+mqRLrbqAW2crGoZ=`qRIznbxlG^5;T<+ zY=#ClLkm<#e!&tr2(=V@?DK=@P5caM#OF~{e-HQJGt}Cz$Yz#eH|kY?2i2i3E&=Uo zpX_Fr`=dTIs$q8QhN^H5=D;PWPq|Z=8y}%Y;+wD zo$tq}HGYmN_ZMma|DcvEejWy{^PiG{)+!UK!OEx#qEMTzH5S6?%ssQ| zAFN+dQ}3PE%kw9vDX*SAl?hW)D=uti*ewdOjERX|)O?@itb&9Qn-; z9DPw8JcQZ{UIon5WKG>4o7q(s~TFxnl>L_ep8g5>yQ4{HvncB*>1aDIJFD z;Uv@uwxZVV5bERlBC3L?)_155enSl?W{BBrDNviOAZEZ&8?T3|x3Nn=4Ys%TLNzoL zb^NBFKd!U!vsjGyD^$hV3)%08sQi6U$80)kY4@StkpDx?=x0=W-)*`Zx3KAXGSm#D zLuDw4+MFd(74OG1cn8&?&!{Q&3pGnn)7lU<6D@4KBdS~v)Qn9+b!d)x?mEi|XwBB5 z3huTZK^?oZsDjT>4ZlaNd6FV#M5$37_D6kI1fpi90O}MJ#+q0O)$jt;dtj9(&Jd3h zC`rP3tdEJq%=@4ns^Q+K28W{7b}Tl*xv2NX->3oj6!mgOV@gy<7NU0j3RJo6sE(Y# z=9sn^Kibj0GmwDJ{Tr)yaWm3XsN)ujm2eD}#>=PtPYDsRODtc(2e?(RI-Ns{s{eCI&cAvZC)^bDL(N1k)Eb7P)~p<=!D^^uR2S8;UZ@cdMvZI)YO_wZ z@!wG+-H!TZbQD$3EmZl3;jS6+E1U5Hs>e<#lff6&k<_RPGN8_FK~zV>QTgklI?%>G z?}nPO!KfLXh6Qmhssraxr{}6`6MRdXHS@D(LmkHu)CeL`o2emciaViZ&P8=#5~^bh zZTec&rrw3>z*kf~-et^E_+kigw+eyW1cswt7}2O>_W-lu7u4noC~IaS2o=wdI@iT9 zFV;tmYz*eZ$*37RfUWQvsslyKnS2$I4!cfu0(!?cL1l=-QrHExNup7E;1Fuf&Y(to z6*a|A?ej0F24j>rOO+b46VHSCaH@;S-w$)*M9*{1-*y7}(s&=W#$Qn1coIdJhO=R2 z;`vY&)yAyY$EGj90OAKR7$0E)^s8Xjyb|UoJ{a|Bxe+zcKQOk=|91i!X{?IoK}sx3 zJPT&Q_NYxb3AM?7#iqCro8fnx-lUS5p?0X5=w=;_YH$JS1+*6R1?LC4+DrkJ&F6AK z)Mgojnt>^(J+Kd+=Mw(|7R0EqB8z#(|u}~-JS@wNi(33+4$42GcIY%NhA zRtqs3K1Ah@Q`^jVaV)O$KZSs%`W%+WKT!q4>X=_F48qF9w_!!}u503vs1eOZHMkOs z;zKNm>Fb#WYoL~36sn!2sF5GXP<_RDVl$+#Z$?lAHNv*2f-`M=6KVz?qDJyBYU+a< znDj{0`=JBsyiddqxF5CYay2yN>S84E@fbq;&J6-(F;OEg&)@s4g-ngJ7N_G&Y=naw zo8N-nLcM^JHZjLG6sr)Qh?=?E7>XI1n*8-JfcRw8Qfx#G;5xe12qb7`dfXT_m6K2n zpG18YG;MBPnSHP%@g=AZKSb@3Y*AjGzug*+T7r3~nYxap@FQw-7H(noT4mJp#w|Gi z8cBZ=%Hd-B;2G+@5VNH*2kM<2Y2&?7YdIIyq5bHO|Dp!q-^z5bAvPnv2&?NkYH6#t z_VWB8x7*q^73?HIYxxEBhDy@Lz7equ@iABg&!9e3eA=2R&V#jyw?)q}!vV^N`LIGe z^D6F#Iz^MQAs#~Qk@RkR^JTCa7A9dM=EfH`p0b1KKvnBB4CnbZ)Hfl&j$Y1DEQFf+ ze{dj%b}~ORZbg00zrp30=@+wP$5HLM4+*GX>ds!y1gwJ<@Db`g5ZJ{`ZC%t7^hPzj z7zg2gR0GAknx*Q2DnAQz-~-gi<90L0vKVUVx*~hSb!HGyh1XFPeL_unP^$6JAFhv*bO^+J~d|)=2AG)QB&l-Vbqm>6B4ZaRN& z@B!*rrRrxkTLEiBj3Rv)YDS*e^celk$OBP7z|=z>uZ@@%&!Lv`6?!@_z{~STyOHQ> zS8pW{fq!6eEIiQsz|jl!NJ4`bGh?!$=G9vmI}&e* z+I+`Q4gGh z=O6SQ<>j=;f3Y#PA8k&_G1Sz*Lrr~xF<#DMER1RJ25KOGx&(9_a*p-#{PmiusHt9z z$?-Dk75oCV`@P1QsVs|{`WC2NzZA7+&RJieM(#b{9LM~q7gv8&{Yz1M&%H`OYhP!A z`3kiF6BA#C0k|2}<146+{9)s9CYrsH8MQP~sF@gz_3%CFm{pu)rg{*jB)$Q+;W6~n z`5!dd%)kuPvD#(5gKGE(YGkRWm}68BHL_Z$SL`saS*M|H351gQuIBDUaU7BQY*kLv^r$eclsweEXxyZ9?Tc zf?Dfy*bHONFf-f=V`>e05{Qlc@IDU3co;R)tZgUM)Xm2DxB+A0Zq(=b0aW?t)<4jn z_-E9T`OPxV^Pvy%Q1r!;=<3*2C!ihewEe&G}b`S0v~gOoBOPsvDxFu(`E6YJ?*&4o*PLzzkG} z=VB#Xg*t8@Fd?R&Yw`zTEaJgf4#Q9#88X+ta8{C_3a{CWw^3{T5H$l&P!)bbjWqT= zGefCRGm{0AVi+oa71W4ZU?S{}DmT=oPqQv{323S}p&HnSo+(G|frqFH-k@gW8){P} zoNq?vhcSo;pvq^#wpaig;at>X@!aeW)EpeF!~5%}D%Zrr~s0mv|7S zqN0Zsi}R0nRNcJW6H#DL{qp1&CxiQ4@uQ6t!ZI=1_yJvG ziTW7+4Yd@<(G4JQmVh$8MV;GtE6t_~MlD6CjYpu~>6KCWUCfK~P#rmqYQSriIbQzO za;P_DN6e3-uo>=H#rao7saBh*3Pz2%32N=fqBhHP)E?Q5n)0Kl({Ks3IiH}GD)(<@ z=^{}1t63Y^^p>b&-Vs$#*WX;T_JeGOv8YWo)n=S+U4WXhrKsJ!8nqM~Q61TdDtFpG zzl3V&7V3?8AN8L28#S;*Ys~Z1E`b0NGN39fiRxJe)TXS1DiCGugc?~NR7ZxQIxrSh zeje&Qu-wKsq3YR<+JwhZr{D%^Q@d~M1Fy9vLsC?QnNb--tQAo&nkJ}*qEIu^0o9?d zsI~8p3vo8;m=^xsY|aLliTD=Gir10nuJhdl9RGFZdq647NrpD4Q!oYfVX@nKAGK#< ztT#Wh`D1_Lg;5>agzDf9)Bp~mX5=br1|Fl9>M!*C`TsWp8gYybW~x%4)-EIJm}Ns% zT*$_Yp++2uT7tT$4mY*wV^HO%VO5-knz?7F&y-iF4*d^3fByH)W{ADftbKe`##E@? zpBA--rBNfVirOO`P&3m9m46;;44QOD;5)t(v2b+i28G ztwl}gb8LaBkC;t65Vf{jQJd}#ssry)n=jK*a|%K+tv>%N63`U4MjfZ|7>@H$=ll+8 z3SVMd^g8C{^uzY3Q}Y;G;ScPDEsvWuzkr2_e?Tost`p|lZv%`Vz6f0fo)ge9%zM&o zo(8B*G8$EI36{eP7>p@Tne@u2a{W=8Z@Epsgj#E_)AmnHusrcTSO@oEeN29a^Iwg? zFK5gM_hK0FtEgS;d)A~EKuuvK)W_)nRD;to6COg%#8Xr`=bU+gWkS6X3!!GXBx>zj z;}hJjUpQ1GF#o)ns%O}ac!mom<7g~K{3eEA%8Oo3H;hDW&V8sUPI$@7>5b*E5$?h4 znCh~5Wrt${;*Bu?C!?NkbO~q%ZeS10am9S2nU52RKSjLX=@oU%_!>@Zek8uN*#b0lj7uOBcOs2VM-ZO4x0@|$uP*b@SE8tPo-bi%I9M8IV zjrdyBt{!&V9LHIx?{a^jPC>Oh<`ir~P4#Qk^Wt~SkK+q4iufyJkGM|cJul}l35zfi zTi!Q4-H2(4f52gw=z%$=Q&A)M1N9yVcxb*S^hY(c0;^-JN2Z>-80f_p64a(V^4PTF z_e6Vz^Vf=iDjbC^aXb2A+NWky1)cIp!P@vs{Y0{ zy)&wOAJnFt^@8)S&-ptf=!-~-m&O2VAZo;gP#q|SYM_F(2C7^`?2oO{2Opp|^K;aD zBHkR55q5|qbWI{&o@=y(mbPDgFVHK>`ngIdc>A525# zur2Y9s6BBRbKrecgK_>e|Hgzbs-YpM`X{1hbQ!86>oJke|8|>j47FR&qt5F?ERSDN z6_onREJZ!cLcA$zt%qYGT!S%iC+cH-FRJ5bQ4PMsg7^hhf9{X={Ff)7W7if{Q8(07 z4nZ}v5cT>ihmH)c1xPiiYU|)xt$5<8_RIi9=MNc_^r+GH>$ye{~A+ZM&jwQES5wKUZpkOnfwYe*d?JfJS}?d#V7cVDlK>o^wAAwdRXa zr(!dzf#ax#Z=k01FVr#fifN38n&M=rrORRCg-}aW8B^%JHmH%WL5*w=s@z2z|7xEnj%$`IBWfmtQ6sL5>Uez|gni<=W@=Uf6U2t35xST>Qj=Tomcb|t<8HG-Up%~Xe@UZoMJ23lc$9E6&w4X8b`8P&i= z)KWY_ZR%I3nMm$ymfFoope+d@sI^>x+APaaQ@jf`6X&rg-o)jYB8j)>!)X_4uiQsX z?GsePF_M~wQ=(2uI$VsQ*d1>o?-joPCo?^&jgdTvLap(7)TTRtYT!K9!7Eq~b0zoo z{MCzLsB+g)9n6x#+w-yA919U&g_@CjsC@rmS*)1So6j81-y{Nha~(ph;aOA%Zlk99 zf2i{w&(Cx;E$VpXK#epMHB*&QA6Cs#r>HOL<9Pyx;YQSeUZZB@D|-I^U&>Tw>N23# zsyJ$G%b+^e81)8gi=K0gIzD4jpPE}xOY{Qk;s-2(6;qoR(Qwp&CZIaJ5VfbG(ev;B zov<11pnCQevtYb5reI#w2uq=kTU}HKTx1QMHK>toLREYaH4`^b19*q}-2aB!V=2;_ z&7LkT=U-D>iG%=bg!ynFX2*3{0Iy) z?srs24xzpu+)2;**9hWdFl+3K0mL(6H!O{Da0?E`y{IWK=I`zK%}7_&k}X0Vs}-od zu?e*#hfwvO!IpRhl`k~F+w-Yd&LyB8Ey5fjW-GZM*@tCf*rU!4*_TpP~lv9<}?wqSo3k$Q9W{(K^qT6O??DvW~-s+ zjfy%&ZS%Tj1dB<~8|xr?zG~rb#Gj)+o~PzBFQ&gRJMpafy*iV#V3kny)w1c^TpQSfdP5yT&#M!)$=;zxma?Gvw9ATliT6j1XbtKdZ%2K9 zc#9P(A3(rv_{S!6P z>V?c^9f3OUb1)b;p+7#yQW(3iX{REpL*0=*<2vIAXoT}|46emY7#wOwP!H8$KhzuY z8gAF~B4#9Suq1JxFw;PJtVFyEYSZmP9mglA8GVV`6N!s@JK;M2egrha`ly~op*qyh zrjJ3r38!K*ylQ=ks^~jvN@Eo>$IBm8J{zjx5Y(;@vz9<@!qS*f=f4VpV%P|^xn`rz z{{hreT*X}Y6q})Mac|ErtGc4{ug3Ox0riFpD`7s}dZEfMK{XhS8o(aZale4BM*NsS zI{bz@$Eix1O_d8ZGf}7xbwIs9T+}WeWz%1xcKHv~ri>YG;z>}a!w>ayL{`)u2}iZl zAe{5BS7b*LRB#jOjkg~&<84%f|6&08lroz%J8DWxpz@bSjj*Y;y?x#jRlYB3^SY=R z8jo7KW2Ia(@^d!fHL8byVh&7D+VnI8)xikVjMPT0aTBbFoltMIZKweqM>UwJjACr?)|`qUEJ}Jc)X2x9W@?pvej2qDZ&3~Y zg?g`iLv7L|<;d0xViMLT5&QrxS7=nsNpf+<=RD)4?4m+UUH$|$NrKwSs^RI-qB&dLk>iIM*jLT6Y zxPy7otD1S9A2rowP@Ab4>a_Gn&B#`pzTbKaLrMRL`reSIx`|h*&iPluC=%of)Nwk3 zrSS!7*9O)wo2M+Q;V8_5gD?PpM-AjGYQ#@bQ~Va|<5yIpuVED#GE)3HA8Dr1G$ZwiLY1*W7anDYN!D=K$Uj~ z5m1lkq0a4cR7Z|sNxX_WPATdbLr^2BgWA>IP#<1{Q8Tq0>*5uxh=Fy@p6G?zI|ESz zn}BRe{{3G90VG7DrtA{t$9t&r>RZpeLUUtd;vuMtr=dD}2es*5qh|7hO^;RIq$fwc z>(gRa%#6KoI_A*%kJrF_Wh#h8crXw()!R^0`vlccqK4j1IHt$y*c9vG2CR&+8=0T! zYN5)nLv`#n>YLId)Bsa9Hm52Rw$}MCNFW&Jpw{FZD&rf}?*1E9QL-lH6`jT!fSSr| zsCRpDRK9x1)H+R39q)uqae(y}Mi4L3l=H8(A4))LIS#dkvrrXpM6KCz)aJU5+B~tF znPV7;%2ym!zBa1CC{#zfqTU~UPQ%o6HPH3VIRE;JbcO^~a1pg@@1Z*O0`(4m zk9rTpZf;)HLDrgBh4j9t53gewg=bJ5%@bw53Dra`!C=(s+Jwr#H_A05JZuv#qc+P; z)RaC%&A>Mthw)pOSMN;gPShT`gQd`?rI~>Wr~%ZoHb*ts9s{upYKiB$1T^ARs40s^ zeMj42)6bwPx`sM-_fb>&4K>09txUOmsF^H`Dqjp$t~#pW2IzTHViV&1Q5|q^5YXB@ zL5wfR&_iS3AYLv`>Ls=yOeN8h1dOrNm>CTL@pst;;UOvJUg95tiW+nSEoM?G(k zy>4BTdPld^B%~64R~G@2jdKEiOD;dz0((S5g&|&n}M$hm6XA)3_3s5hP^{4`Std~$T@B%dh-%uU&?qV8B zjoMuKQTZZKGt&$`4WiyFgHauwg%xmF7tX(?_zemA{QiI%Y3{D3g8bG}sLfUbH3Mx> z-xIo^W^O2|!R4s6-D2YhQ60F5HSqyzi3)Zz>BYNo{;QG@NrFD_=UMNeHdDs#=2I^c za}w`_YG5X6S1&`co%Ls$YIqmE;y9%f+KQJb;_4n!B#v40fMl*aFA5|X0g8Bt4; z0~=ux)C|nPc(?}Dfvu>D_M(>T4658C)Uo~(Gh>Qg=3}}Ds)M~zOX6-NppV;gs8^)Z z+Y}5&6|9Te#r;uBH5>IQxezrYH&9FG-N$^TDvqkJH)@SnV?}(A<*;a9(}AH_UFZJ* z0gWh0KVv%7Cd!T)Q5dRVbyR~hQ5`ve+Dyl=175;$SiHa4#3xXD zSy1`HP)k=5J^%lY2m(6i{jdPeKy9)UsLgd1E7^wm-2|6y5P@85WYDy2GHr)x- z)O|qh?j$44T9-lXiB_o7Gu@`2z_P?&VkOKo%Di9tp-$BvERGLc0-XtD813!(n+X#! znD|}P8!PD;^LgDGYY{(;?a^GhKjmtII(}W zNZegcK)e3}s>dHuYZNxY6lj6Ph%ZOwdx(00_)Ii2Ru037w?)m=YRrX~FbKb+-WRzh znZ4Bt6~B)qb^cRNHovcLfO-Y*!YCEQ-q>u4`Ssg1yh%LGRP#OIFRVtq?KHDFw__*b zFHkdA=U4jz!bsxpQ8QR#x>kRX=-7utwPBiYt_ozLvVWt_u zIn>m~nPq++sEXP{i){QLYCuV6n`2l9>k{vbI=)9S4(&Ua3FyP&4rDuK$izF#kfcBrdAlc^rwaF$Z>AWZr~xQKx9* zBF=wT0*^>gM`|rLKbuX!^2EKDnB!Fu^=9mc`mp&OwKUIB=RW&V^L2d~J|I3HRo|dx z-k$%}(l!hs9=Y65UZ)P_JV^tFBqrSVX!U)`t`cfKujaloG zsHyFUnxWA+9M54>thv^di$?8@FIW+?{%($M7wdG?3&`C`KvVe{)llJeX05xRMs~*f z0oB1&>&*+PEjA;56!jsKb%SZ31Zt*QqB<}VwRxjad*%)*zyC(hvE}c7640)0kJ=4MrDt5B!Gd$Z9G^-2!HB0B$l z2n-}48dY(gEoN;xpw?R6pd9V5T3=6O5RyMHEXDvx0UjJeJHVOCR&BEAv*G3j=1 zXDSvzE#VQ&O8d?O0@|%UJIsTUs3~iNI_INM&-Y?7{Dc~Dyq#uO=SGdVB?jO;Opkj| zpDnjA4OZM`j%zE-Lwq*6#RwcHpbBE{HX|*DWr&Z#-gpM}YAv(J+w&h1+=%VHn2EjK z&Uw;@?qf!X*Vymv3?uFyFhAjVAN2ekFQ*M^2_~Z67fVsc@7h7mzutVS51A=Eikhkz zhs}#5Ginp{KpoRXsIO9+P`m#GYGjFzm{)5q3@1JmmH!ZGCaz)t{)sA={HU41Mn^gS z+H8YK7=t^pC6+#BzN@XoM8wx(Hr$2k;6v1=^g3>Kb5hi&XCP{6x}s+6SJd%zPMD63 zK<%lcm>U0f3A`YX^rWfq8>)c>r_62-LXDs*Y6?4{9}dL;oP)u*3-jS0s8?&iY4cf9 z6DJdQQSbc3XUxZRFN{+9A_AIHue0W_O88+{J-~hV4x8hKb7u4To;P37vY-#?xluC| zjOth!jE#*j99yE6VmT(j?Wj|B1eqcB{{=G@zhDd=j7EJtj>j-I)f`m8D;LeNdx$BC zC%$C9bY{bt#0#OmpcF-Qs5!>NE;hYCYOgH9Shx#))&2njT8oRQrUq%cfUJvzr1QwuuXBGjyNKT>NfM2l& zX1;2^_xD0|z(p0DfpKs(Y7<6dd_07DKb*tr_y|j5!E0t|dZY4BLe0=3boIHto`4$u z2TNks>t;$@qZ;af-q-_Gus7-*J`&ZTg{Tfh+w{HYPy8Bc(|$sgi+{tI2DQXFZ*cxK zMTPByil~a}+YGHx$EiE&l{v#2Z9R+HbT84fiEo-E^Fyt5b{v4Ekg&ybKHkIKK^&i`(Y&ZA^s9IfT+7>L_JV@VJIqn3~IB^ zwee`w={StqE2muoMF?E83BLDCfwZWpD}b8f2vmWFsP{o@)Mgxx0k{UWt50JHUc~+w z`@Z=l^)ReS{1#@!+z-qWy47r;9qPeQR71;9Q@b9u2achZ;yh}TeL$TWpND3|0jOh| z9rZjIRbK_vE4%~hLu@8$VCRv|=sHgbG$7$4>a(EQBlEf43AKriquy}OQ6o$D*!R+GpmwULFi1{tN0ou^O}D8O((rP@6gZbAH02eWwTk9m4^rH9d(1 z@EzvC%rDGHYoaP>ggVEgtg}!Ru11~vBdDoQ@zR{8!l;gyL2bV3HeMfHZJO2ubbLCZ zXZNC}c8rZrMU8m2b%Av$YU)>^%0;85dWVglK{b3CRsMmEKSk}W4=*|Y8cDoYrh>Gn zA0jiMHen>Hf_kWYtuQh6vW~RrGf)FriOT=Gbtmc=9z%8T2CClssQ1jPSDb$p_(X!< zP%&Pccv931_@mxbIZy=(+4Rz=sjQ4DUklYhb5#DesLk68*WwHtFZIT}PohwJ0o)(3$7Mw zsXJTU5d_rpxu_{zf|}x0sHxhHdiNhfjqIrPGU}8(wDEsYdm-UF^I_(PibtSkvIe%r zhN$)qp_k78NdlU})2J824b;^B&!&Gw74Uv|o#U89=l>1?Wqga;1An0^i1ERs$3bnPM5uxRsER^R4Hv;6j6f|#PgH#~ zt@Eu*Q8Tg{wKSVBfzJOv0s(j$bK@J-8m0NuWXy;9A+i{1Qw>0MU><6T7NII!gX;J; z>uyxX57_u6)J$JT&D<08{P%wo{AJ!)`B78V2~|-KR6~7HYdFw45?MRX)s>;!i(C zl5j$vZL}>ErlZ=Z2`D#|26FyvnY2zeoY>Yik2GDr|LKTJ`GP#JgzjV>Oed1rcH$Q@ z&*W~)ecM*jhdeFFypgo2HZ4AJT_x#kRl*Pc)4&uuK8|P2c~&2f^QtB{YO)3kef_G%>$gOwvS4KCUXB)8@ zjc+EcCC|p$hWVG=JXc-vJSAOMTJkQ^Ab571v_hED4(c26%RGO{U4}A#q`M3F$0{;; zkyx8@wYaPD@FeLMNh?pG5E`su8(YXTU8_jXz&)Kj>Fvmuljj8C!Q@ZNeS+sHu?l&j zx!X`@XUcz}JU?paa-Cun$j|)`v1C+m&Q_+U!--G9-$+ZXil{I>72PMjBk3ne`$4>m zEpwg98`(88TDZ4O>8kVp8BV&qh<(Jnr?B{Y;*$gbR`Xzt;fr>bh&o2UypTZ!*swa3|u{ z{&W82e$9i}Wcp4xDHWgM;dUz4#n&~@mBCgrp7?Q|>#9lKeKxH40ynhE?o%jIisAKDlq|76=$d$o%EEaAiEtA^sK_G$6(2jz- zx^iFR9!|z%RMdj>g5VUz^$)IG)cEs?OPJq?damx& zHHelM*oO~@7omIuTgTg9z*5|KU>5DG?<9WdQqSp;U3&` zxnq;YzgF$JidqxfPN(9Tu2}}pKd(?m*F2tW=dMS?XUMN*&+J=7C8)@_Ln+(sj*T&aUpDrKL`FH-!E9?xB z3sf?bMk-LzY1~Hq3z-ASyqiw_yq*wFK*63oD@NWSgiDg&wGEsiy(4+TY#Dx`;2a`c z-gd-`e7h+(!F1SlYVdFg_Z$iyq@w>`2PxEn0^@Dved$y&?q|00SfqPX#+$SzDoFYY z$|SV)yr+@m#P{+1H(STg`m=iCyh4tUsRWH@rLcZ@i-Gqjupj$y`||8IHm9OASf0v% zqfB?=y2cW2Nd6Dx)76^0rEM%7`CoF+LV^x@pCsd$&E!to=$G5PvoVcXH-JiAJx@yQoV z{^{KAS|ZcQ(31v^ardOsN8G)+`*Qn}HjzB{$rE8K7cHoKG3kk^B$P_Ckd~5oH`0&T ze2)otq}*ccL)sd``b|VMHliFCe}qlo00|{1e2K6f(l&-?|>d3QrJo|ag;rS)nN`yD4$Fu*V$iz>r&T=Zx#NC<3#*!g~ zf?0^`(r*#QdkXM9i{~o|hmls8TR(M{rVd^CDAyN5$dixqO~|**KHE!OPq=?2eIV`W z8m>=t9}>q=;1q>*jkArertksoT|C=Qp>;g3z_WQ&cz~Oq?VY3CV+gmW+zVU&6J;K7 zU$YIj<5@H6I8VF<xApZu!x*8GZKgr-kk#8R1@0gbO8|r_=t;@&M?K*3S+~DR{AWj!D`cfbf;or%S zmrB=D@EC>06RykMk34tC(}8dq?q7M&j$Dx)uW{7e$8#@@$fM?9?It^U`l0s!;wh zX{oszuTA*chH$VWZcQK zb38kYx(ae1@`QL}l9q;gnv-vwMn%5f+$D+YI*pCVQ`UB9hOMK=&(HtYJoufv2!%)U za6JWb5uZjS|Gi4knVUTOh4f71Jxd4qJ&fo2WGg>PS~Aj_le¬|#2Dx#QY+G0J`* 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�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 IFy{*X1MzcM#Q*>R delta 43166 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�+S+u!YxFw|5pLv6kf_ypq)aDQI-WdP^D3kgNB1a89YDu|mg<3RU>cTod+ zhea{rAb;O~AEXZIiT*_8XBq6uS3@mDE7ZV;qc-!7B72I@)IqGsYTs(y-L?n#TH*17?9#`)L^V-I)j^hOQPyPbg6>>8%Q zgd?1VPz^Uj&B!d&DL8}LE8kE{R(_Uch~H@u#` z1hiWpp(?~1?VhkEYU+MPt?>j5#I2~Mx{8{CBxBsWye9gl9DP%c^~qmt@knD`ekRn5 zs{&Tn`R_qMQ+mR@i&~?1mbU@-lA5>IrSs1)i6rea6jWbss!+|(6E?TJPfAAuUkV$=*CH{YY)^{FS@ zPr0aL*b+5>@u(_o7}**HAMTbG9oNVira{ab;BbVW`bH54AL}W^>N>E za$h(Wp&I^R@dS%qLv1mP^bx25Kf!UBe~EkL9!D)zjHPa7QkZE_>6tJt7If)ePgMe% zlG>;bg^@19GtJWHU>NCVPz{7Ea}5_ZOW`NdD`HeEz1)2kR6{Loe^mNp43BeB54H$> z|NZ|11R|1f7K88#Y6{<5ddwB>J75CT0D@3UlNGhO8leV0&GHvnd?RWz@52Om1=a3z zRDTgxGBBP0=mcV8LNf!Zg94~?+s4u-q1Je@c?7k#kFh3(Tjd5)$83Qba2M2<*ukid z$C^{n_x*nsf&64FM|FG;wVPwDb`?{hDrQD4RZi4ETA)tF2-MW>GWVl8Jc62mbEx(n zqP~8AL@iCMHJpE~MVdA4NlKbwsHy6QYG9hV+B{%hGhdkD*1C2Qqn#mA_$ET!S?*Xq|h)Zm4(q3e*5;J>4>=A z{Z6?Kb|JnVwHZ@waE5pZgd-szYQ%-iN@hdU)VDXgq2645Exrsj)oW3ka2x8$4x>7{ zh(UN8wO78O2A*W2{os>>Ko%16px$V$P*1W4wHLmkrZ9Mu8(?8n2bEDv(*QMqF6dh_ z)B{bk_)OHmHlmh#AL@bbxOA`QApwo-Un>w}vn!Yx^@^;BYM?W!qXAeON1_JyC+Zv2 z8&n4cx7eEwvlAbKEpRWY7bpZ|FY=m(50s3kaqdcxbNCwyl5ZF5tf5cPz` zQ5}{xTcD2XP|II~T7vZ!--S9o`%v{>q3_@S#oX?WUmjFO7ju%i-aLo;#`6#AiPP_J zGt?Q?@pN-9>Pa72`~_+TUkkEQWdk zRj_z-)QogMbvz37KADLsw-1hP9ep=suv@aEs3$9ps$U+}Q58!M zMGdGPYU#dE_&Yb>S3D!R|BaycFV`UMVk9Kg{Bh->HSGyqCkfA|)s)<^)H+uiTFVxR z&53;N^ZlsamiSTXpQVF8N$ahVaYd$1WZK~0B>1lNq$ejotwyZ=!${anT+0a`AwADegStuhYB=V977ZMsWOf>@Lt-OLM`8ZOq;E4Wq?2Bh z(GQaOx%+XKAzlX`a3`j2J37|2fcr9aBhVoqdY*FB)m4ai8Y{DiIy>oSr!PmJDnDKN z?xt(ultDA&`u1isif5y#m88xhtm_zEq_d`b(9|%}8ejp^UQ$-yAYY@duGD!%x?aAz z`cm#3cOlZYTYCu@+BTQ%``>ZI`3ETOY+R?aZQL)Z^y3;~llzr)T}P;ph{nDXk3hN9 zF4_0Lm+0sgp-kkBpiFk+x`t7%67A$5T#3Bjtj&8k##h4i?x`qWX zj7F1Mn$n-sa0SZG!Nc6T)=)Qqa$~GqE;9$|1Gv51sY#1ZnIX1N^_5tY#LFbSu<7I< z{`r1|;F{$y61c(rJL&7OE9FYlX)EfSAl#SwM{E$Oi1Y7#{&!twkpEe11ARp#?z^xr z<-DV)SkFe2pN8~(I1>ebTtzMXiE<}M>`&Rg_&fKZpUSEHaBJr|>5m!6Vmc{FdO^Zf zX**Dome~feSnK~UiMsTyuQG)i(oufyNQ6__lguOUA>}%fe$3LAkw2S;9+J0!v>kZf z@|H7@>4cMzzm;;j{-&<33bfOmaDCEmgtPTOPr_F#ph6GG{Ay1ZoA6UA<)N`(XtX=w zFndy!{YHEOc?rqW7riEgXHaK1?JXf~Ao;rf;I2+ydg2qw+fQDjoD|eolPT6&Bns&I zK%w=7L+L2?PXkk4vMJSu$Myb3bzS*vC^xN}Iyi*ZK2nR%B+p5VN-t4KdrbKx)O$tx zPU6K0$EBC{#1m2Gy^Z24<^Hwy)rYP%#KX~76Usf-huSX$j!;q8OzvTXGg9C^=>@pY z+oLG|5S2&TV?@Wy+`Gu1hncKg3_5>A8^2Ol7e8KlHWR)~csk*Bmj2Aw4hvVCgxO^1 zN`Q6fyp%Oof_Qj)nx5qMCH*DkeAO)-(OIjG;3a23i%B<#`6)t^i^M0{psEl~%>9csT#oY3C=-K5b!D*h zoyd1s&vH7xL_41-lY%=f@#ZQ^8{WT&WaXYj;j3h(BYiyKLsYoNJ%PIvX{pK6wTJjO z?!T#gjI>UczKgVzv@?KP*LKBZM#A8ya58*`C=@1$$%Ds?sLrKrf9s1LNx-$q}AE;M^`n?#$b=0+% zdcRQiHF*Jq`9IG){iE_5+#9JFo5H%b{M6uRYw#V7Y$ClFZlPuiE7OJYYt$0gD%$yR zJ-0N)4|C^WpfS016`^h#YuCGwPMeZ(-$uFH8aZVR)FW@4g$Gh5I{Er$J;NHyME!}@ z*dOGFCw!a^?%Du-J@P*vXyX!jxhcaxLG@ja^p^?-Swo9xXxmSfa$5Q+oJ{4qRElZ& zODQ|g^8X^QBnxHLx8AgzNS8~7^XE2(n^5Apz+a4PZ1dT}=)per7Qvv5bDk@7UI zU-A67nvnJCnWti#TP$CG!OGA%I)W%%8wXD)8!jzL;v8cl$0 zNl)b^@jMCDY3M&jUX^%7?mfgy5!V$=I2RpEp+Z?~;F3KF2v4@Ks7d~h>mGI2k)M#X z^o05Kf~N_Yg{)1LJ4M(#mOwRiN+-HDkysmVa+e}~q7u2z(b$ixAfwMuo~}-6gu4An zYegqPzEt-=jmS$+y{kVBYzXm&+^JlDUe6AutSgZ*R_Fqmx`xo;ebV(4b#6LK#9fE@ zcG7h{rtuKUrl)=o_i@54Njpb7ak!6BJ}&7isMCn>Eb5gdexAIVl+8{Xdm^#^W6AjF zYmyIV3WjiJp+Fr9FSJ1oF?W%-nNG&jsICx)?|=Cb(|1LpZf@%GZ{z=Wt*}r2IG*1=i^6h_)C%IXRxo`ZWe`T9M? zK|DjApVeDO=Tqzfyy1yV3glkGJx){1z$#HEspTpE0e3&rN76}h>nI*&HgmrwFOKzbh458<$zDaF zcHHG@@CKs{#6M{8JmLJLm!R`_++|7skN7V%u1gfB%usG!`|tpFBNz4kZxjj@vHTy& z8))ap_)s1@!5o@ z*;C9VUWD*i@_O2!_F^s4SCIb9_2J>qEPPiz(vn)a3Djx9fV<*uFwC(L=ti9T0mkvDxb8%&j|lX zUT5O`R@YOJa4yQFqLEy5c=@M}f+-V5-b8EbGy^S4+9(`igCyJYlKcz|>JaH8yfm<% z%(B+u1rl46xqf!h1&(I7-Gz8aPO}JQlYK$7m=CXfiVe^nI7Fed*3fGT9-u%>?&cIYOMI(6jUVN1 z(TJ{JNQ*<>HX7FziM(sv3&P+t9e-dg7oF&~9=Wv20C zRG!Rzknq1hHI&oJ|LSXiSt0)f4gW`(UfdN3$0e`fPjwa%ug*i|{3&fU_0+%b8bqVP zgr-tC0rvqL$W|)-%Du(n7s>l^1<>dY8reAQECw;IuV74$ly8!(a+iAsQ8nla`A3@7z5| zOM?w5bDi`##B~LbwiUbmzYaVPse8xrpOXLM;=dZ^*`j|~bdQv|M7mR{0}Y)++}I6&HmP|%5NiW$4_ykU7@14QbCwD@WzFG_sg`IpK_?>q^f33-?9p^uV;_m8bCp+);_^ z8b;nL;<0J-0QDvj{&5BWZxF2i0xB0Jp(CC2q)>S(7Ng`HD_ww*pP|f6@*|M9QJoOi z6>I})YVp#v)1ETArc+N>11nRXcrwEOP(KUhGLd)t$1hrk5LwF|^?xJdy-kHxG#qLT zknK6eJ%Y4AYkVAe>idj6-66trYyjCQQ-aK{c#(D&Ql=fIBYu^840XK`NZdnU4^Nks zic!hX^^Np;q|Kp1T}yL096{@By{Yutlv_u+I@}SdcZ)V#VHNUba7Uu;`3xpETz zBWBmn06hrk8c1PXi-||Ju;S}}>SPIdD{U}+%))y7pROmA&qn>i+@t8U1M#!ilmTU- z&TphQA^e5(F8U5wg37B&?7$t14x&&f{!g9eBmR-R*W9hB_zz_kTmE}G&qewJZe8!l zdqmzcIy}z3^QU%{pOyR{S8D3k^-{5mJwa(I{J3se!6S4y(;E4M@JPyB;eJ5=I_h?0 za92p*^ixMqXvB}aCFJRv%KeP|{*?RlQ@OR|`#yh4`-)M?2JnT(6EUb_RM<_0y;dnD z@mm%yN7=nrz8N;R^vQ%5(r^-stLcaqenNd+wP>5a-R1d9f3Wq1gt8P^Ktd4;d?vok zMy|pMX)rzUHk7GKyem%@<)_Bu5Z5)x(zei!uG{8RY+-o=XzL_x75-oQzUOCWk`aSK zv2BEdt#S=>3HjscsE2j7ig+o@yT#M+pNRBby{+NKs6PykLi$(AJ;trLll04!A5C9- z3BUFdnMb1=xkE@OO2H-+Y)@F%c*5Z+Gl;vYb>4}}b-CA&mXv{vp=>hB5%lb$%sD(q z{;!1VQ6??%a+H~ZEx2cMx8!b58E;8yttQeBE73?Bd`w|o&#*HVW>CM;&{`U7jW2LF z<%W{p+gFmOBF&%s1a)?hUYWK6$g9U)o%<;DT97u*+E%qt+kc+wWHuv#|1_W{1BF^L zvXO*!T_T(kdz1bNqtJ13%J(MyF!vl4;yOpe6R5M9a-DE0WpriW9!j`7^>huSj;>bR zq5Q=fPX{XK3P+{gF6jIJC$!HR=!UN>oX!RnXpLBLPjNc0O_`Il^;B(Hn^8!6V&O1s zX5k<8eCKbCjckdgj}Gz@uYlp{WEq~Ik;~TcZNi0VBm!kqQmzW|E|wSfr$LqZX__OG zzm@X30!)P$bKCw`)LloZc%NVg{7S`MbkLcG%aFDovtWDDbnRjw^|@bAE(vKDXuLe( zMTBotwlZZ-)6NciK-Jk!`cuk$bp!NzCKE|%qxw!`{ir;bdnsw3iR)Trj-axxAQ~J? zS~JSkqrR?Yln)|p7G(|)e&IUsv?BgH;bD}kM*3jtyth2x^H;RSE0cJNdo_)Bqrr6) z98CpXSqbYZik~U7%SAn%2#@5>VT1TWcm`!MP_I6wwzmJI{0SR;Cemk6{vKs&>iw^4 z4HY|KL2F29g&0T`8n|w0C1{{HX_>7~Ci4CvT#LFBNiRcqCh96for1*usZ){gCDJC* zaZ$>yr_2Syy8gHR%_-c4dk={@xldDI6diQrPQ$&0v`K1+@N}yjg|rByz2h!TN8z}$ zbL(nNCmZPO=j(6U&%>>2GLF~#|H1!P=p7ls+{-BRoV?yNuB*E>{Fbzw3?MDmwx?ak zpl*`i)Z&}S(=`lFQ-74TF_?BAQa35q^p)ZHV_4=Q8u*H9DL@C1d2TNNdi0mv~2vZ~6PJjqs$Wv*kHL-aOi$$^C@1bhLk-Th}A*s?_%$ zATtGl(Wb9~^-uRxjJr2R$sBljo0|9@P^2>8?Ba2!jal2l4fg{%}T zM|iz;n#?LZq0En~Gxeeqc}m$Xl+`uJ22|t!x;nd%ro$+VyHzux=)(xqj8Tqmg1*cq zDHcfunHdsNLt;=QC26td&`OaSmDvZCOSZs*X#_%U#or4v(Ws=Wc@q=_VXYV?(L|_j z`knudG&*oN=Y7ueJm-B;aEKsvkv?n~k2&b3nGcG-oP3X{15z=-X6hgYf5-^4NnO%L z?}ayt(K}4;$*bY?lZjgc7qeTPATOBYQ(rQ4;S{A-!MG0APA&wKSgzNZ&#aF0kTc{C z^sA_)RQc`HCN|c>Z%6lmn;Zsvi1s7c0?p<(>%lK6Pd*BTS+JFSi)l3(L-U5(3}*{IF?191+^h=FZjgTSFBxv)RSjnu^Cr-{ z^dT4yas@e-wmZ!H6T2qROp$i_5ZF4syN&%ZIxdt#BKa}i17@{vooB1G}BqKnF<9tfLCgZg(mw_Gd8TlQ|sS65CQFNyFY3)4wfyN_l!)WWYR^{5h_Fahg3>o8n*0H?5 Dl+cy! diff --git a/locale/zh/LC_MESSAGES/django.po b/locale/zh/LC_MESSAGES/django.po index 937295e8..da98c7b6 100644 --- a/locale/zh/LC_MESSAGES/django.po +++ b/locale/zh/LC_MESSAGES/django.po @@ -199,7 +199,7 @@ msgid "User sections" msgstr "用户页面导航" #: accounts/templates/account.html:44 accounts/templates/account.html:52 -#: admin/forms.py:189 computes/templates/computes/list.html:30 +#: admin/forms.py:185 computes/templates/computes/list.html:30 #: computes/templates/computes/list.html:57 computes/templates/overview.html:46 msgid "VMs" msgstr "虚拟机" @@ -687,12 +687,12 @@ msgstr "权限" msgid "Groups" msgstr "用户组" -#: admin/forms.py:143 +#: admin/forms.py:139 #, python-format msgid "NEW_USER_DEFAULT_INSTANCES: %(name)s is not exactly one VM" msgstr "NEW_USER_DEFAULT_INSTANCES:%(name)s 不是唯一的一台虚拟机" -#: admin/forms.py:190 computes/templates/computes/list.html:58 +#: admin/forms.py:186 computes/templates/computes/list.html:58 #: computes/templates/overview.html:58 instances/forms.py:15 #: instances/templates/allinstances_index_grouped.html:16 #: instances/templates/allinstances_index_nongrouped.html:14 @@ -702,7 +702,7 @@ msgstr "NEW_USER_DEFAULT_INSTANCES:%(name)s 不是唯一的一台虚拟机" msgid "vCPUs" msgstr "vCPU" -#: admin/forms.py:191 computes/templates/computes/instances.html:49 +#: admin/forms.py:187 computes/templates/computes/instances.html:49 #: computes/templates/computes/list.html:59 computes/templates/overview.html:66 #: computes/templates/overview.html:150 #: instances/templates/allinstances_index_grouped.html:17 @@ -714,34 +714,34 @@ msgstr "vCPU" msgid "Memory" msgstr "内存" -#: admin/forms.py:192 instances/models.py:237 +#: admin/forms.py:188 instances/models.py:237 #: instances/templates/create_instance_w2.html:118 #: instances/templates/instances/settings_tab.html:25 #: instances/templates/instances/stats_tab.html:51 msgid "Disk" msgstr "磁盘" -#: admin/forms.py:202 +#: admin/forms.py:198 msgid "No limit" msgstr "不限" -#: admin/forms.py:218 +#: admin/forms.py:214 msgid "Enter a limit or choose No limit." msgstr "请输入限制值,或选择“不限”。" -#: admin/forms.py:230 +#: admin/forms.py:226 msgid "The user must change it at their next login" msgstr "用户必须在下次登录时修改密码" -#: admin/forms.py:236 +#: admin/forms.py:232 msgid "With a password" msgstr "使用密码" -#: admin/forms.py:236 +#: admin/forms.py:232 msgid "Without a password" msgstr "不使用密码" -#: admin/forms.py:242 +#: admin/forms.py:238 msgid "A user without a password cannot be made to change it" msgstr "没有密码的用户无法被要求修改密码" @@ -895,7 +895,7 @@ msgid "IP" msgstr "IP" #: admin/templates/admin/logs.html:56 admin/views.py:286 instances/states.py:19 -#: instances/views.py:415 instances/views.py:417 logs/views.py:17 +#: instances/views.py:414 instances/views.py:416 logs/views.py:17 msgid "Unknown" msgstr "未知" @@ -2279,25 +2279,21 @@ msgstr "客户机架构" msgid "Emulator" msgstr "模拟器" -#: computes/validators.py:25 +#: computes/validators.py:24 msgid "Enter an IPv4 address or a host name, without a scheme, port or path" msgstr "请输入 IPv4 地址或主机名,不带协议、端口或路径" -#: computes/validators.py:36 +#: computes/validators.py:35 msgid "" "The login may contain only letters, digits, '.', '_' and '-', and may not " "start with '-'" msgstr "登录名只能包含字母、数字、'.'、'_' 和 '-',且不能以 '-' 开头" -#: computes/validators.py:42 -msgid "The name must not contain any special characters" -msgstr "名称不能包含任何特殊字符" - -#: computes/validators.py:53 +#: computes/validators.py:47 msgid "Enter an IP address or a host name, without a scheme or port" msgstr "请输入 IP 地址或主机名,不带协议或端口" -#: computes/validators.py:60 +#: computes/validators.py:54 msgid "" "Enter the 64 hexadecimal characters of GSTFSD_KEY in the host's " "/etc/default/webvirt-gstfsd" @@ -2819,7 +2815,7 @@ msgstr "磁盘已复制,但无法定义克隆:%(error)s;请检查这些卷 msgid "Create VM" msgstr "创建虚拟机" -#: instances/jobs.py:773 instances/jobs.py:818 instances/views.py:2459 +#: instances/jobs.py:773 instances/jobs.py:818 instances/views.py:2458 msgid "A virtual machine with this name already exists" msgstr "同名虚拟机已存在" @@ -3207,7 +3203,7 @@ msgid "Disk source" msgstr "磁盘来源" #: instances/templates/add_instance_volume.html:21 -#: instances/templates/create_instance_w2.html:134 instances/views.py:2478 +#: instances/templates/create_instance_w2.html:134 instances/views.py:2477 msgid "New disk" msgstr "新磁盘" @@ -3571,7 +3567,7 @@ msgstr "自定义 CPU 型号" msgid "Size (GiB)" msgstr "大小(GiB)" -#: instances/templates/create_instance_w2.html:161 instances/views.py:2479 +#: instances/templates/create_instance_w2.html:161 instances/views.py:2478 msgid "Existing volumes" msgstr "已有卷" @@ -3607,7 +3603,7 @@ msgstr "设备" msgid "Remove" msgstr "移除" -#: instances/templates/create_instance_w2.html:194 instances/views.py:2480 +#: instances/templates/create_instance_w2.html:194 instances/views.py:2479 msgid "Clone from template" msgstr "从模板克隆" @@ -5613,58 +5609,58 @@ msgstr "无效的 MAC 地址" msgid "More MAC addresses than networks" msgstr "MAC 地址数量多于网络数量" -#: instances/views.py:169 +#: instances/views.py:168 msgid "Enter an IP address, a network such as 192.0.2.0/24, or a MAC address." msgstr "请输入 IP 地址、网络(如 192.0.2.0/24)或 MAC 地址。" -#: instances/views.py:175 instances/views.py:209 +#: instances/views.py:174 instances/views.py:208 msgid "Too many searches are still running; try again shortly." msgstr "仍在运行的搜索过多;请稍后再试。" -#: instances/views.py:257 +#: instances/views.py:256 #, 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:262 #, python-format msgid "The host of '%(name)s' cannot be reached right now." msgstr "目前无法连接“%(name)s”所在的主机。" -#: instances/views.py:264 +#: instances/views.py:263 msgid " Jobs on it can be followed under Jobs in the menu." msgstr " 其上的任务可在菜单的“任务”中跟踪。" -#: instances/views.py:272 +#: instances/views.py:271 #, python-format msgid "'%(name)s' is no longer on its host." msgstr "“%(name)s”已不在其主机上。" -#: instances/views.py:370 +#: instances/views.py:369 msgid "There is no other host to migrate to." msgstr "没有其他可迁移到的主机。" -#: instances/views.py:372 +#: instances/views.py:371 msgid "A VM migrates when it is running, paused or shut off." msgstr "虚拟机在运行、暂停或关机状态下均可迁移。" -#: instances/views.py:374 +#: instances/views.py:373 msgid "" "A VM with snapshots cannot be migrated: its snapshots stay on this host. " "Delete them first." msgstr "有快照的虚拟机无法迁移:其快照保留在本主机上。请先删除快照。" -#: instances/views.py:376 +#: instances/views.py:375 msgid "" "A VM with host devices cannot be migrated: the destination may not have them." " Remove them first." msgstr "有主机设备的虚拟机无法迁移:目标主机可能没有这些设备。请先移除它们。" -#: instances/views.py:640 +#: instances/views.py:639 msgid "The VM was moved meanwhile; try again." msgstr "该虚拟机在此期间已被移动;请重试。" -#: instances/views.py:756 +#: instances/views.py:755 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 " @@ -5674,7 +5670,7 @@ msgstr "" "运行中的虚拟机在此总线上没有可用 PCI 插槽来添加磁盘:如果虚拟机有 SCSI 控制器,请选择 scsi " "总线;或关闭虚拟机后再添加磁盘。“磁盘”选项卡上的“添加 PCIe 插槽”可使其从下次启动起获得可用插槽。新卷会保留在其存储池中,可作为现有卷挂载。" -#: instances/views.py:760 +#: instances/views.py:759 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" @@ -5684,262 +5680,262 @@ msgstr "" "运行中的虚拟机没有可用 PCI 插槽来添加磁盘所需的 SCSI 控制器:请关闭虚拟机后再添加磁盘。“磁盘”选项卡上的“添加 PCIe " "插槽”可使其从下次启动起获得可用插槽。新卷会保留在其存储池中,可作为现有卷挂载。" -#: instances/views.py:778 +#: instances/views.py:777 #, python-format msgid "Invalid disk options: %(options)s" msgstr "无效的磁盘选项:%(options)s" -#: instances/views.py:788 instances/views.py:803 +#: instances/views.py:787 instances/views.py:802 msgid "Templates cannot be started." msgstr "模板无法启动。" -#: instances/views.py:995 +#: instances/views.py:994 #, python-format msgid "Set the gstfsd key of %(compute)s first (Computes, edit the host)" msgstr "请先设置 %(compute)s 的 gstfsd 密钥(计算节点,编辑该主机)" -#: instances/views.py:1002 instances/views.py:1020 instances/views.py:1029 +#: instances/views.py:1001 instances/views.py:1019 instances/views.py:1028 #, python-format msgid "gstfsd error: %(err)s" msgstr "gstfsd 错误:%(err)s" -#: instances/views.py:1030 +#: instances/views.py:1029 msgid "the reply is not signed with the key" msgstr "回复未使用该密钥签名" -#: instances/views.py:1038 +#: instances/views.py:1037 msgid "Shut the VM down, or start its QEMU guest agent, and try again" msgstr "请关闭虚拟机,或启动其 QEMU 客户机代理,然后重试" -#: instances/views.py:1051 +#: instances/views.py:1050 msgid "The change may still be made when the agent answers again." msgstr "当代理再次响应时,此更改仍可能生效。" -#: instances/views.py:1079 +#: instances/views.py:1078 msgid "Reset root password" msgstr "重置 root 密码" -#: instances/views.py:1083 +#: instances/views.py:1082 msgid "Enter a password" msgstr "请输入密码" -#: instances/views.py:1097 +#: instances/views.py:1096 msgid "Select an SSH public key" msgstr "请选择 SSH 公钥" -#: instances/views.py:1119 +#: instances/views.py:1118 #, python-format msgid "Installed new SSH public key %(keyname)s" msgstr "已安装新的 SSH 公钥 %(keyname)s" -#: instances/views.py:1139 +#: instances/views.py:1138 msgid "Enter a whole number of vCPUs" msgstr "请输入整数个 vCPU" -#: instances/views.py:1143 +#: instances/views.py:1142 msgid "Shut off the VM to change its vCPUs" msgstr "请关闭虚拟机以更改其 vCPU" -#: instances/views.py:1146 +#: instances/views.py:1145 msgid "The current vCPUs cannot be more than the maximum" msgstr "当前 vCPU 数不能超过最大值" -#: instances/views.py:1153 +#: instances/views.py:1152 #, python-format msgid "%(quota)s: cannot resize the CPU of '%(instance_name)s'." msgstr "%(quota)s:无法调整“%(instance_name)s”的 CPU。" -#: instances/views.py:1161 +#: instances/views.py:1160 #, python-format msgid "vCPUs set to %(cur)s (maximum %(max)s)" msgstr "vCPU 已设为 %(cur)s(最大 %(max)s)" -#: instances/views.py:1180 +#: instances/views.py:1179 msgid "Enter a whole number for memory" msgstr "请输入整数内存值" -#: instances/views.py:1183 +#: instances/views.py:1182 msgid "The current memory cannot be more than the maximum" msgstr "当前内存不能超过最大值" -#: instances/views.py:1187 +#: instances/views.py:1186 #, python-format msgid "%(quota)s: cannot resize the memory of '%(instance_name)s'." msgstr "%(quota)s:无法调整“%(instance_name)s”的内存。" -#: instances/views.py:1193 +#: instances/views.py:1192 #, python-format msgid "Memory set to %(cur)s MiB (maximum %(max)s MiB)" msgstr "内存已设为 %(cur)s MiB(最大 %(max)s MiB)" -#: instances/views.py:1213 +#: instances/views.py:1212 msgid "Enter disk sizes as whole GiB" msgstr "请以整数 GiB 输入磁盘大小" -#: instances/views.py:1217 +#: instances/views.py:1216 #, python-format msgid "%(dev)s is %(size)s: a disk cannot shrink" msgstr "%(dev)s 为 %(size)s:磁盘不能缩小" -#: instances/views.py:1225 +#: instances/views.py:1224 msgid "No disks were selected or valid for resizing." msgstr "未选择磁盘或没有可调整大小的有效磁盘。" -#: instances/views.py:1234 +#: instances/views.py:1233 #, python-format msgid "%(quota)s: cannot resize the disks of '%(instance_name)s'." msgstr "%(quota)s:无法调整“%(instance_name)s”的磁盘。" -#: instances/views.py:1246 +#: instances/views.py:1245 #, python-format msgid "The storage pool of %(dev)s cannot resize its volumes" msgstr "%(dev)s 所在的存储池无法调整其卷的大小" -#: instances/views.py:1248 +#: instances/views.py:1247 #, python-format msgid "Disk is resized: %(dev)s" msgstr "磁盘已调整大小:%(dev)s" -#: instances/views.py:1342 +#: instances/views.py:1341 msgid "The VM's machine has no PCIe slots to add" msgstr "该虚拟机的机器类型没有可添加的 PCIe 插槽" -#: instances/views.py:1347 +#: instances/views.py:1346 #, python-format msgid "%(count)s PCIe slots added" msgstr "已添加 %(count)s 个 PCIe 插槽" -#: instances/views.py:1349 +#: instances/views.py:1348 #, python-format msgid "%(count)s PCIe slots added: the VM gets them at its next start" msgstr "已添加 %(count)s 个 PCIe 插槽:虚拟机在下次启动时获得它们" -#: instances/views.py:1395 +#: instances/views.py:1394 #, python-format msgid "%(volume)s is already a disk of this VM" msgstr "%(volume)s 已是此虚拟机的磁盘" -#: instances/views.py:1485 +#: instances/views.py:1484 msgid "Volume changes are applied. But it will be activated after shutdown" msgstr "卷更改已应用,但将在关机后生效" -#: instances/views.py:1490 +#: instances/views.py:1489 msgid "Volume is changed successfully." msgstr "卷已成功更改。" -#: instances/views.py:1508 +#: instances/views.py:1507 #, python-format msgid "Disk %(dev)s is not a storage volume of this instance" msgstr "磁盘 %(dev)s 不是此虚拟机的存储卷" -#: instances/views.py:1515 +#: instances/views.py:1514 #, python-format msgid "Disk %(dev)s has a pending change; delete it once the VM is shut down" msgstr "磁盘 %(dev)s 有待生效的更改;请在虚拟机关机后删除它" -#: instances/views.py:1530 +#: instances/views.py:1529 #, python-format msgid "Volume %(vol)s is used by another VM; detach it instead" msgstr "卷 %(vol)s 正被另一台虚拟机使用;请改为分离它" -#: instances/views.py:1542 +#: instances/views.py:1541 #, 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:1553 +#: instances/views.py:1552 #, python-format msgid "Disk %(dev)s was detached, but its volume was kept: %(err)s" msgstr "磁盘 %(dev)s 已分离,但其卷已保留:%(err)s" -#: instances/views.py:1579 +#: instances/views.py:1578 #, python-format msgid "This VM cannot take a CD-ROM on the %(bus)s bus now" msgstr "该虚拟机现在无法在 %(bus)s 总线上添加 CD-ROM" -#: instances/views.py:1582 +#: instances/views.py:1581 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:1587 +#: instances/views.py:1586 #, python-format msgid "%(image)s is already in a CD-ROM of this VM" msgstr "%(image)s 已在此虚拟机的某个光驱中" -#: instances/views.py:1668 +#: instances/views.py:1667 #, python-format msgid "Pool %(pool)s was not read again: %(err)s" msgstr "未重新读取存储池 %(pool)s:%(err)s" -#: instances/views.py:1689 +#: instances/views.py:1688 #, python-format msgid "Snapshot was not deleted: %(err)s" msgstr "快照未删除:%(err)s" -#: instances/views.py:1804 +#: instances/views.py:1803 msgid "Add at least one device to the boot order." msgstr "请至少向启动顺序中添加一个设备。" -#: instances/views.py:1818 +#: instances/views.py:1817 msgid "Boot order changed. It applies at the next start." msgstr "启动顺序已更改,将在下次启动时生效。" -#: instances/views.py:1820 +#: instances/views.py:1819 msgid "Boot order changed successfully." msgstr "启动顺序已成功更改。" -#: instances/views.py:1840 +#: instances/views.py:1839 msgid "The XML is empty" msgstr "XML 为空" -#: instances/views.py:1844 instances/views.py:2469 +#: instances/views.py:1843 instances/views.py:2468 #, python-format msgid "The XML is not well-formed: %(error)s" msgstr "XML 格式不正确:%(error)s" -#: instances/views.py:1846 +#: instances/views.py:1845 #, python-format msgid "The XML must keep the VM's UUID %(uuid)s." msgstr "XML 必须保留虚拟机的 UUID %(uuid)s。" -#: instances/views.py:1850 +#: instances/views.py:1849 msgid "" "The definition has changed since the editor was opened. Reload the page to " "edit the current one." msgstr "自打开编辑器以来定义已被更改。请重新加载页面以编辑当前定义。" -#: instances/views.py:1862 +#: instances/views.py:1861 msgid "The XML definition was saved." msgstr "XML 定义已保存。" -#: instances/views.py:1864 +#: instances/views.py:1863 msgid "The XML definition was saved; the VM uses it from its next start." msgstr "XML 定义已保存;虚拟机从下次启动起使用它。" -#: instances/views.py:1945 +#: instances/views.py:1944 msgid "Select one network interface to change" msgstr "请选择一个要更改的网络接口" -#: instances/views.py:1983 +#: instances/views.py:1982 msgid "Network Device Config is changed. Please shutdown instance to activate." msgstr "网络设备配置已更改。请关闭虚拟机以使其生效。" -#: instances/views.py:1985 +#: instances/views.py:1984 msgid "Network device changed" msgstr "网络设备已更改" -#: instances/views.py:1997 +#: instances/views.py:1996 msgid "No network selected" msgstr "未选择网络" -#: instances/views.py:2002 +#: instances/views.py:2001 #, python-format msgid "The VM already has a network device with MAC %(mac)s" msgstr "虚拟机已有 MAC 地址为 %(mac)s 的网络设备" -#: instances/views.py:2021 +#: instances/views.py:2020 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 " @@ -5947,137 +5943,129 @@ msgid "" msgstr "" "运行中的虚拟机没有可用 PCI 插槽来添加网络设备:请关机后再添加设备。“磁盘”选项卡上的“添加 PCIe 插槽”可使其从下次启动起获得可用插槽。" -#: instances/views.py:2062 instances/views.py:2068 +#: instances/views.py:2061 instances/views.py:2067 msgid "The VM has it" msgstr "虚拟机已有此设备" -#: instances/views.py:2099 +#: instances/views.py:2098 #, python-format msgid "The host has no USB device %(device)s" msgstr "主机上没有 USB 设备 %(device)s" -#: instances/views.py:2120 +#: instances/views.py:2119 #, python-format msgid "The host has no PCI device %(device)s" msgstr "主机上没有 PCI 设备 %(device)s" -#: instances/views.py:2138 +#: instances/views.py:2137 #, 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:2183 instances/views.py:2213 +#: instances/views.py:2182 instances/views.py:2212 msgid "Select a network interface and a QoS direction" msgstr "请选择网络接口和 QoS 方向" -#: instances/views.py:2186 vrtManager/network.py:459 +#: instances/views.py:2185 vrtManager/network.py:454 msgid "QoS rates must be whole numbers" msgstr "QoS 速率必须为整数" -#: instances/views.py:2193 networks/views.py:229 +#: instances/views.py:2192 networks/views.py:229 #, python-format msgid "%(qos_dir)s QoS is set" msgstr "%(qos_dir)s QoS 已设置" -#: instances/views.py:2198 +#: instances/views.py:2197 #, 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:2220 networks/views.py:255 +#: instances/views.py:2219 networks/views.py:255 #, python-format msgid "%(qos_dir)s QoS is deleted" msgstr "%(qos_dir)s QoS 已删除" -#: instances/views.py:2225 +#: instances/views.py:2224 #, 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:2253 +#: instances/views.py:2252 msgid "Only one owner is allowed and the one already added" msgstr "只允许一个所有者,且已添加" -#: instances/views.py:2255 +#: instances/views.py:2254 #, python-format msgid "%(user)s is already an owner" msgstr "%(user)s 已是所有者" -#: instances/views.py:2300 +#: instances/views.py:2299 #, python-format msgid "Console settings were not saved: %(errors)s" msgstr "控制台设置未保存:%(errors)s" -#: instances/views.py:2322 +#: instances/views.py:2321 msgid "" "Error setting console password. You should check that your instance have an " "graphic device." msgstr "设置控制台密码出错。请检查虚拟机是否有图形设备。" -#: instances/views.py:2369 +#: instances/views.py:2368 msgid "Shut the VM down to change whether it is a template." msgstr "请关闭虚拟机以更改其是否为模板。" -#: instances/views.py:2375 +#: instances/views.py:2374 #, python-format msgid "%(quota)s: '%(instance_name)s' stays a template." msgstr "%(quota)s:“%(instance_name)s”仍为模板。" -#: instances/views.py:2457 +#: instances/views.py:2456 msgid "The XML has no name" msgstr "XML 中没有名称" -#: instances/views.py:2471 webvirtcloud/middleware.py:126 +#: instances/views.py:2470 webvirtcloud/middleware.py:126 #, python-format msgid "libvirt Error - %(exception)s" msgstr "libvirt 错误 - %(exception)s" -#: instances/views.py:2478 +#: instances/views.py:2477 msgid "An empty disk of the size you set" msgstr "按设定大小创建的空磁盘" -#: instances/views.py:2479 +#: instances/views.py:2478 msgid "Volumes already in a pool" msgstr "存储池中已有的卷" -#: instances/views.py:2480 +#: instances/views.py:2479 msgid "A copy of a template volume" msgstr "模板卷的副本" -#: instances/views.py:2569 +#: instances/views.py:2568 msgid "You haven't defined any storage pools" msgstr "您尚未定义任何存储池" -#: instances/views.py:2571 +#: instances/views.py:2570 msgid "You haven't defined any network pools" msgstr "您尚未定义任何网络池" -#: instances/views.py:2634 +#: instances/views.py:2633 msgid "Flavor Created" msgstr "规格已创建" -#: instances/views.py:2642 +#: instances/views.py:2641 msgid "Create Flavor" msgstr "创建规格" -#: instances/views.py:2657 -msgid "Flavor Updated" -msgstr "规格已更新" - -#: instances/views.py:2663 -msgid "Update Flavor" -msgstr "更新规格" - -#: instances/views.py:2675 +#: instances/views.py:2653 msgid "Flavor Deleted" msgstr "规格已删除" -#: instances/views.py:2681 +#: instances/views.py:2659 msgid "Only the size template goes; VMs made from it keep their size." msgstr "仅删除此规格;由它创建的虚拟机保持其大小。" @@ -8427,49 +8415,49 @@ msgid "" "encrypted anew." msgstr "新值会立即替换旧值;之前用口令加密的内容不会重新加密。" -#: vrtManager/connection.py:51 +#: vrtManager/connection.py:46 msgid "Connection closed (error)" msgstr "连接已关闭(错误)" -#: vrtManager/connection.py:52 +#: vrtManager/connection.py:47 msgid "Connection closed (end of file)" msgstr "连接已关闭(文件结束)" -#: vrtManager/connection.py:53 +#: vrtManager/connection.py:48 msgid "Connection closed (keepalive timeout)" msgstr "连接已关闭(保活超时)" -#: vrtManager/connection.py:54 +#: vrtManager/connection.py:49 msgid "Connection closed (client closed)" msgstr "连接已关闭(客户端已关闭)" -#: vrtManager/connection.py:147 +#: vrtManager/connection.py:142 #, 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:219 +#: vrtManager/connection.py:214 #, python-format msgid "Connection Failed: %(host)s did not answer within %(seconds)s s" msgstr "连接失败:%(host)s 在 %(seconds)s 秒内未响应" -#: vrtManager/connection.py:230 +#: vrtManager/connection.py:225 msgid "the connection closed right after opening" msgstr "连接在打开后立即关闭" -#: vrtManager/connection.py:243 +#: vrtManager/connection.py:238 #, python-format msgid "Connection Failed: %(error)s" msgstr "连接失败:%(error)s" -#: vrtManager/connection.py:312 +#: vrtManager/connection.py:307 #, python-format msgid "Connection closed (%(reason)s)" msgstr "连接已关闭(%(reason)s)" -#: vrtManager/connection.py:455 +#: vrtManager/connection.py:450 #, python-format msgid "Connection Failed: %(host)s is not connected" msgstr "连接失败:%(host)s 未连接" @@ -9035,106 +9023,106 @@ msgid "" "it first" msgstr "网络 %(net)s 运行时的地址与其保存的地址不同;请先停止再启动它" -#: vrtManager/network.py:339 +#: vrtManager/network.py:334 #, python-format msgid "Network %(net)s has no such address" msgstr "网络 %(net)s 没有此地址" -#: vrtManager/network.py:344 +#: vrtManager/network.py:339 #, python-format msgid "The range start %(address)s is not in %(subnet)s" msgstr "范围起始 %(address)s 不在 %(subnet)s 中" -#: vrtManager/network.py:345 +#: vrtManager/network.py:340 #, python-format msgid "The range start %(address)s is not in the network" msgstr "范围起始 %(address)s 不在网络中" -#: vrtManager/network.py:346 +#: vrtManager/network.py:341 #, python-format msgid "The range end %(address)s is not in %(subnet)s" msgstr "范围结束 %(address)s 不在 %(subnet)s 中" -#: vrtManager/network.py:347 +#: vrtManager/network.py:342 #, python-format msgid "The range end %(address)s is not in the network" msgstr "范围结束 %(address)s 不在网络中" -#: vrtManager/network.py:348 +#: vrtManager/network.py:343 #, python-format msgid "The fixed address %(address)s is not in %(subnet)s" msgstr "固定地址 %(address)s 不在 %(subnet)s 中" -#: vrtManager/network.py:349 +#: vrtManager/network.py:344 #, python-format msgid "The fixed address %(address)s is not in the network" msgstr "固定地址 %(address)s 不在网络中" -#: vrtManager/network.py:358 +#: vrtManager/network.py:353 #, python-format msgid "%(address)s is not an IP address" msgstr "%(address)s 不是 IP 地址" -#: vrtManager/network.py:363 +#: vrtManager/network.py:358 #, python-format msgid "%(address)s is the host's own address on the network" msgstr "%(address)s 是主机自己在该网络上的地址" -#: vrtManager/network.py:369 +#: vrtManager/network.py:364 #, python-format msgid "Stop network %(net)s to change its DHCP range" msgstr "请停止网络 %(net)s 后再更改其 DHCP 范围" -#: vrtManager/network.py:373 +#: vrtManager/network.py:368 #, python-format msgid "This address of network %(net)s has no DHCP range" msgstr "网络 %(net)s 的此地址没有 DHCP 范围" -#: vrtManager/network.py:377 +#: vrtManager/network.py:372 #, python-format msgid "The range starts at %(start)s, after its end %(end)s" msgstr "范围起始 %(start)s 在其结束 %(end)s 之后" -#: vrtManager/network.py:379 +#: vrtManager/network.py:374 #, python-format msgid "The range takes in %(address)s, the host's own address" msgstr "范围包含主机自己的地址 %(address)s" -#: vrtManager/network.py:388 +#: vrtManager/network.py:383 #, python-format msgid "Network %(net)s has no fixed address %(address)s" msgstr "网络 %(net)s 没有固定地址 %(address)s" -#: vrtManager/network.py:410 +#: vrtManager/network.py:405 #, python-format msgid "The fixed address %(original)s is gone meanwhile; reload the page" msgstr "固定地址 %(original)s 已不存在;请重新加载页面" -#: vrtManager/network.py:415 +#: vrtManager/network.py:410 #, python-format msgid "%(address)s is another entry's fixed address" msgstr "%(address)s 是另一条目的固定地址" -#: vrtManager/network.py:417 +#: vrtManager/network.py:412 #, python-format msgid "%(mac_duid)s has another fixed address, %(other)s" msgstr "%(mac_duid)s 已有另一个固定地址 %(other)s" -#: vrtManager/network.py:419 +#: vrtManager/network.py:414 #, python-format msgid "The name %(name)s has another fixed address, %(other)s" msgstr "名称 %(name)s 已有另一个固定地址 %(other)s" -#: vrtManager/network.py:455 +#: vrtManager/network.py:450 msgid "Direction must be inbound or outbound" msgstr "方向必须是入站或出站" -#: vrtManager/network.py:482 +#: vrtManager/network.py:477 #, python-format msgid "The XML must define network %(net)s" msgstr "XML 必须定义网络 %(net)s" -#: vrtManager/network.py:484 +#: vrtManager/network.py:479 msgid "The XML must keep the network's UUID" msgstr "XML 必须保留网络的 UUID" @@ -9357,18 +9345,18 @@ msgid "" "start; detach those disks first" msgstr "虚拟机 %(vms)s 通过名称使用存储池 %(name)s 中的磁盘,将无法再启动;请先分离这些磁盘" -#: vrtManager/storage.py:279 +#: vrtManager/storage.py:270 #, python-format 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:145 +#: vrtManager/util.py:95 #, python-format msgid "The XML is not valid: %(err)s" msgstr "XML 无效:%(err)s" -#: vrtManager/util.py:147 +#: vrtManager/util.py:97 msgid "The XML may not declare a DTD" msgstr "XML 不能声明 DTD" diff --git a/networks/tests/test_network_changes.py b/networks/tests/test_network_changes.py index 877c2bcb..aab99ff1 100644 --- a/networks/tests/test_network_changes.py +++ b/networks/tests/test_network_changes.py @@ -65,7 +65,7 @@ class NetworkChangeTests(SimpleTestCase): # the running one for its addresses, the saved one for its limits and the XML editor net = self.network() with patch.object(net.net, "XMLDesc", wraps=net.net.XMLDesc) as xml: - net.get_ip_networks(), net.get_network_forward(), net.get_network_mac(), net.get_qos() + net.get_ip_networks(), net.get_network_mac(), net.get_qos() net.get_bridge_device(), net.get_mode(), net.saved_xml self.assertEqual(xml.call_count, 2) diff --git a/static/js/please_wait.js b/static/js/please_wait.js index 39aabe6b..c70bb64e 100644 --- a/static/js/please_wait.js +++ b/static/js/please_wait.js @@ -6,13 +6,6 @@ function showPleaseWaitDialog() { pleaseModal.show(); backgroundJobRunning = true; } -function hidePleaseWaitDialog() { - var pleaseModal = new bootstrap.Modal(document.getElementById('pleaseWaitDialog'), { - keyboard: false - }) - pleaseModal.hide(); - backgroundJobRunning = false; -} // a form marked data-please-wait shows the dialog while it is sent document.addEventListener("submit", function (event) { if (event.target.matches("form[data-please-wait]")) showPleaseWaitDialog(); diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 91b14684..190803b0 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -3,8 +3,6 @@ import contextlib import io import logging import os -import re -import socket import threading import time import uuid @@ -23,9 +21,6 @@ CONN_SOCKET = 4 CONN_TLS = 3 CONN_SSH = 2 CONN_TCP = 1 -TLS_PORT = 16514 -SSH_PORT = 22 -TCP_PORT = 16509 # libvirt has no timeout for opening a connection: an unreachable host # blocks for the kernel's TCP connect timeout (about 2 minutes), a daemon @@ -457,34 +452,6 @@ class wvmConnectionManager(object): raise util.ConnectionFailed(error["text"], **error["values"]) return live - def host_is_up(self, conn_type, hostname, timeout=1): - """True if the libvirt endpoint of hostname accepts a TCP (or Unix - socket) connection. This is a reachability probe only: it does not - check credentials or libvirt itself. hostname may carry a port - ("host:port", "[v6]:port").""" - if conn_type == CONN_SOCKET: - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - try: - sock.settimeout(timeout) - sock.connect("/var/run/libvirt/libvirt-sock") - return True - except OSError: - return False - finally: - sock.close() - default_port = {CONN_SSH: SSH_PORT, CONN_TCP: TCP_PORT, CONN_TLS: TLS_PORT}.get(conn_type) - if default_port is None: - return False - host, port = str(hostname), default_port - match = re.fullmatch(r"\[?([^\[\]]+?)\]?:(\d+)", host) - if match and (host.startswith("[") or host.count(":") == 1): - host, port = match.group(1), int(match.group(2)) - try: - with socket.create_connection((host.strip("[]"), port), timeout=timeout): - return True - except OSError: - return False - connection_manager = wvmConnectionManager( settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, "LIBVIRT_KEEPALIVE_INTERVAL") else 5, settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, "LIBVIRT_KEEPALIVE_COUNT") else 5, @@ -633,12 +600,6 @@ class wvmConnect(object): release = ver return f"{major}.{minor}.{release}" - def is_kvm_supported(self): - """ - :return: kvm support or not - """ - return util.is_kvm_available(self.get_cap_xml()) - def get_storages(self, only_actives=False): """ :return: list of active or all storages @@ -776,21 +737,6 @@ class wvmConnect(object): return util.get_xml_path(self.get_cap_xml(), func=machines) - def get_emulators(self): - """ - :return: host emulators list - """ - - def emulators(ctx): - result = {} - for arch in ctx.xpath("/capabilities/guest/arch"): - emulator = arch.xpath("emulator") - arch_name = arch.xpath("@name")[0] - result[arch_name] = emulator - return result - - return util.get_xml_path(self.get_cap_xml(), func=emulators) - def get_os_loaders(self, arch="x86_64", machine="pc"): """ :param arch: architecture @@ -922,12 +868,6 @@ class wvmConnect(object): """ return ["raw", "qcow", "qcow2"] - def get_file_extensions(self): - """ - :return: available image filename extensions - """ - return ["img", "qcow", "qcow2"] - def get_video_models(self, arch, machine): """ :param arch: architecture @@ -1105,15 +1045,6 @@ class wvmConnect(object): def get_network(self, net): return self.wvm.networkLookupByName(net) - def get_network_forward(self, net_name): - def get_forward(doc): - forward_mode = util.get_xpath(doc, "/network/forward/@mode") - return forward_mode or "isolated" - - net = self.get_network(net_name) - xml = net.XMLDesc(0) - return util.get_xml_path(xml, func=get_forward) - def get_nwfilter(self, name): return self.wvm.nwfilterLookupByName(name) @@ -1229,18 +1160,6 @@ class wvmConnect(object): paths += [v for v in (source.get("file"), source.get("dev"), source.get("name")) if v] return paths - def get_snapshots(self): - instance = [] - for snap_id in self.wvm.listDomainsID(): - dom = self.wvm.lookupByID(int(snap_id)) - if dom.snapshotNum(0) != 0: - instance.append(dom.name()) - for name in self.wvm.listDefinedDomains(): - dom = self.wvm.lookupByName(name) - if dom.snapshotNum(0) != 0: - instance.append(dom.name()) - return instance - def can_change_interfaces(self): """Whether the host's libvirt can define interfaces: the udev backend only reads them. The definition sent is invalid, so nothing is diff --git a/vrtManager/create.py b/vrtManager/create.py index f0f4f267..727065df 100644 --- a/vrtManager/create.py +++ b/vrtManager/create.py @@ -60,27 +60,6 @@ def get_rbd_storage_data(stg): class wvmCreate(wvmConnect): - def get_storages_images(self): - """ - Function return all images on all storages - """ - images = [] - storages = self.get_storages(only_actives=True) - for storage in storages: - stg = self.get_storage(storage) - with contextlib.suppress(Exception): - stg.refresh(0) - images.extend(img for img in stg.listVolumes() if not img.lower().endswith(".iso")) - return images - - def get_os_type(self): - """Get guest os type""" - return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/os_type") - - def get_host_arch(self): - """Get host architecture""" - return util.get_xml_path(self.get_cap_xml(), "/capabilities/host/cpu/arch") - def create_volume(self, storage, name, size, image_format, metadata=False, disk_owner_uid=0, disk_owner_gid=0): size = int(size) * 1073741824 stg = self.get_storage(storage) diff --git a/vrtManager/network.py b/vrtManager/network.py index 2c35e6ef..b274313b 100644 --- a/vrtManager/network.py +++ b/vrtManager/network.py @@ -326,11 +326,6 @@ class wvmNetwork(wvmConnect): def get_network_mac(self): return self.tree.xpath("string(mac/@address)") - def get_network_forward(self): - """Its forward mode (None: isolated) and the device it forwards through.""" - forward = self.tree.find("forward") - return [forward.get("mode"), forward.get("dev")] if forward is not None else [None, None] - def _ip(self, index): """The saved of that index, and what ip_networks tells of it.""" tree = self.config() diff --git a/vrtManager/storage.py b/vrtManager/storage.py index 81d76faf..b41a2bb2 100644 --- a/vrtManager/storage.py +++ b/vrtManager/storage.py @@ -253,15 +253,6 @@ class wvmStorage(wvmConnect): return util.get_xml_path(self._XMLDesc(0), func=hosts) - def get_pretty_allocation(self): - return util.pretty_bytes(self.get_allocation()) - - def get_pretty_available(self): - return util.pretty_bytes(self.get_available()) - - def get_pretty_capacity(self): - return util.pretty_bytes(self.get_capacity()) - def get_volumes(self): return self.pool.listVolumes() diff --git a/vrtManager/tests/test_connection.py b/vrtManager/tests/test_connection.py index daec0f5c..ebbb6cb2 100644 --- a/vrtManager/tests/test_connection.py +++ b/vrtManager/tests/test_connection.py @@ -2,7 +2,6 @@ import contextlib import os -import socket import subprocess import sys import threading @@ -21,29 +20,6 @@ from vrtManager import connection from vrtManager.connection import CONN_SSH, CONN_TCP, SSH_COMMAND, wvmConnectionManager -def closed_port(): - sock = socket.socket() - sock.bind(("127.0.0.1", 0)) - port = sock.getsockname()[1] - sock.close() - return port - - -class HostIsUpTestCase(unittest.TestCase): - def setUp(self): - self.manager = wvmConnectionManager.__new__(wvmConnectionManager) - - def test_reachable_host_is_true(self): - server = socket.socket() - server.bind(("127.0.0.1", 0)) - server.listen(1) - self.addCleanup(server.close) - self.assertIs(self.manager.host_is_up(CONN_TCP, f"127.0.0.1:{server.getsockname()[1]}"), True) - - def test_unreachable_host_is_false_not_an_exception(self): - self.assertIs(self.manager.host_is_up(CONN_TCP, f"127.0.0.1:{closed_port()}"), False) - - class ConnectionManagerTestCase(unittest.TestCase): def setUp(self): patcher = patch("vrtManager.connection.wvmEventLoop") diff --git a/vrtManager/tests/test_util.py b/vrtManager/tests/test_util.py index f53973f8..67077761 100644 --- a/vrtManager/tests/test_util.py +++ b/vrtManager/tests/test_util.py @@ -6,16 +6,10 @@ if not settings.configured: settings.configure(MAC_OUI="52:54:10") from vrtManager.util import ( - compareMAC, get_xml_path, - is_kvm_available, - pretty_bytes, - pretty_mem, - randomMAC, randomPasswd, randomUUID, validate_macaddr, - validate_uuid, vol_dev_type, vol_driver_type, xml_escape, @@ -31,38 +25,6 @@ class TestVrtManagerUtil(unittest.TestCase): # Ensure successive UUIDs are distinct self.assertNotEqual(uuid_str, randomUUID()) - def test_validate_uuid(self): - valid_dashed = "c9a646d3-9c61-4cd8-8024-f6b72a6642d9" - self.assertEqual(validate_uuid(valid_dashed), valid_dashed) - - valid_no_dash = "c9a646d39c614cd88024f6b72a6642d9" - self.assertEqual(validate_uuid(valid_no_dash), valid_dashed) - - with self.assertRaises(ValueError): - validate_uuid("invalid-uuid-too-short") - - with self.assertRaises(ValueError): - validate_uuid(12345) - - def test_random_mac(self): - mac = randomMAC() - self.assertTrue(mac.startswith("52:54:10:")) - parts = mac.split(":") - self.assertEqual(len(parts), 6) - for part in parts: - self.assertEqual(len(part), 2) - int(part, 16) # valid hex - - def test_compare_mac(self): - mac1 = "52:54:10:00:00:01" - mac2 = "52:54:10:00:00:02" - self.assertEqual(compareMAC(mac1, mac1), 0) - self.assertEqual(compareMAC(mac1, mac2), -1) - self.assertEqual(compareMAC(mac2, mac1), 1) - # Different lengths - self.assertEqual(compareMAC("52:54", "52:54:10"), -1) - self.assertEqual(compareMAC("52:54:10", "52:54"), 1) - def test_validate_macaddr(self): self.assertIsNone(validate_macaddr(None)) self.assertIsNone(validate_macaddr("52:54:10:aa:bb:cc")) @@ -103,23 +65,6 @@ class TestVrtManagerUtil(unittest.TestCase): with self.assertRaises(ValueError): get_xml_path(xml) - def test_is_kvm_available(self): - kvm_xml = "" - qemu_xml = "" - self.assertTrue(is_kvm_available(kvm_xml)) - self.assertFalse(is_kvm_available(qemu_xml)) - - def test_pretty_mem(self): - # Value in KB - self.assertEqual(pretty_mem(1024), " 1 MB") - self.assertEqual(pretty_mem(1024 * 1024), "1024 MB") - self.assertEqual(pretty_mem(16 * 1024 * 1024), "16.00 GB") - - def test_pretty_bytes(self): - # Value in Bytes - self.assertEqual(pretty_bytes(10 * 1024 * 1024), "10.00 MB") - self.assertEqual(pretty_bytes(2 * 1024 * 1024 * 1024), "2.00 GB") - def test_vol_dev_type(self): self.assertEqual(vol_dev_type("ide"), "hd") self.assertEqual(vol_dev_type("fdc"), "fd") diff --git a/vrtManager/util.py b/vrtManager/util.py index 8fd232d4..acb26262 100644 --- a/vrtManager/util.py +++ b/vrtManager/util.py @@ -1,6 +1,5 @@ from django.utils.translation import gettext_noop import ipaddress -import random import secrets import re import string @@ -8,7 +7,6 @@ import string import libvirt import lxml.etree as etree -from django.conf import settings from django.utils.translation import gettext @@ -61,22 +59,6 @@ class HostBusy(ConnectionFailed): (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 - - -def randomMAC(): - """Generate a random MAC address.""" - # qemu MAC - mac = settings.MAC_OUI + ":%02x:%02x:%02x" % ( - random.randint(0x00, 0xFF), - random.randint(0x00, 0xFF), - random.randint(0x00, 0xFF), - ) - return mac - - def randomUUID(): """Generate a random UUID.""" u = [secrets.randbelow(256) for _ in range(16)] @@ -90,18 +72,6 @@ def randomPasswd(length=12, alphabet=string.ascii_letters + string.digits): return "".join([secrets.choice(alphabet) for _ in range(length)]) -def get_max_vcpus(conn, guest_type=None): - """@param conn: libvirt connection to poll for max possible vcpus - @param guest_type: optional guest type (kvm, etc.)""" - if type is None: - guest_type = conn.getType() - try: - m = conn.getMaxVcpus(guest_type.lower()) - except libvirt.libvirtError: - m = 32 - return m - - def xml_escape(xml_str): """Replaces chars ' " < > & with xml safe counterparts""" if xml_str is None: @@ -115,26 +85,6 @@ def xml_escape(xml_str): return xml_str -def compareMAC(p, q): - """Compare two MAC addresses""" - pa = p.split(":") - qa = q.split(":") - - if len(pa) != len(qa): - if p > q: - return 1 - else: - return -1 - - for i in range(len(pa)): - n = int(pa[i], 0x10) - int(qa[i], 0x10) - if n > 0: - return 1 - elif n < 0: - return -1 - return 0 - - def parse_xml(xml): """XML a user entered, read for the panel's checks: its entities not expanded, nothing fetched and no DTD; libvirt gets the text itself.""" @@ -181,41 +131,6 @@ def get_xpath(doc, path): return result -def pretty_mem(val): - val = int(val) - if val > (10 * 1024 * 1024): - return "%2.2f GB" % (val / (1024.0 * 1024.0)) - else: - return "%2.0f MB" % (val / 1024.0) - - -def pretty_bytes(val): - val = int(val) - if val > (1024 * 1024 * 1024): - return "%2.2f GB" % (val / (1024.0 * 1024.0 * 1024.0)) - else: - return "%2.2f MB" % (val / (1024.0 * 1024.0)) - - -def validate_uuid(val): - if not isinstance(val, str): - raise ValueError("UUID must be a string.") - - form = re.match("[a-fA-F0-9]{8}[-]([a-fA-F0-9]{4}[-]){3}[a-fA-F0-9]{12}$", val) - if form is None: - form = re.match("[a-fA-F0-9]{32}$", val) - if form is None: - raise ValueError( - "UUID must be a 32-digit hexadecimal number. It may take " - "the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may " - "omit hyphens altogether." - ) - - else: # UUID had no dashes, so add them in - val = val[0:8] + "-" + val[8:12] + "-" + val[12:16] + "-" + val[16:20] + "-" + val[20:32] - return val - - def validate_macaddr(val): if val is None: return diff --git a/webvirtcloud/common_tags.py b/webvirtcloud/common_tags.py index d9f97044..8f30ce60 100644 --- a/webvirtcloud/common_tags.py +++ b/webvirtcloud/common_tags.py @@ -24,6 +24,3 @@ def class_active(request, pattern): return "active" if re.search(pattern, request.path) else "" -@register.simple_tag -def has_perm(user, permission_codename): - return bool(user.has_perm(permission_codename)) diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template index 209ad568..7d422e87 100644 --- a/webvirtcloud/settings.py.template +++ b/webvirtcloud/settings.py.template @@ -355,7 +355,6 @@ QEMU_KEYMAPS = [ LIBVIRT_KEEPALIVE_INTERVAL = 5 LIBVIRT_KEEPALIVE_COUNT = 5 -ALLOW_EMPTY_PASSWORD = False NEW_USER_DEFAULT_INSTANCES = [] # Days the owners of a VM that vanished from its compute are kept, in case it comes back INSTANCE_OWNERSHIP_RETENTION_DAYS = 30