2016-11-13 14:34:38 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
|
2022-11-14 10:48:21 +00:00
|
|
|
import datetime
|
2023-05-30 10:45:51 +00:00
|
|
|
from itertools import chain
|
2018-02-27 11:39:27 +00:00
|
|
|
|
2017-11-14 01:44:16 +00:00
|
|
|
from celery import shared_task
|
2018-12-18 03:29:21 +00:00
|
|
|
from celery.utils.log import get_task_logger
|
|
|
|
from django.core.files.storage import default_storage
|
2022-11-14 10:48:21 +00:00
|
|
|
from django.utils import timezone
|
2023-02-16 10:32:04 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2018-12-18 03:29:21 +00:00
|
|
|
|
2023-06-08 10:04:07 +00:00
|
|
|
from common.storage.replay import ReplayStorageHandler
|
2019-01-15 02:23:30 +00:00
|
|
|
from ops.celery.decorator import (
|
2022-11-01 03:52:51 +00:00
|
|
|
register_as_period_task, after_app_ready_start,
|
|
|
|
after_app_shutdown_clean_periodic
|
2019-01-15 02:23:30 +00:00
|
|
|
)
|
2022-11-01 03:52:51 +00:00
|
|
|
from orgs.utils import tmp_to_builtin_org
|
2023-05-30 10:45:51 +00:00
|
|
|
from orgs.utils import tmp_to_root_org
|
2020-09-27 06:34:47 +00:00
|
|
|
from .backends import server_replay_storage
|
2023-05-30 10:45:51 +00:00
|
|
|
from .const import ReplayStorageType, CommandStorageType
|
2022-11-14 10:48:21 +00:00
|
|
|
from .models import (
|
2023-05-30 10:45:51 +00:00
|
|
|
Status, Session, Task, AppletHostDeployment,
|
|
|
|
AppletHost, ReplayStorage, CommandStorage
|
2022-11-14 10:48:21 +00:00
|
|
|
)
|
2023-05-30 10:45:51 +00:00
|
|
|
from .notifications import StorageConnectivityMessage
|
2017-12-04 08:41:00 +00:00
|
|
|
|
|
|
|
CACHE_REFRESH_INTERVAL = 10
|
2017-12-04 12:15:47 +00:00
|
|
|
RUNNING = False
|
2018-12-18 03:29:21 +00:00
|
|
|
logger = get_task_logger(__name__)
|
2016-11-13 14:34:38 +00:00
|
|
|
|
2017-11-14 01:44:16 +00:00
|
|
|
|
2023-02-02 07:57:06 +00:00
|
|
|
@shared_task(verbose_name=_('Periodic delete terminal status'))
|
2018-02-27 11:39:27 +00:00
|
|
|
@register_as_period_task(interval=3600)
|
|
|
|
@after_app_ready_start
|
2019-01-15 02:23:30 +00:00
|
|
|
@after_app_shutdown_clean_periodic
|
2018-02-27 11:39:27 +00:00
|
|
|
def delete_terminal_status_period():
|
2021-03-26 11:09:34 +00:00
|
|
|
yesterday = timezone.now() - datetime.timedelta(days=7)
|
2018-02-27 11:39:27 +00:00
|
|
|
Status.objects.filter(date_created__lt=yesterday).delete()
|
2017-12-04 08:41:00 +00:00
|
|
|
|
|
|
|
|
2023-02-02 07:57:06 +00:00
|
|
|
@shared_task(verbose_name=_('Clean orphan session'))
|
2019-01-15 02:23:30 +00:00
|
|
|
@register_as_period_task(interval=600)
|
2018-03-06 09:05:36 +00:00
|
|
|
@after_app_ready_start
|
2019-01-15 02:23:30 +00:00
|
|
|
@after_app_shutdown_clean_periodic
|
2023-10-18 11:13:35 +00:00
|
|
|
@tmp_to_root_org()
|
2018-03-06 09:05:36 +00:00
|
|
|
def clean_orphan_session():
|
|
|
|
active_sessions = Session.objects.filter(is_finished=False)
|
|
|
|
for session in active_sessions:
|
2022-02-28 11:28:58 +00:00
|
|
|
# finished task
|
|
|
|
Task.objects.filter(args=str(session.id), is_finished=False).update(
|
|
|
|
is_finished=True, date_finished=timezone.now()
|
|
|
|
)
|
|
|
|
# finished session
|
2019-02-19 04:50:33 +00:00
|
|
|
if session.is_active():
|
2019-01-15 02:23:30 +00:00
|
|
|
continue
|
|
|
|
session.is_finished = True
|
|
|
|
session.date_end = timezone.now()
|
|
|
|
session.save()
|
2018-12-18 03:29:21 +00:00
|
|
|
|
|
|
|
|
2023-02-02 07:57:06 +00:00
|
|
|
@shared_task(verbose_name=_('Upload session replay to external storage'))
|
2020-09-27 06:34:47 +00:00
|
|
|
def upload_session_replay_to_external_storage(session_id):
|
|
|
|
logger.info(f'Start upload session to external storage: {session_id}')
|
|
|
|
session = Session.objects.filter(id=session_id).first()
|
|
|
|
if not session:
|
|
|
|
logger.error(f'Session db item not found: {session_id}')
|
|
|
|
return
|
2022-11-01 03:52:51 +00:00
|
|
|
|
2023-06-08 10:04:07 +00:00
|
|
|
replay_storage = ReplayStorageHandler(session)
|
2023-06-13 03:33:08 +00:00
|
|
|
local_path, url = replay_storage.find_local()
|
2020-09-27 06:34:47 +00:00
|
|
|
if not local_path:
|
|
|
|
logger.error(f'Session replay not found, may be upload error: {local_path}')
|
|
|
|
return
|
2022-11-01 03:52:51 +00:00
|
|
|
|
2020-09-27 06:34:47 +00:00
|
|
|
abs_path = default_storage.path(local_path)
|
2021-12-08 07:35:22 +00:00
|
|
|
remote_path = session.get_relative_path_by_local_path(abs_path)
|
2020-09-27 06:34:47 +00:00
|
|
|
ok, err = server_replay_storage.upload(abs_path, remote_path)
|
|
|
|
if not ok:
|
|
|
|
logger.error(f'Session replay upload to external error: {err}')
|
|
|
|
return
|
2022-11-01 03:52:51 +00:00
|
|
|
|
2020-09-27 06:34:47 +00:00
|
|
|
try:
|
|
|
|
default_storage.delete(local_path)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return
|
2022-10-28 10:19:44 +00:00
|
|
|
|
|
|
|
|
2023-02-24 09:59:32 +00:00
|
|
|
@shared_task(
|
|
|
|
verbose_name=_('Run applet host deployment'),
|
2023-05-09 11:46:34 +00:00
|
|
|
activity_callback=lambda self, did, *args, **kwargs: ([did],)
|
2023-02-24 09:59:32 +00:00
|
|
|
)
|
2022-10-28 10:19:44 +00:00
|
|
|
def run_applet_host_deployment(did):
|
2022-11-01 03:52:51 +00:00
|
|
|
with tmp_to_builtin_org(system=1):
|
|
|
|
deployment = AppletHostDeployment.objects.get(id=did)
|
|
|
|
deployment.start()
|
2022-11-14 10:48:21 +00:00
|
|
|
|
|
|
|
|
2023-02-24 09:59:32 +00:00
|
|
|
@shared_task(
|
|
|
|
verbose_name=_('Install applet'),
|
2023-08-01 09:42:16 +00:00
|
|
|
activity_callback=lambda self, ids, applet_id, *args, **kwargs: (ids,)
|
2023-02-24 09:59:32 +00:00
|
|
|
)
|
2023-08-01 09:42:16 +00:00
|
|
|
def run_applet_host_deployment_install_applet(ids, applet_id):
|
2022-11-14 10:48:21 +00:00
|
|
|
with tmp_to_builtin_org(system=1):
|
2023-08-01 09:42:16 +00:00
|
|
|
for did in ids:
|
|
|
|
deployment = AppletHostDeployment.objects.get(id=did)
|
|
|
|
deployment.install_applet(applet_id)
|
2023-05-09 11:46:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
@shared_task(
|
|
|
|
verbose_name=_('Generate applet host accounts'),
|
|
|
|
activity_callback=lambda self, host_id, *args, **kwargs: ([host_id],)
|
|
|
|
)
|
|
|
|
def applet_host_generate_accounts(host_id):
|
|
|
|
applet_host = AppletHost.objects.filter(id=host_id).first()
|
|
|
|
if not applet_host:
|
|
|
|
return
|
|
|
|
|
|
|
|
with tmp_to_builtin_org(system=1):
|
|
|
|
applet_host.generate_accounts()
|
2023-05-30 10:45:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
@shared_task(verbose_name=_('Check command replay storage connectivity'))
|
|
|
|
@register_as_period_task(crontab='0 0 * * *')
|
|
|
|
@tmp_to_root_org()
|
|
|
|
def check_command_replay_storage_connectivity():
|
|
|
|
errors = []
|
|
|
|
replays = ReplayStorage.objects.exclude(
|
|
|
|
type__in=[ReplayStorageType.server, ReplayStorageType.null]
|
|
|
|
)
|
|
|
|
commands = CommandStorage.objects.exclude(
|
|
|
|
type__in=[CommandStorageType.server, CommandStorageType.null]
|
|
|
|
)
|
|
|
|
|
|
|
|
for instance in chain(replays, commands):
|
|
|
|
msg = None
|
|
|
|
try:
|
|
|
|
is_valid = instance.is_valid()
|
|
|
|
except Exception as e:
|
|
|
|
is_valid = False
|
|
|
|
msg = _("Test failure: {}".format(str(e)))
|
|
|
|
if is_valid:
|
|
|
|
continue
|
|
|
|
errors.append({
|
|
|
|
'msg': msg or _("Test failure: Account invalid"),
|
|
|
|
'type': instance.get_type_display(),
|
|
|
|
'name': instance.name
|
|
|
|
})
|
|
|
|
|
|
|
|
if not errors:
|
|
|
|
return
|
|
|
|
|
|
|
|
StorageConnectivityMessage(errors).publish_async()
|