Merge remote-tracking branch 'origin/master' into master3.1.6

master3.3
Mike Hiretsky 11 years ago
commit 3498b914b7

@ -18,6 +18,7 @@ import sys
import os
import stat
import re
import errno
import xml.dom.minidom as minidom
import xml
import importlib
@ -36,18 +37,20 @@ from itertools import *
# < <= == != >= >
from operator import lt, le, eq, ne, ge, gt
from utils.common import _error, _warning
from utils.common import _error, _warning,getTupleVersion,getPortageUidGid
from utils.text import _toUNICODE, convertStrListDict
from utils.portage import isPkgInstalled,reVerSplitToPV
from utils.content import PkgContents,checkContents,getCfgFiles,fillContents
from utils.files import (getModeFile, listDirectory,removeDir, typeFile,
scanDirectory,
scanDirectory,timeout,
pathJoin,readFile,readLinesFile,process,STDOUT)
from datavars import DataVarsError
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_lib3',sys.modules[__name__])
PORTAGEUID,PORTAGEGID = getPortageUidGid()
class TemplatesInterrupt(Exception):
"""
Interrupt templates appling
@ -2224,7 +2227,8 @@ class _file(_error):
return F_CONF
def openFiles(self, nameFileTemplate, nameFileConfig, typeFormat=None):
def openFiles(self, nameFileTemplate, nameFileConfig, typeFormat=None,
newBuffer=None):
"""Открывает шаблон и конфигурационный файл"""
self.textConfig = ""
self.textTemplate = ""
@ -2241,7 +2245,10 @@ class _file(_error):
if self.configMode == T_NEWCFG:
origConfigName = re.sub(r'/._cfg\d{4}_([^/]+)$','/\\1',
self.nameFileConfig)
self.textConfig = readFile(origConfigName)
if newBuffer is None:
self.textConfig = readFile(origConfigName)
else:
self.textConfig = newBuffer
else:
self.textConfig = self.F_CONF.read()
@ -2845,7 +2852,7 @@ class templateFunction(_error, _warning, _shareTemplate, _shareTermsFunction):
if len(versions) == 1:
return versions.values()[0]
else:
return versions[max(versions.keys())]
return versions[max(versions.keys(),key=getTupleVersion)]
else:
return ""
@ -3766,7 +3773,8 @@ class templateFunction(_error, _warning, _shareTemplate, _shareTermsFunction):
# Меняем владельца в случае необходимости
if os.path.exists(self.fileConfigIni):
uid, gid = getModeFile(self.fileConfigIni, "owner")
if self.uid!=uid or self.gid!=gid:
if not self.uid in (uid,PORTAGEUID) or \
not self.gid in (gid,PORTAGEGID):
os.chown(self.fileConfigIni, self.uid, self.gid)
return textTemplateTmp
@ -5203,6 +5211,8 @@ gettext -d cl_template "$*"
if self.objVar.Get('cl_protect_use_set') == 'on':
pathOldFile = self.fixNameFileConfig(pathOldFile)
pathOldFile = self.checkOnNewConfigName(pathOldFile)
# буффер для использование в link=
newBuffer = None
applyFiles = [pathOldFile]
# Фильтрация шаблонов по названию файла
realPath = os.path.join("/",pathOldFile.partition(self._baseDir)[2])
@ -5233,6 +5243,7 @@ gettext -d cl_template "$*"
if typeAppendTemplate == "clear":
try:
open(pathOldFile, "w").truncate(0)
newBuffer = ""
except:
self.setError(_("Template error") + ": " +\
nameFileTemplate)
@ -5279,6 +5290,7 @@ gettext -d cl_template "$*"
if os.path.islink(pathOldFile):
# удаляем ссылку
try:
newBuffer = ""
os.unlink(pathOldFile)
except:
self.setError(_("Template error") + ": " +\
@ -5289,6 +5301,7 @@ gettext -d cl_template "$*"
if os.path.isfile(pathOldFile):
# удаляем файл
try:
newBuffer = ""
os.remove(pathOldFile)
except:
self.setError(_("Template error") + ": " +\
@ -5307,6 +5320,7 @@ gettext -d cl_template "$*"
if not os.path.exists(templateFile):
if os.path.exists(pathOldFile):
try:
newBuffer = ""
os.remove(pathOldFile)
except:
self.setError(_("Template error") + ": " +\
@ -5336,6 +5350,7 @@ gettext -d cl_template "$*"
return ([], False)
if os.path.exists(pathOldFile):
try:
newBuffer = ""
os.remove(pathOldFile)
except:
self.setError(_("Template error") + ": " +\
@ -5346,6 +5361,7 @@ gettext -d cl_template "$*"
if foundTemplateFile:
try:
FD = open(pathOldFile, "w+")
newBuffer = buff
FD.write(buff)
FD.close()
except:
@ -5448,7 +5464,8 @@ gettext -d cl_template "$*"
preReturn(pathProg)
return ([], False)
if not flagSymlink:
self.openFiles(nameFileTemplate, pathOldFile,objHeadNew.fileType)
self.openFiles(nameFileTemplate, pathOldFile,objHeadNew.fileType,
newBuffer)
if self.getError():
return ([], False)
if not objHeadNew.params.has_key("chown"):
@ -5505,7 +5522,7 @@ gettext -d cl_template "$*"
not objHeadNew.params.has_key("symbolic") and\
objHeadNew.params.has_key("link"):
preReturn(pathProg)
return ([], False)
return (applyFiles, False)
if not pathOldFile in self.dictProcessedTemplates:
self.dictProcessedTemplates[pathOldFile] = []
self.dictProcessedTemplates[pathOldFile].append(nameFileTemplate)
@ -6182,13 +6199,28 @@ class iniParser(_error, templateFormat):
"""установка прав создаваемого ini-файла"""
self.mode = mode
def lockfile(self,fd,fn,timeout=5):
"""
Блокировка файла с таймаутом
"""
for i in range(0,timeout):
try:
fcntl.flock(fd, fcntl.LOCK_EX)
return True
except IOError,e:
if e.errno != errno.EAGAIN:
raise e
time.sleep(1)
else:
raise TemplatesError(_("Timeout lock %s")%fn)
def openIniFile(self):
if not self.text is None:
return self.text
if not os.access(self.iniFile, os.R_OK):
return ""
self.FD = open(self.iniFile, "r")
fcntl.flock(self.FD.fileno(), fcntl.LOCK_EX)
self.lockfile(self.FD.fileno(),self.iniFile)
textIni = self.FD.read()
return textIni
@ -6200,7 +6232,7 @@ class iniParser(_error, templateFormat):
except (IOError,OSError),e:
self.FD = open(self.iniFile, "r")
self.readOnly = True
fcntl.flock(self.FD.fileno(), fcntl.LOCK_EX)
self.lockfile(self.FD.fileno(), self.iniFile)
textIni = self.FD.read()
return textIni
@ -6213,7 +6245,7 @@ class iniParser(_error, templateFormat):
try:
# Создание файла
self.FD = open(self.iniFile, "w+")
fcntl.flock(self.FD.fileno(), fcntl.LOCK_EX)
self.lockfile(self.FD.fileno(), self.iniFile)
os.chmod(self.iniFile, self.mode)
except:
self.setError(_("Failed to create the file") +

@ -24,6 +24,8 @@ import sys
import getpass
from types import StringType
import string
import pwd
import grp
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_lib3',sys.modules[__name__])
@ -492,3 +494,13 @@ def isBootstrapDataOnly(directory):
userCalculate = path.join(directory,".calculate")
return (set(listDirectory(directory)) == set([".calculate"]) and
set(listDirectory(userCalculate)) == set(["client_cert"]))
def getPortageUidGid():
"""
Получить uid и gid пользователя portage
"""
data = pwd.getpwnam('portage')
if data:
return data.pw_uid,data.pw_gid
else:
return 250,250

@ -26,6 +26,23 @@ import sys
from itertools import *
import tarfile
from contextlib import contextmanager
import signal
@contextmanager
def timeout(seconds):
def timeout_handler(signum,frame):
pass
original_handler = signal.signal(signal.SIGALRM, timeout_handler)
try:
signal.alarm(seconds)
yield
finally:
signal.alarm(0)
signal.signal(signal.SIGALRM, original_handler)
try:
from magic import open as type_file, MAGIC_NONE as MAGIC_NONE
except ImportError:

Loading…
Cancel
Save