You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-update/pym/builder/utils/cl_builder_update.py

411 lines
20 KiB

# -*- 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"),
}
]