display archive information in the web UI
This commit is contained in:
parent
eb2ab28729
commit
124fad90f0
5 changed files with 221 additions and 13 deletions
|
|
@ -659,8 +659,8 @@ CREATE TABLE archivefiles (
|
|||
filename TEXT NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
md5sum TEXT,
|
||||
PRIMARY KEY (filename, archive_id)
|
||||
PRIMARY KEY (archive_id, filename)
|
||||
) WITHOUT OIDS;
|
||||
CREATE INDEX archivefiles_by_archive_id on archivefiles (archive_id);
|
||||
CREATE INDEX archivefiles_by_filename on archivefiles (filename);
|
||||
|
||||
COMMIT WORK;
|
||||
|
|
|
|||
142
hub/kojihub.py
142
hub/kojihub.py
|
|
@ -2472,6 +2472,131 @@ def get_maven_build(buildInfo, strict=False):
|
|||
WHERE build_id = %%(build_id)i""" % ', '.join(fields)
|
||||
return _singleRow(query, locals(), fields, strict)
|
||||
|
||||
def list_archives(buildInfo, type=None, queryOpts=None):
|
||||
"""
|
||||
Retrieve information about archives generated by a Maven build.
|
||||
buildInfo can be either a string (n-v-r) or an integer
|
||||
(build ID). Returns a list of maps containing the following keys:
|
||||
|
||||
id: unique id of the archive file (integer)
|
||||
type_id: id of the archive type (Java jar, Solaris pkg, Windows exe, etc.) (integer)
|
||||
build_id: id of the build that generated this archive (integer)
|
||||
buildroot_id: id of the buildroot where this archive was built (integer)
|
||||
filename: name of the archive (string)
|
||||
size: size of the archive (integer)
|
||||
md5sum: md5sum of the archive (string)
|
||||
|
||||
If 'type' is specified, then the archives listed will be limited
|
||||
those associated with additional metadata of the given type.
|
||||
Currently supported types are:
|
||||
|
||||
maven
|
||||
|
||||
If 'maven' is specified as a type, each returned map will contain
|
||||
these additional keys:
|
||||
|
||||
group_id: Maven groupId (string)
|
||||
artifact_id: Maven artifactId (string)
|
||||
version: Maven version (string)
|
||||
|
||||
If there are no archives associated with the specified build,
|
||||
an empty list is returned.
|
||||
"""
|
||||
build_id = find_build_id(buildInfo)
|
||||
if not build_id:
|
||||
raise koji.GenericError, 'No matching build found: %s' % buildInfo
|
||||
|
||||
values = {'build_id': build_id}
|
||||
|
||||
tables = ['archiveinfo']
|
||||
joins = []
|
||||
columns = ['id', 'type_id', 'build_id', 'buildroot_id', 'filename', 'size', 'md5sum']
|
||||
clauses = ['build_id = %(build_id)i']
|
||||
|
||||
if type is None:
|
||||
pass
|
||||
elif type == 'maven':
|
||||
tables.append('maven_archives')
|
||||
joins.append('archiveinfo.id = maven_archives.archive_id')
|
||||
columns.extend(['group_id', 'artifact_id', 'version'])
|
||||
else:
|
||||
raise koji.GenericError, 'unsupported archive type: %s' % type
|
||||
|
||||
return QueryProcessor(tables=tables, columns=columns, joins=joins,
|
||||
clauses=clauses, values=values, opts=queryOpts).execute()
|
||||
|
||||
def get_archive(archive_id):
|
||||
"""
|
||||
Get information about the archive with the given ID. Returns a map
|
||||
containing the following keys:
|
||||
|
||||
id: unique id of the archive file (integer)
|
||||
type_id: id of the archive type (Java jar, Solaris pkg, Windows exe, etc.) (integer)
|
||||
build_id: id of the build that generated this archive (integer)
|
||||
buildroot_id: id of the buildroot where this archive was built (integer)
|
||||
filename: name of the archive (string)
|
||||
size: size of the archive (integer)
|
||||
md5sum: md5sum of the archive (string)
|
||||
"""
|
||||
fields = ('id', 'type_id', 'build_id', 'buildroot_id', 'filename', 'size', 'md5sum')
|
||||
select = """SELECT %s FROM archiveinfo
|
||||
WHERE id = %%(archive_id)i""" % ', '.join(fields)
|
||||
return _singleRow(select, locals(), fields)
|
||||
|
||||
def get_maven_archive(archive_id):
|
||||
"""
|
||||
Retrieve Maven-specific information about an archive.
|
||||
Returns a map containing the following keys:
|
||||
|
||||
archive_id: id of the build (integer)
|
||||
group_id: Maven groupId (string)
|
||||
artifact_id: Maven artifact_Id (string)
|
||||
version: Maven version (string)
|
||||
"""
|
||||
fields = ('archive_id', 'group_id', 'artifact_id', 'version')
|
||||
select = """SELECT %s FROM maven_archives
|
||||
WHERE archive_id = %%(archive_id)i""" % ', '.join(fields)
|
||||
return _singleRow(select, locals(), fields)
|
||||
|
||||
def _get_archive_file_query(queryOpts):
|
||||
tables = ('archivefiles',)
|
||||
columns = ('archive_id', 'filename', 'size', 'md5sum')
|
||||
aliases = ('archive_id', 'name', 'size', 'md5')
|
||||
clauses = ('archive_id = %(archive_id)i',)
|
||||
return QueryProcessor(tables=tables, columns=columns,
|
||||
aliases=aliases, clauses=clauses,
|
||||
opts=queryOpts)
|
||||
|
||||
def list_archive_files(archive_id, queryOpts=None):
|
||||
"""
|
||||
Get information about the files contained in the archive with the given ID.
|
||||
Returns a list of maps with with following keys:
|
||||
|
||||
archive_id: id of the archive the file is contained in (integer)
|
||||
name: name of the file (string)
|
||||
md5: md5sum of the file (string)
|
||||
size: uncompressed size of the file (integer)
|
||||
"""
|
||||
query = _get_archive_file_query(queryOpts)
|
||||
query.values = {'archive_id': archive_id}
|
||||
return query.execute()
|
||||
|
||||
def get_archive_file(archive_id, filename):
|
||||
"""
|
||||
Get information about a file with the given filename
|
||||
contained in the archive with the given ID.
|
||||
Returns a map with with following keys:
|
||||
|
||||
archive_id: id of the archive the file is contained in (integer)
|
||||
name: name of the file (string)
|
||||
md5: md5sum of the file (string)
|
||||
size: uncompressed size of the file (integer)
|
||||
"""
|
||||
query = _get_archive_file_query(None)
|
||||
query.clauses += ('filename = %(filename)s',)
|
||||
query.values = {'archive_id': archive_id, 'filename': filename}
|
||||
return query.executeOne()
|
||||
|
||||
def _fetchMulti(query, values):
|
||||
"""Run the query and return all rows"""
|
||||
c = context.cnx.cursor()
|
||||
|
|
@ -3081,10 +3206,19 @@ def import_build_in_place(build):
|
|||
_dml(update,locals())
|
||||
return build_id
|
||||
|
||||
def get_archive_type(filename, strict=False):
|
||||
def _get_archive_type_by_id(type_id, strict=False):
|
||||
select = """SELECT id, name, description, extensions FROM archivetypes
|
||||
WHERE id = %(type_id)i"""
|
||||
return _singleRow(select, locals(), ('id', 'name', 'description', 'extensions'), strict)
|
||||
|
||||
def get_archive_type(filename_or_type_id, strict=False):
|
||||
"""
|
||||
Get the archive type for the given filename, based on the file extension.
|
||||
"""
|
||||
if isinstance(filename_or_type_id, int):
|
||||
return _get_archive_type_by_id(filename_or_type_id, strict)
|
||||
|
||||
filename = filename_or_type_id
|
||||
parts = filename.split('.')
|
||||
if len(parts) < 2:
|
||||
raise koji.GenericError, '%s does not have an extension, unable to determine file type' \
|
||||
|
|
@ -4528,6 +4662,12 @@ class RootExports(object):
|
|||
|
||||
getBuild = staticmethod(get_build)
|
||||
getMavenBuild = staticmethod(get_maven_build)
|
||||
getArchiveType = staticmethod(get_archive_type)
|
||||
listArchives = staticmethod(list_archives)
|
||||
getArchive = staticmethod(get_archive)
|
||||
getMavenArchive = staticmethod(get_maven_archive)
|
||||
listArchiveFiles = staticmethod(list_archive_files)
|
||||
getArchiveFile = staticmethod(get_archive_file)
|
||||
getChangelogEntries = staticmethod(get_changelog_entries)
|
||||
|
||||
def cancelBuild(self, buildID):
|
||||
|
|
|
|||
|
|
@ -105,6 +105,22 @@
|
|||
#end if
|
||||
</td>
|
||||
</tr>
|
||||
#if $archives
|
||||
<tr>
|
||||
<th>Archives</th>
|
||||
<td class="container">
|
||||
<table class="nested">
|
||||
#for $archive in $archives
|
||||
<tr>
|
||||
<td>
|
||||
$archive.filename (<a href="archiveinfo?archiveID=$archive.id">info</a>)
|
||||
</td>
|
||||
</tr>
|
||||
#end for
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
#end if
|
||||
#if $changelog
|
||||
<tr>
|
||||
<th>Changelog</th>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<tr>
|
||||
<th>Size</th><td>$file.size</td>
|
||||
</tr>
|
||||
#if $rpm
|
||||
<tr>
|
||||
<th>Flags</th>
|
||||
<td>
|
||||
|
|
@ -25,6 +26,11 @@
|
|||
#set $epoch = ($rpm.epoch != None and $str($rpm.epoch) + ':' or '')
|
||||
<th>RPM</th><td><a href="rpminfo?rpmID=$rpm.id">$rpm.name-$epoch$rpm.version-$rpm.release.${rpm.arch}.rpm</td>
|
||||
</tr>
|
||||
#elif $archive
|
||||
<tr>
|
||||
<th>Archive</th><td><a href="archiveinfo?archiveID=$archive.id">$archive.filename</a></td>
|
||||
</tr>
|
||||
#end if
|
||||
</table>
|
||||
|
||||
#include "includes/footer.chtml"
|
||||
|
|
|
|||
|
|
@ -810,6 +810,7 @@ def buildinfo(req, buildID):
|
|||
rpms = server.listBuildRPMs(build['id'])
|
||||
rpms.sort(_sortbyname)
|
||||
mavenbuild = server.getMavenBuild(buildID)
|
||||
archives = server.listArchives(build['id'], queryOpts={'order': 'filename'})
|
||||
|
||||
if build['task_id']:
|
||||
task = server.getTaskInfo(build['task_id'], request=True)
|
||||
|
|
@ -821,10 +822,13 @@ def buildinfo(req, buildID):
|
|||
values['rpms'] = rpms
|
||||
values['task'] = task
|
||||
values['mavenbuild'] = mavenbuild
|
||||
values['archives'] = archives
|
||||
|
||||
if req.currentUser:
|
||||
values['perms'] = server.getUserPerms(req.currentUser['id'])
|
||||
else:
|
||||
values['perms'] = []
|
||||
|
||||
values['changelog'] = server.getChangelogEntries(build['id'])
|
||||
if build['state'] == koji.BUILD_STATES['BUILDING']:
|
||||
avgDuration = server.getAverageBuildDuration(build['package_id'])
|
||||
|
|
@ -964,19 +968,61 @@ def rpminfo(req, rpmID, fileOrder='name', fileStart=None):
|
|||
|
||||
return _genHTML(req, 'rpminfo.chtml')
|
||||
|
||||
def fileinfo(req, rpmID, filename):
|
||||
def archiveinfo(req, archiveID, fileOrder='name', fileStart=None):
|
||||
values = _initValues(req, 'Archive Info', 'builds')
|
||||
server = _getServer(req)
|
||||
|
||||
archiveID = int(archiveID)
|
||||
archive = server.getArchive(archiveID)
|
||||
archive_type = server.getArchiveType(archive['type_id'])
|
||||
build = server.getBuild(archive['build_id'])
|
||||
maveninfo = server.getMavenArchive(archive['id'])
|
||||
builtInRoot = None
|
||||
if archive['buildroot_id'] != None:
|
||||
builtInRoot = server.getBuildroot(rpm['buildroot_id'])
|
||||
files = kojiweb.util.paginateMethod(server, values, 'listArchiveFiles', args=[archive['id']],
|
||||
start=fileStart, dataName='files', prefix='file', order=fileOrder)
|
||||
|
||||
values['archiveID'] = archive['id']
|
||||
values['archive'] = archive
|
||||
values['archive_type'] = archive_type
|
||||
values['build'] = build
|
||||
values['maveninfo'] = maveninfo
|
||||
values['builtInRoot'] = builtInRoot
|
||||
|
||||
# XXX FIXME
|
||||
values['buildroots'] = []
|
||||
|
||||
return _genHTML(req, 'archiveinfo.chtml')
|
||||
|
||||
def fileinfo(req, filename, rpmID=None, archiveID=None):
|
||||
values = _initValues(req, 'File Info', 'builds')
|
||||
server = _getServer(req)
|
||||
|
||||
rpmID = int(rpmID)
|
||||
rpm = server.getRPM(rpmID)
|
||||
if not rpm:
|
||||
raise koji.GenericError, 'invalid RPM ID: %i' % rpmID
|
||||
file = server.getRPMFile(rpmID, filename)
|
||||
if not file:
|
||||
raise koji.GenericError, 'no file %s in RPM %i' % (filename, rpmID)
|
||||
|
||||
values['rpm'] = rpm
|
||||
values['rpm'] = None
|
||||
values['archive'] = None
|
||||
|
||||
if rpmID:
|
||||
rpmID = int(rpmID)
|
||||
rpm = server.getRPM(rpmID)
|
||||
if not rpm:
|
||||
raise koji.GenericError, 'invalid RPM ID: %i' % rpmID
|
||||
file = server.getRPMFile(rpm['id'], filename)
|
||||
if not file:
|
||||
raise koji.GenericError, 'no file %s in RPM %i' % (filename, rpmID)
|
||||
values['rpm'] = rpm
|
||||
elif archiveID:
|
||||
archiveID = int(archiveID)
|
||||
archive = server.getArchive(archiveID)
|
||||
if not archive:
|
||||
raise koji.GenericError, 'invalid archive ID: %i' % archiveID
|
||||
file = server.getArchiveFile(archive['id'], filename)
|
||||
if not file:
|
||||
raise koji.GenericError, 'no file %s in archive %i' % (filename, archiveID)
|
||||
values['archive'] = archive
|
||||
else:
|
||||
raise koji.GenericError, 'either rpmID or archiveID must be specified'
|
||||
|
||||
values['file'] = file
|
||||
|
||||
return _genHTML(req, 'fileinfo.chtml')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue