1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

perf: a VM's owners' SSH keys in one query

The VM's keys page (instances:sshkeys) and the cloud-init user data
collected the owners' keys with one query an owner. Both now read them
in one query joined over the VM's owners, ordered owner by owner as
before.
This commit is contained in:
catborise 2026-11-04 21:24:25 +03:00
parent 2484d4efb3
commit 4dd72766cf
3 changed files with 23 additions and 10 deletions

View file

@ -90,6 +90,22 @@ class CloudInitTestCase(TestCase):
def test_owner_keys_for_a_unique_name(self):
self.assertIn(self.KEY, self.userdata())
def test_every_owner_s_keys_and_no_one_else_s(self):
second_key, stranger_key = (f"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI{who} {who}@example" for who in ("Second", "Stranger"))
second = get_user_model().objects.create_user("ci_second", password="pw")
UserSSHKey.objects.create(user=second, keyname="k", keypublic=second_key)
UserInstance.objects.create(instance=self.vm, user=second)
stranger = get_user_model().objects.create_user("ci_stranger", password="pw")
UserSSHKey.objects.create(user=stranger, keyname="k", keypublic=stranger_key)
other_vm = Instance.objects.create(compute=self.compute, name="web2", uuid="11111111-2222-3333-4444-999999999993")
UserInstance.objects.create(instance=other_vm, user=stranger)
UserInstance.objects.create(instance=other_vm, user=self.owner)
page = self.userdata()
self.assertLess(page.index(self.KEY), page.index(second_key))
self.assertEqual(page.count(self.KEY), 1)
self.assertNotIn(stranger_key, page)
def test_no_keys_when_the_name_is_taken_twice(self):
other = Compute.objects.create(name="ci-b", hostname="b.example", login="", password="", type=4)
Instance.objects.create(compute=other, name="web1", uuid="11111111-2222-3333-4444-999999999992")

View file

@ -1,7 +1,7 @@
import json
import socket
from accounts.models import UserInstance, UserSSHKey
from accounts.models import UserSSHKey
from computes.models import Compute
from django.contrib.auth.decorators import login_not_required
from django.core.exceptions import PermissionDenied
@ -65,8 +65,9 @@ def os_userdata(request, version):
# into the other VM by naming theirs the same. No keys then.
instances = list(Instance.objects.filter(name=hostname.split(".")[0])[:2]) if hostname else []
if len(instances) == 1:
for ui in UserInstance.objects.filter(instance=instances[0]):
instance_keys += UserSSHKey.objects.filter(user=ui.user).values_list("keypublic", flat=True)
# the keys of the VM's owners, owner by owner
instance_keys = list(UserSSHKey.objects.filter(user__userinstance__instance=instances[0])
.order_by("user__userinstance__id", "id").values_list("keypublic", flat=True))
# quoted, so a comment such as "it's: mine" stays one YAML string
instance_keys = [json.dumps(key) for key in instance_keys]

View file

@ -530,13 +530,9 @@ def sshkeys(request, pk):
:return:
"""
instance = get_instance(request.user, pk)
instance_keys = []
userinstances = UserInstance.objects.filter(instance=instance)
for ui in userinstances:
keys = UserSSHKey.objects.filter(user=ui.user)
for k in keys:
instance_keys.append(k.keypublic)
# the keys of the VM's owners, owner by owner
instance_keys = list(UserSSHKey.objects.filter(user__userinstance__instance=instance)
.order_by("user__userinstance__id", "id").values_list("keypublic", flat=True))
if request.GET.get("plain", ""):
response = "\n".join(instance_keys)
response += "\n"