Dockerisation de ScoDoc #919
184
.dockerignore
Normal file
184
.dockerignore
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# ---> Emacs
|
||||||
|
# -*- mode: gitignore; -*-
|
||||||
|
*~
|
||||||
|
\#*\#
|
||||||
|
/.emacs.desktop
|
||||||
|
/.emacs.desktop.lock
|
||||||
|
*.elc
|
||||||
|
auto-save-list
|
||||||
|
tramp
|
||||||
|
.\#*
|
||||||
|
|
||||||
|
# cask packages
|
||||||
|
.cask/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Flycheck
|
||||||
|
flycheck_*.el
|
||||||
|
|
||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
envsco8/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# Mac OSX OS generated files
|
||||||
|
.DS_Store?
|
||||||
|
Thumbs.db
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
# Subversion (protects when importing)
|
||||||
|
.svn
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
copy
|
||||||
|
|
||||||
|
# Symlinks static ScoDoc
|
||||||
|
app/static/links/[0-9]*.*[0-9]
|
||||||
|
|
||||||
|
# Essais locaux
|
||||||
|
xp/
|
||||||
|
|
||||||
|
/.git
|
||||||
|
/.gitea
|
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
35
Dockerfile
Normal file
35
Dockerfile
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
FROM debian:12
|
||||||
|
|
||||||
|
ARG SCODOC_VERSION=dev \
|
||||||
|
SCODOC_COMMIT=dev \
|
||||||
|
IMAGE_DATE=dev
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.created=$IMAGE_DATE \
|
||||||
|
org.opencontainers.image.authors="ScoDoc" \
|
||||||
|
org.opencontainers.image.url="https://scodoc.org" \
|
||||||
|
org.opencontainers.image.documentation="https://scodoc.org" \
|
||||||
|
org.opencontainers.image.source="https://git.scodoc.org/ScoDoc/ScoDoc.git" \
|
||||||
|
org.opencontainers.image.version=$SCODOC_VERSION \
|
||||||
|
org.opencontainers.image.vendor="ScoDoc" \
|
||||||
|
org.opencontainers.image.licenses="GPL-2.0-only" \
|
||||||
|
org.opencontainers.image.ref.name=$SCODOC_COMMIT \
|
||||||
|
org.opencontainers.image.title="ScoDoc" \
|
||||||
|
org.opencontainers.image.description="ScoDoc: un logiciel libre pour le suivi de la scolarité"
|
||||||
|
|
||||||
|
COPY . /opt/scodoc
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get upgrade --yes \
|
||||||
|
&& useradd --shell /bin/bash --create-home --comment "ScoDoc service" scodoc \
|
||||||
|
&& mkdir -p /opt/scodoc-data \
|
||||||
|
&& chown -R scodoc:scodoc /opt/scodoc /opt/scodoc-data \
|
||||||
|
&& apt-get install --yes curl gcc graphviz graphviz-dev libpq-dev cracklib-runtime libcrack2-dev libpango-1.0-0 pango1.0-tools python3-dev python3-venv python3-pip python3-wheel postgresql-client \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& su -c "(cd /opt/scodoc && python3 -m venv venv && source venv/bin/activate && pip install wheel && pip install -r requirements-3.11.txt)" scodoc \
|
||||||
|
&& rm -rf ~scodoc/.cache/pip
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
HEALTHCHECK CMD curl --fail http://127.0.0.1:8000 || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/opt/scodoc/tools/docker-entrypoint.sh" ]
|
@ -576,7 +576,7 @@ def clear_scodoc_cache():
|
|||||||
# attaque directement redis, court-circuite ScoDoc:
|
# attaque directement redis, court-circuite ScoDoc:
|
||||||
import redis
|
import redis
|
||||||
|
|
||||||
r = redis.Redis()
|
r = redis.Redis(host=(os.environ.get("CACHE_REDIS_HOST") or "localhost"))
|
||||||
r.flushall()
|
r.flushall()
|
||||||
# Also clear local caches:
|
# Also clear local caches:
|
||||||
sco_preferences.clear_base_preferences()
|
sco_preferences.clear_base_preferences()
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
"""Dump base de données pour debug et support technique
|
"""Dump base de données pour debug et support technique
|
||||||
|
|
||||||
Le principe est le suivant:
|
Le principe est le suivant:
|
||||||
1- S'il existe une base en cours d'anonymisation, s'arrête et affiche un msg
|
1- Si la base est en cours d'anonymisation, s'arrête et affiche un msg
|
||||||
d'erreur à l'utilisateur, qui peut décider de la supprimer.
|
d'erreur à l'utilisateur, qui peut décider de la supprimer.
|
||||||
|
|
||||||
2- ScoDoc lance un script qui duplique la base (la copie de SCORT devient ANORT)
|
2- ScoDoc lance un script qui duplique la base (la copie de SCODOC devient SCODOC_ANO)
|
||||||
- (si elle existe deja, s'arrête)
|
- (si elle existe deja, s'arrête)
|
||||||
createdb -E UTF-8 ANORT
|
psql postgres:///SCODOC -c "CREATE DATABASE SCODOC_ANO WITH ENCODING 'UTF8';
|
||||||
pg_dump SCORT | psql ANORT
|
pg_dump postgres:///SCODOC | psql postgres:///SCODOC_ANO
|
||||||
|
|
||||||
|
|
||||||
3- ScoDoc lance le script d'anonymisation config/anonymize_db.py qui:
|
3- ScoDoc lance le script d'anonymisation config/anonymize_db.py qui:
|
||||||
@ -50,11 +50,12 @@ import base64
|
|||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import urllib.parse
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from config import RunningConfig
|
||||||
|
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
@ -72,10 +73,10 @@ def sco_dump_and_send_db(
|
|||||||
traceback_str = base64.urlsafe_b64decode(traceback_str_base64).decode(
|
traceback_str = base64.urlsafe_b64decode(traceback_str_base64).decode(
|
||||||
scu.SCO_ENCODING
|
scu.SCO_ENCODING
|
||||||
)
|
)
|
||||||
# get current (dept) DB name:
|
db_uri = RunningConfig.SQLALCHEMY_DATABASE_URI
|
||||||
cursor = ndb.SimpleQuery("SELECT current_database()", {})
|
db_name = urllib.parse.urlparse(db_uri).path.lstrip("/")
|
||||||
db_name = cursor.fetchone()[0]
|
ano_db_uri = db_uri + "_ANO"
|
||||||
ano_db_name = "ANO" + db_name
|
ano_db_name = db_name + "_ANO"
|
||||||
# Lock
|
# Lock
|
||||||
try:
|
try:
|
||||||
x = open(SCO_DUMP_LOCK, "w+")
|
x = open(SCO_DUMP_LOCK, "w+")
|
||||||
@ -90,13 +91,15 @@ def sco_dump_and_send_db(
|
|||||||
_drop_ano_db(ano_db_name)
|
_drop_ano_db(ano_db_name)
|
||||||
|
|
||||||
# Duplicate database
|
# Duplicate database
|
||||||
_duplicate_db(db_name, ano_db_name)
|
_duplicate_db(db_uri, db_name, ano_db_uri, ano_db_name)
|
||||||
|
|
||||||
# Anonymisation
|
# Anonymisation
|
||||||
anonymize_db(ano_db_name)
|
anonymize_db(ano_db_uri, ano_db_name)
|
||||||
|
|
||||||
# Send
|
# Send
|
||||||
r = _send_db(ano_db_name, message, request_url, traceback_str=traceback_str)
|
r = _send_db(
|
||||||
|
ano_db_uri, ano_db_name, message, request_url, traceback_str=traceback_str
|
||||||
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# Drop anonymized database
|
# Drop anonymized database
|
||||||
@ -109,19 +112,24 @@ def sco_dump_and_send_db(
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def _duplicate_db(db_name, ano_db_name):
|
def _duplicate_db(db_uri: str, db_name: str, ano_db_uri: str, ano_db_name: str):
|
||||||
"""Create new database, and copy old one into"""
|
"""Create new database, and copy old one into"""
|
||||||
cmd = ["createdb", "-E", "UTF-8", ano_db_name]
|
cmd = [
|
||||||
|
"psql",
|
||||||
|
RunningConfig.SQLALCHEMY_DATABASE_URI,
|
||||||
|
"-c",
|
||||||
|
f"CREATE DATABASE \"{ano_db_name}\" WITH ENCODING 'UTF8';",
|
||||||
|
]
|
||||||
log(f"sco_dump_and_send_db/_duplicate_db: {cmd}")
|
log(f"sco_dump_and_send_db/_duplicate_db: {cmd}")
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output(cmd)
|
_ = subprocess.check_output(cmd)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
log(f"sco_dump_and_send_db: exception createdb {e}")
|
log(f"sco_dump_and_send_db: exception psql {e}")
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
f"erreur lors de la creation de la base {ano_db_name}"
|
f"erreur lors de la creation de la base {ano_db_name}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
cmd = f"pg_dump {db_name} | psql {ano_db_name}"
|
cmd = f"pg_dump {db_uri} | psql {ano_db_uri}"
|
||||||
log("sco_dump_and_send_db/_duplicate_db: {}".format(cmd))
|
log("sco_dump_and_send_db/_duplicate_db: {}".format(cmd))
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output(cmd, shell=1)
|
_ = subprocess.check_output(cmd, shell=1)
|
||||||
@ -132,12 +140,12 @@ def _duplicate_db(db_name, ano_db_name):
|
|||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
|
||||||
def anonymize_db(ano_db_name):
|
def anonymize_db(ano_db_uri: str, ano_db_name: str):
|
||||||
"""Anonymize a ScoDoc database"""
|
"""Anonymize a ScoDoc database"""
|
||||||
cmd = os.path.join(scu.SCO_TOOLS_DIR, "anonymize_db.py")
|
cmd = [os.path.join(scu.SCO_TOOLS_DIR, "anonymize_db.py"), ano_db_uri]
|
||||||
log(f"anonymize_db: {cmd}")
|
log(f"anonymize_db: {cmd}")
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output([cmd, ano_db_name])
|
_ = subprocess.check_output(cmd)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
log(f"sco_dump_and_send_db: exception in anonymisation: {e}")
|
log(f"sco_dump_and_send_db: exception in anonymisation: {e}")
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
@ -156,7 +164,11 @@ def _get_scodoc_serial():
|
|||||||
|
|
||||||
|
|
||||||
def _send_db(
|
def _send_db(
|
||||||
ano_db_name: str, message: str = "", request_url: str = "", traceback_str: str = ""
|
ano_db_uri: str,
|
||||||
|
ano_db_name: str,
|
||||||
|
message: str = "",
|
||||||
|
request_url: str = "",
|
||||||
|
traceback_str: str = "",
|
||||||
):
|
):
|
||||||
"""Dump this (anonymized) database and send it to tech support"""
|
"""Dump this (anonymized) database and send it to tech support"""
|
||||||
log(f"dumping anonymized database {ano_db_name}")
|
log(f"dumping anonymized database {ano_db_name}")
|
||||||
@ -203,18 +215,14 @@ def _send_db(
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def _drop_ano_db(ano_db_name):
|
def _drop_ano_db(ano_db_name: str):
|
||||||
"""drop temp database if it exists"""
|
"""drop temp database if it exists"""
|
||||||
existing_databases = [
|
cmd = [
|
||||||
s.split("|")[0].strip()
|
"psql",
|
||||||
for s in subprocess.check_output(["psql", "-l"])
|
RunningConfig.SQLALCHEMY_DATABASE_URI,
|
||||||
.decode(scu.SCO_ENCODING)
|
"-c",
|
||||||
.split("\n")[3:]
|
f"DROP DATABASE IF EXISTS \"{ano_db_name}\";",
|
||||||
]
|
]
|
||||||
if ano_db_name not in existing_databases:
|
|
||||||
log("_drop_ano_db: no temp db, nothing to drop")
|
|
||||||
return
|
|
||||||
cmd = ["dropdb", ano_db_name]
|
|
||||||
log(f"sco_dump_and_send_db: {cmd}")
|
log(f"sco_dump_and_send_db: {cmd}")
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output(cmd)
|
_ = subprocess.check_output(cmd)
|
||||||
|
65
docker-compose.yml
Normal file
65
docker-compose.yml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
services:
|
||||||
|
scodoc:
|
||||||
|
image: scodoc/scodoc
|
||||||
|
container_name: scodoc
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
SCODOC_DATABASE_URI: postgresql://scodb:scodb@db/SCODOC
|
||||||
|
CACHE_REDIS_HOST: cache
|
||||||
|
SCODOC_ADMIN_MAIL: admin@scodoc.local
|
||||||
|
SCODOC_ADMIN_PASSWORD: p@ssword
|
||||||
|
#SCODOC_MAIL_FROM: no-reply@scodoc.local
|
||||||
|
#MAIL_SERVER: smtp.scodoc.local
|
||||||
|
#MAIL_PORT: 587
|
||||||
|
#MAIL_USE_TLS: True
|
||||||
|
#MAIL_USERNAME: scodoc
|
||||||
|
#MAIL_PASSWORD: scodoc
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8000:8000"
|
||||||
|
volumes:
|
||||||
|
- scodata:/opt/scodoc-data
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_started
|
||||||
|
cache:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- db
|
||||||
|
- cache
|
||||||
|
db:
|
||||||
|
image: postgres
|
||||||
|
container_name: scodoc_db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: scodb
|
||||||
|
POSTGRES_PASSWORD: scodb
|
||||||
|
volumes:
|
||||||
|
- scodb:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- db
|
||||||
|
cache:
|
||||||
|
image: valkey/valkey
|
||||||
|
container_name: scodoc_cache
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- cache
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "valkey-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
watchtower:
|
||||||
|
image: containrrr/watchtower
|
||||||
|
container_name: watchtower
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
command: scodoc scodoc_db scodoc_cache --schedule "0 0 2 * * *"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
scodata:
|
||||||
|
scodb:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
db:
|
||||||
|
cache:
|
@ -39,6 +39,8 @@ import sys
|
|||||||
import traceback
|
import traceback
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from psycopg2 import extras
|
from psycopg2 import extras
|
||||||
|
import urllib.parse
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def log(msg):
|
def log(msg):
|
||||||
@ -203,13 +205,14 @@ def anonymize_users(cursor):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def uri_rm_passwd(uri):
|
||||||
|
return re.compile(r'(postgres://[^:]+:)([^@]+)(@)').sub(r'\1*****\3', uri)
|
||||||
|
|
||||||
def anonymize_db(cursor):
|
def anonymize_db(cursor):
|
||||||
"""Traite, une à une, les colonnes indiquées dans ANONYMIZED_FIELDS"""
|
"""Traite, une à une, les colonnes indiquées dans ANONYMIZED_FIELDS"""
|
||||||
for tablecolumn in ANONYMIZED_FIELDS:
|
for tablecolumn in ANONYMIZED_FIELDS:
|
||||||
anonymize_column(cursor, tablecolumn)
|
anonymize_column(cursor, tablecolumn)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
PROCESS_USERS = False
|
PROCESS_USERS = False
|
||||||
if len(sys.argv) < 2 or len(sys.argv) > 3:
|
if len(sys.argv) < 2 or len(sys.argv) > 3:
|
||||||
@ -217,18 +220,19 @@ if __name__ == "__main__":
|
|||||||
if len(sys.argv) > 2:
|
if len(sys.argv) > 2:
|
||||||
if sys.argv[1] != "--users":
|
if sys.argv[1] != "--users":
|
||||||
usage()
|
usage()
|
||||||
dbname = sys.argv[2]
|
dburi = sys.argv[2]
|
||||||
PROCESS_USERS = True
|
PROCESS_USERS = True
|
||||||
else:
|
else:
|
||||||
dbname = sys.argv[1]
|
dburi = sys.argv[1]
|
||||||
|
|
||||||
|
dbname = urllib.parse.urlparse(dburi).path.lstrip("/")
|
||||||
|
|
||||||
log(f"\nAnonymizing database {dbname}")
|
log(f"\nAnonymizing database {dbname}")
|
||||||
cnx_string = "dbname=" + dbname
|
|
||||||
try:
|
try:
|
||||||
cnx = psycopg2.connect(cnx_string)
|
cnx = psycopg2.connect(dburi)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"\n*** Error: can't connect to database {dbname} ***\n")
|
log(f"\n*** Error: can't connect to database {dbname} ***\n")
|
||||||
log(f"""connexion string was "{cnx_string}" """)
|
log(f"""connexion uri was "{uri_rm_passwd(dburi)}" """)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
cnx.set_session(autocommit=False)
|
cnx.set_session(autocommit=False)
|
||||||
|
@ -11,11 +11,17 @@ die() {
|
|||||||
}
|
}
|
||||||
[ $# = 1 ] || [ $# = 2 ] || die "Usage $0 [--drop] db_name"
|
[ $# = 1 ] || [ $# = 2 ] || die "Usage $0 [--drop] db_name"
|
||||||
|
|
||||||
|
if [ -z "${SCODOC_DATABASE_URI}" ]; then
|
||||||
|
PG_URI="postgresql:///postgres"
|
||||||
|
else
|
||||||
|
PG_URI=$(echo $SCODOC_DATABASE_URI | sed 's|/[^/]*$|/postgres|')
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$1" = "--drop" ]
|
if [ "$1" = "--drop" ]
|
||||||
then
|
then
|
||||||
db_name="$2"
|
db_name="$2"
|
||||||
echo "Dropping database $db_name..."
|
echo "Dropping database $db_name..."
|
||||||
dropdb --if-exists "$db_name"
|
psql $PG_URI -c "DROP DATABASE IF EXISTS $db_name;"
|
||||||
else
|
else
|
||||||
db_name="$1"
|
db_name="$1"
|
||||||
fi
|
fi
|
||||||
@ -30,5 +36,5 @@ source "$SCRIPT_DIR"/utils.sh || die "config.sh not found, exiting"
|
|||||||
|
|
||||||
# ---
|
# ---
|
||||||
echo 'Creating postgresql database ' "$db_name"
|
echo 'Creating postgresql database ' "$db_name"
|
||||||
createdb -E UTF-8 -p "$POSTGRES_PORT" -O "$POSTGRES_USER" "$db_name"
|
psql $PG_URI -c "CREATE DATABASE \"$db_name\" WITH ENCODING 'UTF-8';"
|
||||||
echo 'CREATE EXTENSION IF NOT EXISTS "unaccent";' | psql -p "$POSTGRES_PORT" "$db_name" "$POSTGRES_USER"
|
psql $(echo $PG_URI | sed "s|/postgres\$|/$db_name|") -c 'CREATE EXTENSION IF NOT EXISTS "unaccent";'
|
||||||
|
@ -4,5 +4,5 @@ Architecture: amd64
|
|||||||
Maintainer: Emmanuel Viennet <emmanuel@viennet.net>
|
Maintainer: Emmanuel Viennet <emmanuel@viennet.net>
|
||||||
Description: ScoDoc 9
|
Description: ScoDoc 9
|
||||||
Un logiciel pour le suivi de la scolarité universitaire.
|
Un logiciel pour le suivi de la scolarité universitaire.
|
||||||
Depends: adduser, curl, gcc, graphviz, graphviz-dev, libpq-dev, postfix|exim4, cracklib-runtime, libcrack2-dev, libpango-1.0-0, pango1.0-tools, python3-dev, python3-venv, python3-pip, python3-wheel, nginx, postgresql, libpq-dev, redis
|
Depends: adduser, curl, gcc, graphviz, graphviz-dev, libpq-dev, postfix|exim4, cracklib-runtime, libcrack2-dev, libpango-1.0-0, pango1.0-tools, python3-dev, python3-venv, python3-pip, python3-wheel, nginx, postgresql, redis
|
||||||
Recommends: ufw
|
Recommends: ufw
|
||||||
|
105
tools/docker-entrypoint.sh
Executable file
105
tools/docker-entrypoint.sh
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script à lancer en tant que root au démarrage du container Docker
|
||||||
|
|
||||||
|
echo "Initialisation de ScoDoc..."
|
||||||
|
|
||||||
|
# Le répertoire de ce script:
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/config.sh"
|
||||||
|
source "$SCRIPT_DIR/utils.sh"
|
||||||
|
|
||||||
|
if [ -z "${SCODOC_DATABASE_URI}" ]; then
|
||||||
|
echo "La variable d'environnement SCODOC_DATABASE_URI doit être définie pour poursuivre le démarrage."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${FLASK_ENV}" ]; then
|
||||||
|
export FLASK_ENV=production
|
||||||
|
fi
|
||||||
|
|
||||||
|
db_name=$(echo $SCODOC_DATABASE_URI | sed -E 's/.*\/([^\/]+)$/\1/')
|
||||||
|
|
||||||
|
if [[ "$db_name" == "$SCODOC_DATABASE_URI" ]]; then
|
||||||
|
# nom de la base de données par défaut si non spécifié dans l'URI
|
||||||
|
db_name="SCODOC"
|
||||||
|
export SCODOC_DATABASE_URI="$SCODOC_DATABASE_URI/$db_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# URI de la base 'postgres', nécessaire pour les commandes de création de base
|
||||||
|
PG_DATABASE_URI=$(echo "$SCODOC_DATABASE_URI" | sed -E 's|/[^/]+$|/postgres|')
|
||||||
|
|
||||||
|
if [ -z "${CACHE_REDIS_HOST}" ]; then
|
||||||
|
echo "La variable d'environnement CACHE_REDIS_HOST doit être définie pour poursuivre le démarrage."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /opt/scodoc || die "Error: chdir to /opt/scodoc"
|
||||||
|
mkdir -p /opt/scodoc-data || die "Error: mkdir /opt/scodoc-data"
|
||||||
|
# ------------ CREATION ENVIRONNEMENT
|
||||||
|
# Création du fichier .env si absent
|
||||||
|
if ! [ -f /opt/scodoc-data/.env ]; then
|
||||||
|
if [ -z "${SCODOC_ADMIN_MAIL}" ]; then
|
||||||
|
echo "La variable d'environnement SCODOC_ADMIN_MAIL doit être définie pour poursuivre l'installation (nécessaire uniquement pour le premier démarrage)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
SECRET_KEY=$(python3 -c "import uuid; print(uuid.uuid4().hex)")
|
||||||
|
cat > /opt/scodoc-data/.env <<EOF
|
||||||
|
# .env for ScoDoc
|
||||||
|
FLASK_APP=scodoc.py
|
||||||
|
|
||||||
|
SCODOC_ADMIN_MAIL="$SCODOC_ADMIN_MAIL" # important: le mail de admin
|
||||||
|
SECRET_KEY="$SECRET_KEY" # une chaine aléatoire"
|
||||||
|
|
||||||
|
EOF
|
||||||
|
echo "Fichier /opt/scodoc-data/.env créé avec:"
|
||||||
|
cat /opt/scodoc-data/.env
|
||||||
|
echo
|
||||||
|
echo "Vous pouvez le modifier si besoin."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------ VERIFICATIONS DES REPERTOIRES ET DROITS
|
||||||
|
# déjà fait par le Dockerfile, mais certaines fausses manips de nos utilisateurs
|
||||||
|
# ont pu changer ça:
|
||||||
|
set_scodoc_var_dir
|
||||||
|
change_scodoc_file_ownership
|
||||||
|
|
||||||
|
# ------------ CREATION BASE DE DONNEES
|
||||||
|
# Création de la base de données si elle n'existe pas
|
||||||
|
echo "Connexion à la base de données.."
|
||||||
|
if ! pg_isready -d $PG_DATABASE_URI --timeout=30; then
|
||||||
|
echo "Erreur: impossible de se connecter à la base de données."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if psql $PG_DATABASE_URI -lqt | cut -d \| -f 1 | grep -iqw "$db_name"; then
|
||||||
|
echo "Connexion réussie, la base $db_name existe."
|
||||||
|
else
|
||||||
|
echo "Connexion réussie, la base $db_name n'existe pas. Création..."
|
||||||
|
su -c "/opt/scodoc/tools/create_database.sh $db_name" scodoc || die "Erreur: create_database.sh $db_name"
|
||||||
|
echo "Base $db_name créée."
|
||||||
|
# ------------ INITIALISATION BASE DE DONNEES
|
||||||
|
echo
|
||||||
|
echo "Création des tables et du compte admin"
|
||||||
|
echo
|
||||||
|
if [ -z "${SCODOC_ADMIN_PASSWORD}" ]; then
|
||||||
|
echo "La variable d'environnement SCODOC_ADMIN_PASSWORD doit être définie pour poursuivre l'installation (nécessaire uniquement pour le premier démarrage)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
su -c "cd /opt/scodoc; source venv/bin/activate; flask db upgrade; flask sco-db-init; flask user-password admin --password $SCODOC_ADMIN_PASSWORD" scodoc || die "Erreur: sco-db-init"
|
||||||
|
echo
|
||||||
|
echo "Base initialisée et admin créé."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------ LANCEMENT DES SERVICES
|
||||||
|
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "ScoDoc configuré et démarré."
|
||||||
|
echo "Vous pouvez vous connecter en web et vous identifier comme \"admin\"."
|
||||||
|
echo
|
||||||
|
|
||||||
|
su -c "cd /opt/scodoc; /opt/scodoc/venv/bin/gunicorn -b 0.0.0.0:8000 -w 4 --timeout 600 scodoc:app" scodoc
|
@ -1,26 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Initialize database (create tables) for a ScoDoc instance
|
|
||||||
# This script must be executed as user scodoc
|
|
||||||
#
|
|
||||||
# $db_name and $DEPT passed as environment variables
|
|
||||||
|
|
||||||
# Le répertoire de ce script:
|
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
||||||
|
|
||||||
source "$SCRIPT_DIR/config.sh"
|
|
||||||
source "$SCRIPT_DIR/utils.sh"
|
|
||||||
|
|
||||||
if [ "$(id -nu)" != "$SCODOC_USER" ]
|
|
||||||
then
|
|
||||||
echo "$0: script must be runned as user $SCODOC_USER"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
echo 'Initializing tables in database ' "$db_name"
|
|
||||||
$PSQL -U "$POSTGRES_USER" -p "$POSTGRES_PORT" "$db_name" -f "$SCODOC_DIR"/misc/createtables.sql
|
|
||||||
|
|
||||||
|
|
||||||
# Set DeptName in preferences:
|
|
||||||
echo "insert into sco_prefs (name, value) values ('DeptName', '"${DEPT}\'\) | $PSQL -U "$POSTGRES_USER" -p "$POSTGRES_PORT" "$db_name"
|
|
Loading…
Reference in New Issue
Block a user