This commit is contained in:
František Zatloukal 2020-03-05 10:35:57 +01:00
commit 8410499db6
20 changed files with 72 additions and 94 deletions

View file

@ -14,7 +14,7 @@
# - name: run-volume
# mountPath: /run
FROM centos:centos7
FROM fedora:latest
LABEL \
name="Testdays application" \
vendor="Fedora QE" \
@ -27,18 +27,12 @@ USER root
COPY ./testdays.spec /opt/app-root/src/testdays/testdays.spec
# install dependencies defined in RPM spec file
RUN yum -y install epel-release
# Remove this once moved to Fedora base
RUN yum -y install gcc httpd httpd-devel python-pip python-devel
RUN pip install mod_wsgi
RUN yum -y install findutils rpm-build python-pip mod_wsgi httpd python-psycopg2 \
&& rpm --query --requires --specfile /opt/app-root/src/testdays/testdays.spec | xargs -d '\n' yum -y install
RUN dnf -y install findutils rpm-build python3-pip python3-mod_wsgi python3-psycopg2 \
&& rpm --query --requires --specfile /opt/app-root/src/testdays/testdays.spec | xargs -d '\n' dnf -y install
COPY . /opt/app-root/src/testdays/
# install using --no-deps option to ensure nothing comes from PyPi
RUN pip install --no-deps /opt/app-root/src/testdays/
RUN pip3 install --no-deps /opt/app-root/src/testdays/
# fix apache config for container use
RUN sed -i 's#^WSGISocketPrefix .*#WSGISocketPrefix /var/run/wsgi#' /opt/app-root/src/testdays/conf/testdays.conf
@ -60,15 +54,12 @@ RUN chmod -R 0755 /usr/share/testdays/alembic
# clean up
RUN rm -rf /opt/app-root/src/testdays \
&& yum -y autoremove rpm-build \
&& yum clean all
&& dnf -y autoremove rpm-build \
&& dnf clean all
# EXPOSE 5001/tcp
EXPOSE 5001
# Persistent VOLUME
VOLUME [ "/testdays" ]
CMD [ "runserver" ]
ENTRYPOINT [ "/usr/bin/container_start" ]
USER 1001:0

View file

@ -1,4 +1,3 @@
from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig

View file

@ -1,5 +1,5 @@
# you can use this as a template
RESULTSDB_URL = 'http://localhost:5001/api/v1.0'
RESULTSDB_URL = 'http://localhost:5001/api/v2.0'
SECRET_KEY = 'not-really-a-secret'
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://dbuser:dbpassword@dbhost:dbport/dbname'
SHOW_DB_URI = False

View file

@ -1,8 +1,3 @@
# This is required for running on EL6
import __main__
__main__.__requires__ = ['SQLAlchemy >= 0.7', 'Flask >= 0.9', 'jinja2 >= 2.6']
import pkg_resources
# if you're running the app from a virtualenv, uncomment these lines
#activate_this = '/var/www/testdays/env/bin/activate_this.py'
#execfile(activate_this, dict(__file__=activate_this))

View file

@ -1,7 +1,7 @@
#!/usr/bin/bash
if [[ $1 == runserver ]]; then
testdays init_db
mod_wsgi-express start-server /usr/share/testdays/testdays.wsgi --user apache --group apache \
mod_wsgi-express-3 start-server /usr/share/testdays/testdays.wsgi --user apache --group apache \
--port 5001 --threads 5 --include-file /etc/httpd/conf.d/testdays.conf --log-level info \
--log-to-terminal --access-log --startup-log
else

View file

@ -2,7 +2,7 @@
# this is a simple script to aid in the setup of a new db for F18
# init db
python run_cli.py init_db
python3 run_cli.py init_db
# insert mock data
python run_cli.py mock_data
python3 run_cli.py mock_data

View file

@ -1,9 +1,10 @@
Flask==0.9
Flask-SQLAlchemy==0.16
SQLAlchemy== 0.8.7
WTForms==2.0
Flask-WTF==0.10.0
Flask-Login==0.2.2
alembic==0.9.9
resultsdb-api==2.0.0
Werkzeug < 1.0.0
Flask
Flask-SQLAlchemy
SQLAlchemy
WTForms
Flask-WTF
Flask-Login
alembic
resultsdb-api
python-fedora

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
#
# Copyright 2014, Red Hat, Inc
#

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
#
# runapp.py - script to facilitate running the testdays app from the CLI
#

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
from setuptools import setup
import codecs

View file

@ -15,14 +15,14 @@ Source0: https://qadevel.cloud.fedoraproject.org/releases/%{name}/%{name}
BuildArch: noarch
Requires: python-flask
Requires: python-flask-sqlalchemy
Requires: python-flask-wtf
Requires: python-flask-login
Requires: python-alembic
Requires: python-fedora
Requires: python2-resultsdb_api
BuildRequires: python2-devel python-setuptools
Requires: python3-flask
Requires: python3-flask-sqlalchemy
Requires: python3-flask-wtf
Requires: python3-flask-login
Requires: python3-alembic
Requires: python3-fedora
Requires: python3-resultsdb_api
BuildRequires: python3-devel python3-setuptools
%description
Simple app to help record results from Fedora testdays
@ -31,10 +31,10 @@ Simple app to help record results from Fedora testdays
%setup -q
%build
%{__python2} setup.py build
%{__python3} setup.py build
%install
%{__python2} setup.py install --skip-build --root %{buildroot}
%{__python3} setup.py install --skip-build --root %{buildroot}
# apache and wsgi settings
mkdir -p %{buildroot}%{_datadir}/testdays/conf
@ -50,8 +50,8 @@ install conf/settings.py.example %{buildroot}%{_sysconfdir}/testdays/settings.py
%files
%doc README.md conf/*
%{python_sitelib}/testdays
%{python_sitelib}/*.egg-info
%{python3_sitelib}/testdays
%{python3_sitelib}/*.egg-info
%attr(755,root,root) %{_bindir}/testdays
%dir %{_sysconfdir}/testdays

View file

@ -18,8 +18,8 @@
# Josef Skladanka <jskladan@redhat.com>
from flask import Flask, render_template
from flask.ext.login import LoginManager
from flask.ext.sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from . import config
@ -77,7 +77,7 @@ def setup_logging():
root_logger.setLevel(logging.DEBUG)
if app.config['STREAM_LOGGING']:
print "doing stream logging"
print("doing stream logging")
stream_handler = logging.StreamHandler()
stream_handler.setLevel(loglevel)
stream_handler.setFormatter(formatter)
@ -85,7 +85,7 @@ def setup_logging():
app.logger.addHandler(stream_handler)
if app.config['SYSLOG_LOGGING']:
print "doing syslog logging"
print("doing syslog logging")
syslog_handler = logging.handlers.SysLogHandler(address='/dev/log',
facility=logging.handlers.SysLogHandler.LOG_LOCAL4)
syslog_handler.setLevel(loglevel)
@ -94,7 +94,7 @@ def setup_logging():
app.logger.addHandler(syslog_handler)
if app.config['FILE_LOGGING'] and app.config['LOGFILE']:
print "doing file logging to %s" % app.config['LOGFILE']
print("doing file logging to %s" % app.config['LOGFILE'])
file_handler = logging.handlers.RotatingFileHandler(app.config['LOGFILE'], maxBytes=500000, backupCount=5)
file_handler.setLevel(loglevel)
file_handler.setFormatter(formatter)

View file

@ -17,11 +17,6 @@
# Authors:
# Josef Skladanka <jskladan@redhat.com>
# This is required for running on EL6
import __main__
__main__.__requires__ = ['SQLAlchemy >= 0.7', 'Flask >= 0.9', 'jinja2 >= 2.6']
import pkg_resources
import os
import sys
from optparse import OptionParser
@ -48,7 +43,7 @@ def upgrade_db(*args):
context = MigrationContext.configure(db.engine.connect())
current_rev = context.get_current_revision()
print "Upgrading Database to `head` from `%s`" % current_rev
print("Upgrading Database to `head` from `%s`" % current_rev)
al_command.upgrade(alembic_cfg, "head")
@ -61,22 +56,22 @@ def init_alembic(*args):
current_rev = context.get_current_revision()
if not current_rev:
print "Initializing alembic"
print " - Setting the version to the first revision"
print("Initializing alembic")
print(" - Setting the version to the first revision")
al_command.stamp(alembic_cfg, "15f5eeb9f635")
else:
print "Alembic already initialized"
print("Alembic already initialized")
def initialize_db(destructive):
alembic_cfg = get_alembic_config()
print "Initializing database"
print("Initializing database")
if destructive:
print " - Dropping all tables"
print(" - Dropping all tables")
db.drop_all()
print " - Creating tables"
print(" - Creating tables")
db.create_all()
print " - Stamping alembic's current version to 'head'"
print(" - Stamping alembic's current version to 'head'")
al_command.stamp(alembic_cfg, "head")
init_alembic()
@ -84,10 +79,10 @@ def initialize_db(destructive):
def mock_data(destructive):
print "Populating tables with mock-data"
print("Populating tables with mock-data")
if destructive or not db.session.query(User).count():
print " - User"
print(" - User")
data_users = [('admin', 'admin'), ('user', 'user')]
for d in data_users:
@ -96,7 +91,7 @@ def mock_data(destructive):
db.session.commit()
else:
print " - skipped User"
print(" - skipped User")
def main():
possible_commands = ['init_db', 'mock_data', 'upgrade_db', 'init_alembic']
@ -111,9 +106,9 @@ def main():
(options, args) = parser.parse_args()
if len(args) != 1 or args[0] not in possible_commands:
print usage
print(usage)
print
print 'Please use one of the following commands: %s' % str(possible_commands)
print('Please use one of the following commands: %s' % str(possible_commands))
sys.exit(1)
command = {
@ -124,8 +119,8 @@ def main():
}[args[0]]
if not options.destructive:
print "Proceeding with non-destructive init. To perform destructive "\
"steps use -d option."
print("Proceeding with non-destructive init. To perform destructive "\
"steps use -d option.")
command(options.destructive)

View file

@ -16,7 +16,6 @@
#
# Authors:
# Josef Skladanka <jskladan@redhat.com>
from __future__ import print_function
import os
import sys
@ -38,7 +37,7 @@ class Config(object):
SHOW_DB_URI = False
RESULTSDB_URL = 'http://taskotron-local/resultsdb_api/api/v1.0/'
RESULTSDB_URL = 'http://localhost:5001/api/v2.0'
class ProductionConfig(Config):

View file

@ -20,7 +20,7 @@
import re
from flask import Blueprint, render_template, flash, url_for, redirect, make_response
from flask.ext.login import login_required
from flask_login import login_required
from sqlalchemy.orm.exc import NoResultFound
from resultsdb_api import ResultsDBapi
@ -53,7 +53,7 @@ def admin_index():
def event_from_metadata(url):
# grab the respective section from wikipage
data = wiki.get_page_section(url, "TestdayApp Metadata")
data = wiki.get_page_section(url, "TestdayApp Metadata").decode('utf-8')
# matches text from lines enclosed in '=' characters

View file

@ -18,10 +18,10 @@
# Josef Skladanka <jskladan@redhat.com>
from flask import Blueprint, render_template, redirect, flash, url_for, request
from flask.ext.wtf import Form
from flask_wtf import FlaskForm
from wtforms import TextField, PasswordField, HiddenField, RadioField
from wtforms.validators import Required
from flask.ext.login import login_user, logout_user, login_required, current_user, AnonymousUserMixin
from flask_login import login_user, logout_user, login_required, current_user, AnonymousUserMixin
from testdays import app, login_manager
@ -30,7 +30,7 @@ from testdays.models.user import User
login_page = Blueprint('login_page', __name__)
class LoginForm(Form):
class LoginForm(FlaskForm):
username = TextField(u'Username', validators = [Required()])
password = PasswordField(u'Password', validators = [Required()])
next_page = HiddenField()

View file

@ -183,8 +183,7 @@ def preparse_results(event):
matrix = {}
# We want to have the users sorted alphabetically in the table
users = by_user.keys()
users.sort()
users = sorted(by_user.keys())
# Create per-category pre-parsed lines of results
for category in event.categories:
@ -194,8 +193,7 @@ def preparse_results(event):
# Create a line-of-results per each user's profile
for user in users:
# Also, sort by the profile-info alphabetically
user_profiles = by_user[user].keys()
user_profiles.sort()
user_profiles = sorted(by_user[user].keys())
for profile in user_profiles:
data = by_user[user][profile]
# Check whether this user-profile set any results

View file

@ -1,11 +1,11 @@
from flask.ext.wtf import Form
from flask_wtf import FlaskForm
from wtforms.fields import TextField, SelectField, TextAreaField
from wtforms.validators import URL, Required, AnyOf, Regexp
class AddEventForm(Form):
class AddEventForm(FlaskForm):
metadata_url = TextField(u'Metadata URL', validators = [URL()])
class EnterResultFormTC(Form):
class EnterResultFormTC(FlaskForm):
username = TextField(u'Username', validators = [Required()])
col_1 = TextField(u'Profile')
@ -39,7 +39,7 @@ class EnterResultFormTC(Form):
if col_1_name is not None:
self.col_1.label.text = col_1_name
class EnterResultFormTXT(Form):
class EnterResultFormTXT(FlaskForm):
username = TextField(u'Username', validators = [Required()])
col_1 = TextField(u'Profile')

View file

@ -1,8 +1,8 @@
#!/usr/bin/python
#!/usr/bin/python3
# wiki.py - wiki interaction module for autoqa
import fedora.client
from urlparse import urljoin
from urllib.parse import urljoin
import urllib
import simplejson
@ -29,8 +29,8 @@ def __read_page_section(page, secnum):
# use that.
params = {'action':'raw','templates':'expand','section':secnum,'title':page}
url = urljoin(w.base_url, 'index.php')
url += '?' + urllib.urlencode(params, doseq=True)
section = urllib.urlopen(url)
url += '?' + urllib.parse.urlencode(params, doseq=True)
section = urllib.request.urlopen(url)
return section.read()
def get_page_section(page, secname):
@ -71,5 +71,5 @@ def get_autoqa_metadata(page):
if __name__ == '__main__':
import pprint
page = 'User:Jskladan/Sandbox:TestdayAppTemplate'
print "Fetching metadata from %s" % page
print("Fetching metadata from %s" % page)
pprint.pprint(get_page_section(page, 'TestdayApp Metadata'))

View file

@ -18,7 +18,7 @@
# Josef Skladanka <jskladan@redhat.com>
from testdays import db
from flask.ext.login import UserMixin
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model, UserMixin):