Исправлена одновременная настройка и установка пакета

legacy27 3.6.7.9
Mike Hiretsky 4 years ago
parent da8aadda6d
commit 2060eb6676

@ -22,7 +22,7 @@ import importlib
from calculate.lib.utils.portage import getInstalledAtom, RepositoryPath, \
searchProfile, RepositorySubstituting
from calculate.lib.cl_xml import xmlShare
from calculate.lib.utils.system import SystemPath
from calculate.lib.utils.system import SystemPath, FUser, emerge_running
from functools import wraps
import types
import random
@ -50,7 +50,7 @@ from utils.files import (getModeFile, listDirectory, removeDir, typeFile,
scanDirectory, FilesError, dir_sync, find, getProgPath,
pathJoin, readFile, readLinesFile, process)
from utils.mount import Mounts
from utils.tools import iterate_list, has_any
from utils.tools import iterate_list, has_any, Locker
from datavars import DataVarsError, VariableError, CriticalError, SimpleDataVars
from calculate.lib.configparser import (ConfigParser, NoSectionError,
ParsingError)
@ -80,6 +80,19 @@ def catch_no_space_left(f):
return wrapper
def post_unlock_packages(f):
def wrapper(self, *args, **kw):
if not kw.get("rerun", True):
return f(self, *args, **kw)
else:
try:
return f(self, *args, **kw)
except BaseException as e:
raise
finally:
self.unlock_packages()
return wrapper
class DataVarsConfig(SimpleDataVars):
"""
@ -3816,6 +3829,13 @@ class Template(_file, _terms, _warning, xmlShare, _shareTemplate):
self.printERROR = printERROR
self.critical = critical
self.postmergePkgs = []
self._locked_packages = {}
if objVar and objVar.Get("cl_merge_pkg"):
self._locked_packages = {
x.partition(":")[0]: None
for x in objVar.Get('cl_merge_pkg')
}
self.postmergeFile = "/var/lib/calculate/-postmerge"
self.bHasError = False
if printERROR:
@ -3829,6 +3849,15 @@ class Template(_file, _terms, _warning, xmlShare, _shareTemplate):
self.cltObj = None
self.functObj = None
self.mounts = None
# Бесконченое ожидание завершения emerge если выполняется настройка пакетов
#if objVar:
# if (not objVar.Get('cl_ebuild_phase')
# and emerge_running()
# and objVar.GetBool('install.ac_install_merge')):
# self.printWARNING(_("Waiting for emerge to be complete"))
# while emerge_running():
# time.sleep(1)
# Предупреждения
# self.warning = []
# Печатать ли предупреждения о корневых шаблонах без cl_name==pkg
@ -4333,7 +4362,33 @@ gettext -d cl_template "$*"
self.printWARNING("# Calculate ac_install_merge==on")
return skipDirs + skipTemplates
def lock_package(self, pkg, fuser=None):
pkg = pkg.partition(":")[0]
if pkg not in self._locked_packages:
category, _, pkg = pkg.partition("/")
pkglockfile = ("/var/calculate/tmp/portage/"
"{}/.{}.calculate_lockfile".format(category, pkg))
ipcfile = ("/var/db/pkg/"
"{}/.{}*.portage_lockfile".format(category, pkg))
if os.path.exists(pkglockfile):
fuser = fuser or FUser()
if any(fuser.search(ipcfile)):
return False
l = Locker(fn=pkglockfile, timeout=0)
if l.acquire():
self._locked_packages[pkg] = l
return True
return False
return True
def unlock_packages(self):
for pkg, l in self._locked_packages.items():
if l:
l.remove()
self._locked_packages = {}
@catch_no_space_left
@post_unlock_packages
def applyTemplates(self, progress=True, rerun=True):
"""Применяет шаблоны к конфигурационным файлам"""
@ -4484,29 +4539,49 @@ gettext -d cl_template "$*"
self.cltObj.applyTemplatesClt()
finally:
self.objVar.defaultModule = old_mod
if ((self.objVar.Get('cl_merge_pkg') or
self.objVar.Get('cl_action') in (
"sync", "domain", "server_setup",
"undomain")) and
self.objVar.Get('cl_merge_pkg_new')):
self.objVar.Set('cl_root_path',
self.objVar.Get('cl_root_path_next'), force=True)
self.recalculateBaseDir()
self.objVar.Set('cl_merge_pkg_pass', list(
set(self.objVar.Get('cl_merge_pkg_pass')) |
set(self.objVar.Get('cl_merge_pkg')) |
set(self.objVar.Get('cl_merge_pkg_new'))), force=True)
self.objVar.Set('cl_merge_pkg',
self.objVar.Get('cl_merge_pkg_new'), force=True)
self.objVar.Set('cl_merge_pkg_new', [], force=True)
createdDirs = self.createdDirs
filesApply = self.filesApply
self.changeMergePackage(self.objVar.Get('cl_merge_pkg'))
self.applyTemplates(rerun=False)
createdDirs.extend(self.createdDirs)
filesApply.extend(self.filesApply)
self.filesApply = filesApply
self.createdDirs = createdDirs
skip_pkglist = []
if self.objVar.Get('cl_ebuild_phase'):
new_pkglist = []
for pkgn in self.objVar.Get('cl_merge_pkg_new'):
if not pkgn:
continue
if self.lock_package(pkgn):
new_pkglist.append(pkgn)
else:
skip_pkglist.append(pkgn)
self.objVar.Set('cl_merge_pkg_new', new_pkglist, force=True)
else:
new_pkglist = self.objVar.Get('cl_merge_pkg_new')
if new_pkglist:
self.objVar.Set('cl_root_path',
self.objVar.Get('cl_root_path_next'), force=True)
self.recalculateBaseDir()
self.objVar.Set('cl_merge_pkg_pass', list(
set(self.objVar.Get('cl_merge_pkg_pass')) |
set(self.objVar.Get('cl_merge_pkg')) |
set(skip_pkglist) |
set(self.objVar.Get('cl_merge_pkg_new'))), force=True)
self.objVar.Set('cl_merge_pkg',
self.objVar.Get('cl_merge_pkg_new'), force=True)
self.objVar.Set('cl_merge_pkg_new', [], force=True)
createdDirs = self.createdDirs
filesApply = self.filesApply
self.changeMergePackage(self.objVar.Get('cl_merge_pkg'))
self.applyTemplates(rerun=False)
createdDirs.extend(self.createdDirs)
filesApply.extend(self.filesApply)
self.filesApply = filesApply
self.createdDirs = createdDirs
if rerun:
if self.cltObj:
self.queueExecute.extend(self.cltObj.queueExecute)
@ -4891,9 +4966,12 @@ gettext -d cl_template "$*"
mergePkgs = mergePkgs + postmergePkgs
for pkg in mergePkgs:
if not pkg in self.objVar.Get('cl_merge_pkg_new') and \
not pkg in self.objVar.Get('cl_merge_pkg_pass') and \
not pkg in self.objVar.Get('cl_merge_pkg'):
curlistset = set(self.objVar.Get('cl_merge_pkg_new') +
self.objVar.Get('cl_merge_pkg_pass') +
self.objVar.Get('cl_merge_pkg'))
if ":" not in pkg:
curlistset = {x.partition(":")[0] for x in curlistset}
if pkg not in curlistset:
self.objVar.Get('cl_merge_pkg_new').append(pkg)
def checkVfat(self, fn):

@ -1687,8 +1687,16 @@ def checkDigestFile(digestfile):
return result
def getRunCommands(not_chroot=False, chroot=None, uid=None, withpid=False):
def getRunCommands(not_chroot=False, chroot=None, uid=None, withpid=False,
with_lxc=False):
"""List run program"""
def get_mnt(pid):
try:
return os.readlink("/proc/%s/ns/mnt" %pid).strip()
except Exception:
return ""
main_mnt = get_mnt("1")
def getCmd(procNum):
cmdLineFile = '/proc/%s/cmdline' % procNum
@ -1698,6 +1706,9 @@ def getRunCommands(not_chroot=False, chroot=None, uid=None, withpid=False):
if fstat.st_uid != uid:
return ""
if path.exists(cmdLineFile):
if not with_lxc:
if get_mnt(procNum) != main_mnt:
return ""
if not_chroot:
root_link = '/proc/%s/root' % procNum
if os.readlink(root_link) != "/":
@ -1723,5 +1734,3 @@ def getRunCommands(not_chroot=False, chroot=None, uid=None, withpid=False):
map(getCmd,
filter(lambda x: x.isdigit(),
listDirectory('/proc'))))

@ -14,9 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from calculate.lib.utils.files import grepFile
from calculate.lib.utils.tools import cached
from calculate.lib.utils.files import grepFile, getRunCommands
from calculate.lib.utils.tools import cached, traverse
from os import path
import os
from collections import defaultdict
from fnmatch import fnmatch, filter as fnfilter
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
@ -105,3 +108,45 @@ class SystemType(object):
@classmethod
def detect(cls):
return cls.detect_container() or cls.detect_vm()
class FUser(object):
def __init__(self, ffilter=None):
self.ffilter = ffilter
self.ref = defaultdict(list)
self.refresh()
def get_mnt(self, pid):
try:
return os.readlink("/proc/%s/ns/mnt" %pid).strip()
except Exception:
return ""
def get_main_mnt(self):
return self.get_mnt("1")
def refresh(self):
self.ref=defaultdict(list)
main_mnt = self.get_main_mnt()
for p in os.listdir("/proc/"):
if not p.isdigit(): continue
if self.get_mnt(p) != main_mnt: continue
d = "/proc/%s/fd/" % p
try:
for fd in os.listdir(d):
f = os.readlink(d+fd)
self.ref[f].append(p)
except OSError:
pass
def search(self, item):
keys = fnfilter(self.ref.keys(), item)
return traverse(self.ref[k] for k in keys)
def __contains__(self, item):
return item in self.ref
def __getitem__(self, item):
return self.ref[item]
emerge_running = lambda: any(fnmatch(x, "*python-exec/*/emerge*")
for x in getRunCommands(True))

Loading…
Cancel
Save