mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] Rely on APT python library to retrieve packages version
It introduces a new `yunohost.utils` package which will contain common utils used by YunoHost actions. It comes with a work in progress `packages` module with simple methods to retrieve installed version of packages for now.
This commit is contained in:
parent
735053ad14
commit
5afd0c1272
7 changed files with 109 additions and 55 deletions
|
@ -196,12 +196,12 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
# Run the server
|
# Run the server
|
||||||
from moulinette import api, MoulinetteError
|
from moulinette import api, MoulinetteError
|
||||||
from yunohost import get_versions
|
from yunohost.utils.packages import ynh_packages_version
|
||||||
ret = api(_retrieve_namespaces(),
|
ret = api(_retrieve_namespaces(),
|
||||||
host=opts.host, port=opts.port,
|
host=opts.host, port=opts.port,
|
||||||
routes={
|
routes={
|
||||||
('GET', '/installed'): is_installed,
|
('GET', '/installed'): is_installed,
|
||||||
('GET', '/version'): get_versions,
|
('GET', '/version'): ynh_packages_version,
|
||||||
},
|
},
|
||||||
use_cache=opts.use_cache, use_websocket=opts.use_websocket
|
use_cache=opts.use_cache, use_websocket=opts.use_websocket
|
||||||
)
|
)
|
||||||
|
|
|
@ -57,7 +57,7 @@ _global:
|
||||||
help: Display YunoHost packages versions
|
help: Display YunoHost packages versions
|
||||||
action: callback
|
action: callback
|
||||||
callback:
|
callback:
|
||||||
method: yunohost.get_versions
|
method: yunohost.utils.packages.ynh_packages_version
|
||||||
return: true
|
return: true
|
||||||
|
|
||||||
#############################
|
#############################
|
||||||
|
|
|
@ -202,6 +202,10 @@
|
||||||
"user_info_failed" : "Unable to retrieve user information",
|
"user_info_failed" : "Unable to retrieve user information",
|
||||||
"user_home_creation_failed" : "Unable to create user home folder",
|
"user_home_creation_failed" : "Unable to create user home folder",
|
||||||
|
|
||||||
|
"package_unexpected_error" : "An unexpected error occured with the package '{pkgname}'",
|
||||||
|
"package_unknown" : "Unknown package '{pkgname}'",
|
||||||
|
"package_not_installed" : "Package '{pkgname}' is not installed",
|
||||||
|
|
||||||
"admin_password" : "Administration password",
|
"admin_password" : "Administration password",
|
||||||
"ask_firstname" : "First name",
|
"ask_firstname" : "First name",
|
||||||
"ask_lastname" : "Last name",
|
"ask_lastname" : "Last name",
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
""" YunoHost scripts for the moulinette """
|
|
||||||
|
|
||||||
""" License
|
|
||||||
|
|
||||||
Copyright (C) 2015 YUNOHOST.ORG
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program; if not, see http://www.gnu.org/licenses
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
## Packages versions
|
|
||||||
|
|
||||||
def get_version(package):
|
|
||||||
"""Get the version of package"""
|
|
||||||
from moulinette.utils import process
|
|
||||||
return process.check_output(
|
|
||||||
"dpkg-query -W -f='${{Version}}' {0}".format(package)
|
|
||||||
).strip()
|
|
||||||
|
|
||||||
def get_versions(*args, **kwargs):
|
|
||||||
"""Get the version of each YunoHost package"""
|
|
||||||
from collections import OrderedDict
|
|
||||||
return OrderedDict([
|
|
||||||
('moulinette', get_version('moulinette')),
|
|
||||||
('yunohost', get_version('yunohost')),
|
|
||||||
('yunohost-admin', get_version('yunohost-admin')),
|
|
||||||
('ssowat', get_version('ssowat')),
|
|
||||||
])
|
|
||||||
|
|
||||||
def has_min_version(min_version, package='yunohost', strict=False):
|
|
||||||
"""Check if a package has minimum version"""
|
|
||||||
from distutils.version import LooseVersion, StrictVersion
|
|
||||||
cmp_cls = StrictVersion if strict else LooseVersion
|
|
||||||
version = cmp_cls(get_version(package))
|
|
||||||
if version >= cmp_cls(min_version):
|
|
||||||
return True
|
|
||||||
return False
|
|
|
@ -39,8 +39,8 @@ import subprocess
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from . import has_min_version
|
from yunohost.service import service_log
|
||||||
from .service import service_log
|
from yunohost.utils.packages import has_min_version
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.app')
|
logger = getActionLogger('yunohost.app')
|
||||||
|
|
||||||
|
|
0
src/yunohost/utils/__init__.py
Normal file
0
src/yunohost/utils/__init__.py
Normal file
100
src/yunohost/utils/packages.py
Normal file
100
src/yunohost/utils/packages.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" License
|
||||||
|
|
||||||
|
Copyright (C) 2015 YUNOHOST.ORG
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program; if not, see http://www.gnu.org/licenses
|
||||||
|
|
||||||
|
"""
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
import apt
|
||||||
|
from apt_pkg import version_compare
|
||||||
|
|
||||||
|
|
||||||
|
# Exceptions -----------------------------------------------------------------
|
||||||
|
|
||||||
|
class PackageException(Exception):
|
||||||
|
"""Base exception related to a package
|
||||||
|
|
||||||
|
Represent an exception related to the package named `pkgname`. If no
|
||||||
|
`message` is provided, it will first try to use the translation key
|
||||||
|
`message_key` if defined by the derived class. Otherwise, a standard
|
||||||
|
message will be used.
|
||||||
|
|
||||||
|
"""
|
||||||
|
message_key = 'package_unexpected_error'
|
||||||
|
|
||||||
|
def __init__(self, pkgname, message=None):
|
||||||
|
super(PackageException, self).__init__(
|
||||||
|
message or m18n.n(self.message_key, pkgname=pkgname))
|
||||||
|
self.pkgname = pkgname
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownPackage(PackageException):
|
||||||
|
message_key = 'package_unknown'
|
||||||
|
|
||||||
|
|
||||||
|
class UninstalledPackage(PackageException):
|
||||||
|
message_key = 'package_not_installed'
|
||||||
|
|
||||||
|
|
||||||
|
# Packages and cache helpers -------------------------------------------------
|
||||||
|
|
||||||
|
def get_installed_version(*pkgnames, **kwargs):
|
||||||
|
"""Get the installed version of package(s)
|
||||||
|
|
||||||
|
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
|
||||||
|
`True`, an exception will be raised if a package is unknown or not
|
||||||
|
installed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
cache = apt.Cache()
|
||||||
|
strict = kwargs.get('strict', False)
|
||||||
|
versions = OrderedDict()
|
||||||
|
for pkgname in pkgnames:
|
||||||
|
try:
|
||||||
|
pkg = cache[pkgname]
|
||||||
|
except KeyError:
|
||||||
|
if strict:
|
||||||
|
raise UnknownPackage(pkgname)
|
||||||
|
logger.warning(m18n.n('package_unknown', pkgname=pkgname))
|
||||||
|
try:
|
||||||
|
version = pkg.installed.version
|
||||||
|
except AttributeError:
|
||||||
|
if strict:
|
||||||
|
raise UninstalledPackage(pkgname)
|
||||||
|
version = None
|
||||||
|
versions[pkgname] = version
|
||||||
|
if len(pkgnames) == 1:
|
||||||
|
return versions[pkgnames[0]]
|
||||||
|
return versions
|
||||||
|
|
||||||
|
def has_min_version(min_version, package='yunohost'):
|
||||||
|
"""Check if a package has a minimum installed version"""
|
||||||
|
version = get_installed_version(package)
|
||||||
|
if version_compare(version, min_version) > 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# YunoHost related methods ---------------------------------------------------
|
||||||
|
|
||||||
|
def ynh_packages_version(*args, **kwargs):
|
||||||
|
"""Return the version of each YunoHost package"""
|
||||||
|
return get_installed_version(
|
||||||
|
'yunohost', 'yunohost-admin', 'moulinette', 'ssowat',
|
||||||
|
)
|
Loading…
Add table
Reference in a new issue