[entropy] add support for packages-restricted separate packages directory
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Server side packages.db.restricted file
|
||||
# List here atoms (either package key or package key : slot) that should be
|
||||
# considered legally sensible such as libdvdcss and friends
|
||||
|
||||
# LINE CONSTRUCTION:
|
||||
# <atom>
|
||||
# See examples below
|
||||
|
||||
# EXAMPLES:
|
||||
# dev-libs/libdvdcss
|
||||
# app-foo/foo:2
|
||||
# app-foo/foo
|
||||
|
||||
# NOT ALLOWED:
|
||||
# >=app-foo/foo-1.2.3
|
||||
# <app-foo/foo-1.2.3
|
||||
# app-foo/foo-1.2.3
|
||||
@@ -220,7 +220,9 @@ def const_default_settings(rootdir):
|
||||
# returned by EntropyRepository.retrieveDownloadURL())
|
||||
'packagesrelativepath_basedir': "packages",
|
||||
'packagesrelativepath_basedir_nonfree': "packages-nonfree",
|
||||
'packagesrelativepaths': ("packages", "pacakges-nonfree"),
|
||||
'packagesrelativepath_basedir_restricted': "packages-restricted",
|
||||
'packagesrelativepaths': ("packages", "pacakges-nonfree",
|
||||
"packages-restricted"),
|
||||
'packagesrelativepath_basename': ETP_ARCH_CONST,
|
||||
|
||||
'entropyworkdir': default_etp_dir, # Entropy workdir
|
||||
@@ -249,6 +251,8 @@ def const_default_settings(rootdir):
|
||||
'etpdatabaseupdatefile': default_etp_dbfile+".repo_updates",
|
||||
'etpdatabaselicwhitelistfile': default_etp_dbfile+".lic_whitelist",
|
||||
'etpdatabasecriticalfile': default_etp_dbfile+".critical",
|
||||
# per-repository configuration file to list legally sensible pkgs
|
||||
'etpdatabaserestrictedfile': default_etp_dbfile+".restricted",
|
||||
# the local/remote database revision file
|
||||
'etpdatabaserevisionfile': default_etp_dbfile+".revision",
|
||||
# missing dependencies black list file
|
||||
|
||||
@@ -649,6 +649,13 @@ class ServerSystemSettingsPlugin(SystemSettingsPlugin):
|
||||
etpConst['packagesrelativepath_basedir_nonfree'],
|
||||
etpConst['currentarch']
|
||||
)
|
||||
data['repositories'][repoid]['packages_dir_restricted'] = \
|
||||
os.path.join( etpConst['entropyworkdir'],
|
||||
"server",
|
||||
repoid,
|
||||
etpConst['packagesrelativepath_basedir_restricted'],
|
||||
etpConst['currentarch']
|
||||
)
|
||||
data['repositories'][repoid]['store_dir'] = \
|
||||
os.path.join( etpConst['entropyworkdir'],
|
||||
"server",
|
||||
@@ -830,7 +837,8 @@ class ServerSettingsMixin:
|
||||
|
||||
def _get_pkg_dir_names(self):
|
||||
return [etpConst['packagesrelativepath_basedir'],
|
||||
etpConst['packagesrelativepath_basedir_nonfree']]
|
||||
etpConst['packagesrelativepath_basedir_nonfree'],
|
||||
etpConst['packagesrelativepath_basedir_restricted']]
|
||||
|
||||
def _get_remote_database_relative_path(self, repo = None):
|
||||
srv_set = self.SystemSettings[self.sys_settings_plugin_id]['server']
|
||||
@@ -1008,6 +1016,12 @@ class ServerSettingsMixin:
|
||||
return os.path.join(self._get_local_database_dir(repo, branch),
|
||||
etpConst['etpdatabasecriticalfile'])
|
||||
|
||||
def _get_local_restricted_file(self, repo = None, branch = None):
|
||||
if repo is None:
|
||||
repo = self.default_repository
|
||||
return os.path.join(self._get_local_database_dir(repo, branch),
|
||||
etpConst['etpdatabaserestrictedfile'])
|
||||
|
||||
def _get_local_database_keywords_file(self, repo = None, branch = None):
|
||||
if repo is None:
|
||||
repo = self.default_repository
|
||||
@@ -1869,15 +1883,26 @@ class ServerPackagesHandlingMixin:
|
||||
# we need the new path.
|
||||
updated_package_rel_path = package_rel_path
|
||||
srv_set = self.SystemSettings[self.sys_settings_plugin_id]['server']
|
||||
if srv_set['nonfree_packages_dir_support']:
|
||||
def _package_injector_check_license(licenses):
|
||||
return self._is_pkg_free(licenses, repo = to_repo)
|
||||
|
||||
tmp_data = self.Spm().extract_package_metadata(from_file,
|
||||
license_callback = _package_injector_check_license)
|
||||
updated_package_rel_path = tmp_data['download'][:]
|
||||
del tmp_data
|
||||
def _package_injector_check_license(pkg_data):
|
||||
licenses = pkg_data['license'].split()
|
||||
return self._is_pkg_free(licenses, repo = to_repo)
|
||||
|
||||
def _package_injector_check_restricted(pkg_data):
|
||||
pkgatom = entropy.tools.create_package_atom_string(
|
||||
pkg_data['category'], pkg_data['name'], pkg_data['version'],
|
||||
pkg_data['versiontag'])
|
||||
return self._is_pkg_restricted(pkgatom, pkg_data['slot'],
|
||||
repo = to_repo)
|
||||
|
||||
# check if pkg is restricted
|
||||
# and check if pkg is free, we must do this step in any case
|
||||
# XXX: it sucks!
|
||||
tmp_data = self.Spm().extract_package_metadata(from_file,
|
||||
license_callback = _package_injector_check_license,
|
||||
restricted_callback = _package_injector_check_restricted)
|
||||
updated_package_rel_path = tmp_data['download'][:]
|
||||
del tmp_data
|
||||
|
||||
to_file = self.complete_local_upload_package_path(
|
||||
updated_package_rel_path, repo = to_repo)
|
||||
@@ -3779,6 +3804,37 @@ class ServerRepositoryMixin:
|
||||
return []
|
||||
return entropy.tools.generic_file_content_parser(wl_file)
|
||||
|
||||
def _get_restricted_packages(self, repo = None):
|
||||
|
||||
if repo is None:
|
||||
repo = self.default_repository
|
||||
|
||||
rl_file = self._get_local_restricted_file(repo = repo)
|
||||
if not os.path.isfile(rl_file):
|
||||
return []
|
||||
return entropy.tools.generic_file_content_parser(rl_file)
|
||||
|
||||
def _is_pkg_restricted(self, pkg_atom, pkg_slot, repo = None):
|
||||
|
||||
if repo is None:
|
||||
repo = self.default_repository
|
||||
|
||||
restricted_pkgs = self._get_restricted_packages(repo = repo)
|
||||
if not restricted_pkgs:
|
||||
return False
|
||||
|
||||
pkg_key = entropy.tools.dep_getkey(pkg_atom)
|
||||
for r_dep in restricted_pkgs:
|
||||
r_key, r_slot = entropy.tools.dep_getkey(r_dep), \
|
||||
entropy.tools.dep_getslot(r_dep)
|
||||
if r_slot is None:
|
||||
r_slot = pkg_slot
|
||||
|
||||
if (r_key == pkg_key) and (r_slot == pkg_slot):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _is_pkg_free(self, pkg_licenses, repo = None):
|
||||
|
||||
if repo is None:
|
||||
@@ -3808,9 +3864,17 @@ class ServerRepositoryMixin:
|
||||
repo = self.default_repository
|
||||
srv_set = self.SystemSettings[self.sys_settings_plugin_id]['server']
|
||||
|
||||
def _package_injector_check_license(licenses):
|
||||
def _package_injector_check_license(pkg_data):
|
||||
licenses = pkg_data['license'].split()
|
||||
return self._is_pkg_free(licenses, repo = repo)
|
||||
|
||||
def _package_injector_check_restricted(pkg_data):
|
||||
pkgatom = entropy.tools.create_package_atom_string(
|
||||
pkg_data['category'], pkg_data['name'], pkg_data['version'],
|
||||
pkg_data['versiontag'])
|
||||
return self._is_pkg_restricted(pkgatom, pkg_data['slot'],
|
||||
repo = repo)
|
||||
|
||||
dbconn = self.open_server_repository(read_only = False,
|
||||
no_upload = True, repo = repo)
|
||||
self.output(
|
||||
@@ -3826,7 +3890,8 @@ class ServerRepositoryMixin:
|
||||
back = True
|
||||
)
|
||||
mydata = self.Spm().extract_package_metadata(package_file,
|
||||
license_callback = _package_injector_check_license)
|
||||
license_callback = _package_injector_check_license,
|
||||
restricted_callback = _package_injector_check_restricted)
|
||||
self._pump_extracted_package_metadata(mydata, repo,
|
||||
{'injected': inject,})
|
||||
idpackage, revision, mydata = dbconn.handlePackage(mydata)
|
||||
|
||||
@@ -1148,6 +1148,12 @@ class Server(ServerNoticeBoardMixin):
|
||||
data['critical_updates_file'] = critical_updates_file
|
||||
extra_text_files.append(critical_updates_file)
|
||||
|
||||
restricted_file = self.Entropy._get_local_restricted_file(repo)
|
||||
if os.path.isfile(restricted_file) or download:
|
||||
if download:
|
||||
data['restricted_file'] = restricted_file
|
||||
extra_text_files.append(restricted_file)
|
||||
|
||||
keywords_file = self.Entropy._get_local_database_keywords_file(
|
||||
repo)
|
||||
if os.path.isfile(keywords_file) or download:
|
||||
|
||||
@@ -232,7 +232,7 @@ class PortagePlugin(SpmPlugin):
|
||||
'global_make_profile': "/etc/make.profile",
|
||||
}
|
||||
|
||||
PLUGIN_API_VERSION = 4
|
||||
PLUGIN_API_VERSION = 5
|
||||
|
||||
SUPPORTED_MATCH_TYPES = [
|
||||
"bestmatch-visible", "cp-list", "list-visible", "match-all",
|
||||
@@ -759,7 +759,8 @@ class PortagePlugin(SpmPlugin):
|
||||
if defaults:
|
||||
return defaults[0]
|
||||
|
||||
def extract_package_metadata(self, package_file, license_callback = None):
|
||||
def extract_package_metadata(self, package_file, license_callback = None,
|
||||
restricted_callback = None):
|
||||
"""
|
||||
Reimplemented from SpmPlugin class.
|
||||
"""
|
||||
@@ -986,17 +987,6 @@ class PortagePlugin(SpmPlugin):
|
||||
# this actually changes provide format
|
||||
data['provide_extended'] = provide_extended
|
||||
|
||||
# prepare download URL string, check licenses
|
||||
nonfree = False
|
||||
if license_callback is not None:
|
||||
nonfree = not license_callback(data['license'].split())
|
||||
data['download'] = entropy.tools.create_package_dirpath(data['branch'],
|
||||
nonfree = nonfree)
|
||||
data['download'] = os.path.join(data['download'],
|
||||
entropy.tools.create_package_filename(
|
||||
data['category'], data['name'], data['version'],
|
||||
data['versiontag']))
|
||||
|
||||
# Get License text if possible
|
||||
licenses_dir = os.path.join(self.get_setting('PORTDIR'), 'licenses')
|
||||
data['licensedata'] = self._extract_pkg_metadata_license_data(
|
||||
@@ -1025,6 +1015,20 @@ class PortagePlugin(SpmPlugin):
|
||||
# etpapi must be int, as returned by entropy.db.getPackageData
|
||||
data['etpapi'] = int(etpConst['etpapi'])
|
||||
|
||||
# prepare download URL string, check licenses
|
||||
nonfree = False
|
||||
restricted = False
|
||||
if license_callback is not None:
|
||||
nonfree = not license_callback(data)
|
||||
if restricted_callback is not None:
|
||||
restricted = restricted_callback(data)
|
||||
data['download'] = entropy.tools.create_package_dirpath(data['branch'],
|
||||
nonfree = nonfree, restricted = restricted)
|
||||
data['download'] = os.path.join(data['download'],
|
||||
entropy.tools.create_package_filename(
|
||||
data['category'], data['name'], data['version'],
|
||||
data['versiontag']))
|
||||
|
||||
# removing temporary directory
|
||||
shutil.rmtree(tmp_dir, True)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from entropy.misc import LogFile
|
||||
class SpmPlugin(Singleton):
|
||||
"""Base class for Source Package Manager plugins"""
|
||||
|
||||
BASE_PLUGIN_API_VERSION = 4
|
||||
BASE_PLUGIN_API_VERSION = 5
|
||||
|
||||
# this must be reimplemented by subclasses and value
|
||||
# must match BASE_PLUGIN_API_VERSION
|
||||
@@ -359,18 +359,23 @@ class SpmPlugin(Singleton):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def extract_package_metadata(self, package_file, license_callback = None):
|
||||
def extract_package_metadata(self, package_file, license_callback = None,
|
||||
restricted_callback = None):
|
||||
"""
|
||||
Extract Source Package Manager package metadata from given file.
|
||||
|
||||
@param package_file: path to valid SPM package file
|
||||
@type package_file: string
|
||||
@param license_callback: if not None, it will be used to determine
|
||||
@keyword license_callback: if not None, it will be used to determine
|
||||
if package_file can be considered free (as in freedom) or not.
|
||||
Please return True if so, otherwise false. The signature of
|
||||
the callback is: bool callback(list), where list is a list of
|
||||
license names used by package_file.
|
||||
the callback is: bool callback(pkg_metadata).
|
||||
@type license_callback: callable
|
||||
@keyword restricted_callback: if not None, it will be used to determine
|
||||
if package_file can be considered legal in all countries or not.
|
||||
Please return True if so, otherwise false. The signature of
|
||||
the callback is: bool callback(pkg_metadata).
|
||||
@type restricted_callback: callable
|
||||
@return: package metadata extracted
|
||||
@rtype: dict
|
||||
@raise entropy.exceptions.SPMError: when something went bad
|
||||
|
||||
@@ -3116,7 +3116,7 @@ def collect_paths():
|
||||
"""
|
||||
return os.getenv("PATH", "").split(":")
|
||||
|
||||
def create_package_dirpath(branch, nonfree = False):
|
||||
def create_package_dirpath(branch, nonfree = False, restricted = False):
|
||||
"""
|
||||
Create Entropy package relative directory path used for building
|
||||
EntropyRepository "download" metadatum and for handling package file life
|
||||
@@ -3131,6 +3131,8 @@ def create_package_dirpath(branch, nonfree = False):
|
||||
"""
|
||||
if nonfree:
|
||||
down_rel_basedir = etpConst['packagesrelativepath_basedir_nonfree']
|
||||
elif restricted:
|
||||
down_rel_basedir = etpConst['packagesrelativepath_basedir_restricted']
|
||||
else:
|
||||
down_rel_basedir = etpConst['packagesrelativepath_basedir']
|
||||
down_rel_basename = etpConst['packagesrelativepath_basename']
|
||||
|
||||
Reference in New Issue
Block a user