|
|
|
@ -16,7 +16,7 @@
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
from os import path
|
|
|
|
|
from calculate.core.server.func import Action, Tasks
|
|
|
|
|
from calculate.core.server.func import Action, Tasks, AllTasks
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
|
|
|
|
|
from calculate.lib.utils.files import FilesError
|
|
|
|
|
from calculate.desktop.desktop import DesktopError
|
|
|
|
@ -42,69 +42,14 @@ class ClClientSyncLoginAction(Action):
|
|
|
|
|
failedMessage = None
|
|
|
|
|
interruptMessage = __("Synchronization manually interrupted")
|
|
|
|
|
|
|
|
|
|
tasks = [
|
|
|
|
|
# подключить удаленный ресурс домена
|
|
|
|
|
{'name': 'mount_remote',
|
|
|
|
|
'method': 'Client.mountRemoteRes(cl_remote_pw,cl_client_remote_path,'
|
|
|
|
|
'cl_remote_host)',
|
|
|
|
|
'condition': lambda Get: (Get('cl_remote_host') and
|
|
|
|
|
Get('os_remote_auth') and
|
|
|
|
|
not isMount(Get('cl_client_remote_path'))),
|
|
|
|
|
},
|
|
|
|
|
# check on domain user
|
|
|
|
|
{'name': 'domain_user',
|
|
|
|
|
'condition': lambda Get: (Get('os_remote_auth') and
|
|
|
|
|
Get('cl_remote_host') and
|
|
|
|
|
Get('desktop.ur_domain_set') == 'on'),
|
|
|
|
|
'else_message': __("The local profile will be used")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:create_home',
|
|
|
|
|
'message': __("Creating the home directory for {ur_login}"),
|
|
|
|
|
'method': 'Client.createUserDirectory(ur_home_path,ur_uid,'
|
|
|
|
|
'ur_gid)',
|
|
|
|
|
'condition': lambda Get: not path.exists(Get('ur_home_path'))
|
|
|
|
|
},
|
|
|
|
|
# password in kernel key
|
|
|
|
|
{'name': 'domain_user:check_password',
|
|
|
|
|
'condition': lambda Get: Get('desktop.ur_password'),
|
|
|
|
|
'else_error': __("User password not found")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'ecryptfs',
|
|
|
|
|
'message': __("Mounting encrypted data"),
|
|
|
|
|
'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,'
|
|
|
|
|
'ur_home_path,True)',
|
|
|
|
|
'condition': lambda Get: (Get('desktop.ur_home_crypt_set') == 'on' and
|
|
|
|
|
Get('install.cl_autologin') != Get(
|
|
|
|
|
'ur_login'))
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:add_to_cache',
|
|
|
|
|
'essential': False,
|
|
|
|
|
'method': 'Client.cAddUserToCache(ur_login,desktop.ur_password)',
|
|
|
|
|
'failed_warning': __("Unable to cache user info")
|
|
|
|
|
},
|
|
|
|
|
old_sync = [
|
|
|
|
|
# подключить удаленные ресурсы пользователя
|
|
|
|
|
{'name': 'domain_user:mount_resources',
|
|
|
|
|
{'name': 'domain_sync:mount_resources',
|
|
|
|
|
'message': __("Mounting user resources"),
|
|
|
|
|
'method': 'Client.mountUserDomainRes(ur_login,'
|
|
|
|
|
'desktop.ur_password,'
|
|
|
|
|
'ur_uid,ur_gid,"unix","share","homes","ftp")',
|
|
|
|
|
},
|
|
|
|
|
# проверка на попытку открыть вторую сессию для этого пользователя
|
|
|
|
|
{'name': 'two_session',
|
|
|
|
|
'error':
|
|
|
|
|
__("A second X session cannot be opened for user {ur_login}."),
|
|
|
|
|
'condition': lambda dv: (dv.Get('ur_login') in
|
|
|
|
|
dv.Get('desktop.cl_desktop_online_user') and
|
|
|
|
|
int(dv.Select(
|
|
|
|
|
'desktop.cl_desktop_online_count',
|
|
|
|
|
where='desktop.cl_desktop_online_user',
|
|
|
|
|
eq=dv.Get('ur_login'), limit=1) > 1) and
|
|
|
|
|
dv.Get('cl_client_sync') == 'on')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:domain_sync',
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"process")',
|
|
|
|
|
'condition': lambda Get: Get('cl_client_sync') == 'on'
|
|
|
|
|
},
|
|
|
|
|
# подключить профиль пользователя на удаленном домене
|
|
|
|
|
# если на нем находится актуальный профиль
|
|
|
|
|
{'name': 'domain_sync:repl_profile',
|
|
|
|
@ -221,26 +166,154 @@ class ClClientSyncLoginAction(Action):
|
|
|
|
|
(Tasks.hasnot('domain_sync') & Tasks.failed()) |
|
|
|
|
|
Tasks.failed_one_of('mount_resources', 'two_session')
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
new_sync = [
|
|
|
|
|
# подключить удаленные ресурсы пользователя
|
|
|
|
|
{'name': 'domain_sync2:mount_resources2',
|
|
|
|
|
'message': __("Mounting user resources"),
|
|
|
|
|
'method': 'Client.mountUserDomainRes(ur_login,'
|
|
|
|
|
'desktop.ur_password,'
|
|
|
|
|
'ur_uid,ur_gid,"share","homes","ftp")',
|
|
|
|
|
},
|
|
|
|
|
# монтируем профиль локального домена, если локальный профиль
|
|
|
|
|
# старее удаленного доменного или актуальный профиль
|
|
|
|
|
{'name': 'domain_sync2:mount_local2',
|
|
|
|
|
# нет более ранних ошибок и локальный профиль нуждается
|
|
|
|
|
# в синхронизации с удаленным или профиль на локальном домене
|
|
|
|
|
'depend': Tasks.success_all('mount_resources2')
|
|
|
|
|
},
|
|
|
|
|
# синхронизируем с профилем локального домена
|
|
|
|
|
{'name': 'mount_local2!:sync_local2',
|
|
|
|
|
'method': 'Client.syncLoginProfileNew(cl_remote_host,ur_login,desktop.ur_password,ur_uid,'
|
|
|
|
|
'ur_gid,ur_home_path,cl_client_profile_name)',
|
|
|
|
|
},
|
|
|
|
|
# ошибка синхронизации с локальным доменом
|
|
|
|
|
{'name': 'local_sync_error',
|
|
|
|
|
'warning': __(
|
|
|
|
|
"Error synchronizing with the local server {cl_remote_host}"),
|
|
|
|
|
'depend': Tasks.failed_one_of("mount_local2", "sync_local2")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'sync_local2:sync_remote2',
|
|
|
|
|
'method': 'Client.syncLoginProfileNew(cl_replication_host,ur_login,desktop.ur_password,ur_uid,'
|
|
|
|
|
'ur_gid,ur_home_path,cl_client_profile_name)',
|
|
|
|
|
'condition': lambda Get: Get('cl_replication_host')
|
|
|
|
|
},
|
|
|
|
|
# если синхронизация с удаленным доменом прошла с ошибкой
|
|
|
|
|
# синхронизировать локальный профиль с локальным доменом
|
|
|
|
|
# как запасной профиль
|
|
|
|
|
{'name': 'fallback_warning2',
|
|
|
|
|
'warning': __("Error synchronizing with the "
|
|
|
|
|
"{cl_replication_host} remote server"),
|
|
|
|
|
'depend': Tasks.failed_one_of('sync_remote2')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'fallback_warning2!:fallback_sync2',
|
|
|
|
|
'method': 'Client.syncLoginProfileNew(cl_remote_host,ur_login,desktop.ur_password,ur_uid,'
|
|
|
|
|
'ur_gid,ur_home_path,cl_client_profile_name)',
|
|
|
|
|
},
|
|
|
|
|
# сообщение о том, что будет использоваться запасной профиль
|
|
|
|
|
# с локального домена
|
|
|
|
|
{'name': 'fallback_success2',
|
|
|
|
|
'message': __("Got a user fallback profile from the "
|
|
|
|
|
"{cl_remote_host} domain"),
|
|
|
|
|
'depend': Tasks.success_one_of('fallback_sync2')
|
|
|
|
|
},
|
|
|
|
|
# ошибка синхронизации профиль не готов! к использованию
|
|
|
|
|
{'name': 'failed',
|
|
|
|
|
'error': __("Failed to get the user profile from the domain"),
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"error")',
|
|
|
|
|
'depend': (Tasks.failed_all('sync_local2', 'sync_remote2', 'fallback_sync2') |
|
|
|
|
|
Tasks.failed_one_of('mount_resources2', 'two_session'))
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
tasks = [
|
|
|
|
|
# подключить удаленный ресурс домена
|
|
|
|
|
{'name': 'mount_remote',
|
|
|
|
|
'method': 'Client.mountRemoteRes(cl_remote_pw,cl_client_remote_path,'
|
|
|
|
|
'cl_remote_host)',
|
|
|
|
|
'condition': lambda Get: (Get('cl_remote_host') and
|
|
|
|
|
Get('os_remote_auth') and
|
|
|
|
|
not isMount(Get('cl_client_remote_path'))),
|
|
|
|
|
},
|
|
|
|
|
# check on domain user
|
|
|
|
|
{'name': 'domain_user',
|
|
|
|
|
'condition': lambda Get: (Get('os_remote_auth') and
|
|
|
|
|
Get('cl_remote_host') and
|
|
|
|
|
Get('desktop.ur_domain_set') == 'on'),
|
|
|
|
|
'else_message': __("The local profile will be used")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:create_home',
|
|
|
|
|
'message': __("Creating the home directory for {ur_login}"),
|
|
|
|
|
'method': 'Client.createUserDirectory(ur_home_path,ur_uid,'
|
|
|
|
|
'ur_gid)',
|
|
|
|
|
'condition': lambda Get: not path.exists(Get('ur_home_path'))
|
|
|
|
|
},
|
|
|
|
|
# password in kernel key
|
|
|
|
|
{'name': 'domain_user:check_password',
|
|
|
|
|
'condition': lambda Get: Get('desktop.ur_password'),
|
|
|
|
|
'else_error': __("User password not found")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'ecryptfs',
|
|
|
|
|
'message': __("Mounting encrypted data"),
|
|
|
|
|
'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,'
|
|
|
|
|
'ur_home_path,True)',
|
|
|
|
|
'condition': lambda Get: (Get('desktop.ur_home_crypt_set') == 'on' and
|
|
|
|
|
Get('install.cl_autologin') != Get(
|
|
|
|
|
'ur_login'))
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:add_to_cache',
|
|
|
|
|
'essential': False,
|
|
|
|
|
'method': 'Client.cAddUserToCache(ur_login,desktop.ur_password)',
|
|
|
|
|
'failed_warning': __("Unable to cache user info")
|
|
|
|
|
},
|
|
|
|
|
# проверка на попытку открыть вторую сессию для этого пользователя
|
|
|
|
|
{'name': 'two_session',
|
|
|
|
|
'error':
|
|
|
|
|
__("A second X session cannot be opened for user {ur_login}."),
|
|
|
|
|
'condition': lambda dv: (dv.Get('ur_login') in
|
|
|
|
|
dv.Get('desktop.cl_desktop_online_user') and
|
|
|
|
|
int(dv.Select(
|
|
|
|
|
'desktop.cl_desktop_online_count',
|
|
|
|
|
where='desktop.cl_desktop_online_user',
|
|
|
|
|
eq=dv.Get('ur_login'), limit=1) > 1) and
|
|
|
|
|
dv.Get('cl_client_sync') == 'on')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:newsync',
|
|
|
|
|
'method': 'Client.checkSync(cl_remote_host)',
|
|
|
|
|
'essential': False,
|
|
|
|
|
'condition': lambda Get: Get('cl_client_sync') == 'on'
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:domain_sync',
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"process")',
|
|
|
|
|
'condition': lambda Get: Get('cl_client_sync') == 'on',
|
|
|
|
|
'depend': AllTasks.failed_one_of('newsync')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:domain_sync2',
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"process")',
|
|
|
|
|
'condition': lambda Get: Get('cl_client_sync') == 'on',
|
|
|
|
|
'depend': AllTasks.success_one_of('newsync')
|
|
|
|
|
}, ] + old_sync + new_sync + [
|
|
|
|
|
# распаковать ссылки
|
|
|
|
|
{'name': 'domain_sync:unpack_links',
|
|
|
|
|
{'name': 'unpack_links',
|
|
|
|
|
'method': 'Client.unpackLinks(ur_home_path)',
|
|
|
|
|
'failed_warning': __("Failed to unpack the links archive"),
|
|
|
|
|
'depend': Tasks.hasnot('failed')
|
|
|
|
|
'depend': Tasks.hasnot('failed') & Tasks.success_one_of("domain_sync", "domain_sync2")
|
|
|
|
|
},
|
|
|
|
|
# синхронизация профиля завершилась успешно
|
|
|
|
|
{'name': 'domain_sync:success_sync',
|
|
|
|
|
{'name': 'success_sync',
|
|
|
|
|
'message': __("User profile fetched from the domain"),
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"success")',
|
|
|
|
|
'depend': Tasks.success_all('sync_remote', 'unpack_links') |
|
|
|
|
|
Tasks.success()
|
|
|
|
|
Tasks.success() & Tasks.success_one_of("domain_sync", "domain_sync2")
|
|
|
|
|
},
|
|
|
|
|
# во время синхронизации профиля произошли ошибки, которые не
|
|
|
|
|
# гарантируют целостность профиля
|
|
|
|
|
{'name': 'domain_sync:error_sync',
|
|
|
|
|
{'name': 'error_sync',
|
|
|
|
|
'warning': __("User profile modifications will not "
|
|
|
|
|
"be saved to the domain"),
|
|
|
|
|
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"error")',
|
|
|
|
|
'depend': Tasks.hasnot('success_sync', 'failed')
|
|
|
|
|
'depend': Tasks.hasnot('success_sync', 'failed') & Tasks.success_one_of("domain_sync", "domain_sync2")
|
|
|
|
|
},
|
|
|
|
|
# отключить удалённый профиль
|
|
|
|
|
{'name': 'domain_sync:umount_unix',
|
|
|
|
@ -275,6 +348,25 @@ class ClClientSyncLogoutAction(Action):
|
|
|
|
|
Get('desktop.ur_domain_set') == 'on'),
|
|
|
|
|
'else_message': __("The local profile will be used")
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:ecryptfs',
|
|
|
|
|
'message': __("Mounting encrypted data"),
|
|
|
|
|
'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,'
|
|
|
|
|
'ur_home_path,True)',
|
|
|
|
|
'condition': lambda Get: (Get('desktop.ur_home_crypt_set') == 'on' and
|
|
|
|
|
Get('install.cl_autologin') != Get(
|
|
|
|
|
'ur_login'))
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:check_sync',
|
|
|
|
|
'method': 'Client.checkSync(cl_remote_host)',
|
|
|
|
|
'essential': False,
|
|
|
|
|
'condition': lambda Get: Get('cl_client_sync') == 'on'
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:oldsync',
|
|
|
|
|
'depend': AllTasks.failed_one_of('check_sync')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:newsync',
|
|
|
|
|
'depend': AllTasks.success_one_of('check_sync')
|
|
|
|
|
},
|
|
|
|
|
# проверка на попытку отключить ресурсы пользователя в X сессии
|
|
|
|
|
{'name': 'domain_user:in_xsession',
|
|
|
|
|
'error': __("User {ur_login} is already on the X session"),
|
|
|
|
@ -286,9 +378,13 @@ class ClClientSyncLogoutAction(Action):
|
|
|
|
|
'condition': lambda Get: path.exists(Get('ur_home_path')),
|
|
|
|
|
'else_error': __("Home directory {ur_home_path} not found"),
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_user:mount_local',
|
|
|
|
|
{'name': 'oldsync:mount_local',
|
|
|
|
|
'method': 'Client.mountUserDomainRes(ur_login,desktop.ur_password,'
|
|
|
|
|
'ur_uid,ur_gid,"unix")',
|
|
|
|
|
'ur_uid,ur_gid,"unix","homes","share","ftp")',
|
|
|
|
|
},
|
|
|
|
|
{'name': 'newsync:mount_local',
|
|
|
|
|
'method': 'Client.mountUserDomainRes(ur_login,desktop.ur_password,'
|
|
|
|
|
'ur_uid,ur_gid,"homes","share","ftp")',
|
|
|
|
|
},
|
|
|
|
|
# проверить наличие подключенных ресурсов
|
|
|
|
|
{'name': 'domain_user:check_mount',
|
|
|
|
@ -325,6 +421,12 @@ class ClClientSyncLogoutAction(Action):
|
|
|
|
|
'method': 'Client.syncLogoutProfile(cl_remote_host,ur_uid,'
|
|
|
|
|
'ur_gid,ur_home_path,"unix",cl_client_profile_name,'
|
|
|
|
|
'cl_client_symlinks)',
|
|
|
|
|
'depend': Tasks.has('oldsync')
|
|
|
|
|
},
|
|
|
|
|
{'name': 'domain_sync:sync_logout',
|
|
|
|
|
'method': 'Client.syncLogoutProfileNew(cl_remote_host,ur_login,desktop.ur_password,ur_uid,'
|
|
|
|
|
'ur_gid,ur_home_path,cl_client_profile_name,cl_client_symlinks)',
|
|
|
|
|
'depend': Tasks.has('newsync')
|
|
|
|
|
},
|
|
|
|
|
# удалить файлы, которые могут помешать следующему входу в сеанс
|
|
|
|
|
{'name': 'domain_sync:remove_noise_files',
|
|
|
|
|