diff --git a/requirements.txt b/requirements.txt index 131187d569..7995bf1523 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,5 @@ GitPython>=1.0.1 # BSD License (3 clause) six>=1.9.0 # MIT oslo.config>=3.7.0 # Apache-2.0 graphviz>=0.4.0 # MIT License +beautifulsoup4 # MIT +setuptools>=16.0 # PSF/ZPL diff --git a/tools/version_check.py b/tools/version_check.py new file mode 100755 index 0000000000..99fb167122 --- /dev/null +++ b/tools/version_check.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import re +import sys + +from bs4 import BeautifulSoup as bs +from oslo_config import cfg +import pkg_resources +import requests + +from kolla.common import config as common_config + + +# Use an OrderedDict to ensure the results are displayed alphabetically +MAJOR_VERSIONS_MAP = collections.OrderedDict([ + ('ceilometer', 5), + ('cinder', 7), + ('designate', 1), + ('glance', 11), + ('gnocchi', 1), + ('heat', 5), + ('horizon', 8), + ('ironic', 4), + ('keystone', 8), + ('magnum', 1), + ('murano', 1), + ('neutron', 7), + ('nova', 12), + ('swift', 2), + ('zaqar', 1) +]) + +TARBALLS_BASE_URL = 'http://tarballs.openstack.org' +VERSIONS = dict() + + +def retrieve_upstream_versions(): + upstream_versions = dict() + for project in MAJOR_VERSIONS_MAP: + winner = None + series = MAJOR_VERSIONS_MAP[project] + base = '{}/{}'.format(TARBALLS_BASE_URL, project) + r = requests.get(base) + s = bs(r.text, 'html.parser') + + for link in s.find_all('a'): + version = link.get('href') + if (version.endswith('.tar.gz') and + version.startswith('{}-{}'.format(project, series))): + split = '{}-|.tar.gz'.format(project) + candidate = re.split(split, version)[1] + if not winner or more_recent(candidate, winner): + winner = candidate + + if not winner: + print('Could not find version for {}'.format(project)) + continue + + upstream_versions[project] = winner + + VERSIONS['upstream'] = upstream_versions + + +def retrieve_local_versions(conf): + local_versions = dict() + for project in MAJOR_VERSIONS_MAP: + series = MAJOR_VERSIONS_MAP[project] + for project_section in [match.group(0) for match in + (re.search('^{}(?:-base)?$'.format(project), + section) for section in + conf._groups) if match]: + archive = conf[project_section]['location'].split('/')[-1] + if (archive.endswith('.tar.gz') and + archive.startswith('{}-{}'.format(project, series))): + split = '{}-|.tar.gz'.format(project) + local_versions[project] = re.split(split, archive)[1] + + VERSIONS['local'] = local_versions + + +def more_recent(candidate, reference): + return pkg_resources.parse_version(candidate) > \ + pkg_resources.parse_version(reference) + + +def diff_link(project, old_ref, new_ref): + return "https://github.com/openstack/{}/compare/{}...{}".format( + project, old_ref, new_ref) + + +def compare_versions(): + up_to_date = True + for project in VERSIONS['upstream']: + if project in VERSIONS['local']: + upstream_version = VERSIONS['upstream'][project] + local_version = VERSIONS['local'][project] + if more_recent(upstream_version, local_version): + print("{} has newer version {} > {}, see diff at {}".format( + project, upstream_version, local_version, + diff_link(project, local_version, upstream_version))) + up_to_date = False + if up_to_date: + print("Everything is up to date") + + +def main(): + conf = cfg.ConfigOpts() + common_config.parse(conf, sys.argv[1:], prog='kolla-build') + + retrieve_upstream_versions() + retrieve_local_versions(conf) + + compare_versions() + +if __name__ == '__main__': + main()