| #!/usr/bin/python -tt |
| import argparse |
| import koji |
| import os |
| import re |
| import sys |
| import traceback |
| |
| from collections import namedtuple |
| |
| SigEntry = namedtuple('SigEntry', ['cbstag', 'localdir', 'remotedir', 'desturl']) |
| KOJI_URL = 'https://cbs.centos.org/kojihub/' |
| WARNING = "WARNING: {0}: {1} {2}" |
| ERROR = "ERROR: {0}: {1} {2}" |
| TAGREGEX = r'(?P<signame>\w+)(?P<centosversion>\d)-(.*)-(?P<releasestage>candidate|testing|release)$' |
| MIRRORREGEX = r'(?P<centosversion>\d)/(?P<signame>\w+)/(?P<sigstructure>.*)' |
| |
| |
| def main(files=[]): |
| |
| kojiclient = koji.ClientSession(KOJI_URL) |
| tags = [x.get('name') for x in kojiclient.listTags()] |
| |
| for filename in files: |
| print '='*10 + ' Linting: {0} '.format(filename) + '='*10 |
| with open(filename) as thefile: |
| lines = thefile.readlines() |
| |
| for lineno,line in enumerate(map(str.strip, lines)): |
| if line.startswith('#'): |
| continue |
| se = SigEntry(*line.split('|')) |
| |
| # Check that we put the right tags in the right list (testing -> buildlogs, release -> sign) |
| # and that the CentOS Version matches for all the URLs |
| try: |
| gs = re.match(TAGREGEX, se.cbstag.strip('/')).groupdict() |
| if gs['releasestage'] == 'release' and 'buildlogs' in filename: |
| msg = 'release tag in buildlogs list' |
| raise AssertionError |
| |
| if gs['releasestage'] == 'testing' and 'sign' in filename: |
| msg = 'testing tag in sign list' |
| raise AssertionError |
| |
| for attr in ['localdir','remotedir','desturl']: |
| are = re.match(MIRRORREGEX, se._asdict()[attr]).groupdict() |
| if are['centosversion'] != gs['centosversion']: |
| msg = 'version location of {0} does not match the CentOS Version of the CBS tag'.format(attr) |
| raise AssertionError |
| |
| except AttributeError, e: |
| msg = 'bad cbs tag!' |
| print e |
| print(ERROR.format(filename+':'+str(lineno), se.cbstag.strip('/'), msg)) |
| sys.exit(-1) |
| except AssertionError, e: |
| msg = msg or "Unkown error" |
| print(WARNING.format(filename+':'+str(lineno), se.cbstag.strip('/'), msg)) |
| continue |
| |
| # Check that we have trailing slashes for the path components so that RSYNC is happy |
| try: |
| for attr in ['cbstag','localdir','remotedir','desturl']: |
| assert(se._asdict()[attr].endswith('/')) |
| except AssertionError, e: |
| msg = '{} is missing trailing slash!'.format(attr) |
| print(WARNING.format(filename+':'+str(lineno), se.cbstag.strip('/'), msg)) |
| continue |
| |
| try: |
| assert(se.cbstag.strip('/') in tags) |
| except AssertionError, e: |
| print(ERROR.format(filename+':'+str(lineno), se.cbstag.strip('/'), 'CBS Tag does not exist!')) |
| sys.exit(-1) |
| |
| # Check to be sure all the tags have RPMs in them |
| try: |
| builds = kojiclient.getLatestBuilds(se.cbstag.strip('/')) |
| assert(len(builds) > 0) |
| except AssertionError, e: |
| print(ERROR.format(str(lineno), se.cbstag.strip('/'), 'No RPMS in tag!')) |
| sys.exit(-1) |
| |
| if __name__ == '__main__': |
| parser = argparse.ArgumentParser(description="Check the content control entries for sanity. If called without arguments, cclint will look in the current directory for any files named *_list") |
| |
| parser.add_argument('files', metavar='content-control-file', |
| type=str, nargs="*", help="the file to check", |
| default=filter(lambda x: '_list' in x, os.listdir('.')) |
| ) |
| |
| args = parser.parse_args() |
| main(args.files) |