mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
chore: Update UDS admin runtime, polyfills, and main scripts. Updated minor cache definitions
This commit is contained in:
parent
6adcc3e1f4
commit
04f144cd2d
@ -34,11 +34,13 @@ import typing
|
||||
|
||||
|
||||
# Default timeouts, in seconds
|
||||
DEFAULT_CACHE_TIMEOUT: typing.Final[int] = 60 * 3 # 3 minutes
|
||||
LONG_CACHE_TIMEOUT: typing.Final[int] = DEFAULT_CACHE_TIMEOUT * 20 # 1 hour
|
||||
EXTREME_CACHE_TIMEOUT: typing.Final[int] = LONG_CACHE_TIMEOUT * 24 # 1 day
|
||||
SHORT_CACHE_TIMEOUT: typing.Final[int] = DEFAULT_CACHE_TIMEOUT // 3 # 1 minute
|
||||
SHORTEST_CACHE_TIMEOUT: typing.Final[int] = 3 # 3 seconds
|
||||
BASE_CACHE_TIMEOUT: typing.Final[int] = 3 # 3 seconds
|
||||
|
||||
DEFAULT_CACHE_TIMEOUT: typing.Final[int] = BASE_CACHE_TIMEOUT * 60 # 3 minutes
|
||||
LONG_CACHE_TIMEOUT: typing.Final[int] = BASE_CACHE_TIMEOUT * 60 * 60 # 1 hour
|
||||
EXTREME_CACHE_TIMEOUT: typing.Final[int] = BASE_CACHE_TIMEOUT * 60 * 60 * 24 # 1 day
|
||||
SHORT_CACHE_TIMEOUT: typing.Final[int] = BASE_CACHE_TIMEOUT * 20 # 1 minute
|
||||
SHORTEST_CACHE_TIMEOUT: typing.Final[int] = BASE_CACHE_TIMEOUT # 6 seconds
|
||||
|
||||
# Used to mark a cache as not found
|
||||
# use "cache.get(..., default=CACHE_NOT_FOUND)" to check if a cache is non existing instead of real None value
|
||||
|
@ -102,7 +102,9 @@ class DynamicPublication(services.Publication, autoserializable.AutoSerializable
|
||||
retries = data.get('retries', 0) + 1
|
||||
data['retries'] = retries
|
||||
|
||||
if retries > self.max_retries: # Use self to access class variables, so we can override them on subclasses
|
||||
if (
|
||||
retries > self.max_retries
|
||||
): # Use self to access class variables, so we can override them on subclasses
|
||||
return self._error(f'Max retries reached')
|
||||
|
||||
return None
|
||||
@ -190,7 +192,6 @@ class DynamicPublication(services.Publication, autoserializable.AutoSerializable
|
||||
self._queue.insert(0, Operation.RETRY)
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
|
||||
def service(self) -> 'DynamicService':
|
||||
return typing.cast('DynamicService', super().service())
|
||||
|
||||
|
@ -186,16 +186,6 @@ class DynamicService(services.Service, abc.ABC): # pylint: disable=too-many-pub
|
||||
# Default is to stop "hard"
|
||||
return self.stop(caller_instance, vmid)
|
||||
|
||||
def suspend(
|
||||
self, caller_instance: 'DynamicUserService | DynamicPublication', vmid: str
|
||||
) -> None:
|
||||
"""
|
||||
Suspends the machine
|
||||
Defaults to shutdown_machine.
|
||||
Can be overriden if the service supports suspending.
|
||||
"""
|
||||
return self.shutdown(caller_instance, vmid)
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete(
|
||||
self, caller_instance: 'DynamicUserService | DynamicPublication', vmid: str
|
||||
|
@ -132,6 +132,17 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
|
||||
_move_to_l1_queue: typing.ClassVar[list[types.services.Operation]] = [
|
||||
types.services.Operation.START,
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
|
||||
_move_to_l2_queue: typing.ClassVar[list[types.services.Operation]] = [
|
||||
types.services.Operation.SUSPEND,
|
||||
types.services.Operation.SUSPEND_COMPLETED,
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
|
||||
@typing.final
|
||||
def _reset_checks_counter(self) -> None:
|
||||
with self.storage.as_dict() as data:
|
||||
@ -227,7 +238,11 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
self.do_log(types.log.LogLevel.ERROR, f'Error removing machine: {e}')
|
||||
else:
|
||||
logger.debug('Keep on error is enabled, not removing machine')
|
||||
self._set_queue([types.services.Operation.FINISH] if self.keep_state_sets_error else [types.services.Operation.ERROR])
|
||||
self._set_queue(
|
||||
[types.services.Operation.FINISH]
|
||||
if self.keep_state_sets_error
|
||||
else [types.services.Operation.ERROR]
|
||||
)
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
self._set_queue([types.services.Operation.ERROR])
|
||||
@ -280,7 +295,6 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
self._queue.insert(0, types.services.Operation.RETRY)
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
|
||||
# Utility overrides for type checking...
|
||||
# Probably, overriden again on child classes
|
||||
def service(self) -> 'service.DynamicService':
|
||||
@ -343,6 +357,14 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
self._set_queue(self._create_queue_l2_cache.copy())
|
||||
return self._execute_queue()
|
||||
|
||||
@typing.final
|
||||
def move_to_cache(self, level: types.services.CacheLevel) -> types.states.TaskState:
|
||||
if level == types.services.CacheLevel.L1:
|
||||
self._set_queue(self._move_to_l1_queue.copy())
|
||||
else:
|
||||
self._set_queue(self._move_to_l2_queue.copy())
|
||||
return self._execute_queue()
|
||||
|
||||
@typing.final
|
||||
def process_ready_from_os_manager(self, data: typing.Any) -> types.states.TaskState:
|
||||
# Eat the WAIT operation if it is in the queue
|
||||
@ -364,14 +386,26 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
self.cache.put('ready', '1', consts.cache.SHORT_CACHE_TIMEOUT // 2) # short cache timeout
|
||||
self._set_queue([types.services.Operation.FINISH])
|
||||
else:
|
||||
self._set_queue([types.services.Operation.START, types.services.Operation.START_COMPLETED, types.services.Operation.FINISH])
|
||||
self._set_queue(
|
||||
[
|
||||
types.services.Operation.START,
|
||||
types.services.Operation.START_COMPLETED,
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
)
|
||||
except Exception as e:
|
||||
return self._error(f'Error on setReady: {e}')
|
||||
return self._execute_queue()
|
||||
|
||||
def reset(self) -> types.states.TaskState:
|
||||
if self._vmid != '':
|
||||
self._set_queue([types.services.Operation.RESET, types.services.Operation.RESET_COMPLETED, types.services.Operation.FINISH])
|
||||
self._set_queue(
|
||||
[
|
||||
types.services.Operation.RESET,
|
||||
types.services.Operation.RESET_COMPLETED,
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
)
|
||||
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
@ -586,7 +620,7 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
This does nothing, as it's a NOP operation
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def op_destroy_validator(self) -> None:
|
||||
"""
|
||||
This method is called to check if the userservice has an vmid to stop destroying it if needed
|
||||
@ -745,7 +779,7 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
This method is called to check if the service is doing nothing
|
||||
"""
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
|
||||
@typing.final
|
||||
def op_retry_checker(self) -> types.states.TaskState:
|
||||
# If max retrieas has beeen reached, error should already have been set
|
||||
@ -813,7 +847,9 @@ _EXECUTORS: typing.Final[
|
||||
|
||||
# Same af before, but for check methods
|
||||
_CHECKERS: typing.Final[
|
||||
collections.abc.Mapping[types.services.Operation, collections.abc.Callable[[DynamicUserService], types.states.TaskState]]
|
||||
collections.abc.Mapping[
|
||||
types.services.Operation, collections.abc.Callable[[DynamicUserService], types.states.TaskState]
|
||||
]
|
||||
] = {
|
||||
types.services.Operation.INITIALIZE: DynamicUserService.op_initialize_checker,
|
||||
types.services.Operation.CREATE: DynamicUserService.op_create_checker,
|
||||
|
File diff suppressed because one or more lines are too long
@ -102,6 +102,6 @@
|
||||
</svg>
|
||||
</div>
|
||||
</uds-root>
|
||||
<script src="/uds/res/admin/runtime.js?stamp=1714412827" type="module"></script><script src="/uds/res/admin/polyfills.js?stamp=1714412827" type="module"></script><script src="/uds/res/admin/main.js?stamp=1714412827" type="module"></script></body>
|
||||
<script src="/uds/res/admin/runtime.js?stamp=1714699983" type="module"></script><script src="/uds/res/admin/polyfills.js?stamp=1714699983" type="module"></script><script src="/uds/res/admin/main.js?stamp=1714699983" type="module"></script></body>
|
||||
|
||||
</html>
|
||||
|
@ -76,7 +76,7 @@ class TestProxmovLinkedService(UDSTestCase):
|
||||
with fixtures.patch_provider_api() as _api:
|
||||
service = fixtures.create_linked_service()
|
||||
|
||||
storage = utils.find_attr_in_list(fixtures.STORAGES_INFO, 'id', service.datastore.value)
|
||||
storage = utils.search_item_by_attr(fixtures.STORAGES_INFO, 'id', service.datastore.value)
|
||||
# Ensure available is greater that configured on service
|
||||
old_available = storage.available # For future tests to restore it
|
||||
try:
|
||||
|
@ -60,7 +60,7 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
for _ in limited_iterator(lambda: state == types.states.TaskState.RUNNING, limit=128):
|
||||
state = userservice.check_state()
|
||||
# Ensure machine status is always DOWN, so the test does not end
|
||||
utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid).status = ov_types.VMStatus.DOWN
|
||||
utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid).status = ov_types.VMStatus.DOWN
|
||||
|
||||
self.assertEqual(state, types.states.TaskState.ERROR)
|
||||
self.assertGreater(
|
||||
@ -88,7 +88,7 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
# this user service expects the machine to be started at some point, so after a few iterations, we set it to started
|
||||
# note that the user service has a counter for max "recheck" without any success, and if reached, it will fail
|
||||
if counter == 12:
|
||||
vm = utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm = utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm.status = ov_types.VMStatus.UP
|
||||
state = userservice.check_state()
|
||||
|
||||
@ -130,11 +130,11 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
# this user service expects the machine to be started at some point, so after a few iterations, we set it to started
|
||||
# note that the user service has a counter for max "recheck" without any success, and if reached, it will fail
|
||||
if counter == 12:
|
||||
vm = utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm = utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm.status = ov_types.VMStatus.UP
|
||||
# Again, machine will be suspended for L2, so we set it to suspended after a few iterations more
|
||||
if counter == 24:
|
||||
vm = utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm = utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm.status = ov_types.VMStatus.SUSPENDED
|
||||
state = userservice.check_state()
|
||||
|
||||
@ -180,7 +180,7 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
# this user service expects the machine to be started at some point, so after a few iterations, we set it to started
|
||||
# note that the user service has a counter for max "recheck" without any success, and if reached, it will fail
|
||||
if counter == 12:
|
||||
vm = utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm = utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid)
|
||||
vm.status = ov_types.VMStatus.UP
|
||||
state = userservice.check_state()
|
||||
|
||||
@ -221,7 +221,7 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
# skip create and use next in queue
|
||||
userservice._queue.pop(0) # Remove create
|
||||
# And ensure vm is up
|
||||
utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid).status = (
|
||||
utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid).status = (
|
||||
ov_types.VMStatus.UP
|
||||
)
|
||||
|
||||
@ -244,7 +244,7 @@ class TestOVirtLinkedService(UDSTransactionTestCase):
|
||||
state = userservice.check_state()
|
||||
# Ensure that, after a few iterations, the machine is removed (state is UNKNOWN)
|
||||
# if counter == 5:
|
||||
# utils.find_attr_in_list(fixtures.VMS_INFO, 'id', userservice._vmid).status = ov_types.VMStatus.UNKNOWN
|
||||
# utils.search_item_by_attr(fixtures.VMS_INFO, 'id', userservice._vmid).status = ov_types.VMStatus.UNKNOWN
|
||||
|
||||
self.assertEqual(
|
||||
state, types.states.TaskState.FINISHED, f'Graceful: {graceful}, Counter: {counter}'
|
||||
|
@ -163,7 +163,7 @@ class MustBeOfType:
|
||||
def __repr__(self) -> str:
|
||||
return self.__str__()
|
||||
|
||||
def find_attr_in_list(lst: list[T], attribute: str, value: typing.Any) -> T:
|
||||
def search_item_by_attr(lst: list[T], attribute: str, value: typing.Any) -> T:
|
||||
"""
|
||||
Returns an item from a list of items
|
||||
"""
|
||||
@ -172,6 +172,12 @@ def find_attr_in_list(lst: list[T], attribute: str, value: typing.Any) -> T:
|
||||
return item
|
||||
raise ValueError(f'Item with id {value} not found in list')
|
||||
|
||||
def filter_list_by_attr(lst: list[T], attribute: str, value: typing.Any) -> list[T]:
|
||||
"""
|
||||
Returns a list of items from a list of items
|
||||
"""
|
||||
return [item for item in lst if getattr(item, attribute) == value]
|
||||
|
||||
def check_userinterface_values(obj: ui.UserInterface, values: ui.gui.ValuesDictType) -> None:
|
||||
"""
|
||||
Checks that a user interface object has the values specified
|
||||
|
Loading…
Reference in New Issue
Block a user