Debian postinst restart services postgresql and scodoc9. Enhanced error page when DB unavailable.

This commit is contained in:
Emmanuel Viennet 2021-08-30 11:03:24 +02:00
parent 315a80b670
commit 4e836e61d3
7 changed files with 82 additions and 12 deletions

View File

@ -10,11 +10,9 @@ import traceback
import logging import logging
from logging.handlers import SMTPHandler, WatchedFileHandler from logging.handlers import SMTPHandler, WatchedFileHandler
from flask import request from flask import current_app, g, request
from flask import Flask from flask import Flask
from flask import current_app from flask import abort, has_request_context
from flask import g
from flask import has_request_context
from flask import render_template from flask import render_template
from flask.logging import default_handler from flask.logging import default_handler
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
@ -24,6 +22,7 @@ from flask_mail import Mail
from flask_bootstrap import Bootstrap from flask_bootstrap import Bootstrap
from flask_moment import Moment from flask_moment import Moment
from flask_caching import Cache from flask_caching import Cache
import sqlalchemy
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from config import DevConfig from config import DevConfig
@ -52,10 +51,31 @@ def handle_sco_value_error(exc):
def internal_server_error(e): def internal_server_error(e):
"""Bugs scodoc, erreurs 500"""
# note that we set the 500 status explicitly # note that we set the 500 status explicitly
return render_template("error_500.html", SCOVERSION=sco_version.SCOVERSION), 500 return render_template("error_500.html", SCOVERSION=sco_version.SCOVERSION), 500
def render_raw_html(template_filename: str, **args) -> str:
"""Load and render an HTML file _without_ using Flask
Necessary for 503 error mesage, when DB is down and Flask may be broken.
"""
template_path = os.path.join(
current_app.config["SCODOC_DIR"],
"app",
current_app.template_folder,
template_filename,
)
with open(template_path) as f:
txt = f.read().format(**args)
return txt
def postgresql_server_error(e):
"""Erreur de connection au serveur postgresql (voir notesdb.open_db_connection)"""
return render_raw_html("error_503.html", SCOVERSION=sco_version.SCOVERSION), 503
class RequestFormatter(logging.Formatter): class RequestFormatter(logging.Formatter):
"""Ajoute URL et remote_addr for logging""" """Ajoute URL et remote_addr for logging"""
@ -86,6 +106,7 @@ def create_app(config_class=DevConfig):
app.register_error_handler(ScoValueError, handle_sco_value_error) app.register_error_handler(ScoValueError, handle_sco_value_error)
app.register_error_handler(500, internal_server_error) app.register_error_handler(500, internal_server_error)
app.register_error_handler(503, postgresql_server_error)
from app.auth import bp as auth_bp from app.auth import bp as auth_bp
@ -178,7 +199,10 @@ def create_app(config_class=DevConfig):
def set_sco_dept(scodoc_dept: str): def set_sco_dept(scodoc_dept: str):
"""Set global g object to given dept and open db connection if needed""" """Set global g object to given dept and open db connection if needed"""
# Check that dept exists # Check that dept exists
dept = Departement.query.filter_by(acronym=scodoc_dept).first() try:
dept = Departement.query.filter_by(acronym=scodoc_dept).first()
except sqlalchemy.exc.OperationalError:
abort(503)
if not dept: if not dept:
raise ScoValueError(f"Invalid dept: {scodoc_dept}") raise ScoValueError(f"Invalid dept: {scodoc_dept}")
g.scodoc_dept = scodoc_dept # l'acronyme g.scodoc_dept = scodoc_dept # l'acronyme

View File

@ -7,7 +7,7 @@ import psycopg2
import psycopg2.pool import psycopg2.pool
import psycopg2.extras import psycopg2.extras
from flask import g, current_app from flask import g, current_app, abort
import app import app
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
@ -36,7 +36,13 @@ def unquote(s):
def open_db_connection(): def open_db_connection():
"""Open a connection to the database""" """Open a connection to the database"""
g.db_conn = psycopg2.connect(current_app.config["SQLALCHEMY_DATABASE_URI"]) try:
g.db_conn = psycopg2.connect(current_app.config["SQLALCHEMY_DATABASE_URI"])
except psycopg2.OperationalError:
# Dans la majorité des cas, cela signifie que le serveur postgres
# n'est pas lancé.
log("open_db_connection: psycopg2.OperationalError")
abort(503) # HTTP 503 Service Unavailable
def close_db_connection(): def close_db_connection():

