[entropy] goodbye etpConst['spm'], implement new SpmPlugin methods, bump SpmPlugin API
This commit is contained in:
@@ -453,7 +453,7 @@ class ClientSystemSettingsPlugin(SystemSettingsPlugin):
|
||||
'filesbackup': etpConst['filesbackup'],
|
||||
'forcedupdates': etpConst['forcedupdates'],
|
||||
'packagehashes': etpConst['packagehashes'],
|
||||
'ignore_spm_downgrades': etpConst['spm']['ignore-spm-downgrades'],
|
||||
'ignore_spm_downgrades': False,
|
||||
'collisionprotect': etpConst['collisionprotect'],
|
||||
'configprotect': etpConst['configprotect'][:],
|
||||
'configprotectmask': etpConst['configprotectmask'][:],
|
||||
|
||||
@@ -24,7 +24,7 @@ class CalculatorsMixin:
|
||||
# get all the installed packages
|
||||
installed_packages = dbconn.listAllIdpackages()
|
||||
|
||||
pdepend_id = etpConst['spm']['pdepend_id']
|
||||
pdepend_id = etpConst['dependency_type_ids']['pdepend_id']
|
||||
deps_not_matched = set()
|
||||
# now look
|
||||
length = len(installed_packages)
|
||||
@@ -1553,7 +1553,7 @@ class CalculatorsMixin:
|
||||
monotree = set(idpackages) # monodimensional tree
|
||||
|
||||
# post-dependencies won't be pulled in
|
||||
pdepend_id = etpConst['spm']['pdepend_id']
|
||||
pdepend_id = etpConst['dependency_type_ids']['pdepend_id']
|
||||
# check if dependstable is sane before beginning
|
||||
self.clientDbconn.retrieveReverseDependencies(idpackages[0])
|
||||
count = 0
|
||||
|
||||
@@ -1146,18 +1146,19 @@ class Repository:
|
||||
self.Entropy.update_repository_revision(repo)
|
||||
if self.Entropy.indexing:
|
||||
self.do_database_indexing(repo)
|
||||
def_repoid = my_repos['default_repository']
|
||||
if repo == def_repoid:
|
||||
try:
|
||||
self.run_config_files_updates(repo)
|
||||
except Exception as e:
|
||||
entropy.tools.print_traceback()
|
||||
mytxt = "%s: %s" % (
|
||||
blue(_("Configuration files update error, not critical, continuing")),
|
||||
darkred(repr(e)),
|
||||
)
|
||||
self.Entropy.updateProgress(mytxt, importance = 0,
|
||||
type = "info", header = blue(" # "),)
|
||||
|
||||
try:
|
||||
spm_class = self.Entropy.Spm_class()
|
||||
spm_class.entropy_post_repository_update_hook(self.Entropy,
|
||||
repo)
|
||||
except Exception as e:
|
||||
entropy.tools.print_traceback()
|
||||
mytxt = "%s: %s" % (
|
||||
blue(_("Configuration files update error, not critical, continuing")),
|
||||
darkred(repr(e)),
|
||||
)
|
||||
self.Entropy.updateProgress(mytxt, importance = 0,
|
||||
type = "info", header = blue(" # "),)
|
||||
|
||||
# execute post update repo hook
|
||||
self._run_post_update_repository_hook(repo)
|
||||
@@ -1207,197 +1208,6 @@ class Repository:
|
||||
|
||||
return 0
|
||||
|
||||
def run_config_files_updates(self, repo):
|
||||
|
||||
# are we root?
|
||||
if etpConst['uid'] != 0:
|
||||
self.Entropy.updateProgress(
|
||||
brown(_("Skipping configuration files update, you are not root.")),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
return
|
||||
|
||||
# make.conf
|
||||
self._config_updates_make_conf(repo)
|
||||
self._config_updates_make_profile(repo)
|
||||
|
||||
|
||||
def _config_updates_make_conf(self, repo):
|
||||
|
||||
## WARNING: it doesn't handle multi-line variables, yet. remember this.
|
||||
system_make_conf = etpConst['spm']['global_make_conf']
|
||||
|
||||
avail_data = self.Entropy.SystemSettings['repositories']['available']
|
||||
repo_dbpath = avail_data[repo]['dbpath']
|
||||
repo_make_conf = os.path.join(repo_dbpath,
|
||||
os.path.basename(system_make_conf))
|
||||
|
||||
if not (os.path.isfile(repo_make_conf) and \
|
||||
os.access(repo_make_conf, os.R_OK)):
|
||||
return
|
||||
|
||||
make_conf_variables_check = ["CHOST"]
|
||||
|
||||
if not os.path.isfile(system_make_conf):
|
||||
self.Entropy.updateProgress(
|
||||
"%s %s. %s." % (
|
||||
red(system_make_conf),
|
||||
blue(_("does not exist")), blue(_("Overwriting")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
if os.path.lexists(system_make_conf):
|
||||
shutil.move(
|
||||
system_make_conf,
|
||||
"%s.backup_%s" % (system_make_conf,
|
||||
entropy.tools.get_random_number(),)
|
||||
)
|
||||
shutil.copy2(repo_make_conf, system_make_conf)
|
||||
|
||||
elif os.access(system_make_conf, os.W_OK):
|
||||
|
||||
repo_f = open(repo_make_conf, "r")
|
||||
sys_f = open(system_make_conf, "r")
|
||||
repo_make_c = [x.strip() for x in repo_f.readlines()]
|
||||
sys_make_c = [x.strip() for x in sys_f.readlines()]
|
||||
repo_f.close()
|
||||
sys_f.close()
|
||||
|
||||
# read repository settings
|
||||
repo_data = {}
|
||||
for setting in make_conf_variables_check:
|
||||
for line in repo_make_c:
|
||||
if line.startswith(setting+"="):
|
||||
# there can't be bash vars with a space
|
||||
# after its name on declaration
|
||||
repo_data[setting] = line
|
||||
# I don't break, because there might be
|
||||
# other overlapping settings
|
||||
|
||||
differences = {}
|
||||
# update make.conf data in memory
|
||||
for setting in repo_data:
|
||||
for idx in range(len(sys_make_c)):
|
||||
line = sys_make_c[idx]
|
||||
|
||||
if line.startswith(setting+"=") and \
|
||||
(line != repo_data[setting]):
|
||||
|
||||
# there can't be bash vars with a
|
||||
# space after its name on declaration
|
||||
self.Entropy.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_conf), bold(repr(setting)),
|
||||
blue(_("variable differs")), red(_("Updating")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
differences[setting] = repo_data[setting]
|
||||
line = repo_data[setting]
|
||||
sys_make_c[idx] = line
|
||||
|
||||
if differences:
|
||||
|
||||
self.Entropy.updateProgress(
|
||||
"%s: %s." % (
|
||||
red(system_make_conf),
|
||||
blue(_("updating critical variables")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
# backup user make.conf
|
||||
shutil.copy2(system_make_conf,
|
||||
"%s.entropy_backup" % (system_make_conf,))
|
||||
|
||||
self.Entropy.updateProgress(
|
||||
"%s: %s." % (
|
||||
red(system_make_conf),
|
||||
darkgreen("writing changes to disk"),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
# write to disk, safely
|
||||
tmp_make_conf = "%s.entropy_write" % (system_make_conf,)
|
||||
f = open(tmp_make_conf, "w")
|
||||
for line in sys_make_c: f.write(line+"\n")
|
||||
f.flush()
|
||||
f.close()
|
||||
shutil.move(tmp_make_conf, system_make_conf)
|
||||
|
||||
# update environment
|
||||
for var in differences:
|
||||
try:
|
||||
myval = '='.join(differences[var].strip().split("=")[1:])
|
||||
if myval:
|
||||
if myval[0] in ("'", '"',): myval = myval[1:]
|
||||
if myval[-1] in ("'", '"',): myval = myval[:-1]
|
||||
except IndexError:
|
||||
myval = ''
|
||||
os.environ[var] = myval
|
||||
|
||||
def _config_updates_make_profile(self, repo):
|
||||
|
||||
avail_data = self.Entropy.SystemSettings['repositories']['available']
|
||||
repo_dbpath = avail_data[repo]['dbpath']
|
||||
profile_link_name = etpConst['spm']['global_make_profile_link_name']
|
||||
|
||||
repo_make_profile = os.path.join(repo_dbpath, profile_link_name)
|
||||
|
||||
if not (os.path.isfile(repo_make_profile) and \
|
||||
os.access(repo_make_profile, os.R_OK)):
|
||||
return
|
||||
|
||||
system_make_profile = etpConst['spm']['global_make_profile']
|
||||
|
||||
f = open(repo_make_profile, "r")
|
||||
repo_profile_link_data = f.readline().strip()
|
||||
f.close()
|
||||
current_profile_link = ''
|
||||
if os.path.islink(system_make_profile) and \
|
||||
os.access(system_make_profile, os.R_OK):
|
||||
|
||||
current_profile_link = os.readlink(system_make_profile)
|
||||
|
||||
if (repo_profile_link_data != current_profile_link) and \
|
||||
repo_profile_link_data:
|
||||
|
||||
self.Entropy.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_profile), blue("link"),
|
||||
blue(_("differs")), red(_("Updating")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
merge_sfx = ".entropy_merge"
|
||||
os.symlink(repo_profile_link_data, system_make_profile+merge_sfx)
|
||||
if entropy.tools.is_valid_path(system_make_profile+merge_sfx):
|
||||
os.rename(system_make_profile+merge_sfx, system_make_profile)
|
||||
else:
|
||||
# revert change, link does not exist yet
|
||||
self.Entropy.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_profile), blue("new link"),
|
||||
blue(_("does not exist")), red(_("Reverting")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
os.remove(system_make_profile+merge_sfx)
|
||||
|
||||
|
||||
def check_entropy_updates(self):
|
||||
rc = False
|
||||
if not self.noEquoCheck:
|
||||
|
||||
@@ -17,18 +17,11 @@ from entropy.const import *
|
||||
from entropy.exceptions import *
|
||||
from entropy.output import *
|
||||
from entropy.i18n import _
|
||||
import entropy.tools
|
||||
|
||||
class Trigger:
|
||||
|
||||
VALID_PHASES = ("preinstall", "postinstall", "preremove", "postremove",)
|
||||
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):
|
||||
@@ -89,22 +82,20 @@ class Trigger:
|
||||
functions = []
|
||||
|
||||
if self.spm_support:
|
||||
spm_class = self.Entropy.Spm_class()
|
||||
phases_map = spm_class.package_phases_map()
|
||||
while True:
|
||||
if self.pkgdata['spm_phases'] != None:
|
||||
if etpConst['spm']['postinst_phase'] not \
|
||||
if self.pkgdata['spm_phases'] is not None:
|
||||
if phases_map.get('postinstall') not \
|
||||
in self.pkgdata['spm_phases']:
|
||||
break
|
||||
functions.append(self.trigger_spm_postinstall)
|
||||
break
|
||||
|
||||
cont_dirs = set((os.path.dirname(x) for x in self.pkgdata['content']))
|
||||
|
||||
if Trigger.ENV_VARS_DIR in cont_dirs:
|
||||
ldpaths = entropy.tools.collect_linker_paths()
|
||||
if len(cont_dirs) != len(cont_dirs - set(ldpaths)):
|
||||
functions.append(self.trigger_env_update)
|
||||
else:
|
||||
ldpaths = self.Entropy.entropyTools.collect_linker_paths()
|
||||
if len(cont_dirs) != len(cont_dirs - set(ldpaths)):
|
||||
functions.append(self.trigger_env_update)
|
||||
|
||||
if self.pkgdata['trigger']:
|
||||
functions.append(self.trigger_call_ext_postinstall)
|
||||
@@ -117,9 +108,11 @@ class Trigger:
|
||||
|
||||
# Portage phases
|
||||
if self.spm_support:
|
||||
spm_class = self.Entropy.Spm_class()
|
||||
phases_map = spm_class.package_phases_map()
|
||||
while True:
|
||||
if self.pkgdata['spm_phases'] != None:
|
||||
if etpConst['spm']['preinst_phase'] not \
|
||||
if phases_map.get('preinstall') not \
|
||||
in self.pkgdata['spm_phases']:
|
||||
break
|
||||
functions.append(self.trigger_spm_preinstall)
|
||||
@@ -137,12 +130,9 @@ class Trigger:
|
||||
cont_dirs = set((os.path.dirname(x) for x in \
|
||||
self.pkgdata['removecontent']))
|
||||
|
||||
if Trigger.ENV_VARS_DIR in cont_dirs:
|
||||
ldpaths = entropy.tools.collect_linker_paths()
|
||||
if len(cont_dirs) != len(cont_dirs - set(ldpaths)):
|
||||
functions.append(self.trigger_env_update)
|
||||
else:
|
||||
ldpaths = self.Entropy.entropyTools.collect_linker_paths()
|
||||
if len(cont_dirs) != len(cont_dirs - set(ldpaths)):
|
||||
functions.append(self.trigger_env_update)
|
||||
|
||||
if self.pkgdata['trigger']:
|
||||
functions.append(self.trigger_call_ext_postremove)
|
||||
@@ -156,10 +146,12 @@ class Trigger:
|
||||
|
||||
# Portage hook
|
||||
if self.spm_support:
|
||||
spm_class = self.Entropy.Spm_class()
|
||||
phases_map = spm_class.package_phases_map()
|
||||
|
||||
while True:
|
||||
if self.pkgdata['spm_phases'] != None:
|
||||
if etpConst['spm']['prerm_phase'] not \
|
||||
if phases_map.get('preremove') not \
|
||||
in self.pkgdata['spm_phases']:
|
||||
break
|
||||
functions.append(self.trigger_spm_preremove)
|
||||
@@ -169,7 +161,7 @@ class Trigger:
|
||||
# in place and also because doesn't make any difference
|
||||
while True:
|
||||
if self.pkgdata['spm_phases'] != None:
|
||||
if etpConst['spm']['postrm_phase'] not \
|
||||
if phases_map.get('postremove') not \
|
||||
in self.pkgdata['spm_phases']:
|
||||
break
|
||||
functions.append(self.trigger_spm_postremove)
|
||||
@@ -386,7 +378,7 @@ class Trigger:
|
||||
|
||||
tg_pfx = "%s/trigger-" % (etpConst['entropyunpackdir'],)
|
||||
while True:
|
||||
triggerfile = "%s%s" % (tg_pfx, self.Entropy.entropyTools.get_random_number(),)
|
||||
triggerfile = "%s%s" % (tg_pfx, entropy.tools.get_random_number(),)
|
||||
if not os.path.isfile(triggerfile): break
|
||||
|
||||
triggerdir = os.path.dirname(triggerfile)
|
||||
@@ -422,20 +414,13 @@ class Trigger:
|
||||
return my.run(self.phase, self.pkgdata, triggerfile)
|
||||
|
||||
def trigger_env_update(self):
|
||||
|
||||
self.Entropy.clientLog.log(
|
||||
ETP_LOGPRI_INFO,
|
||||
ETP_LOGLEVEL_NORMAL,
|
||||
"[POST] Running env-update"
|
||||
"[POST] Running env_update"
|
||||
)
|
||||
kwargs = {}
|
||||
if etpUi['mute']:
|
||||
kwargs['stdout'] = self.Entropy.clientLog
|
||||
kwargs['stderr'] = self.Entropy.clientLog
|
||||
|
||||
args = (Trigger.ENV_UPDATE_HOOK,)
|
||||
proc = subprocess.Popen(args, **kwargs)
|
||||
proc.wait()
|
||||
self.Spm.environment_update(stdin = self.Entropy.clientLog,
|
||||
stdout = self.Entropy.clientLog)
|
||||
|
||||
def trigger_spm_postinstall(self):
|
||||
|
||||
@@ -444,8 +429,7 @@ class Trigger:
|
||||
importance = 0,
|
||||
header = red(" ## ")
|
||||
)
|
||||
return self.Spm.execute_package_phase(self.pkgdata,
|
||||
Trigger.PHASES['postinstall'])
|
||||
return self.Spm.execute_package_phase(self.pkgdata, 'postinstall')
|
||||
|
||||
def trigger_spm_preinstall(self):
|
||||
|
||||
@@ -454,8 +438,7 @@ class Trigger:
|
||||
importance = 0,
|
||||
header = red(" ## ")
|
||||
)
|
||||
return self.Spm.execute_package_phase(self.pkgdata,
|
||||
Trigger.PHASES['preinstall'])
|
||||
return self.Spm.execute_package_phase(self.pkgdata, 'preinstall')
|
||||
|
||||
def trigger_spm_preremove(self):
|
||||
|
||||
@@ -464,8 +447,7 @@ class Trigger:
|
||||
importance = 0,
|
||||
header = red(" ## ")
|
||||
)
|
||||
return self.Spm.execute_package_phase(self.pkgdata,
|
||||
Trigger.PHASES['preremove'])
|
||||
return self.Spm.execute_package_phase(self.pkgdata, 'preremove')
|
||||
|
||||
def trigger_spm_postremove(self):
|
||||
|
||||
@@ -474,5 +456,4 @@ class Trigger:
|
||||
importance = 0,
|
||||
header = red(" ## ")
|
||||
)
|
||||
return self.Spm.execute_package_phase(self.pkgdata,
|
||||
Trigger.PHASES['postremove'])
|
||||
return self.Spm.execute_package_phase(self.pkgdata, 'postremove')
|
||||
|
||||
@@ -507,69 +507,11 @@ def const_default_settings(rootdir):
|
||||
'default_nice': 0,
|
||||
# Default download socket timeout for Entropy Client transceivers
|
||||
'default_download_timeout': 20,
|
||||
'spm': {
|
||||
# Entropy package dependencies type identifiers
|
||||
'dependency_type_ids': {
|
||||
'(r)depend_id': 0,
|
||||
'pdepend_id': 1,
|
||||
'mdepend_id': 2, # actually, this is entropy-only
|
||||
'ebuild_file_extension': "ebuild",
|
||||
'preinst_phase': "preinst",
|
||||
'postinst_phase': "postinst",
|
||||
'prerm_phase': "prerm",
|
||||
'postrm_phase': "postrm",
|
||||
'setup_phase': "setup",
|
||||
'compile_phase': "compile",
|
||||
'install_phase': "install",
|
||||
'unpack_phase': "unpack",
|
||||
'ebuild_pkg_tag_var': "ENTROPY_PROJECT_TAG",
|
||||
'global_make_conf': rootdir+"/etc/make.conf",
|
||||
'global_package_keywords': rootdir+"/etc/portage/package.keywords",
|
||||
'global_package_use': rootdir+"/etc/portage/package.use",
|
||||
'global_package_mask': rootdir+"/etc/portage/package.mask",
|
||||
'global_package_unmask': rootdir+"/etc/portage/package.unmask",
|
||||
'global_make_profile': rootdir+"/etc/make.profile",
|
||||
'global_make_profile_link_name': "profile.link",
|
||||
# source package manager executable
|
||||
'exec': rootdir+"/usr/bin/emerge",
|
||||
'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",
|
||||
'nodeps_cmd': "--nodeps",
|
||||
'fetchonly_cmd': "--fetchonly",
|
||||
'buildonly_cmd': "--buildonly",
|
||||
'oneshot_cmd': "--oneshot",
|
||||
'pretend_cmd': "--pretend",
|
||||
'verbose_cmd': "--verbose",
|
||||
'nocolor_cmd': "--color=n",
|
||||
'backend': "portage", # default one
|
||||
'xpak_entries': {
|
||||
'description': "DESCRIPTION",
|
||||
'homepage': "HOMEPAGE",
|
||||
'chost': "CHOST",
|
||||
'category': "CATEGORY",
|
||||
'cflags': "CFLAGS",
|
||||
'cxxflags': "CXXFLAGS",
|
||||
'license': "LICENSE",
|
||||
'src_uri': "SRC_URI",
|
||||
'use': "USE",
|
||||
'iuse': "IUSE",
|
||||
'slot': "SLOT",
|
||||
'provide': "PROVIDE",
|
||||
'depend': "DEPEND",
|
||||
'rdepend': "RDEPEND",
|
||||
'pdepend': "PDEPEND",
|
||||
'needed': "NEEDED",
|
||||
'inherited': "INHERITED",
|
||||
'keywords': "KEYWORDS",
|
||||
'contents': "CONTENTS",
|
||||
'counter': "COUNTER",
|
||||
'defined_phases': "DEFINED_PHASES",
|
||||
'pf': "PF",
|
||||
},
|
||||
'system_packages': [],
|
||||
'ignore-spm-downgrades': False,
|
||||
},
|
||||
|
||||
# entropy client packages download speed limit (in kb/sec)
|
||||
|
||||
@@ -860,7 +860,7 @@ class SystemSettings(Singleton, EntropyPluginStore):
|
||||
'proxy': etpConst['proxy'].copy(),
|
||||
'name': etpConst['systemname'],
|
||||
'log_level': etpConst['entropyloglevel'],
|
||||
'spm_backend': etpConst['spm']['backend'],
|
||||
'spm_backend': None,
|
||||
}
|
||||
|
||||
etp_conf = self.__setting_files['system']
|
||||
|
||||
@@ -1043,7 +1043,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
if manual_dep in pkgdata['dependencies']:
|
||||
continue
|
||||
pkgdata['dependencies'][manual_dep] = \
|
||||
etpConst['spm']['mdepend_id']
|
||||
etpConst['dependency_type_ids']['mdepend_id']
|
||||
|
||||
# FIXME: this is Entropy Client related but also part of the
|
||||
# currently implemented metaphor, so let's wait to have a Rule
|
||||
@@ -1261,7 +1261,8 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
for manual_dep in manual_deps:
|
||||
if manual_dep in dep_dict:
|
||||
continue
|
||||
dep_dict[manual_dep] = etpConst['spm']['mdepend_id']
|
||||
dep_dict[manual_dep] = \
|
||||
etpConst['dependency_type_ids']['mdepend_id']
|
||||
|
||||
else:
|
||||
# force to None
|
||||
@@ -1937,7 +1938,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
"""
|
||||
mydict = {}
|
||||
for manual_dep in manual_deps:
|
||||
mydict[manual_dep] = etpConst['spm']['mdepend_id']
|
||||
mydict[manual_dep] = etpConst['dependency_type_ids']['mdepend_id']
|
||||
return self.insertDependencies(idpackage, mydict)
|
||||
|
||||
def removeContent(self, idpackage):
|
||||
@@ -4127,7 +4128,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
@type extended: bool
|
||||
"""
|
||||
return self.retrieveDependencies(idpackage, extended = extended,
|
||||
deptype = etpConst['spm']['pdepend_id'])
|
||||
deptype = etpConst['dependency_type_ids']['pdepend_id'])
|
||||
|
||||
def retrieveManualDependencies(self, idpackage, extended = False):
|
||||
"""
|
||||
@@ -4141,7 +4142,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
@type extended: bool
|
||||
"""
|
||||
return self.retrieveDependencies(idpackage, extended = extended,
|
||||
deptype = etpConst['spm']['mdepend_id'])
|
||||
deptype = etpConst['dependency_type_ids']['mdepend_id'])
|
||||
|
||||
def retrieveDependencies(self, idpackage, extended = False, deptype = None,
|
||||
exclude_deptypes = None):
|
||||
@@ -4154,7 +4155,7 @@ class EntropyRepository(EntropyRepositoryPluginStore, TextInterface):
|
||||
composed by dependency name and dependency type)
|
||||
@type extended: bool
|
||||
@keyword deptype: return only given type of dependencies
|
||||
see etpConst['spm']['*depend_id'] for dependency type
|
||||
see etpConst['dependency_type_ids']['*depend_id'] for dependency type
|
||||
identifiers
|
||||
@type deptype: bool
|
||||
@keyword exclude_deptypes: list of dependency types to exclude
|
||||
|
||||
@@ -22,6 +22,7 @@ from entropy.i18n import _
|
||||
from entropy.misc import RSS
|
||||
from entropy.transceivers import EntropyTransceiver
|
||||
from entropy.db import dbapi2
|
||||
import entropy.tools
|
||||
|
||||
class Server:
|
||||
|
||||
@@ -1252,33 +1253,32 @@ class Server:
|
||||
critical.append(ssl_server_cert)
|
||||
|
||||
# Some information regarding how packages are built
|
||||
spm_files = [
|
||||
(etpConst['spm']['global_make_conf'], "global_make_conf"),
|
||||
(etpConst['spm']['global_package_keywords'],
|
||||
"global_package_keywords"),
|
||||
(etpConst['spm']['global_package_use'], "global_package_use"),
|
||||
(etpConst['spm']['global_package_mask'], "global_package_mask"),
|
||||
(etpConst['spm']['global_package_unmask'], "global_package_unmask"),
|
||||
]
|
||||
for myfile, myname in spm_files:
|
||||
spm_files_map = self.Entropy.Spm_class().config_files_map()
|
||||
spm_syms = {}
|
||||
for myname, myfile in spm_files_map.items():
|
||||
if os.path.islink(myfile):
|
||||
spm_syms[myname] = myfile
|
||||
continue # we don't want symlinks
|
||||
if os.path.isfile(myfile) and os.access(myfile, os.R_OK):
|
||||
data[myname] = myfile
|
||||
extra_text_files.append(myfile)
|
||||
|
||||
make_profile = etpConst['spm']['global_make_profile']
|
||||
rnd_tmp_file = self.Entropy.entropyTools.get_random_temp_file()
|
||||
mytmpdir = os.path.dirname(rnd_tmp_file)
|
||||
mytmpfile = os.path.join(mytmpdir,
|
||||
etpConst['spm']['global_make_profile_link_name'])
|
||||
extra_text_files.append(mytmpfile)
|
||||
# XXX/FIXME: for symlinks, we read their link and send a file with that
|
||||
# content. This is the default behaviour for now and allows to send
|
||||
# /etc/make.profile link pointer correctly.
|
||||
for symname, symfile in spm_syms.items():
|
||||
|
||||
if os.path.islink(make_profile):
|
||||
mylink = os.readlink(make_profile)
|
||||
tmp_file = entropy.tools.get_random_temp_file()
|
||||
mytmpdir = os.path.dirname(tmp_file)
|
||||
mytmpfile = os.path.join(mytmpdir, os.path.basename(symfile))
|
||||
extra_text_files.append(mytmpfile)
|
||||
|
||||
mylink = os.readlink(symfile)
|
||||
f_mkp = open(mytmpfile, "w")
|
||||
f_mkp.write(mylink)
|
||||
f_mkp.flush()
|
||||
f_mkp.close()
|
||||
data['global_make_profile'] = mytmpfile
|
||||
data[symname] = mytmpfile
|
||||
|
||||
return data, critical, extra_text_files
|
||||
|
||||
@@ -3033,7 +3033,7 @@ class Server:
|
||||
header = darkred(" !!! ")
|
||||
)
|
||||
|
||||
exc_txt = self.Entropy.entropyTools.print_exception(
|
||||
exc_txt = entropy.tools.print_exception(
|
||||
returndata = True)
|
||||
for line in exc_txt:
|
||||
self.Entropy.updateProgress(
|
||||
|
||||
@@ -155,87 +155,85 @@ class Base:
|
||||
stdout_err.close()
|
||||
return True, rc
|
||||
|
||||
def compile_atoms( self,
|
||||
queue_id, atoms,
|
||||
pretend = False, oneshot = False,
|
||||
verbose = True, nocolor = True,
|
||||
fetchonly = False, buildonly = False,
|
||||
nodeps = False, custom_use = '', ldflags = '', cflags = ''
|
||||
):
|
||||
def compile_atoms(
|
||||
self,
|
||||
queue_id, atoms,
|
||||
pretend = False, oneshot = False,
|
||||
verbose = True, nocolor = True,
|
||||
fetchonly = False, buildonly = False,
|
||||
nodeps = False, custom_use = '', ldflags = '', cflags = ''):
|
||||
|
||||
queue_data, key = self.SystemManagerExecutor.SystemInterface.get_item_by_queue_id(queue_id, copy = True)
|
||||
sys_intf = self.SystemManagerExecutor.SystemInterface
|
||||
queue_data, key = sys_intf.get_item_by_queue_id(queue_id, copy = True)
|
||||
if queue_data == None:
|
||||
return False, 'no item in queue'
|
||||
|
||||
def set_proc_pid(pid):
|
||||
self._set_processing_pid(queue_id, pid)
|
||||
|
||||
stdout_err = open(queue_data['stdout'], "a+")
|
||||
|
||||
cmd = [etpConst['spm']['env_update_cmd'], "&&"]
|
||||
cmd += etpConst['spm']['source_profile']+["&&"]
|
||||
if custom_use:
|
||||
cmd += ['export USE="']+custom_use.strip().split()+['"', '&&']
|
||||
if ldflags:
|
||||
cmd += ['export LDFLAGS="']+custom_use.strip().split()+['"', '&&']
|
||||
if cflags:
|
||||
cmd += ['export CFLAGS="']+custom_use.strip().split()+['"', '&&']
|
||||
cmd += [etpConst['spm']['exec']]+atoms
|
||||
if pretend:
|
||||
cmd.append(etpConst['spm']['pretend_cmd'])
|
||||
if verbose:
|
||||
cmd.append(etpConst['spm']['verbose_cmd'])
|
||||
if oneshot:
|
||||
cmd.append(etpConst['spm']['oneshot_cmd'])
|
||||
if nocolor:
|
||||
cmd.append(etpConst['spm']['nocolor_cmd'])
|
||||
if fetchonly:
|
||||
cmd.append(etpConst['spm']['fetchonly_cmd'])
|
||||
if buildonly:
|
||||
cmd.append(etpConst['spm']['buildonly_cmd'])
|
||||
if nodeps:
|
||||
cmd.append(etpConst['spm']['nodeps_cmd'])
|
||||
|
||||
stdout_err.write("Preparing to spawn parameter: '%s'. Good luck mate!\n" % (' '.join(cmd),))
|
||||
stdout_err.write("Preparing to spawn compilation of: '%s'"
|
||||
". Good luck mate!\n" % (' '.join(atoms),))
|
||||
stdout_err.flush()
|
||||
|
||||
env = {}
|
||||
if ldflags:
|
||||
env['LDFLAGS'] = ldflags
|
||||
if cflags:
|
||||
env['CFLAGS'] = cflags
|
||||
|
||||
try:
|
||||
p = subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True)
|
||||
self._set_processing_pid(queue_id, p.pid)
|
||||
rc = p.wait()
|
||||
|
||||
spm = sys_intf.Entropy.Spm()
|
||||
status = spm.compile_packages(atoms,
|
||||
stdin = self._get_stdin(queue_id),
|
||||
stdout = stdour_err, stderr = stdout_err, environ = env,
|
||||
pid_write_func = set_proc_pid, pretend = pretend,
|
||||
verbose = verbose, fetch_only = fetchonly,
|
||||
build_only = buildonly, no_dependencies = nodeps,
|
||||
coloured_output = not nocolor, oneshot = oneshot)
|
||||
|
||||
finally:
|
||||
|
||||
stdout_err.write("\n### Done ###\n")
|
||||
stdout_err.flush()
|
||||
stdout_err.close()
|
||||
return True, rc
|
||||
|
||||
return True, status
|
||||
|
||||
def spm_remove_atoms(self, queue_id, atoms, pretend = True, verbose = True, nocolor = True):
|
||||
|
||||
queue_data, key = self.SystemManagerExecutor.SystemInterface.get_item_by_queue_id(queue_id, copy = True)
|
||||
sys_intf = self.SystemManagerExecutor.SystemInterface
|
||||
queue_data, key = sys_intf.get_item_by_queue_id(queue_id, copy = True)
|
||||
if queue_data == None:
|
||||
return False, 'no item in queue'
|
||||
|
||||
def set_proc_pid(pid):
|
||||
self._set_processing_pid(queue_id, pid)
|
||||
|
||||
stdout_err = open(queue_data['stdout'], "a+")
|
||||
|
||||
cmd = [etpConst['spm']['env_update_cmd'], "&&"]
|
||||
cmd += etpConst['spm']['source_profile']+["&&"]
|
||||
cmd += [etpConst['spm']['exec'], etpConst['spm']['remove_cmd']]+atoms
|
||||
if pretend:
|
||||
cmd.append(etpConst['spm']['pretend_cmd'])
|
||||
if verbose:
|
||||
cmd.append(etpConst['spm']['verbose_cmd'])
|
||||
if nocolor:
|
||||
cmd.append(etpConst['spm']['nocolor_cmd'])
|
||||
|
||||
stdout_err.write("Preparing to spawn parameter: '%s'. Good luck mate!\n" % (' '.join(cmd),))
|
||||
stdout_err.write("Preparing to spawn removal of: '%s'"
|
||||
". Good luck mate!\n" % (' '.join(atoms),))
|
||||
stdout_err.flush()
|
||||
|
||||
try:
|
||||
p = subprocess.Popen(' '.join(cmd), stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True)
|
||||
self._set_processing_pid(queue_id, p.pid)
|
||||
rc = p.wait()
|
||||
|
||||
spm = sys_intf.Entropy.Spm()
|
||||
status = spm.remove_packages(atoms,
|
||||
stdin = self._get_stdin(queue_id),
|
||||
stdout = stdour_err, stderr = stdout_err,
|
||||
pid_write_func = set_proc_pid, pretend = pretend,
|
||||
verbose = verbose, fetch_only = fetchonly,
|
||||
build_only = buildonly, no_dependencies = nodeps,
|
||||
coloured_output = not nocolor, oneshot = oneshot)
|
||||
|
||||
finally:
|
||||
|
||||
stdout_err.write("\n### Done ###\n")
|
||||
stdout_err.flush()
|
||||
stdout_err.close()
|
||||
return True, rc
|
||||
|
||||
return True, status
|
||||
|
||||
def enable_uses_for_atoms(self, queue_id, atoms, useflags):
|
||||
|
||||
@@ -350,26 +348,33 @@ class Base:
|
||||
|
||||
def run_spm_info(self, queue_id):
|
||||
|
||||
queue_data, key = self.SystemManagerExecutor.SystemInterface.get_item_by_queue_id(queue_id, copy = True)
|
||||
sys_intf = self.SystemManagerExecutor.SystemInterface
|
||||
queue_data, key = sys_intf.get_item_by_queue_id(queue_id, copy = True)
|
||||
if queue_data == None:
|
||||
return False, 'no item in queue'
|
||||
|
||||
def set_proc_pid(pid):
|
||||
self._set_processing_pid(queue_id, pid)
|
||||
|
||||
stdout_err = open(queue_data['stdout'], "a+")
|
||||
|
||||
cmd = [etpConst['spm']['exec'], etpConst['spm']['info_cmd']]
|
||||
|
||||
stdout_err.write("Preparing to spawn parameter: '%s'. Good luck mate!\n" % (' '.join(cmd),))
|
||||
stdout_err.write("Preparing to spawn SPM info. Good luck mate!\n")
|
||||
stdout_err.flush()
|
||||
|
||||
try:
|
||||
p = subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id))
|
||||
self._set_processing_pid(queue_id, p.pid)
|
||||
rc = p.wait()
|
||||
|
||||
spm = sys_intf.Entropy.Spm()
|
||||
status = spm.print_build_environment_info(
|
||||
stdin = self._get_stdin(queue_id),
|
||||
stdout = stdour_err, stderr = stdout_err,
|
||||
pid_write_func = set_proc_pid, coloured_output = False)
|
||||
|
||||
finally:
|
||||
|
||||
stdout_err.write("\n### Done ###\n")
|
||||
stdout_err.flush()
|
||||
stdout_err.close()
|
||||
return True, rc
|
||||
|
||||
return True, status
|
||||
|
||||
def run_custom_shell_command(self, queue_id, command):
|
||||
|
||||
@@ -379,16 +384,14 @@ class Base:
|
||||
|
||||
stdout_err = open(queue_data['stdout'], "a+")
|
||||
|
||||
cmd = [etpConst['spm']['env_update_cmd'], "&&"]
|
||||
cmd += etpConst['spm']['source_profile']+[";"]
|
||||
cmd += command.split()
|
||||
|
||||
cmd = command.split()
|
||||
cmd = ' '.join(cmd)
|
||||
stdout_err.write("Preparing to spawn parameter: '%s'. Good luck mate!\n" % (cmd,))
|
||||
stdout_err.flush()
|
||||
|
||||
try:
|
||||
p = subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err, stdin = self._get_stdin(queue_id), shell = True)
|
||||
p = subprocess.Popen(cmd, stdout = stdout_err, stderr = stdout_err,
|
||||
stdin = self._get_stdin(queue_id), shell = True)
|
||||
self._set_processing_pid(queue_id, p.pid)
|
||||
rc = p.wait()
|
||||
finally:
|
||||
|
||||
@@ -16,16 +16,41 @@ from entropy.i18n import _
|
||||
from entropy.spm.plugins.skel import SpmPlugin
|
||||
import entropy.spm.plugins.interfaces as plugs
|
||||
|
||||
settings = SystemSettings()
|
||||
default_plugin = settings['system'].get('spm_backend',
|
||||
etpConst['spm']['backend'])
|
||||
_settings = SystemSettings()
|
||||
_USER_PLUG = _settings['system'].get('spm_backend')
|
||||
|
||||
FACTORY = EntropyPluginFactory(SpmPlugin, plugs,
|
||||
default_plugin_name = default_plugin,
|
||||
fallback_plugin_name = etpConst['spm']['backend'])
|
||||
default_plugin_name = _USER_PLUG)
|
||||
|
||||
get_available_plugins = FACTORY.get_available_plugins
|
||||
get_default_class = FACTORY.get_default_plugin
|
||||
|
||||
def get_default_class():
|
||||
"""
|
||||
Return default Source Package Manager plugin class.
|
||||
|
||||
@return: default Source Package Manager plugin class
|
||||
@raise SystemError: if no default plugin class has been specified.
|
||||
This usually means a programming error.
|
||||
"""
|
||||
fallback_used = False
|
||||
myplugs = get_available_plugins()
|
||||
if _USER_PLUG is not None:
|
||||
user_plugin = myplugs.get(_USER_PLUG)
|
||||
if user_plugin is not None:
|
||||
return user_plugin
|
||||
fallback_used = True
|
||||
|
||||
for plug_id in sorted(myplugs):
|
||||
plug_class = myplugs[plug_id]
|
||||
if plug_class.IS_DEFAULT:
|
||||
if fallback_used:
|
||||
import warnings
|
||||
warnings.warn("%s: %s" % (
|
||||
"User configured Source Package Manager Plugin not available, "
|
||||
"using fallback", plug_id,))
|
||||
return plug_class
|
||||
|
||||
raise SystemError("no SPM default plugin configured")
|
||||
|
||||
def get_default_instance(output_interface):
|
||||
"""
|
||||
|
||||
@@ -14,6 +14,7 @@ import bz2
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import subprocess
|
||||
from entropy.const import etpConst, etpUi, const_get_stringtype, \
|
||||
const_convert_to_unicode, const_convert_to_rawstring
|
||||
from entropy.exceptions import FileNotFound, SPMError, InvalidDependString, \
|
||||
@@ -155,7 +156,52 @@ class PortagePlugin(SpmPlugin):
|
||||
"downgrade", "unavailable"
|
||||
]
|
||||
|
||||
package_phases_map = {
|
||||
xpak_entries = {
|
||||
'description': "DESCRIPTION",
|
||||
'homepage': "HOMEPAGE",
|
||||
'chost': "CHOST",
|
||||
'category': "CATEGORY",
|
||||
'cflags': "CFLAGS",
|
||||
'cxxflags': "CXXFLAGS",
|
||||
'license': "LICENSE",
|
||||
'src_uri': "SRC_URI",
|
||||
'use': "USE",
|
||||
'iuse': "IUSE",
|
||||
'slot': "SLOT",
|
||||
'provide': "PROVIDE",
|
||||
'depend': "DEPEND",
|
||||
'rdepend': "RDEPEND",
|
||||
'pdepend': "PDEPEND",
|
||||
'needed': "NEEDED",
|
||||
'inherited': "INHERITED",
|
||||
'keywords': "KEYWORDS",
|
||||
'contents': "CONTENTS",
|
||||
'counter': "COUNTER",
|
||||
'defined_phases': "DEFINED_PHASES",
|
||||
'pf': "PF",
|
||||
}
|
||||
|
||||
_ebuild_entries = {
|
||||
'ebuild_pkg_tag_var': "ENTROPY_PROJECT_TAG",
|
||||
}
|
||||
|
||||
_cmd_map = {
|
||||
'env_update_cmd': "/usr/sbin/env-update",
|
||||
'ask_cmd': "--ask",
|
||||
'info_cmd': "--info",
|
||||
'remove_cmd': "-C",
|
||||
'nodeps_cmd': "--nodeps",
|
||||
'fetchonly_cmd': "--fetchonly",
|
||||
'buildonly_cmd': "--buildonly",
|
||||
'oneshot_cmd': "--oneshot",
|
||||
'pretend_cmd': "--pretend",
|
||||
'verbose_cmd': "--verbose",
|
||||
'nocolor_cmd': "--color=n",
|
||||
'source_profile_cmd': ["source", "/etc/profile"],
|
||||
'exec_cmd': "/usr/bin/emerge",
|
||||
}
|
||||
|
||||
_package_phases_map = {
|
||||
'setup': 'setup',
|
||||
'preinstall': 'preinst',
|
||||
'postinstall': 'postinst',
|
||||
@@ -164,7 +210,16 @@ class PortagePlugin(SpmPlugin):
|
||||
'configure': 'config',
|
||||
}
|
||||
|
||||
PLUGIN_API_VERSION = 2
|
||||
_config_files_map = {
|
||||
'global_make_conf': "/etc/make.conf",
|
||||
'global_package_keywords': "/etc/portage/package.keywords",
|
||||
'global_package_use': "/etc/portage/package.use",
|
||||
'global_package_mask': "/etc/portage/package.mask",
|
||||
'global_package_unmask': "/etc/portage/package.unmask",
|
||||
'global_make_profile': "/etc/make.profile",
|
||||
}
|
||||
|
||||
PLUGIN_API_VERSION = 3
|
||||
|
||||
SUPPORTED_MATCH_TYPES = [
|
||||
"bestmatch-visible", "cp-list", "list-visible", "match-all",
|
||||
@@ -178,6 +233,7 @@ class PortagePlugin(SpmPlugin):
|
||||
'portagetree': {},
|
||||
}
|
||||
|
||||
IS_DEFAULT = True
|
||||
PLUGIN_NAME = 'portage'
|
||||
ENV_FILE_COMP = "environment.bz2"
|
||||
EBUILD_EXT = ".ebuild"
|
||||
@@ -349,7 +405,6 @@ class PortagePlugin(SpmPlugin):
|
||||
for package in self.portage.settings.packages:
|
||||
pkgs = self.match_installed_package(package, match_all = True)
|
||||
system.extend(pkgs)
|
||||
system.extend(etpConst['spm']['system_packages'])
|
||||
return system
|
||||
|
||||
def get_package_categories(self):
|
||||
@@ -768,12 +823,12 @@ class PortagePlugin(SpmPlugin):
|
||||
|
||||
data['keywords'] = set(data['keywords'])
|
||||
needed_file = os.path.join(meta_dir,
|
||||
etpConst['spm']['xpak_entries']['needed'])
|
||||
PortagePlugin.xpak_entries['needed'])
|
||||
|
||||
data['needed'] = self._extract_pkg_metadata_needed(needed_file)
|
||||
|
||||
content_file = os.path.join(meta_dir,
|
||||
etpConst['spm']['xpak_entries']['contents'])
|
||||
PortagePlugin.xpak_entries['contents'])
|
||||
data['content'] = self._extract_pkg_metadata_content(content_file,
|
||||
package_file)
|
||||
data['disksize'] = entropy.tools.sum_file_sizes(data['content'])
|
||||
@@ -788,9 +843,9 @@ class PortagePlugin(SpmPlugin):
|
||||
if data['category'] != PortagePlugin.KERNEL_CATEGORY:
|
||||
kern_dep_key = self._add_kernel_dependency_to_pkg(data)
|
||||
|
||||
file_ext = etpConst['spm']['ebuild_file_extension']
|
||||
file_ext = PortagePlugin.EBUILD_EXT
|
||||
ebuilds_in_path = [x for x in os.listdir(meta_dir) if \
|
||||
x.endswith(".%s" % (file_ext,))]
|
||||
x.endswith(file_ext)]
|
||||
|
||||
if not data['versiontag'] and ebuilds_in_path:
|
||||
# has the user specified a custom package tag inside the ebuild
|
||||
@@ -853,12 +908,14 @@ class PortagePlugin(SpmPlugin):
|
||||
for x in portage_metadata['RDEPEND'].split():
|
||||
if x.startswith("!") or (x in ("(", "||", ")", "")):
|
||||
continue
|
||||
data['dependencies'][x] = etpConst['spm']['(r)depend_id']
|
||||
data['dependencies'][x] = \
|
||||
etpConst['dependency_type_ids']['(r)depend_id']
|
||||
|
||||
for x in portage_metadata['PDEPEND'].split():
|
||||
if x.startswith("!") or (x in ("(", "||", ")", "")):
|
||||
continue
|
||||
data['dependencies'][x] = etpConst['spm']['pdepend_id']
|
||||
data['dependencies'][x] = \
|
||||
etpConst['dependency_type_ids']['pdepend_id']
|
||||
|
||||
data['conflicts'] = [x.replace("!", "") for x in \
|
||||
portage_metadata['RDEPEND'].split() + \
|
||||
@@ -866,7 +923,8 @@ class PortagePlugin(SpmPlugin):
|
||||
x.startswith("!") and not x in ("(", "||", ")", "")]
|
||||
|
||||
if kern_dep_key is not None:
|
||||
data['dependencies'][kern_dep_key] = etpConst['spm']['(r)depend_id']
|
||||
data['dependencies'][kern_dep_key] = \
|
||||
etpConst['dependency_type_ids']['(r)depend_id']
|
||||
|
||||
# Conflicting tagged packages support
|
||||
# Needs Entropy Client System Settings Plugin,
|
||||
@@ -1172,6 +1230,119 @@ class PortagePlugin(SpmPlugin):
|
||||
|
||||
return available
|
||||
|
||||
def compile_packages(self, packages, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
pretend = False, verbose = False, fetch_only = False,
|
||||
build_only = False, no_dependencies = False,
|
||||
ask = False, coloured_output = False, oneshot = False):
|
||||
|
||||
cmd = [PortagePlugin._cmd_map['exec_cmd']]
|
||||
if pretend:
|
||||
cmd.append(PortagePlugin._cmd_map['pretend_cmd'])
|
||||
if verbose:
|
||||
cmd.append(PortagePlugin._cmd_map['verbose_cmd'])
|
||||
if ask:
|
||||
cmd.append(PortagePlugin._cmd_map['ask_cmd'])
|
||||
if oneshot:
|
||||
cmd.append(PortagePlugin._cmd_map['oneshot_cmd'])
|
||||
if not coloured_output:
|
||||
cmd.append(PortagePlugin._cmd_map['nocolor_cmd'])
|
||||
if fetch_only:
|
||||
cmd.append(PortagePlugin._cmd_map['fetchonly_cmd'])
|
||||
if build_only:
|
||||
cmd.append(PortagePlugin._cmd_map['buildonly_cmd'])
|
||||
if no_dependencies:
|
||||
cmd.append(PortagePlugin._cmd_map['nodeps_cmd'])
|
||||
|
||||
cmd.extend(packages)
|
||||
cmd_string = """\
|
||||
%s && %s && %s
|
||||
""" % (PortagePlugin._cmd_map['env_update_cmd'],
|
||||
PortagePlugin._cmd_map['source_profile_cmd'],
|
||||
' '.join(cmd)
|
||||
)
|
||||
|
||||
env = os.environ.copy()
|
||||
if environ is not None:
|
||||
env.update(environ)
|
||||
|
||||
proc = subprocess.Popen(cmd_string, stdout = stdout, stderr = stderr,
|
||||
stdin = stdin, env = env, shell = True)
|
||||
if pid_write_func is not None:
|
||||
pid_write_func(proc.pid)
|
||||
return proc.wait()
|
||||
|
||||
def remove_packages(self, packages, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
pretend = False, verbose = False, no_dependencies = False, ask = False,
|
||||
coloured_output = False):
|
||||
|
||||
cmd = [PortagePlugin._cmd_map['exec_cmd'],
|
||||
PortagePlugin._cmd_map['remove_cmd']]
|
||||
if pretend:
|
||||
cmd.append(PortagePlugin._cmd_map['pretend_cmd'])
|
||||
if verbose:
|
||||
cmd.append(PortagePlugin._cmd_map['verbose_cmd'])
|
||||
if ask:
|
||||
cmd.append(PortagePlugin._cmd_map['ask_cmd'])
|
||||
if not coloured_output:
|
||||
cmd.append(PortagePlugin._cmd_map['nocolor_cmd'])
|
||||
if no_dependencies:
|
||||
cmd.append(PortagePlugin._cmd_map['nodeps_cmd'])
|
||||
|
||||
cmd.extend(packages)
|
||||
cmd_string = """\
|
||||
%s && %s && %s
|
||||
""" % (PortagePlugin._cmd_map['env_update_cmd'],
|
||||
PortagePlugin._cmd_map['source_profile_cmd'],
|
||||
' '.join(cmd)
|
||||
)
|
||||
|
||||
env = os.environ.copy()
|
||||
if environ is not None:
|
||||
env.update(environ)
|
||||
|
||||
proc = subprocess.Popen(cmd_string, stdout = stdout, stderr = stderr,
|
||||
stdin = stdin, env = env, shell = True)
|
||||
if pid_write_func is not None:
|
||||
pid_write_func(proc.pid)
|
||||
return proc.wait()
|
||||
|
||||
def environment_update(self, stdout = None, stderr = None):
|
||||
kwargs = {}
|
||||
if etpUi['mute']:
|
||||
kwargs['stdout'] = stdout
|
||||
kwargs['stderr'] = stderr
|
||||
args = (PortagePlugin._cmd_map['env_update_cmd'],)
|
||||
proc = subprocess.Popen(args, **kwargs)
|
||||
proc.wait()
|
||||
|
||||
def print_build_environment_info(self, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
coloured_output = False):
|
||||
|
||||
cmd = [PortagePlugin._cmd_map['exec_cmd'],
|
||||
PortagePlugin._cmd_map['info_cmd']]
|
||||
if not coloured_output:
|
||||
cmd.append(PortagePlugin._cmd_map['nocolor_cmd'])
|
||||
|
||||
cmd_string = """\
|
||||
%s && %s && %s
|
||||
""" % (PortagePlugin._cmd_map['env_update_cmd'],
|
||||
PortagePlugin._cmd_map['source_profile_cmd'],
|
||||
' '.join(cmd)
|
||||
)
|
||||
|
||||
env = os.environ.copy()
|
||||
if environ is not None:
|
||||
env.update(environ)
|
||||
|
||||
proc = subprocess.Popen(cmd_string, stdout = stdout, stderr = stderr,
|
||||
stdin = stdin, env = env, shell = True)
|
||||
if pid_write_func is not None:
|
||||
pid_write_func(proc.pid)
|
||||
return proc.wait()
|
||||
|
||||
def get_installed_packages(self, categories = None, root = None):
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
@@ -1225,7 +1396,7 @@ class PortagePlugin(SpmPlugin):
|
||||
root = root)
|
||||
|
||||
counter_dir = os.path.dirname(dbbuild)
|
||||
counter_name = etpConst['spm']['xpak_entries']['counter']
|
||||
counter_name = PortagePlugin.xpak_entries['counter']
|
||||
counter_path = os.path.join(counter_dir, counter_name)
|
||||
|
||||
if not os.access(counter_dir, os.W_OK):
|
||||
@@ -1243,7 +1414,7 @@ class PortagePlugin(SpmPlugin):
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
"""
|
||||
counter_path = etpConst['spm']['xpak_entries']['counter']
|
||||
counter_path = PortagePlugin.xpak_entries['counter']
|
||||
entropy_atom = entropy_repository.retrieveAtom(
|
||||
entropy_repository_package_id)
|
||||
|
||||
@@ -2079,11 +2250,25 @@ class PortagePlugin(SpmPlugin):
|
||||
entropy_repository_id, portage_dirs_digest)
|
||||
entropy_repository.commitChanges()
|
||||
|
||||
@staticmethod
|
||||
def package_phases_map():
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
"""
|
||||
return PortagePlugin._package_phases_map.copy()
|
||||
|
||||
@staticmethod
|
||||
def config_files_map():
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
"""
|
||||
return PortagePlugin._config_files_map.copy()
|
||||
|
||||
def execute_package_phase(self, package_metadata, phase_name):
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
"""
|
||||
portage_phase = PortagePlugin.package_phases_map[phase_name]
|
||||
portage_phase = PortagePlugin._package_phases_map[phase_name]
|
||||
phase_calls = {
|
||||
'setup': self._pkg_setup,
|
||||
'preinst': self._pkg_preinst,
|
||||
@@ -2396,6 +2581,207 @@ class PortagePlugin(SpmPlugin):
|
||||
|
||||
return env_rc, msg
|
||||
|
||||
@staticmethod
|
||||
def _config_updates_make_conf(entropy_client, repo):
|
||||
|
||||
## WARNING: it doesn't handle multi-line variables, yet. remember this.
|
||||
system_make_conf = PortagePlugin._config_files_map['global_make_conf']
|
||||
|
||||
avail_data = entropy_client.SystemSettings['repositories']['available']
|
||||
repo_dbpath = avail_data[repo]['dbpath']
|
||||
repo_make_conf = os.path.join(repo_dbpath,
|
||||
os.path.basename(system_make_conf))
|
||||
|
||||
if not (os.path.isfile(repo_make_conf) and \
|
||||
os.access(repo_make_conf, os.R_OK)):
|
||||
return
|
||||
|
||||
make_conf_variables_check = ["CHOST"]
|
||||
|
||||
if not os.path.isfile(system_make_conf):
|
||||
entropy_client.updateProgress(
|
||||
"%s %s. %s." % (
|
||||
red(system_make_conf),
|
||||
blue(_("does not exist")), blue(_("Overwriting")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
if os.path.lexists(system_make_conf):
|
||||
shutil.move(
|
||||
system_make_conf,
|
||||
"%s.backup_%s" % (system_make_conf,
|
||||
entropy.tools.get_random_number(),)
|
||||
)
|
||||
shutil.copy2(repo_make_conf, system_make_conf)
|
||||
|
||||
elif os.access(system_make_conf, os.W_OK):
|
||||
|
||||
repo_f = open(repo_make_conf, "r")
|
||||
sys_f = open(system_make_conf, "r")
|
||||
repo_make_c = [x.strip() for x in repo_f.readlines()]
|
||||
sys_make_c = [x.strip() for x in sys_f.readlines()]
|
||||
repo_f.close()
|
||||
sys_f.close()
|
||||
|
||||
# read repository settings
|
||||
repo_data = {}
|
||||
for setting in make_conf_variables_check:
|
||||
for line in repo_make_c:
|
||||
if line.startswith(setting+"="):
|
||||
# there can't be bash vars with a space
|
||||
# after its name on declaration
|
||||
repo_data[setting] = line
|
||||
# I don't break, because there might be
|
||||
# other overlapping settings
|
||||
|
||||
differences = {}
|
||||
# update make.conf data in memory
|
||||
for setting in repo_data:
|
||||
for idx in range(len(sys_make_c)):
|
||||
line = sys_make_c[idx]
|
||||
|
||||
if line.startswith(setting+"=") and \
|
||||
(line != repo_data[setting]):
|
||||
|
||||
# there can't be bash vars with a
|
||||
# space after its name on declaration
|
||||
entropy_client.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_conf), bold(repr(setting)),
|
||||
blue(_("variable differs")), red(_("Updating")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
differences[setting] = repo_data[setting]
|
||||
line = repo_data[setting]
|
||||
sys_make_c[idx] = line
|
||||
|
||||
if differences:
|
||||
|
||||
entropy_client.updateProgress(
|
||||
"%s: %s." % (
|
||||
red(system_make_conf),
|
||||
blue(_("updating critical variables")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
# backup user make.conf
|
||||
shutil.copy2(system_make_conf,
|
||||
"%s.entropy_backup" % (system_make_conf,))
|
||||
|
||||
entropy_client.updateProgress(
|
||||
"%s: %s." % (
|
||||
red(system_make_conf),
|
||||
darkgreen("writing changes to disk"),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
# write to disk, safely
|
||||
tmp_make_conf = "%s.entropy_write" % (system_make_conf,)
|
||||
f = open(tmp_make_conf, "w")
|
||||
for line in sys_make_c:
|
||||
f.write(line+"\n")
|
||||
f.flush()
|
||||
f.close()
|
||||
shutil.move(tmp_make_conf, system_make_conf)
|
||||
|
||||
# update environment
|
||||
for var in differences:
|
||||
try:
|
||||
myval = '='.join(differences[var].strip().split("=")[1:])
|
||||
if myval:
|
||||
if myval[0] in ("'", '"',): myval = myval[1:]
|
||||
if myval[-1] in ("'", '"',): myval = myval[:-1]
|
||||
except IndexError:
|
||||
myval = ''
|
||||
os.environ[var] = myval
|
||||
|
||||
@staticmethod
|
||||
def _config_updates_make_profile(entropy_client, repo):
|
||||
|
||||
avail_data = entropy_client.SystemSettings['repositories']['available']
|
||||
repo_dbpath = avail_data[repo]['dbpath']
|
||||
profile_link = PortagePlugin._config_files_map['global_make_profile']
|
||||
profile_link_name = os.path.basename(profile_link)
|
||||
|
||||
repo_make_profile = os.path.join(repo_dbpath, profile_link_name)
|
||||
|
||||
if not (os.path.isfile(repo_make_profile) and \
|
||||
os.access(repo_make_profile, os.R_OK)):
|
||||
return
|
||||
|
||||
system_make_profile = \
|
||||
PortagePlugin._config_files_map['global_make_profile']
|
||||
|
||||
f = open(repo_make_profile, "r")
|
||||
repo_profile_link_data = f.readline().strip()
|
||||
f.close()
|
||||
current_profile_link = ''
|
||||
if os.path.islink(system_make_profile) and \
|
||||
os.access(system_make_profile, os.R_OK):
|
||||
|
||||
current_profile_link = os.readlink(system_make_profile)
|
||||
|
||||
if (repo_profile_link_data != current_profile_link) and \
|
||||
repo_profile_link_data:
|
||||
|
||||
entropy_client.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_profile), blue("link"),
|
||||
blue(_("differs")), red(_("Updating")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
merge_sfx = ".entropy_merge"
|
||||
os.symlink(repo_profile_link_data, system_make_profile+merge_sfx)
|
||||
if entropy.tools.is_valid_path(system_make_profile+merge_sfx):
|
||||
os.rename(system_make_profile+merge_sfx, system_make_profile)
|
||||
else:
|
||||
# revert change, link does not exist yet
|
||||
entropy_client.updateProgress(
|
||||
"%s: %s %s. %s." % (
|
||||
red(system_make_profile), blue("new link"),
|
||||
blue(_("does not exist")), red(_("Reverting")),
|
||||
),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
os.remove(system_make_profile+merge_sfx)
|
||||
|
||||
@staticmethod
|
||||
def entropy_client_post_repository_update_hook(entropy_client,
|
||||
entropy_repository_id):
|
||||
|
||||
# are we root?
|
||||
if etpConst['uid'] != 0:
|
||||
entropy_client.updateProgress(
|
||||
brown(_("Skipping configuration files update, you are not root.")),
|
||||
importance = 1,
|
||||
type = "info",
|
||||
header = blue(" @@ ")
|
||||
)
|
||||
return 0
|
||||
|
||||
default_repo = \
|
||||
entropy_client.SystemSettings['repositories']['default_repository']
|
||||
|
||||
if default_repo == entropy_repository_id:
|
||||
PortagePlugin._config_updates_make_conf(entropy_repository_id)
|
||||
PortagePlugin._config_updates_make_profile(entropy_repository_id)
|
||||
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def entropy_install_setup_hook(entropy_client, package_metadata):
|
||||
"""
|
||||
@@ -3280,83 +3666,83 @@ class PortagePlugin(SpmPlugin):
|
||||
def _extract_pkg_metadata_generate_extraction_dict(self):
|
||||
data = {
|
||||
'pf': {
|
||||
'path': etpConst['spm']['xpak_entries']['pf'],
|
||||
'path': PortagePlugin.xpak_entries['pf'],
|
||||
'critical': True,
|
||||
},
|
||||
'chost': {
|
||||
'path': etpConst['spm']['xpak_entries']['chost'],
|
||||
'path': PortagePlugin.xpak_entries['chost'],
|
||||
'critical': True,
|
||||
},
|
||||
'description': {
|
||||
'path': etpConst['spm']['xpak_entries']['description'],
|
||||
'path': PortagePlugin.xpak_entries['description'],
|
||||
'critical': False,
|
||||
},
|
||||
'homepage': {
|
||||
'path': etpConst['spm']['xpak_entries']['homepage'],
|
||||
'path': PortagePlugin.xpak_entries['homepage'],
|
||||
'critical': False,
|
||||
},
|
||||
'slot': {
|
||||
'path': etpConst['spm']['xpak_entries']['slot'],
|
||||
'path': PortagePlugin.xpak_entries['slot'],
|
||||
'critical': False,
|
||||
},
|
||||
'cflags': {
|
||||
'path': etpConst['spm']['xpak_entries']['cflags'],
|
||||
'path': PortagePlugin.xpak_entries['cflags'],
|
||||
'critical': False,
|
||||
},
|
||||
'cxxflags': {
|
||||
'path': etpConst['spm']['xpak_entries']['cxxflags'],
|
||||
'path': PortagePlugin.xpak_entries['cxxflags'],
|
||||
'critical': False,
|
||||
},
|
||||
'category': {
|
||||
'path': etpConst['spm']['xpak_entries']['category'],
|
||||
'path': PortagePlugin.xpak_entries['category'],
|
||||
'critical': True,
|
||||
},
|
||||
'rdepend': {
|
||||
'path': etpConst['spm']['xpak_entries']['rdepend'],
|
||||
'path': PortagePlugin.xpak_entries['rdepend'],
|
||||
'critical': False,
|
||||
},
|
||||
'pdepend': {
|
||||
'path': etpConst['spm']['xpak_entries']['pdepend'],
|
||||
'path': PortagePlugin.xpak_entries['pdepend'],
|
||||
'critical': False,
|
||||
},
|
||||
'depend': {
|
||||
'path': etpConst['spm']['xpak_entries']['depend'],
|
||||
'path': PortagePlugin.xpak_entries['depend'],
|
||||
'critical': False,
|
||||
},
|
||||
'use': {
|
||||
'path': etpConst['spm']['xpak_entries']['use'],
|
||||
'path': PortagePlugin.xpak_entries['use'],
|
||||
'critical': False,
|
||||
},
|
||||
'iuse': {
|
||||
'path': etpConst['spm']['xpak_entries']['iuse'],
|
||||
'path': PortagePlugin.xpak_entries['iuse'],
|
||||
'critical': False,
|
||||
},
|
||||
'license': {
|
||||
'path': etpConst['spm']['xpak_entries']['license'],
|
||||
'path': PortagePlugin.xpak_entries['license'],
|
||||
'critical': False,
|
||||
},
|
||||
'provide': {
|
||||
'path': etpConst['spm']['xpak_entries']['provide'],
|
||||
'path': PortagePlugin.xpak_entries['provide'],
|
||||
'critical': False,
|
||||
},
|
||||
'sources': {
|
||||
'path': etpConst['spm']['xpak_entries']['src_uri'],
|
||||
'path': PortagePlugin.xpak_entries['src_uri'],
|
||||
'critical': False,
|
||||
},
|
||||
'eclasses': {
|
||||
'path': etpConst['spm']['xpak_entries']['inherited'],
|
||||
'path': PortagePlugin.xpak_entries['inherited'],
|
||||
'critical': False,
|
||||
},
|
||||
'counter': {
|
||||
'path': etpConst['spm']['xpak_entries']['counter'],
|
||||
'path': PortagePlugin.xpak_entries['counter'],
|
||||
'critical': False,
|
||||
},
|
||||
'keywords': {
|
||||
'path': etpConst['spm']['xpak_entries']['keywords'],
|
||||
'path': PortagePlugin.xpak_entries['keywords'],
|
||||
'critical': False,
|
||||
},
|
||||
'spm_phases': {
|
||||
'path': etpConst['spm']['xpak_entries']['defined_phases'],
|
||||
'path': PortagePlugin.xpak_entries['defined_phases'],
|
||||
'critical': False,
|
||||
},
|
||||
}
|
||||
@@ -3567,7 +3953,7 @@ class PortagePlugin(SpmPlugin):
|
||||
return pkg_links
|
||||
|
||||
def _extract_pkg_metadata_ebuild_entropy_tag(self, ebuild):
|
||||
search_tag = etpConst['spm']['ebuild_pkg_tag_var']
|
||||
search_tag = PortagePlugin._ebuild_entries['ebuild_pkg_tag_var']
|
||||
ebuild_tag = ''
|
||||
# open in unicode fmt
|
||||
f = open(ebuild, "r")
|
||||
|
||||
@@ -18,7 +18,7 @@ from entropy.misc import LogFile
|
||||
class SpmPlugin(Singleton):
|
||||
"""Base class for Source Package Manager plugins"""
|
||||
|
||||
BASE_PLUGIN_API_VERSION = 2
|
||||
BASE_PLUGIN_API_VERSION = 3
|
||||
|
||||
# this must be reimplemented by subclasses and value
|
||||
# must match BASE_PLUGIN_API_VERSION
|
||||
@@ -31,12 +31,16 @@ class SpmPlugin(Singleton):
|
||||
# Name of your Spm Plugin
|
||||
PLUGIN_NAME = None
|
||||
|
||||
# At least one of your SpmPlugin classes must be set as default
|
||||
# by setting IS_DEFAULT = True
|
||||
# There can't be more than _one_ default SPM plugin, in that case
|
||||
# the first (alphabetically) one will be automatically selected
|
||||
IS_DEFAULT = False
|
||||
|
||||
def init_singleton(self, output_interface):
|
||||
"""
|
||||
Source Package Manager Plugin singleton method.
|
||||
This method must be reimplemented by subclasses.
|
||||
At this stage, you should also consider to tweak etpConst['spm']
|
||||
content (importing etpConst from entropy.const).
|
||||
|
||||
@param output_interface: Entropy output interface
|
||||
@type output_interface: entropy.output.TextInterface based instances
|
||||
@@ -61,7 +65,8 @@ class SpmPlugin(Singleton):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def package_phases(self):
|
||||
@staticmethod
|
||||
def package_phases():
|
||||
"""
|
||||
Return a list of available and valid package build phases.
|
||||
Default value is ["setup", "preinstall", "postinstall", "preremove",
|
||||
@@ -73,6 +78,29 @@ class SpmPlugin(Singleton):
|
||||
return ["setup", "preinstall", "postinstall", "preremove",
|
||||
"postremove", "configure"]
|
||||
|
||||
@staticmethod
|
||||
def package_phases_map():
|
||||
"""
|
||||
Return a map of phases names between Entropy (as keys) and
|
||||
Source Package Manager.
|
||||
|
||||
@return: map of package phases
|
||||
@rtype: dict
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def config_files_map():
|
||||
"""
|
||||
Return a map composed by configuration file identifiers and their
|
||||
path on disk. These configuration files are related to Source Package
|
||||
Manager.
|
||||
|
||||
@return: configuration files map
|
||||
@rtype: dict
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_cache_directory(self, root = None):
|
||||
"""
|
||||
Return Source Package Manager cache directory path.
|
||||
@@ -441,6 +469,133 @@ class SpmPlugin(Singleton):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def compile_packages(self, packages, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
pretend = False, verbose = False, fetch_only = False,
|
||||
build_only = False, no_dependencies = False,
|
||||
ask = False, coloured_output = False, oneshot = False):
|
||||
"""
|
||||
Compile given packages using given compile options. Extra compiler
|
||||
options can be set via environmental variables (CFLAGS, LDFLAGS, etc).
|
||||
By default, this function writes to stdout and can potentially interact
|
||||
with user via stdin/stdout/stderr.
|
||||
By default, when build_only=False, compiled packages are installed onto
|
||||
the running system.
|
||||
|
||||
@param packages: list of Source Package Manager package names
|
||||
@type packages: list
|
||||
@keyword stdin: custom standard input
|
||||
@type stdin: file object or valid file descriptor number
|
||||
@keyword stdout: custom standard output
|
||||
@type stdout: file object or valid file descriptor number
|
||||
@keyword stderr: custom standard error
|
||||
@type stderr: file object or valid file descriptor number
|
||||
@keyword environ: dict
|
||||
@type environ: map of environmental variables
|
||||
@keyword pid_write_func: function to call with execution pid number
|
||||
@type pid_write_func: callable function, signature func(int_pid_number)
|
||||
@keyword pretend: just show what would be done
|
||||
@type pretend: bool
|
||||
@keyword verbose: execute compilation in verbose mode
|
||||
@type verbose: bool
|
||||
@keyword fetch_only: fetch source code only
|
||||
@type fetch_only: bool
|
||||
@keyword build_only: do not actually touch live system (don't install
|
||||
compiled
|
||||
@type build_only: bool
|
||||
@keyword no_dependencies: ignore possible build time dependencies
|
||||
@type no_dependencies: bool
|
||||
@keyword ask: ask user via stdin before executing the required tasks
|
||||
@type ask: bool
|
||||
@keyword coloured_output: allow coloured output
|
||||
@type coloured_output: bool
|
||||
@keyword oneshot: when compiled packages are intended to not get
|
||||
recorded into personal user compile preferences (if you are not
|
||||
using a Portage-based SPM, just ignore this)
|
||||
@type oneshot: bool
|
||||
@return: execution status
|
||||
@rtype: int
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def remove_packages(self, packages, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
pretend = False, verbose = False, no_dependencies = False, ask = False,
|
||||
coloured_output = False):
|
||||
"""
|
||||
Compile given packages using given compile options. Extra compiler
|
||||
options can be set via environmental variables (CFLAGS, LDFLAGS, etc).
|
||||
By default, this function writes to stdout and can potentially interact
|
||||
with user via stdin/stdout/stderr.
|
||||
By default, when build_only=False, compiled packages are installed onto
|
||||
the running system.
|
||||
|
||||
@param packages: list of Source Package Manager package names
|
||||
@type packages: list
|
||||
@keyword stdin: custom standard input
|
||||
@type stdin: file object or valid file descriptor number
|
||||
@keyword stdout: custom standard output
|
||||
@type stdout: file object or valid file descriptor number
|
||||
@keyword stderr: custom standard error
|
||||
@type stderr: file object or valid file descriptor number
|
||||
@keyword environ: dict
|
||||
@type environ: map of environmental variables
|
||||
@keyword pid_write_func: function to call with execution pid number
|
||||
@type pid_write_func: callable function, signature func(int_pid_number)
|
||||
@keyword pretend: just show what would be done
|
||||
@type pretend: bool
|
||||
@keyword verbose: execute compilation in verbose mode
|
||||
@type verbose: bool
|
||||
@keyword no_dependencies: ignore possible build time dependencies
|
||||
@type no_dependencies: bool
|
||||
@keyword ask: ask user via stdin before executing the required tasks
|
||||
@type ask: bool
|
||||
@keyword coloured_output: allow coloured output
|
||||
@type coloured_output: bool
|
||||
@return: execution status
|
||||
@rtype: int
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def print_build_environment_info(self, stdin = None, stdout = None,
|
||||
stderr = None, environ = None, pid_write_func = None,
|
||||
coloured_output = False):
|
||||
"""
|
||||
Print build environment info to stdout.
|
||||
|
||||
@keyword stdin: custom standard input
|
||||
@type stdin: file object or valid file descriptor number
|
||||
@keyword stdout: custom standard output
|
||||
@type stdout: file object or valid file descriptor number
|
||||
@keyword stderr: custom standard error
|
||||
@type stderr: file object or valid file descriptor number
|
||||
@keyword environ: dict
|
||||
@type environ: map of environmental variables
|
||||
@keyword pid_write_func: function to call with execution pid number
|
||||
@type pid_write_func: callable function, signature func(int_pid_number)
|
||||
@keyword coloured_output: allow coloured output
|
||||
@type coloured_output: bool
|
||||
@return: execution status
|
||||
@rtype: int
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def environment_update(self, stdout = None, stderr = None):
|
||||
"""
|
||||
Hook used by Entropy Client and Entropy Server to ask Source Package
|
||||
Manager to update /etc/profile* and other environment settings around.
|
||||
Since this is part of the Source Package Manager metaphor it must stay
|
||||
in this class.
|
||||
|
||||
@keyword stdout: custom standard output
|
||||
@type stdout: file object or valid file descriptor number
|
||||
@keyword stderr: custom standard error
|
||||
@type stderr: file object or valid file descriptor number
|
||||
@return: execution status
|
||||
@rtype: int
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_installed_packages(self, categories = None, root = None):
|
||||
"""
|
||||
Return list of packages found in installed packages repository.
|
||||
@@ -645,6 +800,23 @@ class SpmPlugin(Singleton):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def entropy_client_post_repository_update_hook(entropy_client,
|
||||
entropy_repository_id):
|
||||
"""
|
||||
This function is called by Entropy Client when updating Entropy
|
||||
repositories. Place here all your Source Package Manager bullshit and,
|
||||
remember to return an int form execution status.
|
||||
|
||||
@param entropy_client: Entropy Client interface instance
|
||||
@type entropy_client: entropy.client.interfaces.Client.Client
|
||||
@param entropy_repository_id: Entropy Repository unique identifier
|
||||
@type: string
|
||||
@return: execution status
|
||||
@rtype: int
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def entropy_install_setup_hook(entropy_client, package_metadata):
|
||||
"""
|
||||
|
||||
@@ -20,6 +20,7 @@ import os
|
||||
import time
|
||||
import shutil
|
||||
import tarfile
|
||||
import tempfile
|
||||
import subprocess
|
||||
import grp
|
||||
import pwd
|
||||
@@ -2710,14 +2711,9 @@ def get_random_temp_file():
|
||||
@return:
|
||||
@rtype:
|
||||
"""
|
||||
if not os.path.isdir(etpConst['packagestmpdir']):
|
||||
os.makedirs(etpConst['packagestmpdir'])
|
||||
path = os.path.join(etpConst['packagestmpdir'],
|
||||
"temp_"+str(get_random_number()))
|
||||
while os.path.lexists(path):
|
||||
path = os.path.join(etpConst['packagestmpdir'],
|
||||
"temp_"+str(get_random_number()))
|
||||
return path
|
||||
fd, tmp_path = tempfile.mkstemp()
|
||||
os.close(fd)
|
||||
return tmp_path
|
||||
|
||||
def get_file_timestamp(path):
|
||||
"""
|
||||
|
||||
+15
-21
@@ -170,7 +170,8 @@ def repositories(options):
|
||||
for idpackage in idpackages:
|
||||
atom = dbconn.retrieveAtom(idpackage)
|
||||
orig_deps = dbconn.retrieveDependencies(idpackage, extended = True)
|
||||
atom_deps = [x for x in orig_deps if x[1] != etpConst['spm']['mdepend_id']]
|
||||
atom_deps = [x for x in orig_deps if x[1] != \
|
||||
etpConst['dependency_type_ids']['mdepend_id']]
|
||||
atom_manual_deps = [x for x in orig_deps if x not in atom_deps]
|
||||
print_info(brown(" @@ ")+"%s: %s:" % (blue(atom), darkgreen(_("package dependencies")),))
|
||||
for dep_str, dep_id in atom_deps:
|
||||
@@ -196,7 +197,8 @@ def repositories(options):
|
||||
continue
|
||||
|
||||
w_dbconn = Entropy.open_server_repository(repo = repo, read_only = False)
|
||||
atom_deps += [(x, etpConst['spm']['mdepend_id'],) for x in new_mdeps]
|
||||
atom_deps += [(x, etpConst['dependency_type_ids']['mdepend_id'],) \
|
||||
for x in new_mdeps]
|
||||
deps_dict = {}
|
||||
for atom_dep, dep_id in atom_deps:
|
||||
deps_dict[atom_dep] = dep_id
|
||||
@@ -762,15 +764,16 @@ def spm_compile_categories(options, do_list = False):
|
||||
except ValueError:
|
||||
break
|
||||
|
||||
spm = Entropy.Spm()
|
||||
categories = sorted(set(options))
|
||||
packages = Entropy.Spm().get_packages(categories)
|
||||
packages = spm.get_packages(categories)
|
||||
packages = sorted(packages)
|
||||
|
||||
# remove older packages from list (through slot)
|
||||
if not oldslots:
|
||||
oldslots_meta = {}
|
||||
for package in packages:
|
||||
pkg_slot = Entropy.Spm().get_package_metadata(package, "SLOT")
|
||||
pkg_slot = spm.get_package_metadata(package, "SLOT")
|
||||
pkg_key = entropy.tools.dep_getkey(package)
|
||||
obj = oldslots_meta.setdefault(pkg_key, set())
|
||||
obj.add((pkg_slot, package,))
|
||||
@@ -782,10 +785,8 @@ def spm_compile_categories(options, do_list = False):
|
||||
if do_list:
|
||||
print_generic(' '.join(["="+x for x in packages]))
|
||||
else:
|
||||
args = [etpConst['spm']['exec'], etpConst['spm']['ask_cmd'],
|
||||
etpConst['spm']['verbose_cmd']]
|
||||
args.extend(["="+x for x in packages])
|
||||
return subprocess.call(args)
|
||||
return spm.compile_atoms(["="+x for x in packages],
|
||||
ask = True, verbose = True)
|
||||
return 0
|
||||
|
||||
def spm_compile_pkgset(pkgsets, do_rebuild = False, do_dbupdate = False,
|
||||
@@ -804,33 +805,26 @@ def spm_compile_pkgset(pkgsets, do_rebuild = False, do_dbupdate = False,
|
||||
_("package set not found"), pkgset,) ))
|
||||
return 1
|
||||
|
||||
extra_args = []
|
||||
if etpUi['ask']:
|
||||
extra_args.append(etpConst['spm']['ask_cmd'])
|
||||
if etpUi['verbose']:
|
||||
extra_args.append(etpConst['spm']['verbose_cmd'])
|
||||
if etpUi['pretend']:
|
||||
extra_args.append(etpConst['spm']['pretend_cmd'])
|
||||
spm = Entropy.Spm()
|
||||
|
||||
|
||||
done_atoms = set()
|
||||
|
||||
# expand package sets
|
||||
for pkgset in pkgsets:
|
||||
|
||||
set_atoms = [Entropy.Spm().match_package(x) for x in avail_sets[pkgset]]
|
||||
set_atoms = [spm.match_package(x) for x in avail_sets[pkgset]]
|
||||
set_atoms = [x for x in set_atoms if x]
|
||||
|
||||
if not do_rebuild:
|
||||
set_atoms = [x for x in set_atoms if not \
|
||||
Entropy.Spm().match_installed_package(x)]
|
||||
spm.match_installed_package(x)]
|
||||
set_atoms = ["="+x for x in set_atoms]
|
||||
if not set_atoms:
|
||||
continue
|
||||
|
||||
args = [etpConst['spm']['exec']]
|
||||
args.extend(extra_args)
|
||||
args.extend(set_atoms)
|
||||
rc = subprocess.call(args)
|
||||
rc = spm.compile_packages(set_atoms, verbose = etpUi['verbose'],
|
||||
ask = etpUi['ask'], pretend = etpUi['pretend'])
|
||||
if rc != 0:
|
||||
return rc
|
||||
done_atoms.update(set_atoms)
|
||||
|
||||
Reference in New Issue
Block a user