[copr] master: Automatic commit of package [copr-selinux] release [1.31-1]. (6891272)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 689127212b41ecacbea6cf1d47ec4c65aa530a7c
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Wed May 21 12:54:50 2014 +0200
Automatic commit of package [copr-selinux] release [1.31-1].
>---------------------------------------------------------------
rel-eng/packages/copr-selinux | 2 +-
selinux/copr-selinux.spec | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/rel-eng/packages/copr-selinux b/rel-eng/packages/copr-selinux
index 72d0b76..1d2c9c8 100644
--- a/rel-eng/packages/copr-selinux
+++ b/rel-eng/packages/copr-selinux
@@ -1 +1 @@
-1.30-1 selinux/
+1.31-1 selinux/
diff --git a/selinux/copr-selinux.spec b/selinux/copr-selinux.spec
index 74309c1..321040a 100644
--- a/selinux/copr-selinux.spec
+++ b/selinux/copr-selinux.spec
@@ -8,7 +8,7 @@
%{!?_selinux_policy_version: %global _selinux_policy_version %(sed -e 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' /usr/share/selinux/devel/policyhelp 2>/dev/null)}
Name: copr-selinux
-Version: 1.30
+Version: 1.31
Release: 1%{?dist}
Summary: SELinux module for COPR
@@ -110,6 +110,9 @@ fi
%{_mandir}/man8/%{name}-relabel.8*
%changelog
+* Wed May 21 2014 Miroslav Suchý <msuchy(a)redhat.com> 1.31-1
+- follow selinux packaging draft
+
* Tue Mar 18 2014 Miroslav Suchý <msuchy(a)redhat.com> 1.30-1
- finish move selinux into separate package
9 years, 11 months
[copr] master: follow selinux packaging draft (4f203d7)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 4f203d779c59eaa9458e492c2b1a7b1747098807
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Wed May 21 12:53:24 2014 +0200
follow selinux packaging draft
http://fedoraproject.org/wiki/SELinux_Policy_Modules_Packaging_Draft
>---------------------------------------------------------------
backend/copr-backend.spec | 2 ++
backend/copr-be.py | 2 ++
selinux/copr-selinux-enable | 2 +-
selinux/copr-selinux.spec | 11 ++++++++---
4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/backend/copr-backend.spec b/backend/copr-backend.spec
index 86d1885..49392d9 100644
--- a/backend/copr-backend.spec
+++ b/backend/copr-backend.spec
@@ -44,6 +44,8 @@ Requires: python-daemon
Requires: python-lockfile
Requires: python-requests
Requires: python-setproctitle
+Requires: python-retask
+Requires: redis
Requires: logrotate
Requires: fedmsg
Requires: gawk
diff --git a/backend/copr-be.py b/backend/copr-be.py
index 57fdcf8..456ea65 100755
--- a/backend/copr-be.py
+++ b/backend/copr-be.py
@@ -5,6 +5,8 @@ from backend import errors
from backend.dispatcher import Worker
from backend.actions import Action
from bunch import Bunch
+from retask.task import Task
+from retask.queue import Queue
import ConfigParser
import daemon
import glob
diff --git a/selinux/copr-selinux-enable b/selinux/copr-selinux-enable
index 4fdc03e..fdcefb1 100755
--- a/selinux/copr-selinux-enable
+++ b/selinux/copr-selinux-enable
@@ -1,7 +1,7 @@
#!/bin/bash
# Install SELinux policy modules
-for selinuxvariant in targeted; do
+for selinuxvariant in targeted mls; do
/usr/sbin/semodule -s ${selinuxvariant} -l > /dev/null 2>&1 \
&& /usr/sbin/semodule -s ${selinuxvariant} -i /usr/share/selinux/${selinuxvariant}/copr.pp.bz2
done
diff --git a/selinux/copr-selinux.spec b/selinux/copr-selinux.spec
index 197a48b..74309c1 100644
--- a/selinux/copr-selinux.spec
+++ b/selinux/copr-selinux.spec
@@ -2,8 +2,10 @@
%global _pkgdocdir %{_docdir}/%{name}-%{version}
%global __python2 %{__python}
%endif
+
%global moduletype apps
%global modulename copr
+%{!?_selinux_policy_version: %global _selinux_policy_version %(sed -e 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' /usr/share/selinux/devel/policyhelp 2>/dev/null)}
Name: copr-selinux
Version: 1.30
@@ -30,6 +32,9 @@ Requires(post): policycoreutils, libselinux-utils
Requires(post): policycoreutils-python
Requires(post): selinux-policy-targeted
Requires(postun): policycoreutils
+%if "%{_selinux_policy_version}" != ""
+Requires: selinux-policy >= %{_selinux_policy_version}
+%endif
%description
@@ -48,7 +53,7 @@ a2x -d manpage -f manpage man/copr-selinux-enable.8.asciidoc
a2x -d manpage -f manpage man/copr-selinux-relabel.8.asciidoc
perl -i -pe 'BEGIN { $VER = join ".", grep /^\d+$/, split /\./, "%{version}.%{release}"; } s!\@\@VERSION\@\@!$VER!g;' %{modulename}.te
-for selinuxvariant in targeted; do
+for selinuxvariant in targeted mls; do
make NAME=${selinuxvariant} -f /usr/share/selinux/devel/Makefile
bzip2 -9 %{modulename}.pp
mv %{modulename}.pp.bz2 %{modulename}.pp.bz2.${selinuxvariant}
@@ -56,7 +61,7 @@ for selinuxvariant in targeted; do
done
%install
-for selinuxvariant in targeted; do
+for selinuxvariant in targeted mls; do
install -d %{buildroot}%{_datadir}/selinux/${selinuxvariant}
install -p -m 644 %{modulename}.pp.bz2.${selinuxvariant} \
%{buildroot}%{_datadir}/selinux/${selinuxvariant}/%{modulename}.pp.bz2
@@ -87,7 +92,7 @@ fi
%postun
# Clean up after package removal
if [ $1 -eq 0 ]; then
- for selinuxvariant in targeted; do
+ for selinuxvariant in targeted mls; do
/usr/sbin/semodule -s ${selinuxvariant} -l > /dev/null 2>&1 \
&& /usr/sbin/semodule -s ${selinuxvariant} -r %{modulename} || :
done
9 years, 11 months
[copr] master: [backend] epel 5 repo fix (sha256 -> sha) (81f4339)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 81f433926793339dee31d67f6919f21f9ad34767
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Mon May 19 14:25:55 2014 +0200
[backend] epel 5 repo fix (sha256 -> sha)
>---------------------------------------------------------------
backend/backend/mockremote.py | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/backend/backend/mockremote.py b/backend/backend/mockremote.py
index d2f4767..5b9e409 100755
--- a/backend/backend/mockremote.py
+++ b/backend/backend/mockremote.py
@@ -63,11 +63,21 @@ class SortedOptParser(optparse.OptionParser):
def createrepo(path, lock=None):
- if os.path.exists(path + '/repodata/repomd.xml'):
- comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock',
- '--update', path]
+ if "epel-5" in path:
+ # this is because rhel-5 doesn't know sha256
+ if os.path.exists(path + '/repodata/repomd.xml'):
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock',
+ '--update', '-s', 'sha', path]
+ else:
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock',
+ '-s', 'sha', path]
else:
- comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock', path]
+ if os.path.exists(path + '/repodata/repomd.xml'):
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock',
+ '--update', path]
+ else:
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock',
+ path]
if lock:
lock.acquire()
cmd = subprocess.Popen(comm,
9 years, 11 months
[copr] master: [cli] cancel added to the man page (4345dbb)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 4345dbbfa00bc17202d3ff53329a06c5f2437530
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Thu May 15 13:14:27 2014 +0200
[cli] cancel added to the man page
>---------------------------------------------------------------
cli/man/copr-cli.1.asciidoc | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/cli/man/copr-cli.1.asciidoc b/cli/man/copr-cli.1.asciidoc
index b748ab9..2d25522 100644
--- a/cli/man/copr-cli.1.asciidoc
+++ b/cli/man/copr-cli.1.asciidoc
@@ -47,6 +47,9 @@ Build packages for a specified project.
status::
Get the status of the build.
+cancel::
+Cancel a build of given id.
+
`copr-cli create [options]`
~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 years, 11 months
[copr] master: build detail and new builds table (5bd0dd3)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 5bd0dd3f7ed93d89a543423472fab6c503d29952
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Wed May 7 09:59:10 2014 +0200
build detail and new builds table
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/filters.py | 41 ++++++++++-
.../coprs_frontend/coprs/logic/builds_logic.py | 4 +
frontend/coprs_frontend/coprs/static/copr.css | 37 ++++++++---
.../templates/coprs/detail/_builds_table.html | 60 ++++-------------
.../templates/coprs/detail/build-no-project.html | 7 ++
.../coprs/templates/coprs/detail/build.html | 70 ++++++++++++++++++++
.../coprs/views/coprs_ns/coprs_builds.py | 37 ++++++++++-
.../test_views/test_coprs_ns/test_coprs_general.py | 10 ++-
8 files changed, 204 insertions(+), 62 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/filters.py b/frontend/coprs_frontend/coprs/filters.py
index 2153240..8271ddc 100644
--- a/frontend/coprs_frontend/coprs/filters.py
+++ b/frontend/coprs_frontend/coprs/filters.py
@@ -3,6 +3,8 @@ import pytz
import time
import markdown
+import os
+
from flask import Markup
from coprs import app
@@ -22,6 +24,13 @@ def perm_type_from_num(num):
return helpers.PermissionEnum(num)
+(a)app.template_filter("state_from_num")
+def state_from_num(num):
+ if num is None:
+ return "unknown"
+ return helpers.StatusEnum(num)
+
+
@app.template_filter("os_name_short")
def os_name_short(os_name, os_version):
# TODO: make it models.MockChroot method or not?
@@ -43,7 +52,7 @@ def localized_time(time_in, timezone):
"""
if not time_in:
return "Not yet"
- format_tz = "%Y-%m-%d %H:%M:%S %Z"
+ format_tz = "%y-%m-%d %H:%M %Z"
utc_tz = pytz.timezone('UTC')
if timezone:
user_tz = pytz.timezone(timezone)
@@ -55,20 +64,37 @@ def localized_time(time_in, timezone):
@app.template_filter('time_ago')
-def time_ago(time_in):
+def time_ago(time_in, until = None):
""" returns string saying how long ago the time on input was
Input is in EPOCH (seconds since epoch).
"""
- now = datetime.datetime.now()
+ if time_in is None:
+ return " - "
+ if until is not None:
+ now = datetime.datetime.fromtimestamp(until)
+ else:
+ now = datetime.datetime.now()
diff = now - datetime.datetime.fromtimestamp(time_in)
secdiff = int(diff.total_seconds())
if secdiff < 120:
+ # less than 2 minutes
return "1 minute"
elif secdiff < 7200:
+ # less than 2 hours
return str(secdiff/60) + " minutes"
- else:
+ elif secdiff < 172800:
+ # less than 2 days
return str(secdiff/3600) + " hours"
+ elif secdiff < 5184000:
+ # less than 2 months
+ return str(secdiff/86400) + " days"
+ elif secdiff < 63072000:
+ # less than 2 years
+ return str(secdiff/2592000) + " months"
+ else:
+ # more than 2 years
+ return str(secdiff/31536000) + " days"
@app.template_filter("markdown")
@@ -81,3 +107,10 @@ def markdown_filter(data):
html_replacement_text="--RAW HTML NOT ALLOWED--")
return Markup(md.convert(data))
+
+
+(a)app.template_filter("pkg_name")
+def parse_package_name(pkg):
+ if pkg is not None:
+ return helpers.parse_package_name(os.path.basename(pkg))
+ return pkg
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index ba6dac7..4536f2b 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -67,6 +67,10 @@ class BuildsLogic(object):
return models.Build.query.filter(models.Build.id.in_(ids))
@classmethod
+ def get_by_id(cls, id):
+ return models.Build.query.get(id)
+
+ @classmethod
def add(cls, user, pkgs, copr,
repos=None, memory_reqs=None, timeout=None, chroots=[]):
diff --git a/frontend/coprs_frontend/coprs/static/copr.css b/frontend/coprs_frontend/coprs/static/copr.css
index 03586c5..fc245ce 100644
--- a/frontend/coprs_frontend/coprs/static/copr.css
+++ b/frontend/coprs_frontend/coprs/static/copr.css
@@ -21,6 +21,14 @@ h2 {
font-size: 1.1em;
}
+h2.build-detail {
+ font-size: 1.8em;
+}
+
+h3 {
+ font-size: 1.1em;
+}
+
#logo {
position: relative;
top: 8px;
@@ -238,7 +246,7 @@ div.shift-right {
}
dt.field-label {
- margin: 15px 0;
+ margin: 15px 0 0 0;
font-weight: bold;
}
@@ -286,6 +294,10 @@ table.builds-table form {
display: inline;
}
+div.build-buttons form {
+ display: inline;
+}
+
table.builds-table tr.details {
width: 100%;
}
@@ -307,29 +319,36 @@ table.status-table tr:first-child {
background-color: #1f4b89;
}
-tr.build-state:hover {
+table.status-table a {
text-decoration: underline;
- background-color: #E6E6E6;
+}
+
+tr.build-row {
+ color: #666;
+}
+
+tr.build-row-succeeded {
+ color: black;
}
.build-pending {
- color: #3B6EB4;
+ color: #55b;
}
.build-running {
- color: #FF6600;
+ color: #c84;
}
.build-succeeded {
- color: #22DD22;
+ color: #272;
}
.build-failed {
- color: #DD2222;
+ color: #c44;
}
-.build-canceled {
- color: #CDC90C;
+.build-cancelled {
+ color: #666;
}
table.releases th {
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
index 720ef76..d5751fb 100644
--- a/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
@@ -2,57 +2,27 @@
{% macro builds_table(builds, page) %}
{% if builds %}
- <table class="builds-table">
+ <table class="status-table">
<tr>
<th>Id</th>
- <th>Submitted on</th>
- <th>Submitted by</th>
- <th>Started on</th>
- <th>Ended on</th>
- <th>State</th>
+ <th>Package</th>
+ <th>Submitted</th>
+ <th>Build time</th>
+ <th>Status</th>
</tr>
{% for build in builds %}
- <tr class="build-{{ build.state }} build-state">
- <td>{{ build.id }}</td>
-{% if g.user %}
- <td>{{ build.submitted_on|localized_time(g.user.timezone) }}</td>
-{% else %}
- <td>{{ build.submitted_on|localized_time("UTC") }}</td>
-{% endif %}
-
- <td>{{ build.user.name }}</td>
-{% if g.user %}
- <td>{{ build.started_on|localized_time(g.user.timezone) }}</td>
- <td>{{ build.ended_on|localized_time(g.user.timezone) }}</td>
-{% else %}
- <td>{{ build.started_on|localized_time("UTC") }}</td>
- <td>{{ build.ended_on|localized_time("UTC") }}</td>
-{% endif %}
- <td>{{ build.state }}</td>
- </tr>
- <tr class="details">
- <td colspan=6 class="end">
- <div>
- {% if g.user and g.user.can_build_in(copr) %}
- {{ copr_build_cancel_form(build, page) }}
- {% endif %}
- {% if g.user and g.user.can_build_in(copr) %}
- {{ copr_build_repeat_form(build, page) }}
- {% endif %}
- {% if g.user and g.user.can_edit(copr) %}
- {{ copr_build_delete_form(build, page) }}
- {% endif %}
- <div>
- {% if build.results %}
- <h2>Results: </h2><a href="{{ build.results }}">{{ build.results }}</a>
+ <tr class="build-row build-row-{{ build.state }}" >
+ <th><a href="{{url_for("coprs_ns.copr_build", username = build.copr.owner.name, coprname = build.copr.name, build_id = build.id)}}">{{ build.id }}</a></th>
+ <th>{{ build.pkgs|pkg_name }}</th>
+ <th>
+ {% if g.user %}
+ {{ build.submitted_on|localized_time(g.user.timezone) }}
{% else %}
- <h2>No results yet.</h2>
+ {{ build.submitted_on|localized_time("UTC") }}
{% endif %}
- <div>
- <h2>Package URLs:</h2>
- <div class="pkg-url-list">{% if build.pkgs is not none %}{% for pkg in build.pkgs.split() %}<a href="{{ pkg }}">{{ pkg }}</a>
-{% endfor %}{% endif %}</div>
- </td>
+ </th>
+ <th> {{ build.started_on|time_ago(build.ended_on) }} </th>
+ <th class="build-{{ build.state }}">{{ build.state }}</th>
</tr>
{% endfor %}
</table>
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/build-no-project.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/build-no-project.html
new file mode 100644
index 0000000..6e28e6a
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/build-no-project.html
@@ -0,0 +1,7 @@
+{% extends "layout.html" %}
+{% block title%}Build {{ build.id }}{%endblock%}
+{% block body %}
+<h2 class="build-detail"> Build {{ build.id }} </h2>
+<p> Project {{username}}/{{coprname}} doesn't exist!</p>
+<p> You can go to <a href="{{url_for("coprs_ns.copr_build", username = build.copr.owner.name, coprname = build.copr.name, build_id = build.id)}}"> {{ build.copr.owner.name }}/{{build.copr.name }}/build/{{build.id}} </a>to see this build.</p>
+{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/build.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/build.html
new file mode 100644
index 0000000..9f75dfe
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/build.html
@@ -0,0 +1,70 @@
+{% extends "coprs/detail.html" %}
+{% from "coprs/detail/_builds_forms.html" import copr_build_cancel_form, copr_build_repeat_form, copr_build_delete_form %}
+{% block title %}Build {{ build.id }} in {{ build.copr.owner.name }}/{{ build.copr.name }}{% endblock %}
+
+{% block detail_body %}
+
+{% if build.copr != copr %}
+<h2 class="build-detail"> Build {{ build.id }} doesn't belong to this project. </h2>
+<p> You can go to <a href="{{url_for("coprs_ns.copr_build", username = build.copr.owner.name, coprname = build.copr.name, build_id = build.id)}}"> {{ build.copr.owner.name }}/{{ build.copr.name }}/build/{{build.id}} </a>to see this build. </p>
+
+
+{% else %}
+ <h2 class="build-detail"> Build {{ build.id }} in {{ build.copr.owner.name }}/{{ build.copr.name }}</h2>
+ <div class="build-buttons" >
+ {% if g.user and g.user.can_build_in(copr) %}
+ {{ copr_build_cancel_form(build, page) }}
+ {% endif %}
+ {% if g.user and g.user.can_build_in(copr) %}
+ {{ copr_build_repeat_form(build, page) }}
+ {% endif %}
+ {% if g.user and g.user.can_edit(copr) %}
+ {{ copr_build_delete_form(build, page) }}
+ {% endif %}
+ </div>
+
+ <dl>
+ <dt class="field-label"> Package name:<dt>
+ <dd>{{ build.pkgs|pkg_name }}</dd>
+ </dt>
+ <dt class="field-label"> Build time:</dt>
+ <dd><b>Submitted: </b>
+ {% if g.user %}
+ {{ build.submitted_on|localized_time(g.user.timezone) }}
+ {% else %}
+ {{ build.submitted_on|localized_time("UTC") }}
+ {% endif %}
+ ({{ build.submitted_on|time_ago }} ago)
+ </dd>
+ <dd><b>Started: </b>
+ {% if g.user %}
+ {{ build.started_on|localized_time(g.user.timezone) }}
+ {% else %}
+ {{ build.started_on|localized_time("UTC") }}
+ {% endif %}
+ ({{ build.started_on|time_ago }} ago)
+ </dd>
+ <dd><b>Build time: </b> {{ build.started_on|time_ago(build.ended_on) }} </dd>
+ <dt class="field-label"> Results:</dt>
+ {% if build.results %}
+ <dd><a href="{{ build.results }}">{{ build.results }}</a></dd>
+ {% else %}
+ <dd>No results yet</dd>
+ {% endif %}
+ <dt class="field-label"> Chroots:</dt>
+ {% for chroot in build.build_chroots %}
+ <dd><b>{{ chroot.name }}: </b>
+ <span class="build-{{ chroot.status|state_from_num }}">{{ chroot.status|state_from_num }}</span>
+ </dd>
+ {% endfor %}
+ <dt class="field-label"> Package URL:</dt>
+ {% if build.pkgs is not none %}{% for pkg in build.pkgs.split() %}
+ <dd> <a href="{{ pkg }}">{{ pkg }}</a></dd>
+ {% endfor %}{% endif %}
+ <dt class="field-label"> Submitted by:</dt>
+ <dd>{{ build.user.name }}</dd>
+ </dl>
+
+
+{% endif %}
+{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py
index e6a2fa5..20112a5 100644
--- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py
+++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py
@@ -14,6 +14,41 @@ from coprs.exceptions import (ActionInProgressException,
InsufficientRightsException)
+
+(a)coprs_ns.route("/build/<int:build_id>/")
+def copr_build_redirect(build_id):
+ build = builds_logic.BuildsLogic.get_by_id(build_id)
+ if not build:
+ return page_not_found(
+ "Build {0} does not exist.".format(str(build_id)))
+
+ return flask.redirect(flask.url_for("coprs_ns.copr_build",
+ username = build.copr.owner.name,
+ coprname = build.copr.name,
+ build_id = build_id))
+
+
+(a)coprs_ns.route("/<username>/<coprname>/build/<int:build_id>/")
+def copr_build(username, coprname, build_id):
+ build = builds_logic.BuildsLogic.get_by_id(build_id)
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+
+ if not build:
+ return page_not_found(
+ "Build {0} does not exist.".format(str(build_id)))
+
+ if not copr: # but the build does
+ return flask.render_template("coprs/detail/build-no-project.html",
+ build = build,
+ username = username,
+ coprname = coprname)
+
+ return flask.render_template("coprs/detail/build.html",
+ build = build,
+ copr = copr)
+
+
+
@coprs_ns.route("/<username>/<coprname>/builds/", defaults={"page": 1})
@coprs_ns.route("/<username>/<coprname>/builds/<int:page>/")
def copr_builds(username, coprname, page=1):
@@ -27,7 +62,7 @@ def copr_builds(username, coprname, page=1):
flask.g.user, copr=copr)
paginator = helpers.Paginator(
- builds_query, copr.build_count, page, per_page_override=10)
+ builds_query, copr.build_count, page, per_page_override=30)
return flask.render_template("coprs/detail/builds.html",
copr=copr,
diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
index b31e611..06137e7 100644
--- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
+++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
@@ -232,7 +232,9 @@ class TestCoprDetail(CoprsTestCase):
assert '<select id="copr_admin_1" name="copr_admin_1">' in r.data
def test_copr_detail_doesnt_show_cancel_build_for_anonymous(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.get("/coprs/{0}/{1}/".format(self.u2.name, self.c2.name))
+ r = self.tc.get(
+ "/coprs/{0}/{1}/build/{2}/".format(self.u2.name, self.c2.name,
+ str(self.c2.builds[0].id)))
assert "/cancel_build/" not in r.data
@TransactionDecorator("u1")
@@ -241,7 +243,8 @@ class TestCoprDetail(CoprsTestCase):
self.db.session.add_all([self.u2, self.c2])
r = self.test_client.get(
- "/coprs/{0}/{1}/builds/".format(self.u2.name, self.c2.name))
+ "/coprs/{0}/{1}/build/{2}/".format(self.u2.name, self.c2.name,
+ str(self.c2.builds[0].id)))
assert "/cancel_build/" not in r.data
@TransactionDecorator("u2")
@@ -250,7 +253,8 @@ class TestCoprDetail(CoprsTestCase):
self.db.session.add_all([self.u2, self.c2])
r = self.test_client.get(
- "/coprs/{0}/{1}/builds/".format(self.u2.name, self.c2.name))
+ "/coprs/{0}/{1}/build/{2}/".format(self.u2.name, self.c2.name,
+ str(self.c2.builds[0].id)))
assert "/cancel_build/" in r.data
9 years, 12 months
[copr] master: admin/playground page (cbe1c1f)
by asamalik@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit cbe1c1f526442a9daed8708d8efc7678d81ff604
Author: Adam Samalik <asamalik(a)redhat.com>
Date: Wed Apr 30 12:44:29 2014 +0200
admin/playground page
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/forms.py | 8 ++
frontend/coprs_frontend/coprs/logic/coprs_logic.py | 9 +++
.../coprs/templates/admin/_admin_forms.html | 31 +++++++++
.../coprs/templates/admin/layout.html | 3 +
.../coprs/templates/admin/playground.html | 16 +++++
.../coprs/views/admin_ns/admin_general.py | 69 ++++++++++++++++++++
6 files changed, 136 insertions(+), 0 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py
index 691610a..ba5a2a4 100644
--- a/frontend/coprs_frontend/coprs/forms.py
+++ b/frontend/coprs_frontend/coprs/forms.py
@@ -302,3 +302,11 @@ class CoprModifyForm(wtf.Form):
class ModifyChrootForm(wtf.Form):
buildroot_pkgs = wtforms.TextField('Additional packages to be always present in minimal buildroot')
+
+class AdminPlaygroundForm(wtf.Form):
+ playground = wtforms.BooleanField("Playground")
+
+
+class AdminPlaygroundSearchForm(wtf.Form):
+ project = wtforms.TextField("Project")
+
diff --git a/frontend/coprs_frontend/coprs/logic/coprs_logic.py b/frontend/coprs_frontend/coprs/logic/coprs_logic.py
index 73d20c9..1bc8be4 100644
--- a/frontend/coprs_frontend/coprs/logic/coprs_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/coprs_logic.py
@@ -103,6 +103,15 @@ class CoprsLogic(object):
return cls.get_all().filter(models.Copr.playground == True)
@classmethod
+ def set_playground(cls, user, copr):
+ if user.admin:
+ db.session.add(copr)
+ pass
+ else:
+ raise exceptions.InsufficientRightsException(
+ "User is not a system admin")
+
+ @classmethod
def get_multiple_fulltext(cls, user, search_string):
query = (models.Copr.query.join(models.User)
.filter(models.Copr.deleted == False)
diff --git a/frontend/coprs_frontend/coprs/templates/admin/_admin_forms.html b/frontend/coprs_frontend/coprs/templates/admin/_admin_forms.html
new file mode 100644
index 0000000..6e48b6b
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/admin/_admin_forms.html
@@ -0,0 +1,31 @@
+{% from "_helpers.html" import render_field %}
+
+{% macro admin_playground_form(form, copr) %}
+ <form action="{{ url_for('admin_ns.playground_set', username=copr.owner.name, coprname=copr.name) }}" method="post">
+ {{ form.csrf_token }}
+ <table class="status-table">
+ <tbody>
+ <tr>
+ <th>Project</th>
+ <th>Playground</th>
+ <th></th>
+ </tr>
+ <tr>
+ <th>{{copr.owner.name}}/{{copr.name}}</th>
+ <th>{{ form.playground }}</th>
+ <th><input type="submit" value="Set"></th>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+{% endmacro %}
+
+{% macro admin_playground_search(form) %}
+ <form action="{{ url_for('admin_ns.playground') }}" method="post">
+ <dl>
+ {{ form.csrf_token }}
+ Playground flag: {{ form.project }}
+ <dt><input type="submit" value="Set"></dt>
+ </dl>
+ </form>
+{% endmacro %}
diff --git a/frontend/coprs_frontend/coprs/templates/admin/layout.html b/frontend/coprs_frontend/coprs/templates/admin/layout.html
index c8d48c9..23fcd57 100644
--- a/frontend/coprs_frontend/coprs/templates/admin/layout.html
+++ b/frontend/coprs_frontend/coprs/templates/admin/layout.html
@@ -8,6 +8,9 @@
<li class="{% block legal_flag_selected %}unselected{% endblock %}">
<a href="{{ url_for('admin_ns.legal_flag') }}">Legal Flags</a>
</li>
+ <li class="{% block playground_selected %}unselected{% endblock %}">
+ <a href="{{ url_for('admin_ns.playground') }}">Playground</a>
+ </li>
</ul>
</div>
{% block admin_body %}{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/templates/admin/playground.html b/frontend/coprs_frontend/coprs/templates/admin/playground.html
new file mode 100644
index 0000000..7b1b761
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/templates/admin/playground.html
@@ -0,0 +1,16 @@
+{% extends "admin/layout.html" %}
+{% from "admin/_admin_forms.html" import admin_playground_form %}
+{% from "admin/_admin_forms.html" import admin_playground_search %}
+
+{% block playground_selected %}selected{% endblock %}
+
+{% block admin_body %}
+{% if form_search: %}
+{{ admin_playground_search(form_search) }}
+{% endif %}
+
+{% if form_set and copr:%}
+{{ admin_playground_form(form_set, copr) }}
+{% endif %}
+
+{% endblock %}
diff --git a/frontend/coprs_frontend/coprs/views/admin_ns/admin_general.py b/frontend/coprs_frontend/coprs/views/admin_ns/admin_general.py
index 1f91370..e3fbeb4 100644
--- a/frontend/coprs_frontend/coprs/views/admin_ns/admin_general.py
+++ b/frontend/coprs_frontend/coprs/views/admin_ns/admin_general.py
@@ -1,14 +1,19 @@
import time
+import re
import flask
from coprs import db
from coprs import helpers
from coprs import models
+from coprs import forms
+
+from coprs.logic import coprs_logic
from coprs.views.admin_ns import admin_ns
from coprs.views.misc import login_required
+from coprs.exceptions import InsufficientRightsException
@admin_ns.route("/")
@login_required(role=helpers.RoleEnum("admin"))
@@ -42,3 +47,67 @@ def legal_flag_resolve(flag_id):
db.session.commit()
flask.flash("Legal flag resolved")
return flask.redirect(flask.url_for("admin_ns.legal_flag"))
+
+
+(a)admin_ns.route("/playground/", methods=["POST", "GET"])
+(a)login_required(role=helpers.RoleEnum("admin"))
+def playground():
+ form = forms.AdminPlaygroundSearchForm()
+
+ if form.validate_on_submit() and form.project.data:
+ m = re.match(r"(.+)/(.+)", form.project.data)
+ if not m:
+ flask.flash("Please search as username/projectname")
+ else:
+ username = m.group(1)
+ coprname = m.group(2)
+
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+
+ if copr:
+ return flask.redirect(flask.url_for("admin_ns.playground_project",
+ username=username,
+ coprname=coprname))
+ else:
+ flask.flash("This project does not exist")
+
+ return flask.render_template("admin/playground.html", form_search = form)
+
+
+(a)admin_ns.route("/playground/<username>/<coprname>/")
+(a)login_required(role=helpers.RoleEnum("admin"))
+def playground_project(username, coprname):
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+ if not copr:
+ flask.flash("Project {0} does not exist".format(copr))
+ return flask.render_template("admin/playground.html")
+
+ form = forms.AdminPlaygroundForm()
+ form.playground.data = copr.playground
+ return flask.render_template("admin/playground.html",
+ form_set = form,
+ copr = copr)
+
+
+(a)admin_ns.route("/playground/<username>/<coprname>/set/", methods=["POST"])
+(a)login_required(role=helpers.RoleEnum("admin"))
+def playground_set(username, coprname):
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+ if copr:
+ form = forms.AdminPlaygroundForm()
+
+ if form.validate_on_submit():
+ try:
+ copr.playground = form.playground.data
+ coprs_logic.CoprsLogic.set_playground(flask.g.user, copr)
+ except InsufficientRightsException as e:
+ flask.flash(str(e))
+ db.session.rollback()
+ else:
+ flask.flash("Playground flag has been updated")
+ db.session.commit()
+
+ return flask.redirect(flask.url_for("admin_ns.playground_project",
+ username=username,
+ coprname=coprname))
+
10 years
[copr] master: Use "https" in API template (fca65ec)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit fca65ec9882638ba3afa6e699400672a7ef2ac90
Author: Ricky Elrod <ricky(a)elrod.me>
Date: Sat May 3 03:33:58 2014 -0400
Use "https" in API template
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/templates/api.html | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/templates/api.html b/frontend/coprs_frontend/coprs/templates/api.html
index df37ec0..0424c06 100644
--- a/frontend/coprs_frontend/coprs/templates/api.html
+++ b/frontend/coprs_frontend/coprs/templates/api.html
@@ -23,7 +23,7 @@
login = {{ g.user.api_login }}
username = {{ g.user.name }}
token = {{ g.user.api_token }}
-copr_url = http://copr.fedoraproject.org
+copr_url = https://copr.fedoraproject.org
# expiration date: {{ g.user.api_token_expiration }}
</pre>
10 years
[copr] master: Use flask_openid safe_roots to mitigate Covert Redirect. (c8ec08a)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit c8ec08a8bc6b04cdc751420dcaa790319dbf260c
Author: Ralph Bean <rbean(a)redhat.com>
Date: Fri May 2 19:42:01 2014 -0400
Use flask_openid safe_roots to mitigate Covert Redirect.
>---------------------------------------------------------------
frontend/coprs_frontend/coprs/__init__.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/__init__.py b/frontend/coprs_frontend/coprs/__init__.py
index d69a635..b057f26 100644
--- a/frontend/coprs_frontend/coprs/__init__.py
+++ b/frontend/coprs_frontend/coprs/__init__.py
@@ -21,7 +21,7 @@ else:
app.config.from_pyfile("/etc/copr/copr.conf", silent=True)
-oid = OpenID(app, app.config["OPENID_STORE"])
+oid = OpenID(app, app.config["OPENID_STORE"], safe_roots=[])
db = SQLAlchemy(app)
whooshee = Whooshee(app)
10 years