# -*- coding: utf-8 -*- # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from calculate.core.server.func import Action, Tasks from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_template import TemplatesError from calculate.lib.utils.files import FilesError from calculate.update.update import UpdateError from calculate.update.emerge_parser import EmergeError from calculate.lib.utils.git import GitError from calculate.lib.utils.portage import (EmergeLog, EmergeLogNamedTask, PackageList) from calculate.update.update_tasks import EmergeMark _ = lambda x: x setLocalTranslate('cl_update3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) class UpdateConditions(object): @staticmethod def was_installed(pkg, task_name): def func(): task = EmergeLog(EmergeLogNamedTask(task_name)) return bool(PackageList(task.list)[pkg]) return func @staticmethod def need_depclean(pkg, task_name): def func(Get): task = EmergeLog(EmergeLogNamedTask(task_name)) return (bool(PackageList(task.list)[pkg]) or Get('cl_update_outdated_kernel_set') == 'on') return func class ClUpdateAction(Action): """ Действие обновление конфигурационных файлов """ # ошибки, которые отображаются без подробностей native_error = (FilesError, UpdateError, TemplatesError, GitError, EmergeError) successMessage = None failedMessage = None interruptMessage = __("Update manually interrupted") emerge_tasks = [ {'name': 'premerge_group', 'group': __("Checking for updates"), 'tasks': [ {'name': 'premerge', 'message': __("Calculating dependencies"), 'method': 'Update.premerge("-uDN","--with-bdeps=y","@world")', 'condition': lambda Get:Get('cl_update_sync_only_set') == 'off' }], }, {'name': 'premerge:update', 'condition': lambda Get:Get('cl_update_pretend_set') == 'off', 'depend': Tasks.result("premerge", eq='yes') }, {'name': 'update_other', 'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and Get('cl_update_sync_only_set') == 'off') }, {'name': 'update:update_world', 'group': __("Updating packages"), 'tasks': [ {'name': 'update:update_world', 'message': __("Calculating dependencies"), 'method': 'Update.emerge("","-uDN","--with-bdeps=y","@world")', } ] }, {'name': 'update:update_python', 'group': __("Updating Python"), 'tasks': [ {'name': 'update:python_updater', 'message': __('Find & rebuild packages broken due ' 'to a Python upgrade'), 'method': 'Update.emergelike("python-updater")', 'condition': UpdateConditions.was_installed( 'dev-lang/python$', EmergeMark.PythonUpdater), 'decoration': 'Update.update_task("%s")' % EmergeMark.PythonUpdater }, ] }, {'name': 'update:update_perl', 'group': __("Updating Perl"), 'tasks': [ {'name': 'update:perl_cleaner', 'message': __('Find & rebuild packages and Perl header files ' 'broken due to a perl upgrade'), 'method': 'Update.emergelike("perl-cleaner", "all")', 'condition': UpdateConditions.was_installed( 'dev-lang/perl$', EmergeMark.PerlCleaner), 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner }, ] }, {'name': 'update_other:depclean', 'group': __("Cleaning the system from needless packages"), 'tasks': [ {'name': 'update_other:update_depclean', 'message': __("Calculating dependencies"), 'method': 'Update.depclean()', 'condition': UpdateConditions.need_depclean( '.*', EmergeMark.Depclean), 'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean }, ] }, {'name': 'update_other:update_modules', 'group': __("Rebuilding dependent modules"), 'tasks': [ {'name': 'update_other:module_rebuild', 'message': __('Updating Kernel modules'), 'method': 'Update.emerge("","@module-rebuild")', 'condition': UpdateConditions.was_installed( 'sys-kernel/.*source', EmergeMark.KernelModules), 'decoration': 'Update.update_task("%s")' % EmergeMark.KernelModules }, {'name': 'update_other:x11_module_rebuild', 'message': __('Updating X.Org server modules'), 'method': 'Update.emerge("","@x11-module-rebuild")', 'condition': UpdateConditions.was_installed( 'x11-base/xorg-server', EmergeMark.XorgModules), 'decoration': 'Update.update_task("%s")' % EmergeMark.XorgModules }, {'name': 'update_other:preserved_rebuild', 'message': __('Updating preserved libraries'), 'method': 'Update.emerge("","@preserved-rebuild")', 'condition': UpdateConditions.was_installed( '.*', EmergeMark.PreservedLibs), 'decoration': 'Update.update_task("%s")' % EmergeMark.PreservedLibs }, {'name': 'update_other:revdev_rebuild', 'message': __('Checking reverse dependencies'), 'method': 'Update.revdep_rebuild("revdep-rebuild")', 'condition': lambda Get: (Get( 'cl_update_skip_rb_set') == 'off' and UpdateConditions.was_installed( '.*', EmergeMark.RevdepRebuild)()), 'decoration': 'Update.update_task("%s")' % EmergeMark.RevdepRebuild }, {'name': 'update_other:dispatch_conf_end', 'message': __("Updating configuration files"), 'method': 'Update.dispatchConf()', 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and Get('cl_update_pretend_set') == 'off') }, ] }, {'name': 'update:set_upto_date_cache', 'method': 'Update.setUpToDateCache()' } ] # список задач для действия tasks = [ {'name': 'check_schedule', 'method': 'Update.checkSchedule(cl_update_autocheck_interval,' 'cl_update_autocheck_set)', 'condition': lambda Get: ( Get('cl_update_autocheck_schedule_set') == 'on'), }, {'name': 'check_run', 'method': 'Update.checkRun(cl_update_wait_another_set)' }, {'name': 'reps_synchronization', 'group': __("Repositories synchronization"), 'tasks': [ # запасная синхронизация, в ходе которой ветки обновляются до # master {'name': 'sync_reps_fallback', 'foreach': 'cl_update_sync_rep', 'message': __("Fallback syncing the {eachvar:capitalize} repository"), 'method': 'Update.syncRepositories(eachvar)', 'condition': lambda Get: ("getbinpkg" in Get('cl_features') and not Get('cl_update_binhost_data')[0]) }, # обновление переменных информации из binhost {'name': 'update_binhost_list', 'method': 'Update.update_binhost_list()', 'condition': lambda Get: ("getbinpkg" in Get('cl_features') and not Get('cl_update_binhost_data')[0]) }, {'name': 'sync_reps', 'foreach': 'cl_update_sync_rep', 'message': __("Syncing the {eachvar:capitalize} repository"), 'method': 'Update.syncRepositories(eachvar)', 'condition': lambda Get: Get('cl_update_sync_rep') }, {'name': 'check_binhost', 'method': 'Update.check_binhost()', 'condition': lambda Get: "getbinpkg" in Get('cl_features') }, {'name': 'sync_other_reps', 'foreach': 'cl_update_other_rep_name', 'message': __("Syncing the {eachvar:capitalize} repository"), 'method': 'Update.syncLaymanRepository(eachvar)', 'condition': lambda Get: Get('cl_update_other_set') == 'on' }, {'name': 'trim_reps', 'foreach': 'cl_update_sync_rep', 'message': __("Cleaning the history of the " "{eachvar:capitalize} repository"), 'method': 'Update.trimRepositories(eachvar)', 'condition': lambda Get: (Get('cl_update_sync_rep') and Get('cl_update_onedepth_set') == 'on') }, {'name': 'sync_reps:regen_cache', 'foreach': 'cl_update_sync_overlay_rep', 'essential': False, 'method': 'Update.regenCache(eachvar)', 'condition': ( lambda Get: (Get('cl_update_outdate_set') == 'on' and Get('cl_update_egencache_force') != 'skip' or Get('cl_update_egencache_force') == 'force')) }, {'name': 'sync_other_reps:regen_other_cache', 'foreach': 'cl_update_other_rep_name', 'method': 'Update.regenCache(eachvar)', 'essential': False, }, {'name': 'emerge_metadata', 'message': __("Metadata transfer"), 'method': 'Update.emergeMetadata()', 'condition': ( lambda Get: (Get('cl_update_outdate_set') == 'on' and Get('cl_update_metadata_force') != 'skip' or Get('cl_update_metadata_force') == 'force')) }, {'name': 'eix_update', 'message': __("Updating the eix cache for " "{cl_update_eix_repositories}"), 'method': 'Update.eixUpdate(cl_repository_name)', 'condition': ( lambda Get: (Get('cl_update_outdate_set') == 'on' and Get('cl_update_eixupdate_force') != 'skip' or Get('cl_update_eixupdate_force') == 'force')) }, {'name': 'update_setup_cache', 'message': __("Updating the cache of configurable packages"), 'method': 'Update.updateSetupCache()', 'essential': False, 'condition': lambda Get: Get('cl_update_outdate_set') == 'on' }, {'name': 'sync_reps:cleanpkg', 'message': __("Removing obsolete distfiles and binary packages"), 'method': 'Update.cleanpkg()', 'condition': (lambda Get: Get('cl_update_cleanpkg_set') == 'on' and Get('cl_update_outdate_set') == 'on'), 'essential': False }, # сообщение удачного завершения при обновлении репозиториев {'name': 'success_syncrep', 'message': __("Synchronization finished"), 'depend': (Tasks.success() & Tasks.has_any("sync_reps", "sync_other_reps", "emerge_metadata", "eix_update")), } ] }, {'name': 'reps_synchronization', 'group': __("System configuration"), 'tasks': [ {'name': 'revision', 'message': __("Fixing the settings"), 'method': 'Update.applyTemplates(install.cl_source,' 'cl_template_clt_set,True,None,False)', 'condition': lambda Get: Get('cl_templates_locate') }, {'name': 'dispatch_conf', 'message': __("Updating configuration files"), 'method':'Update.dispatchConf()', 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and Get('cl_update_pretend_set') == 'off') }, {'name': 'binhost_changed', 'method': 'Update.message_binhost_changed()' }, ] } ] + emerge_tasks + [ {'name': 'failed', 'error': __("Update failed"), 'depend': (Tasks.failed() & Tasks.hasnot("interrupt") & (Tasks.hasnot("check_schedule") | Tasks.success_all("check_schedule")))}, {'name': 'failed', 'depend': Tasks.failed_all("check_schedule") }, # сообщение удачного завершения при обновлении ревизии {'name': 'success_rev', 'message': __("System update finished!"), 'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and Get('cl_update_pretend_set') == 'off') }, # сообщение удачного завершения при пересоздании world {'name': 'success_world', 'message': __("World rebuild finished!"), 'condition': lambda Get: Get('cl_rebuild_world_set') == 'on' }, ]