mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] Introduce new 'requirements' manifest key (close #113)
The 'requirements' key allows to specify the Debian packages which must be installed and their required version. It must be an array of the package name as the key and its version specifier - for its format, see yunohost.utils.packages.Specifier - as value. For example: "requirements": { "yunohost": ">= 2.4, << 2.5" }
This commit is contained in:
parent
cc4dc54ed3
commit
fba14e55df
3 changed files with 49 additions and 22 deletions
|
@ -20,7 +20,9 @@
|
||||||
"app_not_installed" : "{app:s} is not installed",
|
"app_not_installed" : "{app:s} is not installed",
|
||||||
"app_not_correctly_installed" : "{app:s} seems to be not correctly installed",
|
"app_not_correctly_installed" : "{app:s} seems to be not correctly installed",
|
||||||
"custom_app_url_required" : "You must provide an URL to upgrade your custom app {app:s}",
|
"custom_app_url_required" : "You must provide an URL to upgrade your custom app {app:s}",
|
||||||
"app_recent_version_required" : "{app:s} requires a more recent version of YunoHost",
|
"app_requirements_checking" : "Checking required packages...",
|
||||||
|
"app_requirements_unmeet" : "Requirements are not met, the package {pkgname} ({version}) must be {spec}",
|
||||||
|
"app_requirements_failed" : "Unable to meet requirements: {err}",
|
||||||
"app_upgraded" : "{app:s} successfully upgraded",
|
"app_upgraded" : "{app:s} successfully upgraded",
|
||||||
"app_upgrade_failed" : "Unable to upgrade {app:s}",
|
"app_upgrade_failed" : "Unable to upgrade {app:s}",
|
||||||
"app_id_invalid" : "Invalid app id",
|
"app_id_invalid" : "Invalid app id",
|
||||||
|
|
|
@ -40,7 +40,7 @@ from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.service import service_log
|
from yunohost.service import service_log
|
||||||
from yunohost.utils.packages import meets_version_specifier
|
from yunohost.utils import packages
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.app')
|
logger = getActionLogger('yunohost.app')
|
||||||
|
|
||||||
|
@ -358,13 +358,8 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Check min version
|
# Check requirements
|
||||||
if 'min_version' in manifest \
|
_check_manifest_requirements(manifest)
|
||||||
and not meets_version_specifier(
|
|
||||||
'yunohost', '>> {0}'.format(manifest['min_version'])):
|
|
||||||
raise MoulinetteError(errno.EPERM,
|
|
||||||
m18n.n('app_recent_version_required',
|
|
||||||
app=app_id))
|
|
||||||
|
|
||||||
app_setting_path = apps_setting_path +'/'+ app_id
|
app_setting_path = apps_setting_path +'/'+ app_id
|
||||||
|
|
||||||
|
@ -451,13 +446,8 @@ def app_install(auth, app, label=None, args=None):
|
||||||
|
|
||||||
app_id = manifest['id']
|
app_id = manifest['id']
|
||||||
|
|
||||||
# Check min version
|
# Check requirements
|
||||||
if 'min_version' in manifest \
|
_check_manifest_requirements(manifest)
|
||||||
and not meets_version_specifier(
|
|
||||||
'yunohost', '>> {0}'.format(manifest['min_version'])):
|
|
||||||
raise MoulinetteError(errno.EPERM,
|
|
||||||
m18n.n('app_recent_version_required',
|
|
||||||
app=app_id))
|
|
||||||
|
|
||||||
# Check if app can be forked
|
# Check if app can be forked
|
||||||
instance_number = _installed_instance_number(app_id, last=True) + 1
|
instance_number = _installed_instance_number(app_id, last=True) + 1
|
||||||
|
@ -1371,6 +1361,36 @@ def _encode_string(value):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _check_manifest_requirements(manifest):
|
||||||
|
"""Check if required packages are met from the manifest"""
|
||||||
|
requirements = manifest.get('requirements', dict())
|
||||||
|
# FIXME: Deprecate min_version key
|
||||||
|
if 'min_version' in manifest:
|
||||||
|
requirements['yunohost'] = '>> {0}'.format(manifest['min_version'])
|
||||||
|
logger.debug("the manifest key 'min_version' is deprecated, "
|
||||||
|
"use 'requirements' instead.")
|
||||||
|
if not requirements:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(m18n.n('app_requirements_checking'))
|
||||||
|
|
||||||
|
# Retrieve versions of each required package
|
||||||
|
try:
|
||||||
|
versions = packages.get_installed_version(
|
||||||
|
*requirements.keys(), strict=True, as_dict=True)
|
||||||
|
except packages.PackageException as e:
|
||||||
|
raise MoulinetteError(errno.EINVAL,
|
||||||
|
m18n.n('app_requirements_failed', err=str(e)))
|
||||||
|
|
||||||
|
# Iterate over requirements
|
||||||
|
for pkgname, spec in requirements.items():
|
||||||
|
version = versions[pkgname]
|
||||||
|
if version not in packages.SpecifierSet(spec):
|
||||||
|
raise MoulinetteError(
|
||||||
|
errno.EINVAL, m18n.n('app_requirements_unmeet',
|
||||||
|
pkgname=pkgname, version=version,
|
||||||
|
spec=spec))
|
||||||
|
|
||||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
"""Parse arguments needed for an action from the manifest
|
"""Parse arguments needed for an action from the manifest
|
||||||
|
|
||||||
|
|
|
@ -250,14 +250,18 @@ def get_installed_version(*pkgnames, **kwargs):
|
||||||
"""Get the installed version of package(s)
|
"""Get the installed version of package(s)
|
||||||
|
|
||||||
Retrieve one or more packages named `pkgnames` and return their installed
|
Retrieve one or more packages named `pkgnames` and return their installed
|
||||||
version as a dict or as a string if only one is requested. If `strict` is
|
version as a dict or as a string if only one is requested and `as_dict` is
|
||||||
`True`, an exception will be raised if a package is unknown or not
|
`False`. If `strict` is `True`, an exception will be raised if a package
|
||||||
installed.
|
is unknown or not installed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
cache = apt.Cache()
|
|
||||||
strict = kwargs.get('strict', False)
|
|
||||||
versions = OrderedDict()
|
versions = OrderedDict()
|
||||||
|
cache = apt.Cache()
|
||||||
|
|
||||||
|
# Retrieve options
|
||||||
|
as_dict = kwargs.get('as_dict', False)
|
||||||
|
strict = kwargs.get('strict', False)
|
||||||
|
|
||||||
for pkgname in pkgnames:
|
for pkgname in pkgnames:
|
||||||
try:
|
try:
|
||||||
pkg = cache[pkgname]
|
pkg = cache[pkgname]
|
||||||
|
@ -272,7 +276,8 @@ def get_installed_version(*pkgnames, **kwargs):
|
||||||
raise UninstalledPackage(pkgname)
|
raise UninstalledPackage(pkgname)
|
||||||
version = None
|
version = None
|
||||||
versions[pkgname] = version
|
versions[pkgname] = version
|
||||||
if len(pkgnames) == 1:
|
|
||||||
|
if len(pkgnames) == 1 and not as_dict:
|
||||||
return versions[pkgnames[0]]
|
return versions[pkgnames[0]]
|
||||||
return versions
|
return versions
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue