[copr] master: [frontend] fix: show all platform names in Overviev (917ad1b)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 917ad1b79e0e7f99142a3d038a0689a8ff1a4139
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Tue Aug 4 14:44:25 2015 +0200
[frontend] fix: show all platform names in Overviev
Chroots other than Fedora and Epel would not show up
>---------------------------------------------------------------
.../coprs_frontend/coprs/templates/_helpers.html | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/templates/_helpers.html b/frontend/coprs_frontend/coprs/templates/_helpers.html
index f8573fd..6a78a18 100644
--- a/frontend/coprs_frontend/coprs/templates/_helpers.html
+++ b/frontend/coprs_frontend/coprs/templates/_helpers.html
@@ -68,5 +68,8 @@
<img style="height:1.8em" src="{{ url_for('static', filename='fedora_logo.png') }}"> Fedora {{chroot.os_version}}
{% elif chroot.os_release == "epel" %}
Epel for <img style="height:1.8em" src="{{ url_for('static', filename='centos_logo.png') }}"> CentOS {{chroot.os_version}}
+
+ {% else %}
+ {{ chroot.os_release | capitalize }} {{ chroot.os_version }}
{% endif %}
{% endmacro %}
8 years, 9 months
[copr] master: [frontend] API monitor (f81f4e9)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit f81f4e98894b22808924e33920c5c85acde168dd
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Tue Aug 4 12:08:55 2015 +0200
[frontend] API monitor
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/logic/api_logic.py | 49 ++++++++-----------
.../coprs/views/api_ns/api_general.py | 2 +-
.../tests/test_logic/test_builds_logic.py | 9 +--
3 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/api_logic.py b/frontend/coprs_frontend/coprs/logic/api_logic.py
index 93c7568..359e859 100644
--- a/frontend/coprs_frontend/coprs/logic/api_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/api_logic.py
@@ -31,7 +31,7 @@ class BuildWrapper(object):
class MonitorWrapper(object):
- def __init__(self, monitor_data):
+ def __init__(self, copr, monitor_data):
"""
:arg monitor_data: dict with fields:
"builds": list of models.Build,
@@ -39,43 +39,36 @@ class MonitorWrapper(object):
"packages": tuple (pkg_name, pkg_version, build_results),
"latest_build": models.Build,
"""
+ self.copr = copr
self.monitor_data = monitor_data
def to_dict(self):
out = {}
- chroots = self.monitor_data["chroots"]
- out["chroots"] = chroots
+ out["chroots"] = map(lambda x: x.name, self.copr.active_chroots_sorted)
out["builds"] = [
BuildWrapper(build).to_dict()
- for build in self.monitor_data["builds"]
+ for build in self.copr.builds
]
- packages_fixed = []
- for (pkg_name, results_by_chroot) in self.monitor_data["packages"]:
+
+ packages = []
+
+ for pkg in self.monitor_data:
+ package = pkg["package"]
+ chroots = pkg["build_chroots"]
+
results = {}
- for chroot_name, (build_id, status, pkg_version, _) in zip(chroots, results_by_chroot):
- if status is None or pkg_version is None:
- results[chroot_name] = None
+ for ch in self.copr.active_chroots:
+ if chroots[ch.name]:
+ results[ch.name] = {"build_id": chroots[ch.name].build.id,
+ "status": chroots[ch.name].state,
+ "pkg_version": chroots[ch.name].build.pkg_version}
else:
- results[chroot_name] = dict(build_id=build_id,
- status=status,
- pkg_version=pkg_version)
+ results[ch.name] = None
- packages_fixed.append({
- "pkg_name": pkg_name,
- "pkg_version": None, # legacy
- "results": results
- })
+ packages.append({"pkg_name": package.name,
+ "pkg_version": None,
+ "results": results})
- out["packages"] = packages_fixed
- #
- # [
- # {
- # "pkg_name": pkg_name,
- # "pkg_version": None, # legacy
- # "results": dict(zip(chroots, results_by_chroot))
- # }
- # for (pkg_name, results_by_chroot)
- # in self.monitor_data["packages"]
- # ]
+ out["packages"] = packages
return out
diff --git a/frontend/coprs_frontend/coprs/views/api_ns/api_general.py b/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
index 92cf986..d31dccd 100644
--- a/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -637,7 +637,7 @@ def monitor(username, coprname):
copr = CoprsLogic.get(username, coprname).first()
monitor_data = builds_logic.BuildsMonitorLogic.get_monitor_data(copr)
- output = MonitorWrapper(monitor_data).to_dict()
+ output = MonitorWrapper(copr, monitor_data).to_dict()
jsonout = flask.jsonify(output)
jsonout.status_code = 200
diff --git a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
index 4c6dfbc..7c88ff9 100644
--- a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
+++ b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
@@ -63,14 +63,11 @@ class TestBuildsLogic(CoprsTestCase):
with pytest.raises(MalformedArgumentException):
BuildsLogic.add(**params)
- def test_monitor_logic(self, f_users, f_coprs, f_mock_chroots_many, f_build_many_chroots, f_db):
+ def test_monitor_logic(self, f_users, f_coprs, f_builds, f_mock_chroots_many, f_build_few_chroots, f_db):
copr = self.c1
md = BuildsMonitorLogic.get_monitor_data(copr)
- results = md["packages"][-1][-1]
- mchroots = md["chroots"]
-
- for chr, res in zip(mchroots, results):
- assert helpers.StatusEnum(self.status_by_chroot[chr]) == res[1]
+ assert len(md) == 1
+ assert len(md[0]["build_chroots"]) == 15
def test_build_queue_1(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
self.db.session.commit()
8 years, 9 months
[copr] master: [python][cli] implement srpm upload functionality (adf07fe)
by frostyx@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit adf07fe8f275e1f0c543cd85294e36b660cf73a5
Author: Jakub Kadlčík <jkadlcik(a)redhat.com>
Date: Mon Aug 3 17:45:22 2015 +0200
[python][cli] implement srpm upload functionality
>---------------------------------------------------------------
python/copr/client/client.py | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/python/copr/client/client.py b/python/copr/client/client.py
index aa6bf5a..63f1395 100644
--- a/python/copr/client/client.py
+++ b/python/copr/client/client.py
@@ -14,6 +14,7 @@ import requests
import six
from six.moves import configparser
+from six.moves.urllib.parse import urlparse
if sys.version_info < (2, 7):
@@ -136,7 +137,7 @@ class CoprClient(UnicodeMixin):
return CoprClient(**config)
def _fetch(self, url, data=None, projectname=None, username=None,
- method=None, skip_auth=False, on_error_response=None):
+ method=None, skip_auth=False, on_error_response=None, files=None):
""" Fetches data from server,
checks response and raises a CoprRequestException with nice error message
or CoprUnknownResponseException in case of some some error. \n
@@ -149,6 +150,7 @@ class CoprClient(UnicodeMixin):
:param username: [optional] use alternative username
:param on_error_response: [optional] function to handle responses
with bad status code
+ :param files: [optional] files to upload
:return: deserialized response
:rtype: dict
@@ -166,6 +168,8 @@ class CoprClient(UnicodeMixin):
kwargs["auth"] = (self.login, self.token)
if data is not None:
kwargs["data"] = data
+ if files is not None:
+ kwargs["files"] = files
if method not in ["get", "post", "head", "delete", "put"]:
raise Exception("Method {0} not allowed".format(method))
@@ -308,18 +312,30 @@ class CoprClient(UnicodeMixin):
if not username:
username = self.username
- url = "{0}/coprs/{1}/{2}/new_build/".format(
- self.api_url, username, projectname
- )
data = {
- "pkgs": " ".join(pkgs),
"memory_reqs": memory,
"timeout": timeout
}
+ files = None
+
+ if urlparse(pkgs[0]).scheme != "":
+ api_endpoint = "new_build"
+ data["pkgs"] = " ".join(pkgs)
+ else:
+ try:
+ api_endpoint = "new_build_upload"
+ files = {'pkgs': open(pkgs[0], "rb")}
+ except IOError as e:
+ raise CoprRequestException(e)
+
+ url = "{0}/coprs/{1}/{2}/{3}/".format(
+ self.api_url, username, projectname, api_endpoint
+ )
+
for chroot in chroots or []:
data[chroot] = "y"
- data = self._fetch(url, data, method="post")
+ data = self._fetch(url, data, method="post", files=files)
response = CoprResponse(
client=self,
8 years, 9 months
[copr] master: [frontend] implement create_new_build_upload in API (ccd1680)
by frostyx@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit ccd1680a9a922a69881d0fd2e3b676514ccc456a
Author: Jakub Kadlčík <jkadlcik(a)redhat.com>
Date: Mon Aug 3 16:57:03 2015 +0200
[frontend] implement create_new_build_upload in API
>---------------------------------------------------------------
.../coprs/views/api_ns/api_general.py | 92 +++++++++++++++++++-
1 files changed, 91 insertions(+), 1 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/views/api_ns/api_general.py b/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
index 222c155..92cf986 100644
--- a/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/frontend/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -1,10 +1,15 @@
import base64
import datetime
+import os
+import shutil
+import tempfile
import json
import urlparse
-
import flask
+from werkzeug import secure_filename
+
+from coprs import app
from coprs import db
from coprs import exceptions
from coprs import forms
@@ -20,6 +25,9 @@ from coprs.logic import builds_logic
from coprs.logic import coprs_logic
from coprs.logic.coprs_logic import CoprsLogic
+from coprs.exceptions import (ActionInProgressException,
+ InsufficientRightsException)
+
@api_ns.route("/")
def api_home():
@@ -304,6 +312,88 @@ def copr_new_build(username, coprname):
return jsonout
+(a)api_ns.route("/coprs/<username>/<coprname>/new_build_upload/", methods=["POST"])
+@api_login_required
+def copr_new_build_upload(username, coprname):
+ copr = coprs_logic.CoprsLogic.get(username, coprname).first()
+ httpcode = 200
+ if not copr:
+ output = {"output": "notok", "error":
+ "Copr with name {0} does not exist.".format(coprname)}
+ httpcode = 500
+
+ else:
+ form = forms.BuildFormUploadFactory.create_form_cls(
+ copr.active_chroots)(csrf_enabled=False)
+
+ # are there any arguments in POST which our form doesn't know?
+ if any([post_key not in form.__dict__.keys()
+ for post_key in flask.request.form.keys()]):
+ output = {"output": "notok",
+ "error": "Unknown arguments passed (non-existing chroot probably)"}
+ httpcode = 500
+
+ elif form.validate_on_submit():
+ tmp = tempfile.mkdtemp(dir=app.config["SRPM_STORAGE_DIR"])
+ tmp_name = os.path.basename(tmp)
+ filename = secure_filename(form.pkgs.data.filename)
+ file_path = os.path.join(tmp, filename)
+ form.pkgs.data.save(file_path)
+
+ # get the package name vithout version and release
+ pkgname = helpers.parse_package_name(filename)
+
+ # make the pkg public
+ pkg_url = "https://{hostname}/tmp/{tmp_dir}/{srpm}".format(
+ hostname=app.config["PUBLIC_COPR_HOSTNAME"],
+ tmp_dir=tmp_name,
+ srpm=filename)
+
+ # check which chroots we need
+ chroots = []
+ for chroot in copr.active_chroots:
+ if chroot.name in form.selected_chroots:
+ chroots.append(chroot)
+
+ # create json describing the build source
+ source_type = helpers.BuildSourceEnum("srpm_upload")
+ source_json = json.dumps({"tmp": tmp_name,
+ "pkg": filename})
+
+ # create a new build
+ try:
+ build = builds_logic.BuildsLogic.add(
+ user=flask.g.user,
+ pkgs=pkg_url,
+ copr=copr,
+ chroots=chroots,
+ source_type=source_type,
+ source_json=source_json,
+ enable_net=form.enable_net.data)
+
+ if flask.g.user.proven:
+ build.memory_reqs = form.memory_reqs.data
+ build.timeout = form.timeout.data
+
+ db.session.commit()
+
+ except (ActionInProgressException, InsufficientRightsException) as e:
+ flask.flash(str(e))
+ db.session.rollback()
+ shutil.rmtree(tmp)
+
+ output = {"output": "ok",
+ "ids": [build.id],
+ "message": "Build was added to {0}.".format(coprname)}
+ else:
+ output = {"output": "notok", "error": "Invalid request"}
+ httpcode = 500
+
+ jsonout = flask.jsonify(output)
+ jsonout.status_code = httpcode
+ return jsonout
+
+
@api_ns.route("/coprs/build_status/<build_id>/", methods=["GET"])
@api_login_required
def build_status(build_id):
8 years, 9 months
[copr] master: [frontend] Monitor view from Packages (629287a)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 629287a3cbd0a0fc8a72e2472b837bf61face861
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Tue Aug 4 10:39:53 2015 +0200
[frontend] Monitor view from Packages
>---------------------------------------------------------------
.../coprs_frontend/coprs/logic/builds_logic.py | 68 +++-------------
frontend/coprs_frontend/coprs/models.py | 10 ++-
.../coprs/templates/coprs/detail/monitor.html | 83 +++++--------------
.../templates/coprs/detail/monitor/detailed.html | 63 +++++++++++++++
.../templates/coprs/detail/monitor/simple.html | 61 ++++++++++++++
.../coprs/views/coprs_ns/coprs_general.py | 43 +++++++----
6 files changed, 195 insertions(+), 133 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index 473f2b4..a392e93 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -376,60 +376,16 @@ class BuildsLogic(object):
class BuildsMonitorLogic(object):
@classmethod
def get_monitor_data(cls, copr):
- # builds are sorted by build id descending
- builds = BuildsLogic.get_multiple_by_copr(copr).all()
-
- chroots = set(chroot.name for chroot in copr.active_chroots)
- if builds:
- latest_build = builds[0]
- chroots.union([chroot.name for chroot in latest_build.build_chroots])
- else:
- latest_build = None
-
- chroots = sorted(chroots)
-
- # { pkg_name -> { chroot -> (build_id, pkg_version, status) }}
- build_result_by_pkg_chroot = defaultdict(lambda: defaultdict(lambda: None))
-
- # collect information about pkg version and build states
- for build in builds:
- chroot_results = {chroot.name: chroot.state for chroot in build.build_chroots}
-
- pkg = os.path.basename(build.pkgs)
- pkg_name = helpers.parse_package_name(pkg)
-
- for chroot_name, state in chroot_results.items():
- # set only latest version/state
- if build_result_by_pkg_chroot[pkg_name][chroot_name] is None:
- build_result_by_pkg_chroot[pkg_name][chroot_name] = (build.id, build.pkg_version, state)
-
- # "transpose" data to present build status per package
+ copr_packages = sorted(copr.packages, key=lambda pkg: pkg.name)
packages = []
- for pkg_name, chroot_dict in build_result_by_pkg_chroot.items():
- br = []
- try:
- latest_build_id = max([build_id for build_id, pkg_version, state
- in chroot_dict.values()])
- except ValueError:
- latest_build_id = None
-
- for chroot_name in chroots:
- chroot_result = chroot_dict.get(chroot_name)
- if chroot_result:
- build_id, pkg_version, state = chroot_result
- br.append((build_id, state, pkg_version, chroot_name))
- else:
- br.append((latest_build_id, None, None, chroot_name))
-
- packages.append((pkg_name, br))
-
- packages.sort()
-
- result = {
- "builds": builds,
- "chroots": chroots,
- "packages": packages,
- "latest_build": latest_build,
- }
- app.logger.debug("Monitor data: \n{}".format(pprint.pformat(result)))
- return result
+ for pkg in copr_packages:
+ chroots = {}
+ for ch in copr.active_chroots:
+ query = (models.BuildChroot.query.join(models.Build)
+ .filter(models.Build.package_id == pkg.id)
+ .filter(models.BuildChroot.mock_chroot_id == ch.id)
+ .filter(models.BuildChroot.status != helpers.StatusEnum("canceled")))
+ query = query.order_by(models.BuildChroot.build_id.desc()).first()
+ chroots[ch.name] = query
+ packages.append({"package": pkg, "build_chroots": chroots})
+ return packages
diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py
index bf037b8..95bca55 100644
--- a/frontend/coprs_frontend/coprs/models.py
+++ b/frontend/coprs_frontend/coprs/models.py
@@ -184,12 +184,20 @@ class Copr(db.Model, helpers.Serializer):
return filter(lambda x: x.is_active, self.mock_chroots)
@property
+ def active_chroots_sorted(self):
+ """
+ Return list of active mock_chroots of this copr
+ """
+
+ return sorted(self.active_chroots, key=lambda ch: ch.name)
+
+ @property
def active_chroots_grouped(self):
"""
Return list of active mock_chroots of this copr
"""
- chroots = [("{} {}".format(c.os_release, c.os_version), c.arch) for c in self.active_chroots]
+ chroots = [("{} {}".format(c.os_release, c.os_version), c.arch) for c in self.active_chroots_sorted]
output = []
for os, chs in itertools.groupby(chroots, operator.itemgetter(0)):
output.append((os, [ch[1] for ch in chs]))
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor.html
index aa2e03b..176a864 100644
--- a/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor.html
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor.html
@@ -2,71 +2,32 @@
{% from "coprs/detail/_build_states.html" import build_states %}
{% block title %}Monitor {{ copr.owner.name }}/{{ copr.name }}{% endblock %}
{% block monitor_selected %}active{% endblock %}
+
{%block project_breadcrumb %}
-<li class="active">
- Monitor
+<li>
+ <a href="{{ url_for('coprs_ns.copr_build_monitor', username = copr.owner.name, coprname = copr.name) }}">
+ Monitor
+ </a>
+ {% block project_breadcrumb_monitor %}
+ {%endblock%}
</li>
{%endblock%}
{% block detail_body %}
-<table class="table table-striped table-bordered">
- <thead>
- <h2> Build Monitor </h2>
- <p>This view presents states of the last build for each package. Click on the state to see details.</p>
- <tr>
- <th rowspan="2">Package</th>
- <!--<th rowspan="2">Version</th>-->
- {% for i, chroot in oses %}
- <th colspan="{{i}}">
- {{ chroot|capitalize }}
- </th>
- {% endfor %}
- </tr>
- <tr>
- {% for chroot in archs %}
- <th>
- {{ chroot }}
- </th>
- {% endfor %}
- </tr>
- </thead>
- <tbody>
- {% if build %}
- {% for package, states_by_chroot in packages %}
- <tr>
- <td>{{ package }}</td>
- {% for build_id, state, pkg_version, chroot in states_by_chroot %}
- <td class="centered">
- {% if state %}
- <a class="build-{{ state }}"
- href="{{ url_for('coprs_ns.copr_build',
- username=copr.owner.name,
- coprname=copr.name,
- build_id=build_id) }}">
- {{ state }}
- </a> <br />
- {% if pkg_version %}
- <small class="text-muted"> {{ pkg_version }} </small>
- {% endif %}
- {% else %}
- {% if build_id %}
- <a href="{{ url_for('coprs_ns.copr_repeat_build',
- username=copr.owner.name,
- coprname=copr.name,
- build_id=build_id,
- chroot=chroot) }}">new build</a>
- {% endif %}
- {% endif %}
- </td>
- {% endfor %}
- </tr>
- {% endfor %}
- {% else %}
- <tr>
- <td colspan="{{archs|length +1}}">No builds so far...</td>
- </tr>
- {% endif %}
- </tbody>
-</table>
+<ul class="nav nav-tabs nav-tabs-pf">
+ <li class="{% block monitor_simple_selected %}{% endblock %}">
+ <a href="{{ url_for('coprs_ns.copr_build_monitor', username = copr.owner.name, coprname = copr.name) }}">
+ Simple
+ </a>
+ </li>
+ <li class="{% block monitor_detailed_selected %}{% endblock %}">
+ <a href="{{ url_for('coprs_ns.copr_build_monitor_detailed', username = copr.owner.name, coprname = copr.name) }}">
+ Detailed
+ </a>
+ </li>
+</ul>
+
+{% block monitor_table %}{% endblock %}
+
{{ build_states() }}
{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/detailed.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/detailed.html
new file mode 100644
index 0000000..45ff80b
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/detailed.html
@@ -0,0 +1,63 @@
+{% extends "coprs/detail/monitor.html" %}
+{% from "coprs/detail/_build_states.html" import build_states %}
+
+{% block project_breadcrumb_monitor %}
+<li class="active">
+ Detailed
+</li>
+{% endblock %}
+
+{% block monitor_detailed_selected %}active{% endblock %}
+
+{% block monitor_table %}
+<h2> Detailed Build Monitor </h2>
+<p>States of last builds of every package in this project. One package can have more builds. Each field contains a build id, state and package version.</p>
+<table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th rowspan="2">Package</th>
+ {% for i, chroot in oses %}
+ <th colspan="{{i}}"> {{ chroot|capitalize }}</th>
+ {% endfor %}
+ </tr>
+ <tr>
+ {% for chroot in archs %}
+ <th> {{ chroot }} </th>
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for package in monitor %}
+ <tr>
+ <td style="white-space:nowrap">
+ <a href="{{ url_for('coprs_ns.copr_package',
+ username=copr.owner.name,
+ coprname=copr.name,
+ package_name=package["package"].name) }}">
+ {{ package["package"].name }}
+ </a>
+ </td>
+ {% for chroot in copr.active_chroots_sorted %}
+ <td>
+ {% if package["build_chroots"][chroot.name] %}
+ <a href="{{ url_for('coprs_ns.copr_build',
+ username=copr.owner.name,
+ coprname=copr.name,
+ build_id=package["build_chroots"][chroot.name].build.id) }}">
+ <small> {{ package["build_chroots"][chroot.name].build.id }} </small> <br>
+ <span class="build-{{ package["build_chroots"][chroot.name].state }}">
+ {{ package["build_chroots"][chroot.name].state }}
+ </span> <br>
+ <small class="text-muted"> {{ package["build_chroots"][chroot.name].build.pkg_version }} </small>
+ </a>
+ {% else %}
+ -
+ {% endif %}
+ </td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/simple.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/simple.html
new file mode 100644
index 0000000..964a9d4
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/monitor/simple.html
@@ -0,0 +1,61 @@
+{% extends "coprs/detail/monitor.html" %}
+{% from "coprs/detail/_build_states.html" import build_states %}
+
+{% block project_breadcrumb_monitor %}
+<li class="active">
+ Simple
+</li>
+{% endblock %}
+
+{% block monitor_simple_selected %}active{% endblock %}
+
+{% block monitor_table %}
+<h2> Simple Build Monitor </h2>
+<p>States of last builds of every package in this project. One package can have more builds. </p>
+
+<table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th rowspan="2">Package</th>
+ {% for i, chroot in oses %}
+ <th colspan="{{i}}"> {{ chroot|capitalize }}</th>
+ {% endfor %}
+ </tr>
+ <tr>
+ {% for chroot in archs %}
+ <th> {{ chroot }} </th>
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for package in monitor %}
+ <tr>
+ <td style="white-space:nowrap">
+ <a href="{{ url_for('coprs_ns.copr_package',
+ username=copr.owner.name,
+ coprname=copr.name,
+ package_name=package["package"].name) }}">
+ {{ package["package"].name }}
+ </a>
+ </td>
+ {% for chroot in copr.active_chroots_sorted %}
+ <td>
+ {% if package["build_chroots"][chroot.name] %}
+ <a href="{{ url_for('coprs_ns.copr_build',
+ username=copr.owner.name,
+ coprname=copr.name,
+ build_id=package["build_chroots"][chroot.name].build.id) }}">
+ <span class="build-{{ package["build_chroots"][chroot.name].state }}">
+ {{ package["build_chroots"][chroot.name].state }}
+ </span>
+ </a>
+ {% else %}
+ -
+ {% endif %}
+ </td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
index 26dcf5e..82bb5de 100644
--- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
+++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
@@ -645,22 +645,35 @@ def copr_build_monitor(username, coprname):
return page_not_found(
"Copr with name {0} does not exist.".format(coprname))
- form = forms.CoprLegalFlagForm()
+ monitor = builds_logic.BuildsMonitorLogic.get_monitor_data(copr)
+
+ oses = [chroot.os for chroot in copr.active_chroots_sorted]
+ oses_grouped = [(len(list(group)), key) for key, group in groupby(oses)]
+ archs = [chroot.arch for chroot in copr.active_chroots_sorted]
+
+ return flask.render_template("coprs/detail/monitor/simple.html",
+ copr=copr,
+ monitor=monitor,
+ oses=oses_grouped,
+ archs=archs)
+
+
+(a)coprs_ns.route("/<username>/<coprname>/monitor-detailed/")
+def copr_build_monitor_detailed(username, coprname):
+ try:
+ copr = coprs_logic.CoprsLogic.get(username, coprname, with_mock_chroots=True).one()
+ except sqlalchemy.orm.exc.NoResultFound:
+ return page_not_found(
+ "Copr with name {0} does not exist.".format(coprname))
monitor = builds_logic.BuildsMonitorLogic.get_monitor_data(copr)
- md_chroots = monitor["chroots"]
- active_chroots = sorted(
- copr.active_chroots,
- key=lambda chroot: md_chroots.index(chroot.name)
- )
- oses = [chroot.os for chroot in active_chroots]
+ oses = [chroot.os for chroot in copr.active_chroots_sorted]
oses_grouped = [(len(list(group)), key) for key, group in groupby(oses)]
- archs = [chroot.arch for chroot in active_chroots]
-
- kwargs = dict(copr=copr, oses=oses_grouped, archs=archs,
- form=form)
- kwargs.update(monitor)
- kwargs["build"] = kwargs["latest_build"]
- del kwargs["latest_build"]
- return flask.render_template("coprs/detail/monitor.html", **kwargs)
+ archs = [chroot.arch for chroot in copr.active_chroots_sorted]
+
+ return flask.render_template("coprs/detail/monitor/detailed.html",
+ copr=copr,
+ monitor=monitor,
+ oses=oses_grouped,
+ archs=archs)
8 years, 9 months
[copr] master: typo (5f5b0e9)
by vgologuz@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 5f5b0e9f1727e6c9fa1104d85f784a45b1dfc98d
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Mon Aug 3 18:55:02 2015 +0200
typo
>---------------------------------------------------------------
backend/backend/actions.py | 2 +-
.../coprs_frontend/coprs/logic/actions_logic.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/backend/backend/actions.py b/backend/backend/actions.py
index 5670ee9..abdcf5f 100644
--- a/backend/backend/actions.py
+++ b/backend/backend/actions.py
@@ -118,7 +118,7 @@ class Action(object):
.format(ext_data))
return
- target_dir = ext_data.get("results_dir_name") or ext_data.get("src_pkg_name")
+ target_dir = ext_data.get("result_dir_name") or ext_data.get("src_pkg_name")
if target_dir is None or target_dir == "":
self.log.error("Bad delete request, ignored. Raw ext_data: {}"
.format(ext_data))
diff --git a/frontend/coprs_frontend/coprs/logic/actions_logic.py b/frontend/coprs_frontend/coprs/logic/actions_logic.py
index 9d47a85..58f388c 100644
--- a/frontend/coprs_frontend/coprs/logic/actions_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/actions_logic.py
@@ -107,7 +107,7 @@ class ActionsLogic(object):
return
data_dict["src_pkg_name"] = build.src_pkg_name
else:
- data_dict["results_dir_name"] = build.result_dir_name
+ data_dict["result_dir_name"] = build.result_dir_name
action = models.Action(
action_type=helpers.ActionTypeEnum("delete"),
8 years, 9 months
[copr] master: [frontend] delete action now supports new build results naming schema (d38b0d6)
by vgologuz@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit d38b0d6531c877ad7be1b9686af88b511ff21fba
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Mon Aug 3 18:40:02 2015 +0200
[frontend] delete action now supports new build results naming schema
>---------------------------------------------------------------
backend/backend/actions.py | 1 -
.../coprs_frontend/coprs/logic/actions_logic.py | 37 ++++++++++++++++++++
.../coprs_frontend/coprs/logic/builds_logic.py | 24 +------------
frontend/coprs_frontend/coprs/models.py | 6 +++
.../tests/test_logic/test_builds_logic.py | 3 ++
5 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/backend/backend/actions.py b/backend/backend/actions.py
index 4fb68f0..5670ee9 100644
--- a/backend/backend/actions.py
+++ b/backend/backend/actions.py
@@ -125,7 +125,6 @@ class Action(object):
return
path = os.path.join(self.destdir, project)
-
self.log.info("Deleting package {0}".format(target_dir))
self.log.info("Copr path {0}".format(path))
diff --git a/frontend/coprs_frontend/coprs/logic/actions_logic.py b/frontend/coprs_frontend/coprs/logic/actions_logic.py
index a32dfe7..9d47a85 100644
--- a/frontend/coprs_frontend/coprs/logic/actions_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/actions_logic.py
@@ -82,3 +82,40 @@ class ActionsLogic(object):
created_on=int(time.time()),
)
db.session.add(action)
+
+ @classmethod
+ def send_delete_build(cls, build):
+ """ Schedules build delete action
+ :type build: models.Build
+ """
+ # don't delete skipped chroots
+ chroots_to_delete = [
+ chroot.name for chroot in build.build_chroots
+ if chroot.state not in ["skipped"]
+ ]
+ if len(chroots_to_delete) == 0:
+ return
+
+ data_dict = {
+ "username": build.copr.owner.name,
+ "projectname": build.copr.name,
+ "chroots": chroots_to_delete
+ }
+ # import ipdb; ipdb.set_trace()
+ if build.is_older_results_naming_used:
+ if build.src_pkg_name is None or build.src_pkg_name == "":
+ return
+ data_dict["src_pkg_name"] = build.src_pkg_name
+ else:
+ data_dict["results_dir_name"] = build.result_dir_name
+
+ action = models.Action(
+ action_type=helpers.ActionTypeEnum("delete"),
+ object_type="build",
+ object_id=build.id,
+ old_value="{0}/{1}".format(build.copr.owner.name,
+ build.copr.name),
+ data=json.dumps(data_dict),
+ created_on=int(time.time())
+ )
+ db.session.add(action)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index f609582..473f2b4 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -20,6 +20,7 @@ from coprs.helpers import StatusEnum
from coprs.logic import coprs_logic
from coprs.logic import users_logic
from coprs.logic import packages_logic
+from coprs.logic.actions_logic import ActionsLogic
log = app.logger
@@ -345,28 +346,7 @@ class BuildsLogic(object):
# Only failed, finished, succeeded get here.
if build.state not in ["cancelled"]: # has nothing in backend to delete
- # don't delete skipped chroots
- chroots_to_delete = [
- chroot.name for chroot in build.build_chroots
- if chroot.state not in ["skipped"]
- ]
-
- if chroots_to_delete and build.src_pkg_name:
- data_dict = {"src_pkg_name": build.src_pkg_name,
- "username": build.copr.owner.name,
- "projectname": build.copr.name,
- "chroots": chroots_to_delete}
-
- action = models.Action(
- action_type=helpers.ActionTypeEnum("delete"),
- object_type="build",
- object_id=build.id,
- old_value="{0}/{1}".format(build.copr.owner.name,
- build.copr.name),
- data=json.dumps(data_dict),
- created_on=int(time.time())
- )
- db.session.add(action)
+ ActionsLogic.send_delete_build(build)
for build_chroot in build.build_chroots:
db.session.delete(build_chroot)
diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py
index aa3547f..bf037b8 100644
--- a/frontend/coprs_frontend/coprs/models.py
+++ b/frontend/coprs_frontend/coprs/models.py
@@ -364,6 +364,12 @@ class Build(db.Model, helpers.Serializer):
chroots = association_proxy("build_chroots", "mock_chroot")
@property
+ def is_older_results_naming_used(self):
+ # we have changed result directory naming together with transition to dist-git
+ # that's why we use so strange criterion
+ return self.build_chroots[0].git_hash is None
+
+ @property
def result_dir_name(self):
return "{:08d}-{}".format(self.id, self.package.name)
diff --git a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
index f5d9e08..4c6dfbc 100644
--- a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
+++ b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
@@ -205,12 +205,15 @@ class TestBuildsLogic(CoprsTestCase):
def test_delete_build_bad_src_pkg(
self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+ # has meaning only for the builds with old result dir naming schema
+
self.b1.pkgs = "http://example.com/"
self.db.session.add(self.b1)
self.db.session.commit()
expected_chroots_to_delete = set()
for bchroot in self.b1_bc:
+ bchroot.git_hash = None
expected_chroots_to_delete.add(bchroot.name)
assert len(ActionsLogic.get_many().all()) == 0
8 years, 9 months
[copr] master: [backend] support new results naming in the build deletion action (7254fee)
by vgologuz@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 7254fee3741132b41c5314a459fea266f5e0877f
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Mon Aug 3 18:17:19 2015 +0200
[backend] support new results naming in the build deletion action
>---------------------------------------------------------------
backend/backend/actions.py | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/backend/backend/actions.py b/backend/backend/actions.py
index 83aac77..4fb68f0 100644
--- a/backend/backend/actions.py
+++ b/backend/backend/actions.py
@@ -112,15 +112,21 @@ class Action(object):
projectname = ext_data["projectname"]
chroots_requested = set(ext_data["chroots"])
- if not ext_data.get("src_pkg_name"):
- self.log.error("Delete build action missing `src_pkg_name` field, check frontend version. Raw ext_data: {}"
+ if "src_pkg_name" not in ext_data and "result_dir_name" not in ext_data:
+ self.log.error("Delete build action missing `src_pkg_name` or `result_dir_name` field,"
+ " check frontend version. Raw ext_data: {}"
.format(ext_data))
return
- package_name = ext_data["src_pkg_name"]
+ target_dir = ext_data.get("results_dir_name") or ext_data.get("src_pkg_name")
+ if target_dir is None or target_dir == "":
+ self.log.error("Bad delete request, ignored. Raw ext_data: {}"
+ .format(ext_data))
+ return
path = os.path.join(self.destdir, project)
- self.log.info("Deleting package {0}".format(package_name))
+
+ self.log.info("Deleting package {0}".format(target_dir))
self.log.info("Copr path {0}".format(path))
try:
@@ -132,20 +138,20 @@ class Action(object):
chroots_to_do = chroot_list.intersection(chroots_requested)
if not chroots_to_do:
self.log.info("Nothing to delete for delete action: package {}, {}"
- .format(package_name, ext_data))
+ .format(target_dir, ext_data))
return
for chroot in chroots_to_do:
self.log.debug("In chroot {0}".format(chroot))
altered = False
- pkg_path = os.path.join(path, chroot, package_name)
+ pkg_path = os.path.join(path, chroot, target_dir)
if os.path.isdir(pkg_path):
self.log.info("Removing build {0}".format(pkg_path))
shutil.rmtree(pkg_path)
altered = True
else:
- self.log.debug("Package {0} dir not found in chroot {1}".format(package_name, chroot))
+ self.log.debug("Package {0} dir not found in chroot {1}".format(target_dir, chroot))
if altered:
self.log.debug("Running createrepo")
8 years, 9 months
[copr] master: typo (b6e861f)
by vgologuz@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit b6e861f58307f01ab095b67c383df3e6a95d943e
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Mon Aug 3 16:39:57 2015 +0200
typo
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/models.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py
index cd97787..aa3547f 100644
--- a/frontend/coprs_frontend/coprs/models.py
+++ b/frontend/coprs_frontend/coprs/models.py
@@ -640,7 +640,7 @@ class BuildChroot(db.Model, helpers.Serializer):
self.name,
]
if self.git_hash is not None and self.build.package:
- parts.append(self.build.package.name)
+ parts.append(self.build.result_dir_name)
else:
parts.append(self.build.src_pkg_name)
8 years, 9 months
[copr] master: [copr][frontend] add support for legacy build result_url 2 (26d3080)
by vgologuz@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 26d308023d86711e99245d8c227ba1fd45ae456b
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Mon Aug 3 16:25:28 2015 +0200
[copr][frontend] add support for legacy build result_url 2
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/models.py | 30 +++++++++++++++++-------------
1 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py
index b2d8dbd..cd97787 100644
--- a/frontend/coprs_frontend/coprs/models.py
+++ b/frontend/coprs_frontend/coprs/models.py
@@ -1,5 +1,6 @@
import datetime
import json
+import os
from sqlalchemy.ext.associationproxy import association_proxy
from libravatar import libravatar_url
@@ -625,7 +626,7 @@ class BuildChroot(db.Model, helpers.Serializer):
return None
@property
- def result_url(self):
+ def result_dir(self):
# hide changes occurred after migration to dist-git
# if build has defined dist-git, it means that new schema should be used
# otherwise use older structure
@@ -633,19 +634,22 @@ class BuildChroot(db.Model, helpers.Serializer):
# old: results/valtri/ruby/fedora-rawhide-x86_64/rubygem-aws-sdk-resources-2.1.11-1.fc24/
# new: results/asamalik/rh-perl520/epel-7-x86_64/00000187-rh-perl520/
- kwargs = {
- "backend_url": app.config["BACKEND_BASE_URL"],
- "owner": self.build.copr.owner.username,
- "copr": self.build.copr.name,
- "chroot": self.name,
- "result_dir_name": self.build.result_dir_name,
- "src_pkg_name": self.build.src_pkg_name,
- }
- if self.git_hash is not None:
- template = "{backend_url}/{owner}/{copr}/{chroot}/{package_name}"
+ parts = [
+ self.build.copr.owner.username,
+ self.build.copr.name,
+ self.name,
+ ]
+ if self.git_hash is not None and self.build.package:
+ parts.append(self.build.package.name)
else:
- template = "{backend_url}/{owner}/{copr}/{chroot}/{src_pkg_name}"
- return template.format(**kwargs)
+ parts.append(self.build.src_pkg_name)
+
+ return os.path.join(*parts)
+
+ @property
+ def result_url(self):
+
+ return "{}/results/{}".format(app.config["BACKEND_BASE_URL"], self.result_dir)
def __str__(self):
return "<BuildChroot: {}>".format(self.to_dict())
8 years, 9 months