# -*- coding: utf-8 -*-
# Copyright 2013-2015 Calculate Ltd. 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 os
import sys
import re
from os import path
from calculate . lib . datavars import ( Variable , VariableError ,
ReadonlyVariable , ReadonlyTableVariable ,
TableVariable , FieldValue ,
HumanReadable ,
SimpleDataVars , DataVarsError )
from calculate . lib . utils . files import readFile , listDirectory , process , pathJoin
from calculate . lib . configparser import ConfigParser
from calculate . lib . cl_lang import setLocalTranslate
from calculate . lib . utils . text import simplify_profiles
from calculate . lib . utils . git import Git , GitError
from calculate . lib . utils . portage import Layman
from . . profile import ( RepositoryStorageSet , DEFAULT_BRANCH ,
LocalStorage , ProfileRepository , CacheStorage )
from calculate . lib . variables import linux as lib_linux
from calculate . lib . variables import env
from calculate . update . update_info import UpdateInfo
import urllib2
import time
_ = lambda x : x
setLocalTranslate ( ' cl_update3 ' , sys . modules [ __name__ ] )
class VariableAcUpdateSync ( ReadonlyVariable ) :
"""
Action variable which has value " up " for package install and
install this package
"""
def get ( self ) :
action = self . Get ( " cl_action " )
if action in ( " sync " , ) :
if self . Get ( ' cl_update_world ' ) :
return self . Get ( ' cl_update_world ' )
return " "
class VariableClUpdateWorldDefault ( Variable ) :
"""
Ad - hoc
"""
value = " update "
class VariableClUpdateWorld ( Variable ) :
type = " choice "
opt = [ " --world " ]
syntax = " -- {choice} -world "
metavalue = " MODE "
def init ( self ) :
self . help = ( " ' rebuild ' - " + _ ( " rebuild the system packages list " ) +
" , \n ' merge ' - " + _ ( " append the profile packages list " ) +
" , \n ' update ' - " + _ ( " update the system packages list " ) )
self . label = _ ( " System packages list " )
def get ( self ) :
return self . Get ( ' cl_update_world_default ' )
def choice ( self ) :
return [ ( " rebuild " , _ ( " Rebuild " ) ) ,
( " merge " , _ ( " Merge " ) ) ,
( " update " , _ ( " Update " ) ) ]
class VariableClRebuildWorldSet ( Variable ) :
"""
List of action update world , rebuild world ,
"""
type = " bool "
opt = [ " --rebuild-world " ]
untrusted = True
value = " off "
def init ( self ) :
self . help = _ ( " Rebuild world " )
self . label = _ ( " Rebuild world " )
class VariableClUpdateRevSet ( Variable ) :
"""
List of action update world , rebuild world ,
"""
type = " bool "
opt = [ " --update-rev " ]
untrusted = True
value = " on "
check_after = [ " cl_update_sync_rep " ,
" cl_update_metadata_force " ,
" cl_update_other_set " ,
" cl_update_eixupdate_force " ]
def init ( self ) :
self . help = _ ( " make a revision update " )
self . label = _ ( " Make a revision update " )
class VariableClUpdateRep ( Variable ) :
"""
Обновлять репозитории до конкретной ревизии или до последней
"""
type = " choice "
value = " rev "
def choice ( self ) :
return [ " last " , " rev " ]
class VariableClUpdateRepData ( ReadonlyTableVariable ) :
"""
Информация о репозиториях
"""
source = [ ' cl_update_rep_name ' ,
' cl_update_rep_url ' ,
' cl_update_rep_path ' ,
' cl_update_rep_rev ' ]
class VariableClUpdateRepName ( Variable ) :
"""
Список имен используемых репозиториев
"""
type = " list "
value = [ ]
class VariableClUpdateRepUrl ( Variable ) :
"""
Список путей до репозиториев
"""
type = " list "
value = [ ]
class VariableClUpdateLaymanConfig ( ReadonlyVariable ) :
"""
Объект конфига layman
"""
type = " object "
def get ( self ) :
chroot = self . Get ( ' cl_chroot_path ' )
cp = ConfigParser ( )
cp . read ( path . join ( chroot , ' etc/layman/layman.cfg ' ) )
return cp
class VariableClUpdateLaymanStorage ( Variable ) :
"""
Путь к репозиториям layman
"""
param_name = " storage "
fallback_value = " var/lib/layman "
def get ( self ) :
cp = self . Get ( ' cl_update_layman_config ' )
res = cp . get ( ' MAIN ' , self . param_name , fallback = self . fallback_value )
return pathJoin ( self . Get ( ' cl_chroot_path ' ) , res )
class VariableClUpdateRepPath ( ReadonlyVariable ) :
"""
Пути до репозиториев
"""
type = " list "
mapPath = { ' portage ' : ' usr/portage ' ,
' gentoo ' : ' /usr/portage ' }
def get ( self ) :
repPath = self . Get ( ' cl_update_layman_storage ' )
chroot_path = self . Get ( ' cl_chroot_path ' )
def generatePaths ( names ) :
for name in names :
if name in self . mapPath :
yield path . join ( chroot_path , self . mapPath [ name ] )
else :
yield path . join ( repPath , name )
return list ( generatePaths ( self . Get ( ' cl_update_rep_name ' ) ) )
class VariableClUpdateRepRev ( Variable ) :
"""
Ревизии до которых необходимо обновить репозитории
"""
type = " list "
def get ( self ) :
cp = ConfigParser ( )
revisions = self . Get ( ' update.cl_update_binhost_revisions ' )
if revisions :
cp . read_string ( unicode ( revisions [ 0 ] ) )
branch = self . Get ( ' cl_update_branch ' )
def generateBranch ( ) :
for repname , branchname in zip (
self . Get ( ' cl_update_rep_name ' ) ,
self . Get ( ' cl_update_branch_name ' ) ) :
if branchname == Git . Reference . Tag :
yield cp . get ( " vcs " , repname , fallback = branch )
else :
yield branchname
return list ( generateBranch ( ) )
class VariableClUpdateBranch ( Variable ) :
"""
Ветка на которую будет обновляться репозиторий если - getbinpkg
"""
value = Git . Reference . Master
class VariableClUpdateBranchData ( TableVariable ) :
"""
Выбор веток репозиториев до которых необходимо обновиться
"""
opt = [ " --branch " ]
metavalue = ' REFS '
untrusted = True
source = [ " cl_update_branch_rep " ,
" cl_update_branch_name " ]
def init ( self ) :
self . help = _ ( " set references for repository (REPOSITORY:REF) " )
self . label = _ ( " Repositories references " )
def raiseReadonlyIndexError ( self , fieldname = " " , variablename = " " , value = " " ) :
"""
Неизвестный оврелей
"""
raise VariableError ( _ ( " Repository %s not found " ) % value )
class VariableClUpdateBranchRep ( ReadonlyVariable ) :
"""
Список доступных репозиторием
"""
type = " list "
def init ( self ) :
self . label = _ ( " Repository " )
def get ( self ) :
return self . Get ( ' cl_update_rep_name ' )
class VariableClUpdateBinhostData ( ReadonlyTableVariable ) :
"""
Таблица содержащая
binhost / содержимое файла ревизий / время доступа
"""
source = [ " cl_update_binhost_host " ,
" cl_update_binhost_revisions " ,
" cl_update_binhost_time " ]
def check_binhost ( self , binhost ) :
revision_files = [ path . join ( binhost , x )
for x in self . Get ( ' cl_update_binhost_revision_path ' ) ]
timeout = self . GetInteger ( ' cl_update_binhost_timeout ' )
try :
data = None
for fn in revision_files :
if data is None :
data = urllib2 . urlopen ( fn , timeout = timeout ) . read ( )
elif data != urllib2 . urlopen ( fn , timeout = timeout ) . read ( ) :
return " "
return data
except urllib2 . URLError :
return " "
re_revison = re . compile ( " \ w+=( \ w+) " )
def binhost_key ( self , data ) :
host , t = data
try :
cp = ConfigParser ( )
cp . read_string ( data . decode ( ' utf-8 ' ) )
data = sum ( int ( x ) for x in cp [ ' vcs ' ] . values ( ) )
except ( TypeError , KeyError ) as e :
data = 0
return ( 1 if int ( time ) > = 0 else 0 ,
data ,
- int ( time ) )
def get_timestamp ( self , binhost ) :
DAY = 60 * 60 * 24
timeout = self . GetInteger ( ' cl_update_binhost_timeout ' )
timestamp_file = path . join ( binhost ,
self . Get ( ' cl_update_binhost_timestamp_path ' ) )
try :
t = time . time ( )
data = urllib2 . urlopen ( timestamp_file ,
timeout = timeout ) . read ( ) . strip ( )
if data . isdigit ( ) and t - int ( data ) < 5 * DAY :
return data , int ( ( time . time ( ) - t ) * 1000 )
except urllib2 . URLError as e :
pass
except BaseException as e :
if isinstance ( e , KeyboardInterrupt ) :
raise
pass
return " " , - 1
def get ( self , hr = HumanReadable . No ) :
binhost = self . Get ( ' cl_update_binhost ' )
recheck = self . GetBool ( ' cl_update_binhost_recheck_set ' )
def generate_by_timestamp ( ) :
for host in self . Get ( ' cl_update_binhost_list ' ) :
if host :
ts_content , duration = self . get_timestamp ( host )
if ts_content :
yield host , ts_content , str ( duration )
if not recheck and binhost :
ts , t = self . get_timestamp ( binhost )
if ts :
data = self . check_binhost ( binhost )
if data :
return [ [ binhost , data , str ( t ) ] ]
for host , ts , t in sorted ( generate_by_timestamp ( ) ,
key = lambda x : ( - int ( x [ 1 ] ) , int ( x [ 2 ] ) ) ) :
data = self . check_binhost ( host )
if data :
return [ [ host , data , str ( t ) ] ]
return [ [ ] ]
class VariableClUpdateBinhostRecheckSet ( Variable ) :
"""
Принудительно обновить binhost
"""
type = " bool "
value = " off "
opt = [ " --scan " ]
def init ( self ) :
self . help = _ ( " search for the most appropriate update server " )
self . label = _ ( " Search for the most appropriate update server " )
class VariableClUpdateBinhostHost ( FieldValue , ReadonlyVariable ) :
"""
Список имен прочих репозиториев
"""
type = " list "
source_variable = " cl_update_binhost_data "
column = 0
class VariableClUpdateBinhostRevisions ( FieldValue , ReadonlyVariable ) :
"""
Список имен прочих репозиториев
"""
type = " list "
source_variable = " cl_update_binhost_data "
column = 1
class VariableClUpdateBinhostTime ( FieldValue , ReadonlyVariable ) :
"""
Список имен прочих репозиториев
"""
type = " list "
source_variable = " cl_update_binhost_data "
column = 2
class VariableClUpdateBranchName ( Variable ) :
"""
Список доступных репозиторием
"""
type = " choiceedit-list "
def init ( self ) :
self . label = _ ( " Reference " )
def choice ( self ) :
return [
Git . Reference . Tag ,
Git . Reference . Master ,
Git . Reference . Develop ,
Git . Reference . Update ]
def get ( self ) :
if " getbinpkg " in self . Get ( ' cl_features ' ) :
return [ Git . Reference . Tag for x in self . Get ( ' cl_update_rep_name ' ) ]
else :
branch = self . Get ( ' cl_update_branch ' )
return [ branch for x in self . Get ( ' cl_update_rep_name ' ) ]
class VariableClUpdateSyncRep ( Variable ) :
"""
Обновляемый репозиторий
"""
type = " choice-list "
element = " selecttable "
opt = [ " -r " , " --repositories " ]
metavalue = " REPOSITORIES "
untrusted = True
@property
def rep_name ( self ) :
return self . Get ( ' update.cl_update_rep_name ' )
def init ( self ) :
self . help = _ ( " synchronized repositories (all by default) " )
self . label = _ ( " Synchronized repositories " )
def set ( self , value ) :
orderList = self . rep_name
return sorted ( value , key = lambda x :
( orderList . index ( x ) if x in orderList else - 1 ) , reverse = True )
def get ( self ) :
return list ( reversed ( self . rep_name ) )
def choice ( self ) :
return self . rep_name
class VariableClUpdateSyncOverlayRep ( ReadonlyVariable ) :
"""
Обновляемые репозитории ( исключая portage )
"""
type = " list "
def get ( self ) :
return filter ( lambda x : x != " portage " , self . Get ( ' cl_update_sync_rep ' ) )
class VariableClUpdateOutdateSet ( ReadonlyVariable ) :
"""
Флаг устанавливаемый в ходе обновления репозиториев ,
сообщающий что хотя бы один из запланированных репозиториев
обновлен и следует обновляет различные метаданные
Если обновляются прочие оверлеи - данные считаются что устарели
"""
type = " bool "
def get ( self ) :
if ( self . Get ( ' cl_update_other_set ' ) == ' on ' and
self . Get ( ' cl_update_other_rep_name ' ) ) :
return " on "
return " off "
class VariableClUpdateMetadataForce ( Variable ) :
"""
Принудительное действие с метаданными
"""
type = " choice "
value = " auto "
opt = [ " --update-metadata " ]
syntax = " -- {choice} -update-metadata "
metavalue = " MODE "
#untrusted = True
def init ( self ) :
self . help = ( " ' force ' - " + _ ( " force the update ebuilds metadata " ) +
" , \n ' skip ' - " + _ ( " skip the ebuild metadata update " ) +
" , \n ' auto ' - " + _ ( " update metadata if it is outdated " ) )
self . label = _ ( " Update metadata " )
def choice ( self ) :
return [ ( " force " , _ ( " Force " ) ) ,
( " skip " , _ ( " Skip " ) ) ,
( " auto " , _ ( " If needed " ) ) ]
class VariableClUpdateEgencacheForce ( Variable ) :
"""
Принудительное выполнение egencache
"""
type = " choice "
value = " auto "
opt = [ " --egencache " ]
syntax = " -- {choice} -egencache "
metavalue = " MODE "
#untrusted = True
def init ( self ) :
self . help = ( " ' force ' - " + _ ( " force the update of the overlays cache " ) +
" , \n ' skip ' - " + _ ( " skip the update of the overlays cache " ) +
" , \n ' auto ' - " + _ ( " update the overlays cache if outdated " ) )
self . label = _ ( " Update the overlays cache " )
def choice ( self ) :
return [ ( " force " , _ ( " Force " ) ) ,
( " skip " , _ ( " Skip " ) ) ,
( " auto " , _ ( " If needed " ) ) ]
class VariableClUpdateEixupdateForce ( Variable ) :
"""
Принудительное действие с eix - update
"""
type = " choice "
value = " auto "
opt = [ " --eix-update " ]
syntax = " -- {choice} -eix-update "
metavalue = " MODE "
#untrusted = True
def init ( self ) :
self . help = ( " ' force ' - " + _ ( " force the eix cache update " ) +
" , \n ' skip ' - " + _ ( " skip the eix cache update " ) +
" , \n ' auto ' - " + _ ( " update the eix cache if it "
" is outdated " ) )
self . label = _ ( " Update the eix cache " )
def choice ( self ) :
return [ ( " force " , _ ( " Force " ) ) ,
( " skip " , _ ( " Skip " ) ) ,
( " auto " , _ ( " If needed " ) ) ]
class VariableClUpdateOtherSet ( Variable ) :
"""
Обновить остальные оверлеи
"""
type = " bool "
value = " off "
opt = [ " -o " , " --update-other " ]
def init ( self ) :
self . help = _ ( " update other overlays " )
self . label = _ ( " Update other overlays " )
class VariableClUpdateOtherRepData ( ReadonlyTableVariable ) :
"""
Информация о прочих репозиториях
"""
source = [ ' cl_update_other_rep_name ' ,
' cl_update_other_rep_path ' ]
portdir_overlay = " main.cl_portdir_overlay "
def generator ( self ) :
repNames = self . Get ( ' update.cl_update_rep_name ' )
chroot_path = self . Get ( ' cl_chroot_path ' )
layman = Layman ( self . Get ( ' update.cl_update_layman_installed ' ) ,
self . Get ( ' update.cl_update_layman_make ' ) ,
self . Get ( ' update.cl_update_layman_conf ' ) ,
prefix = chroot_path )
layman_overlays = layman . get_installed ( )
for rpath in self . Get ( self . portdir_overlay ) :
repo_file = path . join ( rpath , " profiles/repo_name " )
rname = readFile ( repo_file ) . strip ( ) or path . basename ( rpath )
if rname in layman_overlays and rname not in repNames :
yield ( rname , rpath )
def get ( self , hr = HumanReadable . No ) :
return list ( self . generator ( ) )
class VariableClUpdateOtherRepName ( FieldValue , ReadonlyVariable ) :
"""
Список имен прочих репозиториев
"""
type = " list "
source_variable = " cl_update_other_rep_data "
column = 0
class VariableClUpdateOtherRepPath ( FieldValue , ReadonlyVariable ) :
"""
Список путей до прочих репозиториев
"""
type = " list "
source_variable = " cl_update_other_rep_data "
column = 1
class VariableClUpdateLaymanInstalled ( VariableClUpdateLaymanStorage ) :
"""
Путь до файла layman installed . xml
"""
param_name = " installed "
fallback_value = " var/lib/layman/installed.xml "
class VariableClUpdateLaymanMake ( VariableClUpdateLaymanStorage ) :
"""
Путь до файла make . conf изменяемого layman ` ом
"""
param_name = " make_conf "
fallback_value = " var/lib/layman/make.conf "
class VariableClUpdateLaymanConf ( VariableClUpdateLaymanStorage ) :
"""
Путь до конфигурационного файла репозиториев для layman
"""
param_name = " repos_conf "
fallback_value = " etc/portage/repos.conf/layman.conf "
class VariableClUpdatePretendSet ( Variable ) :
"""
Запустить предварительную проверку на обновления
"""
type = " bool "
value = " off "
opt = [ " -p " , " --pretend " ]
def init ( self ) :
self . label = _ ( " Pretend a package update " )
self . help = _ ( " instead of actually performing the update, "
" simply display the list of packages that "
" will be installed " )
class VariableClUpdateSyncOnlySet ( Variable ) :
"""
Н е выполнять установку / обновление пакетов при обновлении
"""
type = " bool "
value = " off "
opt = [ " -s " , " --sync-only " ]
def init ( self ) :
self . label = _ ( " Only synchronize repositories " )
self . help = _ ( " do not update packages " )
def check ( self , value ) :
if ( value == " on " and self . Get ( ' cl_rebuild_world_set ' ) != ' on ' and
not self . Get ( ' cl_update_sync_rep ' ) and
self . Get ( ' cl_update_other_set ' ) == ' off ' and
self . Get ( ' cl_update_rev_set ' ) == ' off ' and
self . Get ( ' cl_update_metadata_force ' ) != " force " and
self . Get ( ' cl_update_eixupdate_force ' ) != " force " ) :
raise VariableError ( _ ( " Select at least one sync repository " ) )
class VariableClUpdateWaitAnotherSet ( Variable ) :
"""
Ждать завершения другого процесса обновления
"""
type = " bool "
value = " on "
opt = [ " --wait-another-update " ]
def init ( self ) :
self . label = _ ( " Wait for another update to be complete " )
self . help = _ ( " wait until the running update is finished " )
class VariableClUpdateProfileStorage ( ReadonlyVariable ) :
type = " object "
def get ( self ) :
return RepositoryStorageSet (
LocalStorage ( ' /var/lib/layman ' ) ,
CacheStorage ( ' /var/calculate/tmp/update ' ) )
class VariableClUpdateRepHost ( Variable ) :
type = " list "
value = [ ' calculate ' ]
class VariableClUpdateRepHostUrl ( Variable ) :
type = " list "
value = [ ' git://git.calculate.ru/calculate/ %s .git ' ]
class VariableClUpdateProfileDatavars ( ReadonlyVariable ) :
type = " object "
profile = " cl_update_profile_system "
profiles_path = " cl_update_profile_path "
profiles_shortname = " cl_update_profile_shortname "
def get ( self ) :
profile = self . Get ( self . profile )
path_profile = self . Select ( self . profiles_path ,
where = self . profiles_shortname ,
eq = profile , limit = 1 )
if path_profile :
return DataVarsUpdateProfile ( path_profile )
return " "
class VariableClUpdateProfileLinuxFullname ( ReadonlyVariable ) :
"""
Имя системы в профиле
"""
def init ( self ) :
self . label = _ ( " Distribution name " )
datavars = " cl_update_profile_datavars "
def get ( self ) :
dv = self . Get ( self . datavars )
if dv :
try :
subname = dv . Get ( ' os_linux_subname ' )
linuxname = dv . Get ( ' os_linux_name ' )
linuxver = dv . Get ( ' os_linux_ver ' )
if subname :
return " %s %s %s " % ( linuxname , linuxver , subname )
return " %s %s " % ( linuxname , linuxver )
except DataVarsError as s :
raise VariableError ( " Wrong Calculate Linux profile " )
return " "
class VariableClUpdateProfileDependData ( ReadonlyTableVariable ) :
"""
Зависимые репозитории
"""
source = [ ' cl_update_profile_depend_name ' ,
' cl_update_profile_depend_url ' ]
datavars = " cl_update_profile_datavars "
def init ( self ) :
self . label = _ ( " Used repositories " )
@staticmethod
def url_like ( url1 , url2 ) :
match1 = VariableClUpdateProfileUrl . re_url . search ( url1 )
match2 = VariableClUpdateProfileUrl . re_url . search ( url2 )
if match1 and match2 :
return match1 . group ( 2 ) . lower ( ) == match2 . group ( 2 ) . lower ( )
return False
def get ( self , hr = HumanReadable . No ) :
dv = self . Get ( self . datavars )
# TODO: неиспользуемая переменная возможно
# испольуется для инициализации
#url = self.Get('cl_update_profile_url').lower()
if dv :
return reversed ( zip ( dv . Get ( ' cl_update_rep_name ' ) ,
dv . Get ( ' cl_update_rep_url ' ) ) )
return " "
setValue = Variable . setValue
class VariableClUpdateTemplatesLocate ( Variable ) :
"""
Выбранные типы хранилищ шаблонов
"""
type = " choice-list "
element = " selecttable "
opt = [ " -T " , " --templates " ]
metavalue = " TEMPLATES "
untrusted = True
check_after = [ ' cl_update_profile_system ' ]
profile_datevars = " update.cl_update_profile_datavars "
descriptionMap = { ' overlay ' : _ ( ' Overlay templates ' ) ,
' local ' : _ ( ' Local templates ' ) ,
' calculate ' : _ ( " Calculate overlay templates " ) ,
' distros ' : _ ( ' Distribution templates ' ) ,
' distro ' : _ ( ' Distribution templates ' ) ,
' remote ' : _ ( ' Remote templates ' ) ,
' clt ' : _ ( ' clt templates ' ) }
def init ( self ) :
self . label = _ ( " Templates location " )
self . help = _ ( " select the location for templates %s " ) \
% " , " . join ( self . get ( ) )
def get ( self ) :
dv = self . Get ( self . profile_datevars )
if dv :
return dv . Get ( ' cl_template_location ' ) + [ ' clt ' ]
else :
return self . Get ( ' cl_templates_locate ' )
def choice ( self ) :
descr = lambda x : self . descriptionMap . get ( x ,
_ ( " %s overlay templates " % x ) )
return map ( lambda x : ( x , descr ( x ) ) , self . get ( ) )
class VariableClUpdateProfileDependName ( FieldValue , ReadonlyVariable ) :
type = " list "
source_variable = " cl_update_profile_depend_data "
column = 0
def init ( self ) :
self . label = _ ( " Name " )
class VariableClUpdateProfileDependUrl ( FieldValue , ReadonlyVariable ) :
type = " list "
source_variable = " cl_update_profile_depend_data "
column = 1
def init ( self ) :
self . label = _ ( " URL " )
class VariableClUpdateProfileRepName ( ReadonlyVariable ) :
type = " list "
def get ( self ) :
dv = self . Get ( ' cl_update_profile_datavars ' )
if dv :
return dv . Get ( ' cl_update_rep_name ' )
return [ ]
class VariableClUpdateProfileSyncRep ( ReadonlyVariable ) :
type = " list "
def get ( self ) :
return list ( reversed ( self . Get ( ' cl_update_profile_rep_name ' ) ) )
class VariableClUpdateProfileRepUrl ( ReadonlyVariable ) :
type = " list "
def get ( self ) :
dv = self . Get ( ' cl_update_profile_datavars ' )
if dv :
return dv . Get ( ' cl_update_rep_url ' )
return [ ]
class VariableClUpdateProfileLinuxVer ( ReadonlyVariable ) :
"""
Имя системы в профиле
"""
def init ( self ) :
self . label = _ ( " System profile version " )
def get ( self ) :
dv = self . Get ( ' cl_update_profile_datavars ' )
if dv :
return dv . Get ( ' os_linux_ver ' )
return " "
class VariableClUpdateProfileLinuxName ( ReadonlyVariable ) :
"""
Имя системы в профиле
"""
def get ( self ) :
dv = self . Get ( ' cl_update_profile_datavars ' )
if dv :
dv . Get ( ' os_linux_name ' )
return " "
class VariableClUpdateProfileUrl ( Variable ) :
"""
URL текущего репозитория
"""
untrusted = True
check_after = [ " cl_update_profile_branch " ]
opt = [ " --url " ]
metavalue = " URL "
profile = " cl_profile_system "
branch = " cl_update_profile_branch "
storage = " cl_update_profile_storage "
default_url = " git://git.calculate.ru/calculate/distros.git "
profiles_shortname = ' cl_update_profile_shortname '
@property
def current_root ( self ) :
return ' / '
def init ( self ) :
self . label = _ ( " Profile repository " )
self . help = _ ( " set the profile repository " )
re_url = re . compile (
r " ^(?:( %s )://)?( \ w[ \ w \ ./:-]+? \ w)( \ .git)?$ " % " | " . join (
[ " http " , " https " , " git " ] ) )
re_shortname = re . compile ( ' ^(?:([ \ w \ .-]+):)?([ \ w \ .-]+)$ ' )
@classmethod
def normalize_url ( cls , url ) :
match = cls . re_url . match ( url )
if not match :
raise VariableError ( _ ( " Wrong repository URL " ) )
url = match . group ( 2 )
url = " %s :// %s " % ( match . group ( 1 ) or " git " , url )
url = " %s .git " % url
return url
def url_by_shortname ( self , value ) :
match = self . re_shortname . match ( value )
if not match . group ( 1 ) :
template = self . Get ( ' update.cl_update_rep_host_url ' )
if template :
template = template [ 0 ]
else :
template = self . Select ( ' update.cl_update_rep_host_url ' ,
where = ' update.cl_update_rep_host ' ,
eq = match . group ( 1 ) , limit = 1 )
if not template :
raise VariableError ( _ ( " Failed to determine the repository host " ) )
try :
return template % match . group ( 2 )
except TypeError :
raise VariableError ( _ ( " Failed to determine the repository host " ) )
def set ( self , value ) :
if self . re_shortname . match ( value ) :
value = self . url_by_shortname ( value )
return self . normalize_url ( value )
def check ( self , value ) :
if not value :
raise VariableError ( " Need to specify profile repository " )
try :
branch = self . Get ( self . branch )
self . Get ( self . storage ) . get_profiles ( value , branch )
except GitError as e :
raise VariableError ( str ( e ) )
if not self . Get ( self . profiles_shortname ) :
raise VariableError ( _ ( " Repository %s has no profiles " ) % value )
def get ( self ) :
try :
profile = self . Get ( self . profile )
if profile :
while ( profile != self . current_root and
" .git " not in listDirectory ( profile ) ) :
profile = path . dirname ( profile )
if profile == self . current_root :
return " "
git = Git ( )
return git . get_url ( profile , " origin " ) or " "
except Exception :
pass
return self . default_url
class VariableClUpdateProfileRepoName ( ReadonlyVariable ) :
def init ( self ) :
self . label = _ ( " Repository name " )
storage = " cl_update_profile_storage "
url = " cl_update_profile_url "
def get ( self ) :
rep_set = self . Get ( self . storage )
url = self . Get ( self . url )
rep = rep_set . get_repository ( url , branch = None )
if rep :
return rep . repo_name
return " "
class VariableClUpdateProfileBranch ( Variable ) :
"""
Текущий репозиторий
"""
untrusted = True
type = " edit "
opt = [ " --branch " ]
metavalue = " BRANCH "
storage = " cl_update_profile_storage "
url = " cl_update_profile_url "
value = DEFAULT_BRANCH
def init ( self ) :
self . label = _ ( " Repository branch " )
self . help = _ ( " set the repository branch " )
def check ( self , value ) :
pass
## TODO: проверка ветки
#try:
# url = self.Get('cl_update_profile_url')
# self.Get('cl_update_profile_storage').get_profiles(url, value)
#except GitError as e:
# raise VariableError(str(e))
class VariableClProfileRepository ( ReadonlyVariable ) :
"""
Репозиторий из которого будут получены профили
"""
type = " object "
def get ( self ) :
try :
profile_dn = self . Get ( ' cl_profile_system ' )
while profile_dn != ' / ' and " .git " not in listDirectory ( profile_dn ) :
profile_dn = path . dirname ( profile_dn )
if profile_dn == ' / ' :
return " "
ls = LocalStorage ( path . dirname ( profile_dn ) )
return ProfileRepository ( path . basename ( profile_dn ) , ls )
except Exception :
return " "
class VariableClProfileData ( ReadonlyTableVariable ) :
"""
Таблица данных о текущих профилях системы
"""
source = [ ]
repository = " cl_profile_repository "
def profile_filter ( self , profiles ) :
arch = self . Get ( ' os_arch_machine_gentoo ' )
return [ x for x in profiles if x . arch == arch ]
def get ( self , hr = HumanReadable . No ) :
rep = self . Get ( self . repository )
if not rep :
return [ [ ] ]
profiles = rep . get_profiles ( )
if not profiles :
return [ [ ] ]
repo_name = profiles [ 0 ] . repository . repo_name
filtered_profiles = self . profile_filter ( profiles )
full_name = [ x . profile for x in filtered_profiles ]
profile_path = [ x . path for x in filtered_profiles ]
profile_arch = [ x . arch for x in filtered_profiles ]
short_name = simplify_profiles ( full_name )
full_name = [ " %s : %s " % ( repo_name , x ) for x in full_name ]
return zip ( full_name ,
short_name ,
profile_path ,
profile_arch )
setValue = Variable . setValue
class VariableClUpdateProfileRepository ( ReadonlyVariable ) :
"""
Репозиторий из которого будет извлечён список профилей
"""
type = " object "
url = " cl_update_profile_url "
storage = " cl_update_profile_storage "
branch = " cl_update_profile_branch "
sync_set = " update.cl_update_profile_sync_set "
def get ( self ) :
url = self . Get ( self . url )
if not url :
return " "
try :
rep_set = self . Get ( self . storage )
branch = self . Get ( self . branch )
rep = rep_set . get_repository ( url , branch )
if rep and self . Get ( self . sync_set ) == ' on ' :
rep . sync ( )
return rep_set . get_repository ( url , branch ) or " "
except GitError :
return " "
class VariableClUpdateProfileRepositoryName ( ReadonlyVariable ) :
"""
Название репозитория , из которого будут извлечены профили
"""
def get ( self ) :
rep = self . Get ( ' cl_update_profile_repository ' )
if rep :
return rep . repo_name
return " "
class VariableClUpdateProfileData ( VariableClProfileData ) :
source = [ " cl_update_profile_fullname " ,
" cl_update_profile_shortname " ,
" cl_update_profile_path " ,
" cl_update_profile_arch " ]
repository = " cl_update_profile_repository "
class VariableClUpdateProfileFullname ( FieldValue , ReadonlyVariable ) :
"""
Полное название профиля
"""
type = " list "
source_variable = " cl_update_profile_data "
column = 0
class VariableClUpdateProfileShortname ( FieldValue , ReadonlyVariable ) :
"""
Упрощенное название профиля
"""
type = " list "
source_variable = " cl_update_profile_data "
column = 1
class VariableClUpdateProfilePath ( FieldValue , ReadonlyVariable ) :
"""
Путь от корня до профиля
"""
type = " list "
source_variable = " cl_update_profile_data "
column = 2
class VariableClUpdateProfileArch ( FieldValue , ReadonlyVariable ) :
"""
Архитектура профиля
"""
type = " list "
source_variable = " cl_update_profile_data "
column = 3
class VariableClUpdateProfileSystem ( Variable ) :
"""
Профиль системы ( симлинк / etc / make . profile ' )
"""
type = " choice "
opt = [ " cl_update_profile_system " ]
untrusted = True
metavalue = " PROFILE "
profiles_path = " cl_update_profile_path "
profiles_shortname = " cl_update_profile_shortname "
profiles_fullname = " cl_update_profile_fullname "
profiles_arch = " cl_update_profile_arch "
profile = " cl_profile_system "
url = " cl_update_profile_url "
gentoo_arch = ' os_arch_machine_gentoo '
def init ( self ) :
self . label = _ ( " System profile " )
self . help = _ ( " set the system profile " )
def check ( self , profile ) :
if not profile :
raise VariableError ( _ ( " You must specify the profile " ) )
path_profile = self . Select ( self . profiles_path ,
where = self . profiles_shortname ,
eq = profile , limit = 1 )
profile_fullname = self . Select ( self . profiles_fullname ,
where = self . profiles_shortname ,
eq = profile , limit = 1 )
if path_profile :
dv = DataVarsUpdateProfile ( path_profile )
if " : " in profile_fullname :
repo_name = profile_fullname . partition ( " : " ) [ 0 ]
else :
repo_name = " "
try :
if ( not dv . Get ( ' cl_update_rep_name ' ) or
not dv . Get ( ' cl_update_rep_url ' ) ) :
raise VariableError (
_ ( " Repository variables "
" were not configured for the profile " ) )
if not dv . Get ( ' os_linux_name ' ) :
raise VariableError ( " " )
if repo_name not in list ( dv . Get ( ' cl_update_rep_name ' ) ) :
raise VariableError (
_ ( " Overlay %s is not specified "
" in cl_update_rep_name " ) % repo_name )
except ( DataVarsError , VariableError ) as e :
if str ( e ) :
message = " . " + str ( e )
else :
message = " "
raise VariableError ( _ ( " The selected profile is not Calculate " )
+ message )
else :
raise VariableError ( _ ( " Wrong Calculate profile " ) )
def get ( self ) :
try :
profile_system = self . Get ( self . profile )
profile = self . Select ( self . profiles_shortname ,
where = self . profiles_path ,
eq = profile_system , limit = 1 )
if profile :
return profile
except VariableError :
pass
shortname = self . Get ( self . profiles_shortname )
if len ( shortname ) == 1 :
return shortname [ 0 ]
return " "
def choice ( self ) :
url = self . Get ( self . url )
if not url :
return [ ]
arch = self . Get ( self . gentoo_arch )
profiles = zip ( * self . Select ( [ self . profiles_shortname ,
self . profiles_fullname ] ,
where = self . profiles_arch , eq = arch ) )
if profiles :
short_name , full_name = profiles
return zip ( short_name , full_name )
return [ ]
class DataVarsUpdateProfile ( SimpleDataVars ) :
"""
Упрощенная модель переменных для получения данных с удаленного профиля
"""
source = [ ' cl_update_rep_name ' ,
' cl_update_rep_url ' ,
' cl_update_rep_path ' ,
' cl_update_rep_rev ' ,
' cl_update_branch_name ' ]
def __init__ ( self , profile , chroot_path = ' / ' , recheck = None ) :
SimpleDataVars . __init__ (
self ,
lib_linux . VariableOsLinuxName ( ) ,
lib_linux . VariableOsLinuxShortname ( ) ,
lib_linux . VariableOsLinuxSubname ( ) ,
lib_linux . VariableOsLinuxVer ( ) ,
lib_linux . VariableClProfileSystem ( ) ,
env . VariableClRepositoryData ( ) ,
env . VariableClRepositoryName ( ) ,
env . VariableClRepositoryLocation ( ) ,
env . VariableClChrootPath ( ) ,
env . VariableClTemplateLocation ( ) ,
env . VariableClTemplatePath ( ) ,
env . VariableClEmergeConfig ( systemRoot = chroot_path ) ,
env . VariableClFeatures ( ) ,
VariableClUpdateRepData ( section = " update " ) ,
VariableClUpdateRepPath ( section = " update " ) ,
VariableClUpdateRepRev ( section = " update " ) ,
VariableClUpdateBranch ( section = " update " ) ,
VariableClUpdateBranchName ( section = " update " ) ,
VariableClUpdateLaymanConfig ( section = " update " ) ,
VariableClUpdateLaymanStorage ( section = " update " ) ,
VariableClUpdateRepName ( section = " update " ) ,
VariableClUpdateRep ( section = " update " ) ,
VariableClUpdateRepUrl ( section = " update " ) ,
VariableClUpdateBinhost ( section = " update " ) ,
VariableClUpdateBinhostData ( section = " update " ) ,
VariableClUpdateBinhostHost ( section = " update " ) ,
VariableClUpdateBinhostRecheckSet ( section = " update " ) ,
VariableClUpdateBinhostRevisions ( section = " update " ) ,
VariableClUpdateBinhostTime ( section = " update " ) ,
VariableClUpdateBinhostTimeout ( section = " update " ) ,
VariableClUpdateBinhostTimestampPath ( section = " update " ) ,
VariableClUpdateBinhostList ( section = " update " ) ,
VariableClUpdateBinhostRevisionPath ( section = " update " ) ,
)
self [ ' cl_profile_system ' ] = profile
self [ ' cl_chroot_path ' ] = chroot_path
if recheck is not None :
self [ ' cl_update_binhost_recheck_set ' ] = recheck
self . flIniFileFrom ( profile )
def __repr__ ( self ) :
return " Profile variables "
class VariableClUpdateProfileSyncSet ( Variable ) :
"""
Синхронизировать репозиторий перед сменой профиля
"""
type = " bool "
value = " off "
opt = [ " -u " , " --update-cache " ]
def init ( self ) :
self . label = _ ( " Update the cache " )
self . help = _ ( " Update the cache " )
class VariableClUpdateAutocheckSet ( Variable ) :
"""
Выполнять / невыполнять автопроверку обновлений
"""
type = " bool "
value = " on "
opt = [ " -a " , " --autocheck " ]
def init ( self ) :
self . label = _ ( " Automatically check updates " )
self . help = _ ( " automatically check updates " )
class VariableClUpdateAutocheckInterval ( Variable ) :
"""
Интервал выполнения проверки
"""
type = " choiceedit "
opt = [ " -I " , " --autocheck-interval " ]
metavalue = " INTERVAL "
def init ( self ) :
self . label = _ ( " Interval for the updates checking " )
self . help = _ ( " set interval for the updates checking " )
def choice ( self ) :
return [ [ " 6h " , _ ( " every six hours " ) ] ,
[ " 12h " , _ ( " every twelve hours " ) ] ,
[ " 1d " , _ ( " daily " ) ] ]
class VariableClUpdateAutocheckScheduleSet ( Variable ) :
"""
Запустить проверку только если с о времени последнего запуска прошло
необходимое время
"""
type = " bool "
value = " off "
opt = [ " --schedule " ]
def init ( self ) :
self . label = _ ( " Consider the autocheck schedule " )
self . help = _ ( " consider the autocheck schedule " )
class VariableClUpdateEmergelistSet ( Variable ) :
"""
Вывести список пакетов в формате emerge
"""
type = " bool "
value = " off "
opt = [ " -e " , " --emergelist " ]
def init ( self ) :
self . label = _ ( " Emerge-like packages list " )
self . help = _ ( " display the packages list in emerge format " )
class VariableClUpdateKernelVersion ( ReadonlyVariable ) :
"""
Текущая версия ядра
"""
def get ( self ) :
return process ( ' /bin/uname ' , ' -r ' ) . read ( ) . strip ( )
class VariableClUpdateKernelSrcPath ( ReadonlyVariable ) :
"""
Каталог содержащий исходный код текущего ядра
"""
def get ( self ) :
kernel_ver = self . Get ( ' cl_update_kernel_version ' )
for template_path in ( " /lib/modules/ %s /build " ,
" /usr/src/linux- %s " ) :
src_path = template_path % kernel_ver
if path . exists ( src_path ) :
if path . islink ( src_path ) :
return os . readlink ( src_path )
else :
return src_path
else :
return " "
class VariableClUpdateKernelPkg ( ReadonlyVariable ) :
"""
Пакет текущего ядра
"""
def get ( self ) :
src_path = self . Get ( ' cl_update_kernel_src_path ' )
if src_path :
qfile = process ( ' /usr/bin/qfile ' , ' -vC ' , src_path )
if qfile . success ( ) :
return qfile . read ( ) . partition ( " " ) [ 0 ]
return " "
class VariableClUpdateLinesLimit ( Variable ) :
"""
Количество выводимых строк при ошибке
"""
type = " int "
value = " 30 "
class VariableClUpdateSkipSetupSet ( Variable ) :
"""
Пропустить выполнение cl - setup - system в cl - update - profile
"""
type = " bool "
value = " off "
opt = [ " --skip-setup-system " ]
def init ( self ) :
self . label = _ ( " Skip the system setup " )
self . help = _ ( " skip the system setup " )
class VariableClUpdateCleanpkgSet ( Variable ) :
"""
Пропустить выполнение cl - setup - system в cl - update - profile
"""
type = " bool "
value = " off "
opt = [ " --clean-pkg " ]
def init ( self ) :
self . label = _ ( " Clean obsolete programs archives " )
self . help = _ ( " clean obsolete programs archives " )
class VariableClUpdateOutdatedKernelPath ( Variable ) :
"""
Файл - флаг наличия устаревшего , неудаленного ядра
"""
value = " /var/lib/calculate/calculate-update/outdated_kernel "
class VariableClUpdateSkipRbSet ( Variable ) :
"""
Пропусить revdep - rebuild
"""
type = " bool "
value = " off "
opt = [ " -R " , " --skip-revdep-rebuild " ]
def init ( self ) :
self . label = _ ( " Skip reverse dependencies check " )
self . help = _ ( " skip reverse dependencies check " )
class VariableClUpdateOutdatedKernelSet ( ReadonlyVariable ) :
"""
Есть наличие устаревшего ядра
"""
type = " bool "
def get ( self ) :
ui = UpdateInfo ( self . parent )
return " on " if ui . outdated_kernel else " off "
class VariableClUpdateBinhostList ( Variable ) :
"""
Список хостов с бинарными обновлениями
"""
type = " list "
value = [ " ftp://ftp.calculate-linux.ru/pub/calculate " ]
class VariableClUpdateBinhost ( Variable ) :
"""
Хост с бинарными обновлениями
"""
value = " "
class VariableClUpdateBinhostRevisionPath ( Variable ) :
"""
Путь до revisions файлов
"""
type = " list "
value = [
" grp/default/ini.env " ,
" grp/kde/ini.env " ,
" grp/server/ini.env " ,
" grp/x/ini.env "
]
class VariableClUpdateBinhostTimestampPath ( Variable ) :
"""
Путь до файла timestamp
"""
value = " timestamp "
class VariableClUpdateBinhostTimeout ( Variable ) :
"""
Таймаут на проверку одного binhost
"""
type = " int "
value = " 5 "