Commit 9a5e60ef authored by Leo Iannacone's avatar Leo Iannacone

Merge remote-tracking branch 'github/sbuild' into sbuild

parents 6e198d93 5e000d58
debomatic-webui debomatic-webui
=============== ===============
**debomatic-webui** is a web interface for [Deb-o-Matic](https://launchpad.net/debomatic) aims to give to users a simple way to browse logs and to know what's going on debomatic build service providing a real-time packages status. **debomatic-webui** is a web interface for [Deb-o-Matic](http://debomatic.github.io) aims to give to users a simple way to browse logs and to know what's going on debomatic build service providing a real-time packages status.
This interface is built up on [node](http://nodejs.org/) platform and uses intensely [socket.io](http://socket.io/) and [jquery](http://jquery.com/) technologies. This interface is built up on [node](http://nodejs.org/) platform and uses intensely [socket.io](http://socket.io/) and [jquery](http://jquery.com/) technologies.
Whenever you want to leave a suggestion or file a bug report, please open a [new issue](https://github.com/LeoIannacone/debomatic-webui/issues). Whenever you want to leave a suggestion or file a bug report, please open a [new issue](https://github.com/LeoIannacone/debomatic-webui/issues).
......
...@@ -32,6 +32,7 @@ from collections import defaultdict ...@@ -32,6 +32,7 @@ from collections import defaultdict
class DebomaticModule_JSONLoggerStart: class DebomaticModule_JSONLoggerStart:
def __init__(self): def __init__(self):
self.logger = DebomaticModule_JSONLogger() self.logger = DebomaticModule_JSONLogger()
self.first = True self.first = True
...@@ -44,6 +45,7 @@ class DebomaticModule_JSONLoggerStart: ...@@ -44,6 +45,7 @@ class DebomaticModule_JSONLoggerStart:
class DebomaticModule_JSONLoggerStop: class DebomaticModule_JSONLoggerStop:
def __init__(self): def __init__(self):
self.logger = DebomaticModule_JSONLogger() self.logger = DebomaticModule_JSONLogger()
self.last = True self.last = True
...@@ -64,30 +66,30 @@ class DebomaticModule_JSONLogger: ...@@ -64,30 +66,30 @@ class DebomaticModule_JSONLogger:
def _set_json_logfile_name(self, args): def _set_json_logfile_name(self, args):
"""If debomatic config file has section [jsonlogger] try to get """If debomatic config file has section [jsonlogger] try to get
'jsonfile' option and override the default value.""" 'jsonfile' option and override the default value."""
if 'opts' in args and \ if (args.opts.has_section('jsonlogger') and
args['opts'].has_section('jsonlogger') and \ args.opts.has_option('jsonlogger', 'jsonfile')):
args['opts'].has_option('jsonlogger', 'jsonfile'): self.jsonfile = args.opts.get('jsonlogger', 'jsonfile').strip()
self.jsonfile = args['opts'].get('jsonlogger', 'jsonfile').strip()
def _get_package_json_filename(self, args): def _get_package_json_filename(self, args):
"""Get the path of package JSON file""" """Get the path of package JSON file"""
return '%(directory)s/pool/%(package)s/%(package)s.json' % args return ('%(directory)s/pool/%(package)s/%(package)s.json' %
{'directory': args.directory, 'package': args.package})
def _get_distribution_status(self, args): def _get_distribution_status(self, args, with_success=False):
"""From args to distribution status""" """From args to distribution status"""
status = {} status = {}
status['status'] = args['cmd'] status['status'] = args.action
status['distribution'] = args['distribution'] status['distribution'] = args.distribution
if 'success' in args: if with_success:
status['success'] = args['success'] status['success'] = args.success
return status return status
def _get_package_status(self, args): def _get_package_status(self, args):
"""From args to package status""" """From args to package status"""
status = {} status = {}
for k in ['package', 'distribution', 'uploader']: status['package'] = args.package
if k in args: status['distribution'] = args.distribution
status[k] = args[k] status['uploader'] = args.uploader
return status return status
def _append_json_logfile(self, args, status): def _append_json_logfile(self, args, status):
...@@ -126,11 +128,15 @@ class DebomaticModule_JSONLogger: ...@@ -126,11 +128,15 @@ class DebomaticModule_JSONLogger:
num /= 1024.0 num /= 1024.0
def pre_chroot(self, args): def pre_chroot(self, args):
if args.action is None:
return
distribution = self._get_distribution_status(args) distribution = self._get_distribution_status(args)
self._append_json_logfile(args, distribution) self._append_json_logfile(args, distribution)
def post_chroot(self, args): def post_chroot(self, args):
distribution = self._get_distribution_status(args) if args.action is None:
return
distribution = self._get_distribution_status(args, with_success=True)
self._append_json_logfile(args, distribution) self._append_json_logfile(args, distribution)
def pre_build(self, args): def pre_build(self, args):
...@@ -145,18 +151,19 @@ class DebomaticModule_JSONLogger: ...@@ -145,18 +151,19 @@ class DebomaticModule_JSONLogger:
def post_build(self, args): def post_build(self, args):
status = self._get_package_status(args) status = self._get_package_status(args)
status['status'] = 'build' status['status'] = 'build'
status['success'] = args['success'] status['success'] = args.success
status['files'] = {} status['files'] = {}
resultdir = os.path.join(args['directory'], 'pool', args['package']) resultdir = os.path.join(args.directory, 'pool', args.package)
for filename in os.listdir(resultdir): for filename in os.listdir(resultdir):
if filename.endswith('.json'): if filename.endswith('.json'):
continue continue
full_path = os.path.join(resultdir, filename) full_path = os.path.join(resultdir, filename)
info = {} info = {}
info['size'] = self._get_human_size(os.path.getsize(full_path)) info['size'] = self._get_human_size(os.path.getsize(full_path))
tag = LogParser(full_path).parse() tag, level = LogParser(full_path).parse()
if tag: if tag:
info['tags'] = tag info['tags'] = tag
info['level'] = level
status['files'][filename] = info status['files'][filename] = info
self._write_package_json(args, status) self._write_package_json(args, status)
status.pop('files', None) status.pop('files', None)
...@@ -165,6 +172,7 @@ class DebomaticModule_JSONLogger: ...@@ -165,6 +172,7 @@ class DebomaticModule_JSONLogger:
# Parser for log files # Parser for log files
class LogParser(): class LogParser():
def __init__(self, file_path): def __init__(self, file_path):
self.file = file_path self.file = file_path
self.basename = os.path.basename(file_path) self.basename = os.path.basename(file_path)
...@@ -173,16 +181,18 @@ class LogParser(): ...@@ -173,16 +181,18 @@ class LogParser():
def parse(self): def parse(self):
if not os.path.isfile(self.file): if not os.path.isfile(self.file):
return None return None
result = None tag = None
# level can be: info, warning, danger
level = "info" # by default
if self.extension == 'lintian': if self.extension == 'lintian':
result = self.parse_lintian() tag, level = self.parse_lintian()
elif self.extension == 'autopkgtest': elif self.extension == 'autopkgtest':
result = self.parse_autopkgtest() tag, level = self.parse_autopkgtest()
elif self.extension == 'piuparts': elif self.extension == 'piuparts':
result = self.parse_piuparts() tag, level = self.parse_piuparts()
elif self.extension == 'blhc': elif self.extension == 'blhc':
result = self.parse_blhc() tag, level = self.parse_blhc()
return result return tag, level
def parse_lintian(self): def parse_lintian(self):
tags = defaultdict(int) tags = defaultdict(int)
...@@ -190,7 +200,13 @@ class LogParser(): ...@@ -190,7 +200,13 @@ class LogParser():
for line in fd: for line in fd:
if len(line) >= 2 and line[0] != 'N' and line[1] == ':': if len(line) >= 2 and line[0] != 'N' and line[1] == ':':
tags[line[0]] += 1 tags[line[0]] += 1
return self._from_tags_to_result(tags) tags = self._from_tags_to_result(tags)
level = "info"
if 'E' in tags:
level = "danger"
elif 'W' in tags:
level = "warning"
return tags, level
def parse_autopkgtest(self): def parse_autopkgtest(self):
tags = defaultdict(int) tags = defaultdict(int)
...@@ -211,14 +227,14 @@ class LogParser(): ...@@ -211,14 +227,14 @@ class LogParser():
tags[info[0]] += 1 tags[info[0]] += 1
elif found and line == '\n': elif found and line == '\n':
break break
return self._from_tags_to_result(tags) return self._from_tags_to_result(tags), 'danger'
def parse_piuparts(self): def parse_piuparts(self):
with open(self.file, 'r') as fd: with open(self.file, 'r') as fd:
lines = fd.readlines() lines = fd.readlines()
if len(lines) == 0 or lines[-1].find('ERROR:') >= 0: if len(lines) == 0 or lines[-1].find('ERROR:') >= 0:
return 'E' return 'E', 'danger'
return None return None, None
def parse_blhc(self): def parse_blhc(self):
tags = defaultdict(int) tags = defaultdict(int)
...@@ -229,7 +245,7 @@ class LogParser(): ...@@ -229,7 +245,7 @@ class LogParser():
continue continue
tag = info[0].replace('FLAGS', '') tag = info[0].replace('FLAGS', '')
tags[tag] += 1 tags[tag] += 1
return ' '.join(sorted(list(tags.keys()))) return ' '.join(sorted(list(tags.keys()))), 'warning'
def _from_tags_to_result(self, tags): def _from_tags_to_result(self, tags):
keys = sorted(list(tags.keys())) keys = sorted(list(tags.keys()))
......
...@@ -88,6 +88,7 @@ List of files to not show in webui ...@@ -88,6 +88,7 @@ List of files to not show in webui
config.debomatic.excluded_files = [ config.debomatic.excluded_files = [
"datestamp" "datestamp"
"json" "json"
"build"
] ]
### ###
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
"serve-static": "*", "serve-static": "*",
"errorhandler ": "*", "errorhandler ": "*",
"ejs": "1.*", "ejs": "1.*",
"socket.io": "1.*", "socket.io": "1.2.*",
"tail": "*", "tail": "*",
"glob": "*", "glob": "*",
"extend": "*" "extend": "*"
......
...@@ -271,8 +271,9 @@ function Page_Distrubion(socket) { ...@@ -271,8 +271,9 @@ function Page_Distrubion(socket) {
var html_file = $('<li id="file-' + f.orig_name + '">' + var html_file = $('<li id="file-' + f.orig_name + '">' +
'<a title="' + f.orig_name + '" href="' + '<a title="' + f.orig_name + '" href="' +
Utils.from_view_to_hash(tmp) + '">' + Utils.from_view_to_hash(tmp) + '">' +
'<span class="tags pull-right"></span>' + '<span class="name">' + f.name + '</span>' +
'<span class="name">' + f.name + '</span></a></li>'); '<span class="tags"></span>' +
'</a></li>');
html_file.on('click', function () { html_file.on('click', function () {
files.select(this); files.select(this);
}); });
...@@ -339,13 +340,20 @@ function Page_Distrubion(socket) { ...@@ -339,13 +340,20 @@ function Page_Distrubion(socket) {
show: function () { show: function () {
$('#files').show(); $('#files').show();
}, },
set_tags: function (file, tags) { set_tags: function (file, tags, level) {
// debug(2, "setting tag", file, tags); // debug(2, "setting tag", file, tags);
$('li[id="file-' + file + '"] .tags').html(tags); $('li[id="file-' + file + '"] .tags').html(tags);
$('li[id="file-' + file + '"] .tags')[0].className = "pull-right tags label label-" + level;
}, },
set_size: function (file, size) { set_size: function (file, size) {
// debug(2, "setting size", file, size); // debug(2, "setting size", file, size);
$('[id="file-' + file + '"] a').append('<span class="size">' + size + '</span>'); var $file = $('[id="file-' + file + '"]');
var $tags = $file.find(".tags");
var $size = $('<span class="size pull-right">' + size + '</span>');
if ($tags.length > 0)
$size.insertBefore($tags);
else
$file.append($size);
} }
}; };
...@@ -360,7 +368,7 @@ function Page_Distrubion(socket) { ...@@ -360,7 +368,7 @@ function Page_Distrubion(socket) {
for (var file in s_files) { for (var file in s_files) {
if (s_files.hasOwnProperty(file)) { if (s_files.hasOwnProperty(file)) {
if (s_files[file].hasOwnProperty('tags')) if (s_files[file].hasOwnProperty('tags'))
files.set_tags(file, s_files[file].tags); files.set_tags(file, s_files[file].tags, s_files[file].level);
if (s_files[file].hasOwnProperty('size')) if (s_files[file].hasOwnProperty('size'))
files.set_size(file, s_files[file].size); files.set_size(file, s_files[file].size);
} }
......
...@@ -148,7 +148,7 @@ footer .info { ...@@ -148,7 +148,7 @@ footer .info {
font-size: 70%; font-size: 70%;
color: rgba(0,0,0,0.25); color: rgba(0,0,0,0.25);
float: right; float: right;
min-width: 60px; min-width: 54px;
text-align: right; text-align: right;
display: inline-block; display: inline-block;
line-height: 20px; line-height: 20px;
...@@ -157,7 +157,7 @@ footer .info { ...@@ -157,7 +157,7 @@ footer .info {
#logs .size { #logs .size {
float: none; float: none;
line-height: 0px; line-height: 12px;
} }
#logs .active .size { #logs .active .size {
...@@ -165,10 +165,15 @@ footer .info { ...@@ -165,10 +165,15 @@ footer .info {
} }
#logs .name { #logs .name {
min-width: 75px; min-width: 95px;
display: inline-block; display: inline-block;
} }
#logs .tags {
margin-top: -3px;
padding-top: 3px;
}
#status span { #status span {
font-weight: bold; font-weight: bold;
font-size: small; font-size: small;
...@@ -297,10 +302,6 @@ footer .info { ...@@ -297,10 +302,6 @@ footer .info {
white-space: nowrap; white-space: nowrap;
} }
#disk-usage .ct-label.ct-size {
font-size: 0.72em;
}
/* add more colors to graphs */ /* add more colors to graphs */
.ct-series-e .ct-bar, .ct-series-e .ct-bar,
.ct-chart .ct-series.ct-series-e .ct-line, .ct-chart .ct-series.ct-series-e .ct-line,
......
...@@ -68,7 +68,7 @@ get_tablesorter ...@@ -68,7 +68,7 @@ get_tablesorter
get_github "twbs" "bootstrap" "3.2.0" "dist" get_github "twbs" "bootstrap" "3.2.0" "dist"
# get chartist # get chartist
get_github "gionkunz" "chartist-js" "0.4.0" "libdist" get_github "gionkunz" "chartist-js" "0.7.2" "dist"
if [ "`ls -1`" != "" ] ; then mv * ${EXT_LIBS_DIR} ; fi if [ "`ls -1`" != "" ] ; then mv * ${EXT_LIBS_DIR} ; fi
cd && rm -r ${TMP_DIR} cd && rm -r ${TMP_DIR}
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<li><a href="#remove-packages" data-toggle="tab">Remove</a></li> <li><a href="#remove-packages" data-toggle="tab">Remove</a></li>
<li><a href="#rebuild-packages" data-toggle="tab">Rebuild</a></li> <li><a href="#rebuild-packages" data-toggle="tab">Rebuild</a></li>
<li><a href="#porter-uploads" data-toggle="tab">Porter</a></li> <li><a href="#porter-uploads" data-toggle="tab">Porter</a></li>
<li><a href="#binary-nmu-uploads" data-toggle="tab">Binary NMU</a></li>
<li><a href="#rebuild-packages-with-extra-build-dependencies" data-toggle="tab">Rebuild with extra</a></li> <li><a href="#rebuild-packages-with-extra-build-dependencies" data-toggle="tab">Rebuild with extra</a></li>
</ul> </ul>
...@@ -79,15 +80,25 @@ upload.</p> ...@@ -79,15 +80,25 @@ upload.</p>
cannot be downloaded and processed by Deb-o-Matic. cannot be downloaded and processed by Deb-o-Matic.
</div> </div>
</div> </div>
<div class="tab-pane" id="binary-nmu-uploads">
<h3>Binary NMU uploads</h3>
<p>You could want to prepare a binary NMU (or binNMU) upload, a binary-only upload which generates architecture dependent binaries only, together with a changelog entry describing why the upload was needed. Additional information can be found in <a href="https://www.debian.org/doc/manuals/developers-reference/pkgs.html#porter-guidelines">Debian Developer's Reference</a>.</p>
<p>In order to do so, you must use the <code>binnmu</code> command:</p>
<pre>echo 'binnmu foo_version dist binNMU_version "changelog" John Doe &lt;jdoe@debian.org&gt;' &gt; foo.commands</pre>
<p>where <code>foo</code> is the name of the source package you want to rebuild, <code>version</code> is the version of the package you want to rebuild, <code>dist</code> is the distribution which rebuild package for, <code>binNMU_version</code> is the progressive binNMU number, <code>changelog</code> is the reason why the upload was prepared (enclosed in quotation marks), and the rest of the string is the address to be used as maintainer field, which is usually the developer who is preparing the upload.</p>
<div class="alert alert-warning">
<b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they cannot be downloaded and processed by Deb-o-Matic.
</div>
</div>
<div class="tab-pane" id="rebuild-packages-with-extra-build-dependencies"> <div class="tab-pane" id="rebuild-packages-with-extra-build-dependencies">
<h3>Rebuild packages with extra build-dependencies</h3> <h3>Rebuild packages with extra build-dependencies</h3>
<p>You could want to rebuild a package already in the mirrors also adding a <p>You could want to rebuild a package already in the mirrors also adding a
specific build-dependency to see whether it compiles with a newer library specific build-dependency to see whether it compiles with a newer library
version. In order to do so, you must use the <code>builddep</code> command:</p> version. In order to do so, you must use the <code>builddep</code> command:</p>
<pre>echo "builddep foo_version dist extrapackage=packageversion" &gt; foo.commands</pre> <pre>echo "builddep foo_version dist extrapackage (>= packageversion)" &gt; foo.commands</pre>
<p>where <code>extrapackage</code> is the name of the package you want to install before <p>where <code>extrapackage</code> is the name of the package you want to install before
the compilation takes place, and <code>packageversion</code> is the optional version of the compilation takes place, and <code>packageversion</code> is the optional version of
the package you want to install.</p> the package you want to install. More than one package can be defined, separated by commas.</p>
<div class="alert alert-warning"> <div class="alert alert-warning">
<b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they <b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they
cannot be downloaded and processed by Deb-o-Matic. cannot be downloaded and processed by Deb-o-Matic.
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<script src="/external_libs/tablesorter/jquery.tablesorter.min.js"></script> <script src="/external_libs/tablesorter/jquery.tablesorter.min.js"></script>
<script src="/external_libs/tablesorter/jquery.tablesorter.widgets.min.js"></script> <script src="/external_libs/tablesorter/jquery.tablesorter.widgets.min.js"></script>
<script src="/external_libs/bootstrap-3.2.0/js/bootstrap.min.js"></script> <script src="/external_libs/bootstrap-3.2.0/js/bootstrap.min.js"></script>
<script src="/external_libs/chartist-js-0.4.0/chartist.min.js"></script> <script src="/external_libs/chartist-js-0.7.2/chartist.min.js"></script>
<script> <script>
var config = <%- JSON.stringify(web) %> var config = <%- JSON.stringify(web) %>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/external_libs/bootstrap-3.2.0/css/bootstrap.min.css"> <link rel="stylesheet" href="/external_libs/bootstrap-3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="/external_libs/bootstrap-3.2.0/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="/external_libs/bootstrap-3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/external_libs/chartist-js-0.4.0/chartist.min.css"> <link rel="stylesheet" href="/external_libs/chartist-js-0.7.2/chartist.min.css">
<link rel="stylesheet" href="/external_libs/tablesorter/theme.bootstrap.css"> <link rel="stylesheet" href="/external_libs/tablesorter/theme.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css?<%= version %>"> <link rel="stylesheet" href="/stylesheets/style.css?<%= version %>">
</head> </head>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<article id="home" class="page row"> <article id="home" class="page row">
<header class="col-md-12"> <header class="col-md-12">
<h1>Welcome!</h1> <h1>Welcome!</h1>
<p class="text-muted lead">This is <%= web.debomatic.architecture %> Debian source package build service powered by <a class="alert-link" href="http://launchpad.net/debomatic" target="_blank">Deb-o-Matic</a></p> <p class="text-muted lead">This is <%= web.debomatic.architecture %> Debian source package build service powered by <a class="alert-link" href="http://debomatic.github.io" target="_blank">Deb-o-Matic</a></p>
</header> </header>
<section> <section>
...@@ -104,7 +104,7 @@ scp_compress = 1 ...@@ -104,7 +104,7 @@ scp_compress = 1
<p>It is also extendable using modules that are loaded and executed <p>It is also extendable using modules that are loaded and executed
during the build phases.</p> during the build phases.</p>
<p><a class="btn btn-primary" href="http://launchpad.net/debomatic" target="_blank">Get more!</a></p> <p><a class="btn btn-primary" href="http://debomatic.github.io" target="_blank">Get more!</a></p>
</section> </section>
</article> </article>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment