Browse Source

Добавлена команда выбора профиля

tags/3.2.0_alpha12
Mike Khiretskiy 7 years ago
parent
commit
cd67891d05
7 changed files with 900 additions and 19 deletions
  1. +1
    -1
      update/datavars.py
  2. +5
    -0
      update/package_tools.py
  3. +244
    -0
      update/profile.py
  4. +53
    -2
      update/update.py
  5. +110
    -0
      update/utils/cl_update_profile.py
  6. +441
    -16
      update/variables/update.py
  7. +46
    -0
      update/wsdl_update.py

+ 1
- 1
update/datavars.py View File

@@ -13,7 +13,6 @@
# 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.

__app__ = 'calculate-update'
__version__ = '3.1.8'

@@ -32,3 +31,4 @@ class DataVarsUpdate(DataVars):
self.importVariables()
self.importVariables('calculate.update.variables')
self.defaultModule = "update"


+ 5
- 0
update/package_tools.py View File

@@ -17,6 +17,7 @@ from collections import Mapping, defaultdict

import re
import sys
from calculate.lib.cl_template import iniParser
from calculate.lib.utils.colortext.palette import TextState
from calculate.lib.utils.tools import AddonError, SavableIterator
import time
@@ -177,6 +178,10 @@ class Git:
def is_git(gitpath):
return path.isdir(Git._gitDir(gitpath))

def get_url(self, rpath, remote_name):
ini_parser = iniParser(path.join(Git._gitDir(rpath), "config"))
return ini_parser.getVar(u'remote "%s"'%remote_name, "url")

def cloneRepository(self, url, rpath, branch, cb_progress=None):
"""
Сделать локальную копию репозитория


+ 244
- 0
update/profile.py View File

@@ -0,0 +1,244 @@
#-*- coding: utf-8 -*-

# Copyright 2014 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 sys
from os import path
import shutil
import os
from calculate.lib.utils.files import listDirectory, readFile, readLinesFile, \
makeDirectory, removeDir
from package_tools import Git
from update import UpdateError

from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__])

DEFAULT_BRANCH = "master"


class RepositoryStorage(object):
directory = '/tmp'

def __init__(self, directory):
self.directory = directory
makeDirectory(directory)

def __iter__(self):
git = Git()
for dn in listDirectory(self.directory, onlyDir=True, fullPath=True):
if git.is_git(dn):
yield ProfileRepository(path.basename(dn), self)

def get_profiles(self, url, branch=DEFAULT_BRANCH):
return []

class ProfileStorage(RepositoryStorage):
def get_profiles(self, url, branch=DEFAULT_BRANCH):
rep = self.get_repository(url, branch)
if rep:
return rep.get_profiles()
return None

def get_repository(self, url, branch=DEFAULT_BRANCH):
return None

class LocalStorage(ProfileStorage):
"""
Локальное хранилище репозиториев, при запросе по урлу смотрит, доступные
репозитории если находит подходящий - возвращает его профили
"""
def get_repository(self, url, branch=DEFAULT_BRANCH):
for rep in self:
if rep.is_like(url, branch):
return rep


class CacheStorage(ProfileStorage):
"""
Хранилище репозиториев, при запросе по урлу смотрит, доступные
репозитории если находит подходящий - возвращает его профили,
если не находит - скачивает и возвращает профили
"""
def get_repository(self, url, branch=DEFAULT_BRANCH):
for rep in self:
if rep.is_like(url, branch):
return rep
else:
return ProfileRepository.clone(url, self, branch)

class RepositoryStorageSet(RepositoryStorage):
"""
Набор хранилищ репозиториев
"""
def __init__(self):
self.storages = [LocalStorage('/var/lib/layman'),
CacheStorage('/var/calculate/tmp/update')]

def get_profiles(self, url, branch=DEFAULT_BRANCH):
"""
Получить профили из указанного репозитория
"""
for storage in self.storages:
profiles = storage.get_profiles(url, branch)
if profiles is not None:
return profiles
return None

def __iter__(self):
for storage in self.storages:
for rep in storage:
yield rep

def get_repository(self, url, branch=DEFAULT_BRANCH):
"""
Получить репозиторий по параметрам
"""
for rep in self:
if rep.is_like(url, branch):
return rep
return None

def is_local(self, url, branch=DEFAULT_BRANCH):
"""
Проверить является ли репозиторий с указанными параметрами
локальным
"""
rep = self.get_repository(url, branch)
if rep and isinstance(rep.storage, LocalStorage):
return True
return False

def __repr__(self):
return "Repository set"

class Profile(object):
"""
Профиль репозитория
"""
available_arch = ["amd64", "x86"]

def __init__(self, repository, profile, arch):
self.repository = repository
self.profile = profile
self.arch = arch

@property
def path(self):
return path.join(self.repository.directory,"profiles", self.profile)

@classmethod
def from_string(cls, repository, s):
parts = filter(None, s.split())
if len(parts) == 3 and parts[0] in cls.available_arch:
return Profile(repository, parts[1], parts[0])
return None

def __repr__(self):
return "<Profile (%s) %s:%s from %s>" % (self.arch,
self.repository.repo_name,
self.profile,
self.repository.directory)


class ProfileRepository(object):
"""
Репозиторий либо скачивается, либо берется из кэша
"""
def __init__(self, name, storage):
self._storage = storage
self.name = name

@property
def storage(self):
return self._storage

@storage.setter
def storage(self, storage):
if storage.directory != self._storage.directory:
newpath = path.join(storage.directory, self.name)
if self.directory == newpath:
return
try:
if path.exists(newpath):
removeDir(newpath)
shutil.move(self.directory, newpath)
self._storage = storage
except OSError as e:
raise UpdateError(_("Failed to move profile: %s") %
str(e))

@classmethod
def clone(cls, url, storage, branch=DEFAULT_BRANCH):
name = path.basename(url)
if name.endswith(".git"):
name = name[:-4]
git = Git()
rpath = path.join(storage.directory, name)
if path.exists(rpath):
removeDir(rpath)
git.cloneRepository(url, rpath, branch)
pr = cls(name, storage)
repo_name = pr.repo_name
if name != repo_name:
rpath_new = path.join(storage.directory, repo_name)
if not path.exists(rpath_new):
os.rename(rpath, rpath_new)
pr = cls(repo_name, storage)
return pr

@property
def repo_name(self):
return readFile(path.join(self.directory,
"profiles/repo_name")).strip()

def is_like(self, url, branch=DEFAULT_BRANCH):
if self.url == url and (branch is None or self.branch == branch):
return True
return False

@property
def directory(self):
"""
Получить локальную директорию на данные репозитория
"""
return path.join(self.storage.directory, self.name)

@property
def url(self):
git = Git()
return git.get_url(self.directory, "origin")

@property
def branch(self):
git = Git()
return git.getBranch(self.directory)

def sync(self):
"""
Синхронизировать репозиторий
"""
git = Git()
git.pullRepository(self.directory)

def get_profiles(self):
"""
Получить список профилей репозитория
"""
profiles_desc = path.join(self.directory, "profiles/profiles.desc")
return filter(None, (Profile.from_string(self, line)
for line in readLinesFile(profiles_desc)))

def __repr__(self):
return "<ProfileRepository %s url=%s>" % (self.directory, self.url)

+ 53
- 2
update/update.py View File

@@ -22,6 +22,7 @@ import os
import time
from calculate.core.server.gen_pid import search_worked_process, ProcessStatus
from calculate.lib.cl_template import SystemIni
from calculate.lib.datavars import DataVarsError

from calculate.lib.utils.tools import AddonError
from calculate.lib.utils.colortext.palette import TextState
@@ -37,12 +38,12 @@ Colors = TextState.Colors
from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir,
PercentProgress, process, getRunCommands,
readFile)
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
RegexpLocalization, _)
import emerge_parser
import logging
from emerge_parser import EmergeParser, EmergeCommand, EmergeError, EmergeCache

from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
RegexpLocalization, _)
setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)

@@ -165,6 +166,10 @@ class Update:
if not self._syncRepository(repname, url, rpath, revision, branch,
cb_progress=self.setProgress):
return "skip"
layman = Layman(dv.Get('cl_update_layman_installed'),
dv.Get('cl_update_layman_make'))
if repname != "portage":
layman.add(repname, url, rpath)
return True
except GitError as e:
if e.addon:
@@ -655,3 +660,49 @@ class Update:

return decor

def migrateCacheRepository(self, url, branch):
rep_set = self.clVars.Get('cl_update_profile_storage')
rep = rep_set.get_repository(url, branch)
if rep:
rep.storage = rep_set.storages[0]
self.clVars.Invalidate('cl_update_profile_storage')
return True


def reconfigureProfileVars(self):
"""
Синхронизировать репозитории
"""
dv = self.clVars

profile_dv = dv.Get('cl_update_profile_datavars')
try:
for var_name in ('cl_update_rep_rev',
'cl_update_rep_path',
'cl_update_rep_url',
'cl_update_rep_name',
'cl_update_branch_name',
'cl_profile_system',
'cl_update_layman_storage',
'cl_update_rep'):
dv.Set(var_name, profile_dv.Get(var_name), force=True)
except DataVarsError:
raise UpdateError(_("Wrong profile"))
return True

def setProfile(self):
profile = self.clVars.Select('cl_profile_path',
where='cl_profile_shortname',
eq=self.clVars.Get('cl_update_profile_system'), limit=1)
if not profile:
raise UpdateError(_("Failed to determine profile %s") %
self.clVars.Get('cl_update_profile_system'))
profile_path = path.relpath(profile, '/etc/portage')
try:
for rm_fn in filter(path.exists,
('/etc/make.profile', '/etc/portage/make.profile')):
os.unlink(rm_fn)
os.symlink(profile_path, '/etc/portage/make.profile')
except (OSError,IOError) as e:
raise UpdateError(_("Failed to set profile: %s")%str(e))
return True

+ 110
- 0
update/utils/cl_update_profile.py View File

@@ -0,0 +1,110 @@
#-*- coding: utf-8 -*-

# Copyright 2010-2013 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 sys
from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError
from calculate.update.update import UpdateError
from calculate.update.package_tools import GitError

setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)


class ClUpdateProfileAction(Action):
"""
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, UpdateError, GitError)

successMessage = __("Update profile successed")
failedMessage = __("Update profile failed")
interruptMessage = __("Update profile manually interrupted")


# список задач для дейсвия
tasks = [
{'name': 'check_run',
'method': 'Update.checkRun(cl_update_wait_another_set)'},
{'name': 'migrate_repository',
'method': 'Update.migrateCacheRepository('
'cl_update_profile_rep,cl_update_profile_branch)',
'message': __("Repository transfer"),
'condition': lambda Get: not (
Get('cl_update_profile_storage').is_local(
Get('cl_update_profile_rep'),
Get('cl_update_profile_branch')))
},
{'name': 'reconfigure_vars',
'method': 'Update.reconfigureProfileVars()'
},
{'name': 'reps_synchronization',
'group': __("Repositories synchronization"),
'tasks': [
{'name': 'sync_reps',
'foreach': 'cl_update_profile_sync_rep',
'message': __("Syncing the {eachvar:capitalize} repository"),
'method': 'Update.syncRepositories(eachvar)',
#'condition': lambda Get: Get('cl_update_profile_sync_rep')
},
{'name': 'sync_reps:regen_cache',
'foreach': 'cl_update_sync_overlay_rep',
'message': __("Updating the {eachvar:capitalize} repository cache"),
'essential': False,
'method': 'Update.regenCache(eachvar)',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_metadata_force') != 'skip' or
Get('cl_update_metadata_force') == 'force'))
},
{'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"),
'method': 'Update.eixUpdate()',
'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or
Get('cl_update_eixupdate_force') == 'force'))
},
# сообщение удачного завершения при обновлении репозиториев
{'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': __("Setting up profile"),
'tasks': [
{'name': 'set_profile',
'message': __("Switching to {cl_update_profile_system} profile"),
'method': 'Update.setProfile()'
},
]
}
]

+ 441
- 16
update/variables/update.py View File

@@ -19,14 +19,20 @@ import sys
import re
from os import path
from calculate.lib.datavars import (Variable, VariableError,
ReadonlyVariable, ReadonlyTableVariable, TableVariable, FieldValue)
ReadonlyVariable, ReadonlyTableVariable, TableVariable, FieldValue,
SimpleDataVars, DataVarsError)
from calculate.lib.utils.portage import searchProfile
from calculate.lib.utils.files import readLinesFile, readFile, makeDirectory, \
listDirectory

from calculate.lib.cl_lang import setLocalTranslate
from calculate.update.emerge_parser import EmergeCache
from calculate.lib.utils.text import simplify_profiles
from calculate.update.package_tools import Git, GitError, Layman
from calculate.update.profile import RepositoryStorageSet, DEFAULT_BRANCH

from calculate.lib.variables.linux import VariableOsLinuxName, \
VariableOsLinuxSubname, VariableOsLinuxVer


setLocalTranslate('cl_update3',sys.modules[__name__])

@@ -113,19 +119,6 @@ class VariableClUpdateRepUrl(Variable):
type = "list"
value = []

class VariableClUpdateSystemProfile(ReadonlyVariable):
"""
Профиль системы (симлинк /etc/make.profile')
"""
def get(self):
try:
make_profile = self.Get('cl_make_profile')
return path.normpath(
path.join(path.dirname(make_profile),
os.readlink(make_profile)))
except:
raise VariableError(_("Failed to determine the system profile"))

class VariableClUpdateLaymanStorage(ReadonlyVariable):
"""
Путь к репозиториям layman
@@ -165,7 +158,7 @@ class VariableClUpdateRepRev(Variable):

def get(self):
if self.Get('cl_update_rep') == 'rev':
revPaths = searchProfile(self.Get('cl_update_system_profile'),
revPaths = searchProfile(self.Get('cl_profile_system'),
"rev")
if revPaths:
revPath = revPaths[-1]
@@ -432,3 +425,435 @@ class VariableClUpdateWaitAnotherSet(Variable):
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()

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"

def get(self):
profile = self.Get('cl_update_profile_system')
path_profile = self.Select('cl_profile_path',
where='cl_profile_shortname',
eq=profile, limit=1)
if path_profile:
return DataVarsUpdateProfile(path_profile)
return ""

class VariableClUpdateProfileLinuxFullname(ReadonlyVariable):
"""
Имя системы в профиле
"""
def init(self):
self.label = _("Profile system name")

def get(self):
dv = self.Get('cl_update_profile_datavars')
if dv:
try:
subname = dv.Get('os_linux_subname')
linuxname = dv.Get('os_linux_name')
if subname:
return "%s %s" % (linuxname, subname)
return linuxname
except DataVarsError:
raise VariableError("Wrong Calculate Linux profile")
return ""

class VariableClUpdateProfileDependData(ReadonlyTableVariable):
"""
Зависимые репозитории
"""
source = ['cl_update_profile_depend_name',
'cl_update_profile_depend_url']

def init(self):
self.label = _("Used repositories")

@staticmethod
def url_like(url1, url2):
match1 = VariableClUpdateProfileRep.re_url.search(url1)
match2 = VariableClUpdateProfileRep.re_url.search(url2)
if match1 and match2:
return match1.group(2).lower() == match2.group(2).lower()
return False


def get(self, hr=False):
dv = self.Get('cl_update_profile_datavars')
url = self.Get('cl_update_profile_rep').lower()
if dv:
return reversed(zip(dv.Get('cl_update_rep_name'),
dv.Get('cl_update_rep_url')))
return ""

setValue = Variable.setValue

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 = _("Profile system 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 VariableClUpdateProfileRep(Variable):
"""
Текущий репозиторий
"""
untrusted = True
check_after = "cl_update_profile_branch"

opt = ["--url"]

def init(self):
self.label = _("Profile repository")
self.help = _("set 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(_("Failed 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('cl_update_rep_host_url')
if template:
template = template[0]
else:
template = self.Select('cl_update_rep_host_url',
where='cl_update_rep_host',
eq=match.group(1), limit=1)
if not template:
raise VariableError(_("Failed to determine repository host"))

try:
return template % match.group(2)
except TypeError:
raise VariableError(_("Failed to determine 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('cl_update_profile_branch')
self.Get('cl_update_profile_storage').get_profiles(value, branch)
except GitError as e:
raise VariableError(str(e))
if not self.Get('cl_profile_shortname'):
raise VariableError(_("Repository %s has not profiles")%value)

def get(self):
try:
profile = self.Get('cl_profile_system')
while profile != '/' and ".git" not in listDirectory(profile):
profile = path.dirname(profile)
if profile == '/':
return ""
git = Git()
return git.get_url(profile, "origin") or ""
except:
return "git://git.calculate.ru/calculate/distros.git"

class VariableClUpdateProfileRepoName(ReadonlyVariable):
def init(self):
self.label = _("Repository name")

def get(self):
rep_set = self.Get('cl_update_profile_storage')
url = self.Get('cl_update_profile_rep')
rep = rep_set.get_repository(url)
if rep:
return rep.repo_name
return ""


class VariableClUpdateProfileBranch(Variable):
"""
Текущий репозиторий
"""
untrusted = True

type = "edit"
opt = ["--branch"]

def init(self):
self.label = _("Repository branch")
self.help = _("set repository branch")

def check(self, value):
pass
## TODO: проверка ветки
#try:
# url = self.Get('cl_update_profile_rep')
# self.Get('cl_update_profile_storage').get_profiles(url, value)
#except GitError as e:
# raise VariableError(str(e))

def get(self):
rep_set = self.Get('cl_update_profile_storage')
url = self.Get('cl_update_profile_rep')
#print url, rep_set.is_local(url, branch=None)
if rep_set.is_local(url, branch=None):
rep = rep_set.get_repository(url, branch=None)
git = Git()
return git.getBranch(rep.directory)
return DEFAULT_BRANCH


class VariableClProfileSystem(ReadonlyVariable):
"""
Профиль системы (симлинк /etc/make.profile')
"""
def get(self):
try:
make_profile = self.Get('cl_make_profile')
return path.normpath(
path.join(path.dirname(make_profile),
os.readlink(make_profile)))
except:
raise VariableError(_("Failed to determine the system profile"))


class VariableClProfileData(ReadonlyTableVariable):
source = ["cl_profile_fullname",
"cl_profile_shortname",
"cl_profile_path",
"cl_profile_arch"]

def get(self, hr=False):
url = self.Get('cl_update_profile_rep')
if not url:
return [[]]
try:
rep_set = self.Get('cl_update_profile_storage')
branch = self.Get('cl_update_profile_branch')
profiles = rep_set.get_profiles(url, branch)
rep = rep_set.get_repository(url, branch)
except GitError:
return [[]]
arch = self.Get('os_arch_machine_gentoo')
if profiles:
repo_name = profiles[0].repository.repo_name
arch_profiles = [x for x in profiles if x.arch == arch]
full_name = [x.profile for x in arch_profiles]
profile_path = [x.path for x in arch_profiles]
profile_arch = [x.arch for x in arch_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)
return [[]]

setValue = Variable.setValue


class VariableClProfileFullname(FieldValue, ReadonlyVariable):
"""
Полное название профиля
"""
type = "list"
source_variable = "cl_profile_data"
column = 0

class VariableClProfileShortname(FieldValue, ReadonlyVariable):
"""
Упрощенное название профиля
"""
type = "list"
source_variable = "cl_profile_data"
column = 1

class VariableClProfilePath(FieldValue, ReadonlyVariable):
"""
Путь от корня до профиля
"""
type = "list"
source_variable = "cl_profile_data"
column = 2

class VariableClProfileArch(FieldValue, ReadonlyVariable):
"""
Архитектура профиля
"""
type = "list"
source_variable = "cl_profile_data"
column = 3

class VariableClUpdateProfileSystem(Variable):
"""
Профиль системы (симлинк /etc/make.profile')
"""
type = "choice"
opt = ["cl_update_profile_system"]
untrusted = True
metavalue = "PROFILE"

def init(self):
self.label = _("System profile")
self.help = _("set system profile")

def check(self, profile):
if not profile:
raise VariableError(_("Profile must be specified"))
path_profile = self.Select('cl_profile_path',
where='cl_profile_shortname',
eq=profile, limit=1)
if path_profile:
dv = DataVarsUpdateProfile(path_profile)
try:
if (not dv.Get('cl_update_rep_name') or
not dv.Get('cl_update_rep_url')):
raise VariableError(_("Repository variables is not "
"configured in profile"))
if not dv.Get('os_linux_name'):
raise VariableError()
except (DataVarsError, VariableError) as e:
raise VariableError(_("Profile is not Calculate"))
else:
raise VariableError(_("Wrong Calculate profile"))

def get(self):
try:
profile_system = self.Get('cl_profile_system')
profile = self.Select('cl_profile_shortname',
where='cl_profile_path',
eq=profile_system, limit=1)
if profile:
return profile
except VariableError:
pass
shortname = self.Get('cl_profile_shortname')
if len(shortname) == 1:
return shortname[0]
return ""

def choice(self):
url = self.Get('cl_update_profile_rep')
if not url:
return []
arch = self.Get('os_arch_machine_gentoo')
profiles = zip(*self.Select(['cl_profile_shortname',
'cl_profile_fullname'],
where='cl_profile_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):
SimpleDataVars.__init__(self,
VariableOsLinuxName(),
VariableOsLinuxSubname(),
VariableOsLinuxVer(),
VariableClUpdateRepData(section="update"),
VariableClUpdateRepPath(section="update"),
VariableClUpdateRepRev(section="update"),
VariableClUpdateBranchName(section="update"),
VariableClProfileSystem(section="update"),
VariableClUpdateLaymanStorage(section="update"),
VariableClUpdateRepName(section="update"),
VariableClUpdateRep(section="update"),
VariableClUpdateRepUrl(section="update"))
self.cache['cl_profile_system'] = profile
self.flIniFileFrom(profile)

def __repr__(self):
return "Profile variables"

+ 46
- 0
update/wsdl_update.py View File

@@ -23,6 +23,7 @@ from calculate.install.install import InstallError
from calculate.update.update import Update,UpdateError
from calculate.update.package_tools import GitError
from utils.cl_update import ClUpdateAction
from utils.cl_update_profile import ClUpdateProfileAction
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
setLocalTranslate('cl_update3',sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@@ -74,4 +75,49 @@ class Wsdl(WsdlBase):
'cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Update"))]},
#
# Сменить профиль
#
{
# идентификатор метода
'method_name': "update_profile",
# категория метода
'category': __('Update'),
# заголовок метода
'title': __("Update the Profile"),
# иконка для графической консоли
'image': 'preferences-system',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-update-profile',
# права для запуска метода
'rights': ['change_profile'],
# объект содержащий модули для действия
'logic': {'Update': Update},
# описание действия
'action': ClUpdateProfileAction,
# объект переменных
'datavars': "update",
'native_error': (VariableError, DataVarsError,
InstallError, UpdateError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'update_profile'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Repository"),
brief=('cl_update_profile_repo_name',
'cl_update_profile_branch'),
hide=("cl_update_profile_rep",),
normal=('cl_update_profile_rep',),
expert=('cl_update_profile_branch',)),
lambda group: group(_("Profile"),
normal=('cl_update_profile_system',),
brief=('cl_update_profile_system',
'cl_update_profile_linux_fullname',
'cl_update_profile_linux_ver',
'cl_update_profile_depend_data')
)],
'brief': {'next': __("Perform"),
'name': __("Set profile")}},
]

Loading…
Cancel
Save