1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-20 06:50:23 +03:00

Merge remote-tracking branch 'origin/v4.0'

This commit is contained in:
Adolfo Gómez García 2025-01-20 23:52:24 +01:00
commit e738b5c447
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
2 changed files with 28 additions and 11 deletions

View File

@ -37,6 +37,7 @@ from django.utils.translation import gettext_lazy as _
from uds import models
from uds.core import consts, types, ui
from uds.core.managers.servers import ServerManager
from uds.core.util import net, permissions, ensure
from uds.core.util.model import sql_now, process_uuid
from uds.core.exceptions.rest import NotFound, RequestError
@ -321,7 +322,7 @@ class ServersServers(DetailHandler):
def maintenance(self, parent: 'Model', id: str) -> typing.Any:
parent = ensure.is_instance(parent, models.ServerGroup)
"""
Custom method that swaps maintenance mode state for a tunnel server
Custom method that swaps maintenance mode state for a server
:param item:
"""
item = models.Server.objects.get(uuid=process_uuid(id))
@ -403,6 +404,7 @@ class ServersServers(DetailHandler):
class ServersGroups(ModelHandler):
custom_methods = [('stats', True)]
model = models.ServerGroup
model_filter = {
'type__in': [
@ -506,3 +508,18 @@ class ServersGroups(ModelHandler):
item.delete()
except self.model.DoesNotExist:
raise NotFound('Element do not exists') from None
def stats(self, item: 'Model') -> typing.Any:
item = ensure.is_instance(item, models.ServerGroup)
return [
{
'stats': s[0].as_dict() if s[0] else None,
'server': {
'id': s[1].uuid,
'hostname': s[1].hostname,
'ip': s[1].ip,
},
}
for s in ServerManager.manager().get_server_stats(item.servers.all())
]

View File

@ -101,7 +101,7 @@ class ServerManager(metaclass=singleton.Singleton):
counters[uuid] = counters.get(uuid, 0) + 1
def get_server_stats(
self, severs_filter: 'QuerySet[models.Server]'
self, servers_filter: 'QuerySet[models.Server]'
) -> list[tuple[typing.Optional['types.servers.ServerStats'], 'models.Server']]:
"""
Returns a list of stats for a list of servers
@ -118,8 +118,9 @@ class ServerManager(metaclass=singleton.Singleton):
retrieved_stats.append((None, server))
# Retrieve, in parallel, stats for all servers (not restrained)
# Not using a transaction here, as we are only reading data
with ThreadPoolExecutor(max_workers=10) as executor:
for server in severs_filter.select_for_update():
for server in servers_filter.all():
if server.is_restrained():
continue # Skip restrained servers
executor.submit(_retrieve_stats, server)
@ -504,15 +505,14 @@ class ServerManager(metaclass=singleton.Singleton):
Returns:
List of servers sorted by usage
"""
with transaction.atomic():
now = model_utils.sql_now()
fltrs = server_group.servers.filter(maintenance_mode=False)
fltrs = fltrs.filter(Q(locked_until=None) | Q(locked_until__lte=now)) # Only unlocked servers
if excluded_servers_uuids:
fltrs = fltrs.exclude(uuid__in=excluded_servers_uuids)
now = model_utils.sql_now()
fltrs = server_group.servers.filter(maintenance_mode=False)
fltrs = fltrs.filter(Q(locked_until=None) | Q(locked_until__lte=now)) # Only unlocked servers
if excluded_servers_uuids:
fltrs = fltrs.exclude(uuid__in=excluded_servers_uuids)
# Get the stats for all servers, but in parallel
server_stats = self.get_server_stats(fltrs)
# Get the stats for all servers, but in parallel
server_stats = self.get_server_stats(fltrs)
# Sort by weight, lower first (lower is better)
return [s[1] for s in sorted(server_stats, key=lambda x: x[0].weight() if x[0] else 999999999)]