# -*- coding: utf-8 -*- # Copyright 2015-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, isEmptyFile, readFile from calculate.update.emerge_parser import EmergeError from calculate.update.update import UpdateError from ..datavars import BuilderError from os import path from calculate.lib.utils.git import GitError from calculate.lib.utils.portage import (EmergeLogNamedTask, PackageList, EmergeLog, isPkgInstalled) from calculate.install.distr import DistributiveError from calculate.update.update_tasks import EmergeMark _ = lambda x: x setLocalTranslate('cl_builder3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) class BuilderConditions(object): @staticmethod def was_installed(pkg, task_name): def func(Get): task = EmergeLog(EmergeLogNamedTask(task_name), prefix=Get('cl_builder_path')) return bool(PackageList(task.list)[pkg]) return func @staticmethod def need_depclean(pkg, task_name): def func(Get): task = EmergeLog(EmergeLogNamedTask(task_name), prefix=Get('cl_builder_path')) return bool(PackageList(task.list)[pkg]) return func @staticmethod def force_automagic(Get): cache_list = ("/var/calculate/tmp/%s.checkdep" % Get("cl_builder_id_path")) return not isEmptyFile(cache_list, grab=True) @staticmethod def force_preserved(Get): pfile = path.join(Get("cl_builder_path"), "var/lib/portage/preserved_libs_registry") content = readFile(pfile).strip() if not content or content[1:-1].strip() == '': return False else: return True class ClBuilderUpdateAction(Action): """ Действие обновление конфигурационных файлов """ # ошибки, которые отображаются без подробностей native_error = (DistributiveError, FilesError, UpdateError, TemplatesError, BuilderError, GitError, EmergeError) successMessage = None failedMessage = None interruptMessage = __("System update manually interrupted") # список задач для действия tasks = [ {'name': 'check_build_run', 'method': 'Builder.check_build_run()'}, {'name': 'check_chroot_run', 'method': 'Builder.check_chroot_run()'}, {'name': 'clear_log', 'method': 'Builder.clear_log(cl_builder_id_path)', }, {'name': 'allow_scan_binhost', 'method': 'Builder.setVariable("cl_builder_binhost_scan_set",' '"on",True)' }, {'name': 'apply_template', 'message': __("Configuring build"), 'method': 'Builder.applyTemplates(cl_builder_target,False,' 'False,None)', }, {'name': 'invalidate_vars', 'method': 'Builder.invalidateVariables(' '"cl_builder_linux_datavars")' }, {'name': 'reconfigure_vars', 'method': 'Builder.reconfigureProfileVars(' 'cl_builder_linux_datavars,cl_builder_path)' }, {'name': 'apply_branch_vars', 'method': 'Builder.apply_branch_variables()' }, {'name': 'reps_synchronization', 'group': __("Repositories synchronization"), 'tasks': [ # запасная синхронизация, в ходе которой ветки # обновляются до master {'name': 'sync_reps_fallback', 'foreach': 'cl_builder_sync_rep', 'message': __("Fallback syncing the {eachvar:capitalize} " "repository"), 'method': 'Builder.syncRepositories(eachvar,True)', 'condition': lambda Get: ( Get('cl_builder_usetag_set') == "on" and not Get('update.cl_update_binhost_data')[0]) }, # обновление переменных информации из binhost {'name': 'invalidate_vars', 'method': 'Builder.invalidateVariables(' '"cl_builder_linux_datavars")', 'condition': lambda Get: ( Get('cl_builder_usetag_set') == "on" and not Get('update.cl_update_binhost_data')[0]) }, {'name': 'binhost_unavailable', 'error': __("Update server is unavailable"), 'condition': lambda Get: ( Get('cl_builder_usetag_set') == "on" and not Get('update.cl_update_binhost_data')[0]) }, {'name': 'sync_reps', 'foreach': 'cl_builder_sync_rep', 'message': __("Checking {eachvar:capitalize} updates"), 'method': 'Builder.syncRepositories(eachvar)', 'condition': lambda Get: Get('cl_builder_sync_rep') }, {'name': 'check_binhost', 'method': 'Builder.check_binhost(True)', 'condition': lambda Get: Get( 'cl_builder_usetag_set') == "on" }, {'name': 'update_layman', 'message': __("Updating layman cache"), 'method': "Builder.update_layman(cl_builder_path)", 'condition': lambda Get: isPkgInstalled( "app-portage/layman", prefix=Get('cl_chroot_path')), 'essential': False, }, {'name': 'sync_other_reps', 'foreach': 'builder.cl_builder_other_rep_name', 'message': __( "Syncing the {eachvar:capitalize} repository"), 'method': 'Builder.syncLaymanRepository(eachvar)', 'condition': lambda Get: Get( 'update.cl_update_other_set') == 'on' }, {'name': 'trim_reps', 'foreach': 'cl_builder_sync_rep', 'message': __("Cleaning the history of the " "{eachvar:capitalize} repository"), 'method': 'Builder.trimRepositories(eachvar)', 'condition': lambda Get: ( Get('cl_builder_sync_rep') and Get('update.cl_update_onedepth_set') == 'on') }, {'name': 'regen_cache', 'foreach': 'cl_builder_sync_overlay_rep', 'essential': False, 'method': 'Builder.regenCache(eachvar)', 'condition': (lambda Get: ( Get('builder.cl_builder_outdate_set') == 'on' and Get('update.cl_update_egencache_force') != 'skip' or Get('update.cl_update_egencache_force') == 'force')) }, {'name': 'eix_update', 'message': __("Updating the eix cache for " "{cl_builder_eix_repositories}"), 'method': 'Builder.eixUpdate(cl_builder_repository_name)', 'condition': (lambda Get: ( Get('builder.cl_builder_outdate_set') == 'on' and Get('update.cl_update_eixupdate_force') != 'skip' or Get('update.cl_update_eixupdate_force') == 'force')) }, {'name': 'sync_reps:cleanpkg', 'message': __( "Removing obsolete distfiles and binary packages"), 'method': 'Builder.cleanpkg()', 'condition': lambda Get: ( Get('builder.cl_builder_outdate_set') == 'on' and Get('update.cl_update_cleanpkg_set') == 'on'), 'essential': False }, {'name': 'update_packages_cache', 'message': __("Update packages index"), 'method': 'Builder.download_packages(' 'update.cl_update_portage_binhost,' 'update.cl_update_package_cache)', 'essential': False, 'condition': lambda Get: ( Get('update.cl_update_package_cache') and ( Get('builder.cl_builder_outdate_set') == 'on' or Get('update.cl_update_package_cache_set') == 'on')) }, # сообщение удачного завершения при обновлении репозиториев {'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': 'Builder.apply_templates(cl_builder_path,' 'cl_template_clt_set,True,None,False,"sync",' 'cl_builder_linux_datavars)', 'condition': lambda Get: Get('cl_templates_locate') }, {'name': 'dispatch_conf', 'message': __("Updating configuration files"), 'method': 'Builder.dispatchConf(None,cl_builder_path)', 'condition': lambda Get: Get('cl_dispatch_conf') != 'skip' }, ] }, {'name': 'emerge_update_world', 'group': __("Updating packages"), 'tasks': [ {'name': 'update_world', 'message': __("Calculating dependencies"), 'method': 'Builder.emerge_ask(' 'update.cl_update_pretend_set,' '"-uDN","--changed-deps",' '"@world")', 'condition': lambda Get: Get('cl_builder_rebuild_changed_set') == 'on' }, {'name': 'update_world', 'message': __("Calculating dependencies"), 'method': 'Builder.emerge_ask(' 'update.cl_update_pretend_set,' '"-uDN","@world")', 'condition': lambda Get: Get('cl_builder_rebuild_changed_set') != 'on' } ], 'condition': lambda Get: ( Get('update.cl_update_sync_only_set') == 'off') }, {'name': 'update_other', 'condition': lambda Get: ( Get('update.cl_update_pretend_set') == 'off' and Get('update.cl_update_sync_only_set') == 'off') }, {'name': 'update_other:group_changed_packages', 'group': __("Rebuild modified packages"), 'tasks': [ {'name': 'changed_packages', 'message': __("Calculating dependencies"), 'method': 'Builder.rebuild_changed_packages(' 'cl_builder_path,' 'cl_builder_repository_data)', 'condition': lambda Get: Get('cl_builder_rebuild_changed_set') == 'on' } ] }, {'name': 'update_other:update_perl', 'group': __("Updating Perl"), 'tasks': [ {'name': 'perl_cleaner', 'message': __( 'Find & rebuild packages and Perl header files ' 'broken due to a perl upgrade'), 'method': 'Builder.chroot_emergelike(cl_builder_path,' '"perl-cleaner","all")', 'condition': BuilderConditions.was_installed( 'dev-lang/perl$', EmergeMark.PerlCleaner), 'decoration': 'Builder.update_task("%s")' % EmergeMark.PerlCleaner }, ] }, {'name': 'update_other:depclean', 'group': __("Cleaning the system from needless packages"), 'tasks': [ {'name': 'update_depclean', 'message': __("Calculating dependencies"), 'method': 'Builder.depclean()', }, ] }, {'name': 'update_world:update_modules', 'group': __("Rebuilding dependent modules"), 'tasks': [ {'name': 'update_world:module_rebuild', 'message': __('Updating Kernel modules'), 'method': 'Builder.emerge(cl_builder_path,"",' '"@module-rebuild")', 'condition': BuilderConditions.was_installed( 'sys-kernel/.*source', EmergeMark.KernelModules), 'decoration': 'Builder.update_task("%s")' % EmergeMark.KernelModules }, {'name': 'update_world:x11_module_rebuild', 'message': __('Updating X.Org server modules'), 'method': 'Builder.emerge(cl_builder_path,"",' '"@x11-module-rebuild")', 'condition': BuilderConditions.was_installed( 'x11-base/xorg-server', EmergeMark.XorgModules), 'decoration': 'Builder.update_task("%s")' % EmergeMark.XorgModules }, {'name': 'update_world:preserved_rebuild', 'message': __('Updating preserved libraries'), 'method': 'Builder.emerge(cl_builder_path,"",' '"@preserved-rebuild")', 'condition': lambda Get: ( BuilderConditions.was_installed( '.*', EmergeMark.PreservedLibs)(Get) or BuilderConditions.force_preserved(Get)), 'decoration': 'Builder.update_task("%s")' % EmergeMark.PreservedLibs }, {'name': 'update_world:revdev_rebuild', 'message': __('Checking reverse dependencies'), 'method': 'Builder.chroot_revdep_rebuild(cl_builder_path,' '"revdep-rebuild")', 'condition': lambda Get: ( Get('update.cl_update_skip_rb_set') == 'off' and BuilderConditions.was_installed( '.*', EmergeMark.RevdepRebuild)(Get)), 'decoration': 'Builder.update_task("%s")' % EmergeMark.RevdepRebuild }, ], 'depend': Tasks.has("update_other") }, {'name': 'update_other:check_automagic_group', 'group': __("Check for auto depends"), 'tasks': [ {'name': 'check_automagic', 'method': 'Builder.check_automagic(cl_builder_path)', 'condition': lambda Get: ( Get('builder.cl_builder_check_automagic_set') == 'on' and (BuilderConditions.was_installed( '.*', EmergeMark.Automagic)(Get) or BuilderConditions.force_automagic(Get))), 'decoration': 'Builder.update_task("%s")' % EmergeMark.Automagic }, ] }, {'name': 'update_world:update_configures', 'group': __("Completion of the system update"), 'tasks': [ {'name': 'update_world:dispatch_conf_end', 'message': __("Updating configuration files"), 'method': 'Builder.dispatchConf(None,cl_builder_path)', 'condition': lambda Get: Get('cl_dispatch_conf') != 'skip' }, {'name': 'update_world:binary_cleaning', 'message': __("Cleaning the binary repository"), 'method': 'Builder.binaryCleaning()', 'condition': lambda Get: Get( 'cl_builder_usetag_set') == "off" }, ], 'depend': Tasks.has("update_other") }, {'name': 'update_other:reading_news_group', 'group': __("Last news:"), 'tasks': [ {'name': 'update_other:reading_news', 'method': 'Builder.reading_news(cl_builder_path)', 'essential': False }, ] }, {'name': 'update_other:check_obsolete', 'method': 'Builder.check_obsolete(cl_builder_path)' }, ] + [ {'name': 'failed', 'error': __("Failed to update the system"), 'depend': (Tasks.failed() & Tasks.hasnot("interrupt") & Tasks.success_all("check_build_run")) }, # сообщение удачного завершения при обновлении ревизии {'name': 'update_other:success_rev', 'message': __("The system was successfully updated"), } ]