# -*- 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 , AllTasks
from calculate . lib . cl_lang import setLocalTranslate , getLazyLocalTranslate
from calculate . lib . cl_template import TemplatesError
from calculate . lib . utils . binhosts import BinhostError
from calculate . lib . utils . files import FilesError , readFile
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 , isPkgInstalled ,
EmergeLogNamedTask , PackageList )
from calculate . update . update_tasks import EmergeMark
_ = lambda x : x
setLocalTranslate ( ' cl_update3 ' , sys . modules [ __name__ ] )
__ = getLazyLocalTranslate ( _ )
def get_synchronization_tasks ( object_name ) :
Object = lambda s : " %s . %s " % ( object_name , s )
return [
{ ' name ' : ' reps_synchronization ' ,
' group ' : __ ( " Repositories synchronization " ) ,
' tasks ' : [
# создать объект проверки PGP
{ ' name ' : ' prepare_gpg ' ,
' method ' : Object ( " prepare_gpg() " ) ,
} ,
# создать объект хранилище серверов обновлений
{ ' name ' : ' create_binhost_data ' ,
' method ' : Object ( ' create_binhost_data() ' )
} ,
# проверить валиден ли текущий хост
{ ' name ' : ' check_current_binhost ' ,
' message ' : __ ( " Checking current binhost " ) ,
' essential ' : False ,
' method ' : Object ( ' check_current_binhost(update.cl_update_binhost) ' ) ,
' condition ' : lambda GetBool , Get : (
not GetBool ( ' update.cl_update_binhost_recheck_set ' ) and
Get ( ' update.cl_update_sync_rep ' ) and
Get ( ' update.cl_update_binhost ' ) )
} ,
{ ' name ' : ' not_use_search:failed_base_binhost ' ,
' error ' : __ ( " Failed to use base binhost " ) ,
' method ' : Object ( " delete_binhost() " ) ,
' depend ' : AllTasks . failed_all ( " check_current_binhost " )
} ,
{ ' name ' : ' group_find_binhost ' ,
' group ' : ' ' ,
' while ' : ( ~ AllTasks . has_any ( " detect_best_binhost " ) &
( ( AllTasks . failed_all ( " update_packages_cache " )
& ~ AllTasks . has_any ( " not_use_search " ) ) |
~ AllTasks . has_any ( " sync_reps " ) ) ) & Tasks . success ( ) ,
' condition ' : lambda GetBool , Get : ( GetBool ( ' update.cl_update_usetag_set ' ) and
Get ( ' update.cl_update_sync_rep ' ) ) ,
' tasks ' : [
# найти лучший сервер обновлений
{ ' name ' : ' detect_best_binhost ' ,
' method ' : Object ( ' detect_best_binhost() ' ) ,
' essential ' : False ,
' depend ' : ( Tasks . success ( ) & ~ AllTasks . has_any ( " not_use_search " ) &
( ~ AllTasks . success_one_of ( " check_current_binhost " ) |
AllTasks . success_all ( " sync_reps " ) ) ) ,
} ,
# запасная синхронизация, в ходе которой ветки обновляются до
# master
{ ' name ' : ' sync_reps_fallback ' ,
' foreach ' : ' update.cl_update_sync_rep ' ,
' message ' :
__ ( " Fallback syncing the { eachvar:capitalize} repository " ) ,
' method ' : Object ( ' syncRepositories(eachvar,True) ' ) ,
' depend ' : Tasks . success ( ) & AllTasks . failed_one_of ( " detect_best_binhost " ) ,
} ,
# обновление переменных информации из binhost
{ ' name ' : ' sync_reps_fallback:update_binhost_list ' ,
' method ' : Object ( ' update_binhost_list() ' ) ,
' depend ' : Tasks . success ( ) & AllTasks . failed_one_of ( " detect_best_binhost " ) ,
} ,
# найти лучший сервер обновлений
{ ' name ' : ' sync_reps_fallback:detect_best_binhost ' ,
' method ' : Object ( ' detect_best_binhost() ' ) ,
' depend ' : Tasks . success ( ) & AllTasks . failed_one_of ( " detect_best_binhost " ) ,
} ,
{ ' name ' : ' sync_reps ' ,
' foreach ' : ' update.cl_update_sync_rep ' ,
' message ' : __ ( " Checking { eachvar:capitalize} updates " ) ,
' method ' : Object ( ' syncRepositories(eachvar) ' ) ,
' condition ' : lambda Get : Get ( ' update.cl_update_sync_rep ' ) ,
' depend ' : Tasks . success ( ) & ~ AllTasks . success_all ( " update_packages_cache " )
} ,
{ ' name ' : ' sync_reps:update_local_info_binhost ' ,
' method ' : Object ( ' update_local_info_binhost() ' ) ,
} ,
{ ' name ' : ' sync_reps:update_binhost_list ' ,
' essential ' : False ,
' method ' : Object ( ' update_binhost_list() ' ) ,
' condition ' : lambda GetBool : GetBool ( ' update.cl_update_outdate_set ' )
} ,
{ ' name ' : ' sync_reps:update_packages_cache ' ,
' message ' : __ ( " Update packages index " ) ,
' method ' : Object ( ' download_packages(update.cl_update_portage_binhost, '
' update.cl_update_package_cache,update.cl_update_package_cache_sign, '
' update.cl_update_gpg) ' ) ,
' essential ' : False ,
' condition ' : lambda Get , GetBool : (
Get ( ' update.cl_update_package_cache ' ) and (
Get ( ' update.cl_update_outdate_set ' ) == ' on ' or
Get ( ' update.cl_update_package_cache_set ' ) == ' on ' ) )
} ,
] ,
} ,
{ ' name ' : ' no_server ' ,
' error ' : __ ( " Failed to find the binary updates server " ) ,
' method ' : Object ( " delete_binhost() " ) ,
# method: который должен удалить текущую информацию о сервере обновлений
' depend ' : ( ~ Tasks . has_any ( " failed_base_binhost " ) & ( Tasks . failed ( ) |
Tasks . success ( ) & AllTasks . failed_one_of ( " update_packages_cache " ) ) ) ,
' condition ' : lambda GetBool , Get : ( GetBool ( ' update.cl_update_usetag_set ' ) and
Get ( ' update.cl_update_sync_rep ' ) ) ,
} ,
{ ' name ' : ' sync_reps ' ,
' foreach ' : ' update.cl_update_sync_rep ' ,
' message ' : __ ( " Checking { eachvar:capitalize} updates " ) ,
' method ' : Object ( ' syncRepositories(eachvar) ' ) ,
' condition ' : lambda Get , GetBool : ( Get ( ' update.cl_update_sync_rep ' ) and
not GetBool ( ' update.cl_update_usetag_set ' ) ) ,
} ,
{ ' name ' : ' update_layman ' ,
' message ' : __ ( " Layman cache update " ) ,
' method ' : Object ( ' update_layman() ' ) ,
' condition ' : lambda Get : ( isPkgInstalled (
" app-portage/layman " , prefix = Get ( ' cl_chroot_path ' ) ) and
Get ( ' cl_chroot_path ' ) != " / " ) ,
' essential ' : False ,
} ,
{ ' name ' : ' sync_other_reps ' ,
' foreach ' : ' update.cl_update_other_rep_name ' ,
' message ' : __ ( " Syncing the { eachvar:capitalize} repository " ) ,
' method ' : Object ( ' syncLaymanRepository(eachvar) ' ) ,
' condition ' : lambda GetBool : GetBool ( ' update.cl_update_other_set ' )
} ,
{ ' name ' : ' trim_reps ' ,
' foreach ' : ' update.cl_update_sync_rep ' ,
' message ' : __ ( " Cleaning the history of the "
" { eachvar:capitalize} repository " ) ,
' method ' : Object ( ' trimRepositories(eachvar) ' ) ,
' condition ' : lambda Get : ( Get ( ' update.cl_update_sync_rep ' ) and
Get ( ' update.cl_update_onedepth_set ' ) == ' on ' )
} ,
{ ' name ' : ' sync_reps:regen_cache ' ,
' foreach ' : ' update.cl_update_sync_overlay_rep ' ,
' essential ' : False ,
' method ' : Object ( ' regenCache(eachvar) ' ) ,
' condition ' : (
lambda Get : ( Get ( ' update.cl_update_outdate_set ' ) == ' on ' and
Get ( ' update.cl_update_egencache_force ' ) != ' skip ' or
Get ( ' update.cl_update_egencache_force ' ) == ' force ' ) )
} ,
{ ' name ' : ' sync_other_reps:regen_other_cache ' ,
' foreach ' : ' update.cl_update_other_rep_name ' ,
' method ' : Object ( ' regenCache(eachvar) ' ) ,
' essential ' : False ,
} ,
{ ' name ' : ' eix_update ' ,
' message ' : __ ( " Updating the eix cache for "
" {update.cl_update_eix_repositories} " ) ,
' method ' : Object ( ' eixUpdate(cl_repository_name) ' ) ,
' condition ' : (
lambda Get : ( Get ( ' update.cl_update_outdate_set ' ) == ' on ' and
Get ( ' update.cl_update_eixupdate_force ' ) != ' skip ' or
Get ( ' update.cl_update_eixupdate_force ' ) == ' force ' ) )
} ,
{ ' name ' : ' update_setup_cache ' ,
' message ' : __ ( " Updating the cache of configurable packages " ) ,
' method ' : Object ( ' updateSetupCache() ' ) ,
' essential ' : False ,
' condition ' : lambda Get : Get ( ' update.cl_update_outdate_set ' ) == ' on '
} ,
{ ' name ' : ' sync_reps:cleanpkg ' ,
' message ' : __ ( " Removing obsolete distfiles and binary packages " ) ,
' method ' : Object ( ' cleanpkg() ' ) ,
' condition ' : (
lambda Get : Get ( ' update.cl_update_cleanpkg_set ' ) == ' on ' and
Get ( ' update.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 " ) ) ,
}
]
} ,
]
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_force_depclean_set ' ) == ' on '
or Get ( ' cl_update_outdated_kernel_set ' ) == ' on ' )
return func
@staticmethod
def force_preserved ( Get ) :
pfile = " /var/lib/portage/preserved_libs_registry "
content = readFile ( pfile ) . strip ( )
if not content or content [ 1 : - 1 ] . strip ( ) == ' ' :
return False
else :
return True
class ClUpdateAction ( Action ) :
"""
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = ( FilesError , UpdateError ,
TemplatesError , BinhostError ,
GitError , EmergeError )
successMessage = None
failedMessage = None
interruptMessage = __ ( " Update manually interrupted " )
emerge_tasks = [
{ ' name ' : ' save_bdeps_val ' ,
' method ' : ' Update.save_with_bdeps() ' ,
' essential ' : False
} ,
{ ' name ' : ' premerge_group ' ,
' group ' : __ ( " Checking for updates " ) ,
' tasks ' : [
{ ' name ' : ' premerge ' ,
' message ' : __ ( " Calculating dependencies " ) ,
' method ' : ' Update.premerge( " -uDN " , " @world " ) ' ,
' condition ' : lambda Get : (
Get ( ' cl_update_sync_only_set ' ) == ' off ' and
Get ( ' cl_update_pretend_set ' ) == ' on ' )
} ] ,
} ,
{ ' name ' : ' update ' ,
' condition ' : lambda Get : Get ( ' cl_update_pretend_set ' ) == ' off ' ,
} ,
{ ' 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_world ' ,
' message ' : __ ( " Calculating dependencies " ) ,
' method ' : ' Update.emerge_ask(cl_update_pretend_set, '
' " -uDN " , " @world " ) ' ,
}
] ,
' condition ' : lambda Get : Get ( ' cl_update_sync_only_set ' ) == ' off '
} ,
{ ' name ' : ' update_other:update_perl ' ,
' group ' : __ ( " Updating Perl " ) ,
' tasks ' : [
{ ' name ' : ' update_other: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 ' : lambda Get : ( UpdateConditions . was_installed (
' .* ' , EmergeMark . PreservedLibs ) ( ) or
UpdateConditions . force_preserved ( Get ) ) ,
' 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) '
} ,
] + get_synchronization_tasks ( " Update " ) + [
{ ' name ' : ' system_configuration ' ,
' group ' : __ ( " System configuration " ) ,
' tasks ' : [
{ ' name ' : ' binhost_changed ' ,
' method ' : ' Update.message_binhost_changed() '
} ,
{ ' name ' : ' revision ' ,
' message ' : __ ( " Fixing the settings " ) ,
' method ' : ' Update.applyTemplates(install.cl_source, '
' cl_template_clt_set,True,None,False) ' ,
' condition ' : lambda Get , GetBool : ( Get ( ' cl_templates_locate ' ) and
( Get ( ' cl_update_world ' ) != " update " or
GetBool ( ' cl_update_outdate_set ' ) or
GetBool ( ' cl_update_binhost_recheck_set ' ) or
GetBool ( ' cl_update_force_fix_set ' ) or
GetBool ( ' update.cl_update_package_cache_set ' ) ) )
} ,
{ ' name ' : ' dispatch_conf ' ,
' message ' : __ ( " Updating configuration files " ) ,
' method ' : ' Update.dispatchConf() ' ,
' condition ' : lambda Get , GetBool : ( Get ( ' cl_dispatch_conf ' ) != ' skip ' and
Get ( ' cl_update_pretend_set ' ) == ' off ' and
( GetBool ( ' cl_update_outdate_set ' ) or
GetBool ( ' cl_update_binhost_recheck_set ' ) or
GetBool ( ' cl_update_force_fix_set ' ) or
GetBool ( ' update.cl_update_package_cache_set ' ) ) )
} ,
]
}
] + 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 '
} ,
]