[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:
Jérôme Lebleu 2016-03-08 15:56:29 +01:00
parent 735053ad14
commit 5afd0c1272
7 changed files with 109 additions and 55 deletions

View file

@ -196,12 +196,12 @@ if __name__ == '__main__':
# Run the server
from moulinette import api, MoulinetteError
from yunohost import get_versions
from yunohost.utils.packages import ynh_packages_version
ret = api(_retrieve_namespaces(),
host=opts.host, port=opts.port,
routes={
('GET', '/installed'): is_installed,
('GET', '/version'): get_versions,
('GET', '/version'): ynh_packages_version,
},
use_cache=opts.use_cache, use_websocket=opts.use_websocket
)

View file

@ -57,7 +57,7 @@ _global:
help: Display YunoHost packages versions
action: callback
callback:
method: yunohost.get_versions
method: yunohost.utils.packages.ynh_packages_version
return: true
#############################

View file

@ -202,6 +202,10 @@
"user_info_failed" : "Unable to retrieve user information",
"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",
"ask_firstname" : "First name",
"ask_lastname" : "Last name",

View file

@ -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

View file

@ -39,8 +39,8 @@ import subprocess
from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger
from . import has_min_version
from .service import service_log
from yunohost.service import service_log
from yunohost.utils.packages import has_min_version
logger = getActionLogger('yunohost.app')

View file

View 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',
)