[entropy.spm] Plugin interface refactoring, move Portage stuff away from Entropy Client Trigger interface

This commit is contained in:
Fabio Erculiani
2009-09-26 14:52:40 +02:00
parent 4224567074
commit 71b0f8dff8
6 changed files with 437 additions and 522 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ Proposed for Entropy 1.0 (before and after) (requires API changes, perhaps):
1.0_beta1:
- move sensible pkgs to alt dir
- entropy.client.interfaces.trigger, move Portage code to entropy.spm
- move etpConst['spm'] to entropy.spm
- entropy.db hookable plugins support (atom/dep validation, db taint,
pkg add, pkg rm)
- Transform Sulfur into Entropy Store:
@@ -352,7 +352,7 @@ class Package:
importance = 0,
header = red(" ## ")
)
return Spm.configure_installed_package(self.pkgmeta)
return Spm.execute_package_phase(self.pkgmeta, "configure")
def __remove_package(self):
@@ -2338,6 +2338,10 @@ class Package:
self.pkgmeta['key'], self.pkgmeta['slot'] = key, slot
self.pkgmeta['version'] = \
self.Entropy.clientDbconn.retrieveVersion(idpackage)
self.pkgmeta['category'] = \
self.Entropy.clientDbconn.retrieveCategory(idpackage)
self.pkgmeta['name'] = \
self.Entropy.clientDbconn.retrieveName(idpackage)
self.pkgmeta['accept_license'] = \
self.Entropy.clientDbconn.retrieveLicensedataKeys(idpackage)
self.pkgmeta['steps'] = []
+38 -401
View File
@@ -22,8 +22,14 @@ from entropy.i18n import _
class Trigger:
VALID_PHASES = ("preinstall", "postinstall", "preremove", "postremove",)
ENV_VARS_DIR = "/etc/env.d"
ENV_UPDATE_HOOK = "env-update"
ENV_VARS_DIR = etpConst['spm']['env_dir_reference']
ENV_UPDATE_HOOK = etpConst['spm']['env_update_cmd']
PHASES = {
'preinstall': "preinstall",
'postinstall': "postinstall",
'preremove': "preremove",
'postremove': "postremove",
}
import entropy.tools as entropyTools
def __init__(self, entropy_client, phase, pkgdata, package_action = None):
@@ -199,7 +205,8 @@ class Trigger:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[POST] ATTENTION Cannot run External trigger for "+mykey+"!! "+str(Exception)+": "+str(e)
"[POST] ATTENTION Cannot run External trigger for " + \
mykey + "!! " + str(Exception) + ": " + str(e)
)
mytxt = "%s: %s %s. %s." % (
bold(_("QA")),
@@ -425,410 +432,40 @@ class Trigger:
def trigger_spm_postinstall(self):
stdfile = open("/dev/null", "w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
myebuild = None
if os.path.isdir(self.pkgdata['xpakdir']) and \
os.access(self.pkgdata['xpakdir'], os.R_OK):
myebuild = [self.pkgdata['xpakdir']+"/"+x for x \
in os.listdir(self.pkgdata['xpakdir']) if \
x.endswith(etpConst['spm']['source_build_ext'])]
if myebuild:
myebuild = myebuild[0]
portage_atom = self.pkgdata['category'] + "/" + \
self.pkgdata['name'] + "-" + self.pkgdata['version']
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("post-install phase")),),
importance = 0,
header = red(" ## ")
)
try:
if not etpUi['debug']:
sys.stdout = stdfile
self.__ebuild_setup_phase(myebuild, portage_atom)
if not etpUi['debug']:
sys.stdout = oldstdout
rc = self.Spm.execute_package_phase(portage_atom, myebuild,
"postinstall",
work_dir = self.pkgdata['unpackdir'],
licenses_accepted = self.pkgdata['accept_license']
)
if rc == 1:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[POST] ATTENTION Cannot properly run Source Package Manager post-install (pkg_postinst()) trigger for " + \
str(portage_atom) + ". Something bad happened."
)
except Exception, e:
sys.stdout = oldstdout
self.entropyTools.print_traceback()
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[POST] ATTENTION Cannot run Source Package Manager trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e)
)
mytxt = "%s: %s %s. %s. %s: %s" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(portage_atom)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
)
self.Entropy.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
sys.stderr = oldstderr
sys.stdout = oldstdout
stdfile.close()
return 0
def __ebuild_setup_phase(self, ebuild, portage_atom):
rc = 0
env_file = os.path.join(self.pkgdata['unpackdir'], "portage",
portage_atom, "temp/environment")
if not os.path.isfile(env_file):
# FIXME: please remove as soon as upstream fixes it
# FIXME: workaround for buggy linux-info.eclass not being
# ported to EAPI=2 yet.
# It is required to make depmod running properly for the
# kernel modules inside this ebuild
# fix KV_OUT_DIR= inside environment
bz2envfile = os.path.join(self.pkgdata['xpakdir'],
"environment.bz2")
if "linux-info" in self.pkgdata['eclasses'] and \
os.path.isfile(bz2envfile) and self.pkgdata['versiontag']:
import bz2
envfile = self.Entropy.entropyTools.unpack_bzip2(bz2envfile)
bzf = bz2.BZ2File(bz2envfile,"w")
f = open(envfile,"r")
line = f.readline()
while line:
if line == "KV_OUT_DIR=/usr/src/linux\n":
line = "KV_OUT_DIR=/lib/modules/%s/build\n" % (
self.pkgdata['versiontag'],)
bzf.write(line)
line = f.readline()
f.close()
bzf.close()
os.remove(envfile)
rc = self.Spm.execute_package_phase(portage_atom, ebuild,
"setup",
work_dir = self.pkgdata['unpackdir'],
licenses_accepted = self.pkgdata['accept_license']
)
if rc == 1:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[POST] ATTENTION Cannot properly run Source Package Manager setup"
" phase for "+str(portage_atom)+". Something bad happened."
)
return rc
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("post-install phase")),),
importance = 0,
header = red(" ## ")
)
return self.Spm.execute_package_phase(self.pkgdata,
Trigger.PHASES['postinstall'])
def trigger_spm_preinstall(self):
stdfile = open("/dev/null", "w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
myebuild = None
if os.path.isdir(self.pkgdata['xpakdir']) and \
os.access(self.pkgdata['xpakdir'], os.R_OK):
myebuild = [self.pkgdata['xpakdir']+"/"+x for x in \
os.listdir(self.pkgdata['xpakdir']) if \
x.endswith(etpConst['spm']['source_build_ext'])]
if myebuild:
myebuild = myebuild[0]
portage_atom = self.pkgdata['category'] + "/" + \
self.pkgdata['name'] + "-" + self.pkgdata['version']
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("pre-install phase")),),
importance = 0,
header = red(" ## ")
)
try:
if not etpUi['debug']:
sys.stdout = stdfile
self.__ebuild_setup_phase(myebuild, portage_atom)
if not etpUi['debug']:
sys.stdout = oldstdout
rc = self.Spm.execute_package_phase(portage_atom, myebuild,
"preinstall",
work_dir = self.pkgdata['unpackdir'],
licenses_accepted = self.pkgdata['accept_license']
)
if rc == 1:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot properly run Source Package Manager pre-install (pkg_preinst()) trigger for " + \
str(portage_atom)+". Something bad happened."
)
except Exception, e:
sys.stdout = oldstdout
self.entropyTools.print_traceback()
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot run Source Package Manager preinst trigger for "+portage_atom+"!! "+str(Exception)+": "+str(e)
)
mytxt = "%s: %s %s. %s. %s: %s" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(portage_atom)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
)
self.Entropy.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
sys.stderr = oldstderr
sys.stdout = oldstdout
stdfile.close()
return 0
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("pre-install phase")),),
importance = 0,
header = red(" ## ")
)
return self.Spm.execute_package_phase(self.pkgdata,
Trigger.PHASES['preinstall'])
def trigger_spm_preremove(self):
stdfile = open("/dev/null", "w")
oldstderr = sys.stderr
sys.stderr = stdfile
portage_atom = self.pkgdata['category'] + "/" + self.pkgdata['name'] + \
"-" + self.pkgdata['version']
myebuild = self.Spm.get_installed_package_build_script_path(
portage_atom)
self.myebuild_moved = None
if os.path.isfile(myebuild):
try:
myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom)
except EOFError, e:
sys.stderr = oldstderr
stdfile.close()
# stuff on system is broken, ignore it
self.Entropy.updateProgress(
darkred("!!! Ebuild: pkg_prerm() failed, EOFError: ")+str(e)+darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
except ImportError, e:
sys.stderr = oldstderr
stdfile.close()
# stuff on system is broken, ignore it
self.Entropy.updateProgress(
darkred("!!! Ebuild: pkg_prerm() failed, ImportError: ")+str(e)+darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
if os.path.isfile(myebuild):
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("pre-remove phase")),),
importance = 0,
header = red(" ## ")
)
try:
rc = self.Spm.execute_package_phase(portage_atom, myebuild,
"preremove",
work_dir = etpConst['entropyunpackdir']+"/"+portage_atom,
licenses_accepted = self.pkgdata['accept_license']
)
if rc == 1:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot properly run Source Package Manager trigger for " + \
str(portage_atom)+". Something bad happened."
)
except Exception, e:
sys.stderr = oldstderr
stdfile.close()
self.entropyTools.print_traceback()
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot run Source Package Manager " + \
"pre-remove trigger for " + portage_atom + "!! " + \
str(Exception)+": "+str(e)
)
mytxt = "%s: %s %s. %s. %s: %s" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(portage_atom)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
)
self.Entropy.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
return 0
sys.stderr = oldstderr
stdfile.close()
self._remove_overlayed_ebuild()
return 0
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("pre-remove phase")),),
importance = 0,
header = red(" ## ")
)
return self.Spm.execute_package_phase(self.pkgdata,
Trigger.PHASES['preremove'])
def trigger_spm_postremove(self):
stdfile = open("/dev/null", "w")
oldstderr = sys.stderr
sys.stderr = stdfile
portage_atom = self.pkgdata['category'] + "/" + self.pkgdata['name'] + \
"-" + self.pkgdata['version']
myebuild = self.Spm.get_installed_package_build_script_path(
portage_atom)
self.myebuild_moved = None
if os.path.isfile(myebuild):
try:
myebuild = self._setup_remove_ebuild_environment(myebuild, portage_atom)
except EOFError, e:
sys.stderr = oldstderr
stdfile.close()
# stuff on system is broken, ignore it
self.Entropy.updateProgress(
darkred("!!! Ebuild: pkg_postrm() failed, EOFError: ")+str(e)+darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
except ImportError, e:
sys.stderr = oldstderr
stdfile.close()
# stuff on system is broken, ignore it
self.Entropy.updateProgress(
darkred("!!! Ebuild: pkg_postrm() failed, ImportError: ")+str(e)+darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
if os.path.isfile(myebuild):
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("post-remove phase")),),
importance = 0,
header = red(" ## ")
)
try:
rc = self.Spm.execute_package_phase(portage_atom, myebuild,
"postremove",
work_dir = etpConst['entropyunpackdir']+"/"+portage_atom,
licenses_accepted = self.pkgdata['accept_license']
)
if rc == 1:
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot properly run Source Package Manager postremove trigger for " + \
str(portage_atom)+". Something bad happened."
)
except Exception, e:
sys.stderr = oldstderr
stdfile.close()
self.entropyTools.print_traceback()
self.Entropy.clientLog.log(
ETP_LOGPRI_INFO,
ETP_LOGLEVEL_NORMAL,
"[PRE] ATTENTION Cannot run Source Package Manager postremove trigger for " + \
portage_atom+"!! "+str(Exception)+": "+str(e)
)
mytxt = "%s: %s %s. %s. %s: %s" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(portage_atom)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
)
self.Entropy.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
return 0
sys.stderr = oldstderr
stdfile.close()
self._remove_overlayed_ebuild()
return 0
def _setup_remove_ebuild_environment(self, myebuild, portage_atom):
ebuild_dir = os.path.dirname(myebuild)
ebuild_file = os.path.basename(myebuild)
# copy the whole directory in a safe place
dest_dir = os.path.join(etpConst['entropyunpackdir'],"vardb/"+portage_atom)
if os.path.exists(dest_dir):
if os.path.isdir(dest_dir):
shutil.rmtree(dest_dir,True)
elif os.path.isfile(dest_dir) or os.path.islink(dest_dir):
os.remove(dest_dir)
os.makedirs(dest_dir)
items = os.listdir(ebuild_dir)
for item in items:
myfrom = os.path.join(ebuild_dir,item)
myto = os.path.join(dest_dir,item)
shutil.copy2(myfrom,myto)
newmyebuild = os.path.join(dest_dir,ebuild_file)
if os.path.isfile(newmyebuild):
myebuild = newmyebuild
self.myebuild_moved = myebuild
self.Spm._ebuild_env_setup_hook(myebuild)
return myebuild
def _remove_overlayed_ebuild(self):
if not self.myebuild_moved:
return
if not os.path.isfile(self.myebuild_moved):
return
mydir = os.path.dirname(self.myebuild_moved)
shutil.rmtree(mydir, True)
mydir = os.path.dirname(mydir)
content = os.listdir(mydir)
while not content:
os.rmdir(mydir)
mydir = os.path.dirname(mydir)
content = os.listdir(mydir)
self.Entropy.updateProgress(
"SPM: %s" % (brown(_("post-remove phase")),),
importance = 0,
header = red(" ## ")
)
return self.Spm.execute_package_phase(self.pkgdata,
Trigger.PHASES['postremove'])
+3 -3
View File
@@ -526,9 +526,9 @@ def const_default_settings(rootdir):
'global_make_profile_link_name' : "profile.link",
# source package manager executable
'exec': rootdir+"/usr/bin/emerge",
'env_update_cmd': rootdir+"/usr/sbin/env-update",
'source_profile': ["source", rootdir+"/etc/profile"],
'source_build_ext': ".ebuild",
'env_dir_reference': "/etc/env.d",
'env_update_cmd': "/usr/sbin/env-update",
'source_profile': ["source", "/etc/profile"],
'ask_cmd': "--ask",
'info_cmd': "--info",
'remove_cmd': "-C",
@@ -11,10 +11,10 @@
"""
from __future__ import with_statement
import os
import bz2
import sys
import shutil
import tempfile
import bz2
from entropy.const import etpConst, etpUi
from entropy.exceptions import FileNotFound, SPMError, InvalidDependString, \
InvalidData
@@ -139,6 +139,7 @@ class PortagePlugin(SpmPlugin):
}
ENV_FILE_COMP = "environment.bz2"
EBUILD_EXT = ".ebuild"
class paren_normalize(list):
"""Take a dependency structure as returned by paren_reduce or use_reduce
@@ -289,7 +290,7 @@ class PortagePlugin(SpmPlugin):
Reimplemented from SpmPlugin class.
"""
return os.path.join(self._get_vdb_path(root = root), package,
package.split("/")[-1] + etpConst['spm']['source_build_ext'])
package.split("/")[-1] + PortagePlugin.EBUILD_EXT)
def get_installed_package_metadata(self, package, key, root = None):
"""
@@ -1222,6 +1223,7 @@ class PortagePlugin(SpmPlugin):
def _portage_doebuild(self, myebuild, mydo, tree, cpv,
portage_tmpdir = None, licenses = None):
# myebuild = path/to/ebuild.ebuild with a valid unpacked xpak metadata
# tree = "bintree"
# cpv = atom
@@ -1381,26 +1383,396 @@ class PortagePlugin(SpmPlugin):
del keys
return rc
def execute_package_phase(self, package, build_script_path, phase_name,
work_dir = None, licenses_accepted = None):
@staticmethod
def _pkg_compose_atom(package_metadata):
return package_metadata['category'] + "/" + \
package_metadata['name'] + "-" + package_metadata['version']
@staticmethod
def _pkg_compose_xpak_ebuild(package_metadata):
package = PortagePlugin._pkg_compose_atom(package_metadata)
return os.path.join(package_metadata['xpakdir'],
os.path.basename(package) + PortagePlugin.EBUILD_EXT)
def _pkg_remove_overlayed_ebuild(self, moved_ebuild):
mydir = os.path.dirname(moved_ebuild)
shutil.rmtree(mydir, True)
mydir = os.path.dirname(mydir)
content = os.listdir(mydir)
while not content:
os.rmdir(mydir)
mydir = os.path.dirname(mydir)
content = os.listdir(mydir)
def _pkg_remove_ebuild_env_setup_hook(self, ebuild):
ebuild_path = os.path.dirname(ebuild)
myroot = os.path.sep
if etpConst['systemroot']:
myroot = etpConst['systemroot'] + os.path.sep
# we need to fix ROOT= if it's set inside environment
bz2envfile = os.path.join(ebuild_path, PortagePlugin.ENV_FILE_COMP)
if os.path.isfile(bz2envfile) and os.path.isdir(myroot):
envfile = entropy.tools.unpack_bzip2(bz2envfile)
bzf = bz2.BZ2File(bz2envfile, "w")
f = open(envfile, "r")
line = f.readline()
while line:
if line.startswith("ROOT="):
line = "ROOT=%s\n" % (myroot,)
bzf.write(line)
line = f.readline()
f.close()
bzf.close()
os.remove(envfile)
def _pkg_remove_setup_ebuild_env(self, myebuild, portage_atom):
ebuild_dir = os.path.dirname(myebuild)
ebuild_file = os.path.basename(myebuild)
moved_ebuild = None
# copy the whole directory in a safe place
dest_dir = os.path.join(etpConst['entropyunpackdir'],
"vardb/" + portage_atom)
if os.path.exists(dest_dir):
if os.path.isdir(dest_dir):
shutil.rmtree(dest_dir, True)
elif os.path.isfile(dest_dir) or os.path.islink(dest_dir):
os.remove(dest_dir)
os.makedirs(dest_dir)
items = os.listdir(ebuild_dir)
for item in items:
myfrom = os.path.join(ebuild_dir, item)
myto = os.path.join(dest_dir, item)
shutil.copy2(myfrom, myto)
newmyebuild = os.path.join(dest_dir, ebuild_file)
if os.path.isfile(newmyebuild):
myebuild = newmyebuild
moved_ebuild = myebuild
self._pkg_remove_ebuild_env_setup_hook(myebuild)
return myebuild, moved_ebuild
def _pkg_setup(self, package_metadata, skip_if_found = False):
package = PortagePlugin._pkg_compose_atom(package_metadata)
env_file = os.path.join(package_metadata['unpackdir'], "portage",
package, "temp/environment")
if os.path.isfile(env_file) and skip_if_found:
return 0
# FIXME: please remove as soon as upstream fixes it
# FIXME: workaround for buggy linux-info.eclass not being
# ported to EAPI=2 yet.
# It is required to make depmod running properly for the
# kernel modules inside this ebuild
# fix KV_OUT_DIR= inside environment
bz2envfile = os.path.join(package_metadata['xpakdir'],
PortagePlugin.ENV_FILE_COMP)
if "linux-info" in package_metadata['eclasses'] and \
os.path.isfile(bz2envfile) and package_metadata['versiontag']:
envfile = entropy.tools.unpack_bzip2(bz2envfile)
bzf = bz2.BZ2File(bz2envfile,"w")
f = open(envfile,"r")
line = f.readline()
while line:
if line == "KV_OUT_DIR=/usr/src/linux\n":
line = "KV_OUT_DIR=/lib/modules/%s/build\n" % (
package_metadata['versiontag'],)
bzf.write(line)
line = f.readline()
f.close()
bzf.close()
os.remove(envfile)
ebuild = PortagePlugin._pkg_compose_xpak_ebuild(package_metadata)
rc = self._portage_doebuild(ebuild, "setup",
"bintree", package, portage_tmpdir = package_metadata['unpackdir'],
licenses = package_metadata.get('accept_license'))
if rc == 1:
self.log_message(
"[POST] ATTENTION Cannot properly run Source Package Manager"
" setup phase for %s Something bad happened." % (package,)
)
return rc
def _pkg_fooinst(self, package_metadata, phase):
tmp_file = tempfile.mktemp()
stdfile = open(tmp_file, "w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
package = PortagePlugin._pkg_compose_atom(package_metadata)
ebuild = PortagePlugin._pkg_compose_xpak_ebuild(package_metadata)
rc = 0
remove_tmp = True
try:
# is ebuild available
if not (os.path.isfile(ebuild) and os.access(ebuild, os.R_OK)):
return rc
try:
if not etpUi['debug']:
sys.stdout = stdfile
self._pkg_setup(package_metadata, skip_if_found = True)
if not etpUi['debug']:
sys.stdout = oldstdout
rc = self._portage_doebuild(ebuild, phase, "bintree",
package, portage_tmpdir = package_metadata['unpackdir'],
licenses = package_metadata.get('accept_license'))
if rc != 0:
self.log_message(
"[PRE] ATTENTION Cannot properly run SPM %s"
" phase for %s. Something bad happened." % (
phase, package,)
)
except Exception, e:
stdfile.flush()
sys.stdout = oldstdout
entropy.tools.print_traceback()
self.log_message(
"[PRE] ATTENTION Cannot properly run SPM %s"
" phase for %s. Something bad happened."
" Exception %s [%s]" % (
phase, package, Exception, e,)
)
mytxt = "%s: %s %s. %s. %s: %s + %s [%s]" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(package)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
darkred(tmp_file),
brown(phase),
)
self.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
remove_tmp = False
return rc
finally:
sys.stderr = oldstderr
sys.stdout = oldstdout
stdfile.flush()
stdfile.close()
if (rc == 0) and remove_tmp:
try:
os.remove(tmp_file)
except OSError:
pass
def _pkg_foorm(self, package_metadata, phase):
tmp_file = tempfile.mktemp()
stdfile = open(tmp_file, "w")
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stderr = stdfile
rc = 0
remove_tmp = True
moved_ebuild = None
package = PortagePlugin._pkg_compose_atom(package_metadata)
ebuild = self.get_installed_package_build_script_path(package)
try:
if not os.path.isfile(ebuild):
return 0
try:
ebuild, moved_ebuild = self._pkg_remove_setup_ebuild_env(
ebuild, package)
except EOFError, e:
sys.stderr = oldstderr
# stuff on system is broken, ignore it
self.updateProgress(
darkred("!!! Ebuild: pkg_" + phase + "() failed, EOFError: ") + \
str(e) + darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
except ImportError, e:
sys.stderr = oldstderr
# stuff on system is broken, ignore it
self.updateProgress(
darkred("!!! Ebuild: pkg_" + phase + "() failed, ImportError: ") + \
str(e) + darkred(" - ignoring"),
importance = 1,
type = "warning",
header = red(" ## ")
)
return 0
try:
work_dir = os.path.join(etpConst['entropyunpackdir'], package)
rc = self._portage_doebuild(ebuild, phase, "bintree",
package, portage_tmpdir = work_dir,
licenses = package_metadata.get('accept_license'))
if rc != 1:
self.log_message(
"[PRE] ATTENTION Cannot properly run SPM %s trigger "
"for %s. Something bad happened." % (phase, package,)
)
except Exception, e:
stdfile.flush()
sys.stdout = oldstdout
entropy.tools.print_traceback()
self.log_message(
"[PRE] ATTENTION Cannot properly run SPM %s"
" phase for %s. Something bad happened."
" Exception %s [%s]" % (phase, package, Exception, e,)
)
mytxt = "%s: %s %s. %s. %s: %s + %s [%s]" % (
bold(_("QA")),
brown(_("Cannot run Source Package Manager trigger for")),
bold(str(package)),
brown(_("Please report it")),
bold(_("Attach this")),
darkred(etpConst['spmlogfile']),
darkred(tmp_file),
brown(phase),
)
self.updateProgress(
mytxt,
importance = 0,
header = red(" ## ")
)
remove_tmp = False
if moved_ebuild is not None:
if os.path.isfile(moved_ebuild):
self._pkg_remove_overlayed_ebuild(moved_ebuild)
return rc
finally:
sys.stderr = oldstderr
sys.stdout = oldstdout
stdfile.flush()
stdfile.close()
if (rc == 0) and remove_tmp:
try:
os.remove(tmp_file)
except OSError:
pass
def _pkg_preinst(self, package_metadata):
return self._pkg_fooinst(package_metadata, "preinst")
def _pkg_postinst(self, package_metadata):
return self._pkg_fooinst(package_metadata, "postinst")
def _pkg_prerm(self, package_metadata):
return self._pkg_foorm(package_metadata, "prerm")
def _pkg_postrm(self, package_metadata):
return self._pkg_foorm(package_metadata, "postrm")
def _pkg_config(self, package_metadata):
package = PortagePlugin._pkg_compose_atom(package_metadata)
ebuild = self.get_installed_package_build_script_path(package)
if not os.path.isfile(ebuild):
return 2
try:
rc = self._portage_doebuild(ebuild, "config", "bintree",
package, licenses = package_metadata.get('accept_license'))
if rc != 0:
return 3
except Exception, err:
entropy.tools.print_traceback()
mytxt = "%s: %s %s." % (
bold(_("QA")),
brown(_("Cannot run SPM configure phase for")),
bold(str(package)),
)
mytxt2 = "%s: %s, %s" % (
bold(_("Error")),
type(Exception),
err,
)
for txt in (mytxt, mytxt2,):
self.updateProgress(
txt,
importance = 0,
header = red(" ## ")
)
return 1
return 0
def execute_package_phase(self, package_metadata, phase_name):
"""
Reimplemented from SpmPlugin class.
"""
if licenses_accepted is None:
licenses_accepted = []
portage_phase = PortagePlugin.package_phases_map[phase_name]
return self._portage_doebuild(build_script_path, portage_phase,
"bintree", package, work_dir, licenses_accepted)
phase_calls = {
'setup': self._pkg_setup,
'preinst': self._pkg_preinst,
'postinst': self._pkg_postinst,
'prerm': self._pkg_prerm,
'postrm': self._pkg_postrm,
'config': self._pkg_config,
}
return phase_calls[portage_phase](package_metadata)
def add_installed_package(self, package_metadata):
"""
Reimplemented from SpmPlugin class.
"""
atomsfound = set()
category = package_metadata['category']
key = category + "/" + package_metadata['name']
spm_package = key + "-" + package_metadata['version']
spm_package = PortagePlugin._pkg_compose_atom(package_metadata)
key = entropy.tools.dep_getkey(spm_package)
category = key.split("/")[0]
build = self.get_installed_package_build_script_path(spm_package)
pkg_dir = os.path.dirname(build)
@@ -1615,48 +1987,6 @@ class PortagePlugin(SpmPlugin):
return 0
def configure_installed_package(self, package_metadata):
"""
Reimplemented from SpmPlugin class.
"""
atom = package_metadata['key'] + "-" + package_metadata['version']
myebuild = self.get_installed_package_build_script_path(atom)
if not (os.access(myebuild, os.R_OK) and os.path.isfile(myebuild)):
# cannot find ebuild ! ouch!
return 2
try:
rc = self.execute_package_phase(atom, myebuild,
"configure",
licenses_accepted = package_metadata['accept_license']
)
if rc == 1:
return 3
except Exception, err:
entropy.tools.print_traceback()
mytxt = "%s: %s %s." % (
bold(_("QA")),
brown(_("Cannot run SPM configure phase for")),
bold(str(atom)),
)
mytxt2 = "%s: %s, %s" % (
bold(_("Error")),
type(Exception),
err,
)
for txt in (mytxt, mytxt2,):
self.updateProgress(
txt,
importance = 0,
header = red(" ## ")
)
return 1
return 0
@staticmethod
def entropy_install_setup_hook(entropy_client, package_metadata):
"""
@@ -1686,9 +2016,8 @@ class PortagePlugin(SpmPlugin):
portdbdir = 'var/db/pkg'
portdbdir = os.path.join(package_metadata['merge_from'], portdbdir)
portdbdir = os.path.join(portdbdir, package_metadata['category'])
portdbdir = os.path.join(portdbdir, package_metadata['name'] + \
"-" + package_metadata['version'])
portdbdir = os.path.join(portdbdir,
PortagePlugin._pkg_compose_atom(package_metadata))
package_metadata['xpakdir'] = portdbdir
@@ -1753,8 +2082,7 @@ class PortagePlugin(SpmPlugin):
os.symlink(package_metadata['xpakdir'], tolink_dir)
# create fake portage ${D} linking it to imagedir
portage_cpv = package_metadata['category'] + "/" + \
package_metadata['name'] + "-" + package_metadata['version']
portage_cpv = PortagePlugin._pkg_compose_atom(package_metadata)
portage_db_fakedir = os.path.join(
package_metadata['unpackdir'],
@@ -1768,31 +2096,6 @@ class PortagePlugin(SpmPlugin):
return 0
def _ebuild_env_setup_hook(self, ebuild):
ebuild_path = os.path.dirname(ebuild)
myroot = os.path.sep
if etpConst['systemroot']:
myroot = etpConst['systemroot'] + os.path.sep
# we need to fix ROOT= if it's set inside environment
bz2envfile = os.path.join(ebuild_path, PortagePlugin.ENV_FILE_COMP)
if os.path.isfile(bz2envfile) and os.path.isdir(myroot):
envfile = entropy.tools.unpack_bzip2(bz2envfile)
bzf = bz2.BZ2File(bz2envfile, "w")
f = open(envfile, "r")
line = f.readline()
while line:
if line.startswith("ROOT="):
line = "ROOT=%s\n" % (myroot,)
bzf.write(line)
line = f.readline()
f.close()
bzf.close()
os.remove(envfile)
def _get_portage_vartree(self, root = None):
if root is None:
+3 -32
View File
@@ -514,26 +514,16 @@ class SpmPlugin(Singleton):
"""
raise NotImplementedError()
def execute_package_phase(self, package, build_script_path, phase_name,
work_dir = None, licenses_accepted = None):
def execute_package_phase(self, package_metadata, phase_name):
"""
Execute Source Package Manager package phase (postinstall, preinstall,
preremove, postremove, etc).
@param package: package name
@type package: string
@param build_script_path: path to Source Package Manager build script
to call
@type build_script_path: string
@param package_metadata: Entropy package phase metadata
@type package_metadata: dict
@param phase_name: name of the phase to call, must be a valid phase
contained in package_phases() output.
@type phase_name: string
@keyword work_dir: specify a work directory if required by your SPM
@type work_dir: string
@keyword licenses_accepted: list of license names already accepted
that can be given to Source Package Manager (to skip its license
acceptance verification stuff, for example)
@type licenses_accepted: list
@return: phase script exit status
@rtype: int
@raise KeyError: if phase is not available
@@ -575,25 +565,6 @@ class SpmPlugin(Singleton):
"""
raise NotImplementedError()
def configure_installed_package(self, package_metadata):
"""
Configure installed package. Some SPM require users to do manual
stuff on packages.
"package_metadata" is a dictionary featuring the following (relevant)
keys:
['accept_license', 'imagedir', 'xpakpath', 'slot', 'pkgdbpath',
'versiontag', 'version', 'xpakstatus', 'unpackdir', 'revision',
'category', 'repository', 'xpakdir', 'name', 'install_source',
'removeatom'
]
@param package_metadata: Entropy package metadata
@type package_metadata: dict
@return: execution status
@rtype: int
"""
raise NotImplementedError()
@staticmethod
def entropy_install_setup_hook(entropy_client, package_metadata):
"""