mirror of
https://github.com/dkmstr/openuds.git
synced 2025-03-11 00:58:39 +03:00
Fixed user service manager to treat correctly "reset" an instance
This commit is contained in:
parent
5ac2e2a73d
commit
3fbdea1e23
@ -594,6 +594,8 @@ class Ready(BaseReadyChange):
|
||||
result = super().action()
|
||||
|
||||
# Set as "inUse" to false because a ready can only ocurr if an user is not logged in
|
||||
# Note that an assigned dynamic user service that gets "restarted", will be marked as not in use
|
||||
# until it's logged ing again. So, id the system has
|
||||
userservice = self.get_userservice()
|
||||
userservice.set_in_use(False)
|
||||
|
||||
|
@ -764,17 +764,25 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
|
||||
return False
|
||||
|
||||
def reset(self, user_service: UserService) -> None:
|
||||
user_service.refresh_from_db()
|
||||
def reset(self, userservice: UserService) -> None:
|
||||
userservice.refresh_from_db()
|
||||
|
||||
if not user_service.deployed_service.service.get_type().can_reset:
|
||||
if not userservice.deployed_service.service.get_type().can_reset:
|
||||
return
|
||||
|
||||
operations_logger.info('Reseting %s', user_service)
|
||||
operations_logger.info('Reseting %s', userservice)
|
||||
|
||||
userservice_instance = user_service.get_instance()
|
||||
userservice_instance = userservice.get_instance()
|
||||
try:
|
||||
state = userservice_instance.reset()
|
||||
userservice.update_state_date()
|
||||
|
||||
log.log(
|
||||
userservice,
|
||||
types.log.LogLevel.INFO,
|
||||
'Service reset by user',
|
||||
types.log.LogSource.WEB,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception('Reseting service')
|
||||
return
|
||||
@ -782,10 +790,10 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
logger.debug('State: %s', state)
|
||||
|
||||
if state == types.states.TaskState.FINISHED:
|
||||
user_service.update_data(userservice_instance)
|
||||
userservice.update_data(userservice_instance)
|
||||
return
|
||||
|
||||
UserServiceOpChecker.make_unique(user_service, state)
|
||||
UserServiceOpChecker.make_unique(userservice, state)
|
||||
|
||||
def notify_preconnect(self, user_service: UserService, info: types.connections.ConnectionData) -> None:
|
||||
try:
|
||||
|
@ -65,8 +65,11 @@ class StateUpdater(abc.ABC):
|
||||
def save(self, new_state: typing.Optional[str] = None) -> None:
|
||||
if new_state:
|
||||
self.userservice.set_state(new_state)
|
||||
|
||||
instance = self.userservice.get_instance()
|
||||
# logger.debug('Instance: _queue: %s', getattr(instance, '_queue', '????'))
|
||||
|
||||
self.userservice.update_data(self.userservice.get_instance())
|
||||
self.userservice.update_data(instance)
|
||||
|
||||
def log_ip(self) -> None:
|
||||
ip = self.userservice.get_instance().get_ip()
|
||||
@ -186,6 +189,13 @@ class UpdateFromCanceling(StateUpdater):
|
||||
|
||||
self.save(types.states.State.CANCELED)
|
||||
|
||||
class UpdateFromValid(StateUpdater):
|
||||
# Some operations, like "reset", are done on "valid" states
|
||||
# Simply, do nothing on finish except saving the state
|
||||
def state_finish(self) -> None:
|
||||
logger.debug('Finishing %s', self.userservice.friendly_name)
|
||||
# All done
|
||||
self.save()
|
||||
|
||||
class UpdateFromOther(StateUpdater):
|
||||
def state_finish(self) -> None:
|
||||
@ -245,6 +255,7 @@ class UserServiceOpChecker(DelayedTask):
|
||||
types.states.State.PREPARING: UpdateFromPreparing,
|
||||
types.states.State.REMOVING: UpdateFromRemoving,
|
||||
types.states.State.CANCELING: UpdateFromCanceling,
|
||||
types.states.State.USABLE: UpdateFromValid,
|
||||
}.get(types.states.State.from_str(userservice.state), UpdateFromOther),
|
||||
)
|
||||
|
||||
|
@ -41,7 +41,6 @@ from uds.core.util import autoserializable, log
|
||||
from uds.core.util.model import sql_stamp_seconds
|
||||
|
||||
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds import models
|
||||
@ -425,8 +424,7 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
types.services.Operation.FINISH,
|
||||
]
|
||||
)
|
||||
|
||||
return types.states.TaskState.FINISHED
|
||||
return self._execute_queue()
|
||||
|
||||
@typing.final
|
||||
def check_state(self) -> types.states.TaskState:
|
||||
@ -646,7 +644,7 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
|
||||
def op_delete(self) -> None:
|
||||
"""
|
||||
This method is called when the service is removed
|
||||
|
||||
|
||||
Note:
|
||||
If you override this method, probably you will need to override "op_delete_completed" too
|
||||
Because the op_delete_completed method uses the information generated by service().delete
|
||||
|
@ -45,20 +45,6 @@ from uds.models.config import Config as DBConfig
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Pair of section/value removed from current UDS version
|
||||
# Note: As of version 4.0, all previous REMOVED values has been moved to migration script 0043
|
||||
REMOVED_CONFIG_ELEMENTS = {
|
||||
'RGS': (
|
||||
'downloadUrl',
|
||||
'tunnelOpenedTime',
|
||||
),
|
||||
'SAML': (
|
||||
'Organization Name',
|
||||
'Org. Display Name',
|
||||
'Organization URL',
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class Config:
|
||||
# Global configuration values
|
||||
@ -307,13 +293,6 @@ class Config:
|
||||
|
||||
# Skip removed configuration values, even if they are in database
|
||||
logger.debug('Key: %s, val: %s', cfg.section, cfg.key)
|
||||
if cfg.key in REMOVED_CONFIG_ELEMENTS.get(cfg.section, ()):
|
||||
# Try to remove it, a left-behind value
|
||||
try:
|
||||
DBConfig.objects.filter(section=cfg.section, key=cfg.key).delete()
|
||||
except Exception:
|
||||
pass
|
||||
continue
|
||||
|
||||
# Hidden field, not to be edited by admin interface
|
||||
if cfg.field_type == Config.FieldType.HIDDEN:
|
||||
@ -500,12 +479,7 @@ class GlobalConfig:
|
||||
type=Config.FieldType.NUMERIC,
|
||||
help=_('How long should the user service be unused before os manager considers it for removal'),
|
||||
) # Defaults to 10 minutes
|
||||
CHECK_UNUSED_DELAY: Config.Value = Config.section(Config.SectionType.GLOBAL).value(
|
||||
'checkUnusedDelay',
|
||||
'300',
|
||||
type=Config.FieldType.NUMERIC,
|
||||
help=_('Time betwen checks of unused user services by os managers'),
|
||||
) # Defaults to 10 minutes
|
||||
|
||||
# Default CSS Used: REMOVED! (keep the for for naw, for reference, but will be cleaned on future...)
|
||||
# CSS: Config.Value = Config.section(Config.SectionType.GLOBAL).value('css', settings.STATIC_URL + 'css/uds.css', type=Config.FieldType.TEXT_FIELD)
|
||||
# Max logins before blocking an account
|
||||
@ -537,13 +511,6 @@ class GlobalConfig:
|
||||
type=Config.FieldType.BOOLEAN,
|
||||
help=_('Do autorun of service if just one service'),
|
||||
)
|
||||
# Redirect HTTP to HTTPS
|
||||
REDIRECT_TO_HTTPS: Config.Value = Config.section(Config.SectionType.GLOBAL).value(
|
||||
'redirectToHttps',
|
||||
'1',
|
||||
type=Config.FieldType.BOOLEAN,
|
||||
help=_('Redirect HTTP to HTTPS on connection to UDS'),
|
||||
)
|
||||
REDIRECT_TO_TAG_ON_LOGOUT: Config.Value = Config.section(Config.SectionType.GLOBAL).value(
|
||||
'Redirect to tag on logout',
|
||||
'0',
|
||||
@ -866,3 +833,8 @@ signals.post_migrate.connect(_post_migrate)
|
||||
# Will be here for at least one major version, so we can remove them from database for sure
|
||||
Config.removed(Config.SectionType.CUSTOM, 'Logout URL') # Removed on 4.0
|
||||
Config.removed(Config.SectionType.SECURITY, 'Max Audit Logs duration') # Removed on 4.0
|
||||
Config.removed(Config.SectionType.GLOBAL, 'checkUnusedDelay') # Removed on 4.0
|
||||
Config.removed(Config.SectionType.GLOBAL, 'redirectToHttps') # Removed on 4.0
|
||||
|
||||
# Old saml related data
|
||||
Config.removed(Config.SectionType.OTHER, 'Global logout on exit') # Removed on 4.0
|
@ -110,7 +110,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
# objects: 'models.manager.Manager["UserService"]'
|
||||
sessions: 'models.manager.RelatedManager[UserServiceSession]'
|
||||
accounting: 'AccountUsage'
|
||||
|
||||
|
||||
_cached_instance: typing.Optional['services.UserService'] = None
|
||||
|
||||
class Meta(UUIDModel.Meta): # pylint: disable=too-few-public-methods
|
||||
@ -200,7 +200,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
"""
|
||||
if self._cached_instance:
|
||||
return self._cached_instance
|
||||
|
||||
|
||||
# We get the service instance, publication instance and osmanager instance
|
||||
servicepool = self.deployed_service
|
||||
if not servicepool.service:
|
||||
@ -372,7 +372,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
Returns True if this User Service needs an os manager (i.e. parent services pools is marked to use an os manager)
|
||||
"""
|
||||
return bool(self.get_osmanager())
|
||||
|
||||
|
||||
def allow_putting_back_to_cache(self) -> bool:
|
||||
return self.deployed_service.service.get_instance().allow_putting_back_to_cache()
|
||||
|
||||
@ -426,6 +426,10 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
self.state = state
|
||||
self.save(update_fields=['state', 'state_date'])
|
||||
|
||||
def update_state_date(self) -> None:
|
||||
self.state_date = sql_now()
|
||||
self.save(update_fields=['state_date'])
|
||||
|
||||
def set_os_state(self, state: str) -> None:
|
||||
"""
|
||||
Updates the os state (state of the os) of this object and, optionally, saves it
|
||||
@ -552,7 +556,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
# import traceback
|
||||
# logger.info('Removing user service %s', self)
|
||||
# logger.info('\n* '.join(traceback.format_stack()))
|
||||
|
||||
|
||||
if immediate:
|
||||
self.set_state(State.REMOVED)
|
||||
else:
|
||||
@ -606,7 +610,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
||||
|
||||
def notify_preconnect(self) -> None:
|
||||
"""
|
||||
Notifies preconnect to userservice.
|
||||
Notifies preconnect to userservice.
|
||||
TODO: Currently not used
|
||||
"""
|
||||
pass
|
||||
|
@ -46,8 +46,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AssignedAndUnused(Job):
|
||||
frecuency = 300 # Once every 5 minute, but look for GlobalConfig.CHECK_UNUSED_TIME
|
||||
frecuency_cfg = GlobalConfig.CHECK_UNUSED_DELAY
|
||||
frecuency = 60
|
||||
# frecuency_cfg = GlobalConfig.CHECK_UNUSED_DELAY
|
||||
friendly_name = 'Unused services checker'
|
||||
|
||||
def run(self) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user