View File

@ -10,7 +10,9 @@
<p> Si le problème persiste, contacter l'administrateur de votre site, <p> Si le problème persiste, contacter l'administrateur de votre site,
ou écrire la liste "notes" <a href="mailto:notes@listes.univ-paris13.fr">notes@listes.univ-paris13.fr</a> en ou écrire la liste "notes" <a href="mailto:notes@listes.univ-paris13.fr">notes@listes.univ-paris13.fr</a> en
indiquant la version du logiciel indiquant la version du logiciel
(plus d'informations <a href="https://scodoc.org/ListesDeDiffusion/">sur les listes de diffusion</a>). <br />
(plus d'informations sur les listes de diffusion<a href="https://scodoc.org/ListesDeDiffusion/">voir
cette page</a>).
</p> </p>
<p><a href="{{ url_for('scodoc.index') }}">retour à la page d'accueil</a></p> <p><a href="{{ url_for('scodoc.index') }}">retour à la page d'accueil</a></p>

View File

@ -0,0 +1,34 @@
<DOCTYPE! html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Service ScoDoc indisponible !</title>
</head>
<body class="hello">
<header>
<h1>Service ScoDoc indisponible !</h1>
</header>
<h1></h1>
<p>ScoDoc ne parvient pas à charger ses données.</p>
<p>Le plus souvent, ce problème indique que le serveur de base de données n'est pas lancé
ou ne fonctionne pas correctement: prévenir l'administrateur système ou le service
concerné de votre établissement.
</p>
<p><a href="/">retour à la page d'accueil</a></p>
<p> Si le problème persiste après intervention de votre équipe locale,
contacter la liste "notes" <a href="mailto:notes@listes.univ-paris13.fr">notes@listes.univ-paris13.fr</a> en
indiquant la version du logiciel (ScoDoc {SCOVERSION})
<br />(pour plus d'informations sur les listes de diffusion <a
href="https://scodoc.org/ListesDeDiffusion/">voir cette page</a>).
</p>
</body>
</html>

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.0.5" SCOVERSION = "9.0.6"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"

View File

@ -27,9 +27,11 @@ do
echo adding $locname echo adding $locname
echo "$locname ${locname##*.}" >> /etc/locale.gen echo "$locname ${locname##*.}" >> /etc/locale.gen
/usr/sbin/locale-gen --keep-existing /usr/sbin/locale-gen --keep-existing
systemctl restart postgresql
fi fi
done done
echo "debian postinst: scodoc9 is $(systemctl is-active scodoc9)"
# On a besoin d'un postgresql lancé pour la mise à jour
systemctl restart postgresql
# Le numero de version complet, genre 9.0.0 # Le numero de version complet, genre 9.0.0
SCODOC_RELEASE=$(grep SCOVERSION $SCODOC_DIR/sco_version.py | awk '{ print substr($3, 2, length($3)-2) }') SCODOC_RELEASE=$(grep SCOVERSION $SCODOC_DIR/sco_version.py | awk '{ print substr($3, 2, length($3)-2) }')
@ -123,3 +125,5 @@ systemctl start scodoc-updater.timer
systemctl daemon-reload systemctl daemon-reload
systemctl enable scodoc9 systemctl enable scodoc9
# --- RESTART SCODOC
systemctl restart scodoc9

View File

@ -18,8 +18,8 @@ server {
ssl_certificate /opt/scodoc-data/certs/cert.pem; ssl_certificate /opt/scodoc-data/certs/cert.pem;
ssl_certificate_key /opt/scodoc-data/certs/key.pem; ssl_certificate_key /opt/scodoc-data/certs/key.pem;
# write access and error logs to /var/log # write access and error logs to /var/log
access_log /var/log/scodoc_access.log; access_log /var/log/nginx/scodoc_access.log;
error_log /var/log/scodoc_error.log; error_log /var/log/nginx/scodoc_error.log;
location / { location / {
# forward application requests to the gunicorn server # forward application requests to the gunicorn server
proxy_pass http://localhost:8000; proxy_pass http://localhost:8000;