added capability to run a dev container for pa, and if we re-build we create a new .sk and remove old PA_UserState on fresh login. BUG-120 is either fixed by this or at least the log catches it and does not crash now (if we rebuild between re-use)

This commit is contained in:
2024-03-10 23:52:34 +11:00
parent 2665ab086e
commit d86893875d
5 changed files with 29 additions and 16 deletions

5
BUGs
View File

@@ -11,11 +11,6 @@ BUG-119: "Uncaught (in promise) Error: A listener indicated an asynchronous
was received"
investigate this (possible I'm calling check_for_jobs and maybe not doing the async right?)
BUG-120: on tablet:
[2023-04-09 12:21:21,214] ERROR in app: Exception on /view/16978 [GET]
-- should be much more defensive on this now - no more crashes, just persistent errors
(ERROR: pref not found - dn=uid=ddp,ou=users,dc=depaoli,dc=id,dc=au, st=, s=????)
BUG-123: pa_job_manager crashed with timeout on connection (probably when I turned off traefik for a bit?). Regardless, should be more fault tolerant --> maybe offer to restart pa_job_manager IF its crashed?
this definitely happened also, when I shutdown the DB back-end mid job, and it was able to be restarted, so could get f/e to at least suggest a restart of the contianer, or auto-restart job_mgr?

View File

@@ -3,12 +3,13 @@ WORKDIR /code
ENV PJM_UID=500
ENV PJM_GID=500
RUN groupadd -g ${PJM_GID} mythtv && useradd -r -u ${PJM_UID} -g ${PJM_GID} mythtv
RUN apt-get update && apt-get -y install libpq-dev mediainfo cmake libgl1-mesa-glx libglib2.0-0 libjpeg-turbo-progs ffmpeg git
# sudo used in dev container
RUN apt-get update && apt-get -y install libpq-dev mediainfo cmake libgl1-mesa-glx libglib2.0-0 libjpeg-turbo-progs ffmpeg git sudo
COPY . .
RUN pip3 install -r requirements.txt
RUN pip3 install --upgrade pillow --user
EXPOSE 80
RUN echo $RANDOM | md5sum | head -c 30 > /code/.sk
RUN cat /dev/urandom | head -c 50 | md5sum | head -c 32 > /code/.sk
RUN chmod 600 .sk
RUN date > internal/build-date.txt
RUN git log -n 15 > internal/git-log.txt

13
main.py
View File

@@ -11,7 +11,7 @@ from datetime import datetime
import os
import re
import socket
from shared import CreateSelect, CreateFoldersSelect, LocationIcon, DB_URL, PROD_HOST, OLDEST_LOG_LIMIT
from shared import CreateSelect, CreateFoldersSelect, LocationIcon, DB_URL, OLDEST_LOG_LIMIT
# for ldap auth
from flask_ldap3_login import LDAP3LoginManager
@@ -86,6 +86,7 @@ from files import Entry
from person import Person
from settings import Settings
from user import PAUser
from states import PA_UserState
####################################### GLOBALS #######################################
# allow jinja2 to call these python functions directly
@@ -148,6 +149,11 @@ def login():
# Successfully logged in, We can now access the saved user object via form.user.
login_user(form.user, remember=True) # Tell flask-login to log them in.
next = request.args.get("next")
# just (re)-authenticated, so clear old state from UserState, to avoid re-using old data that is no longer valid
PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn).delete()
db.session.commit()
if next:
return redirect(next) # Send them back where they came from
else:
@@ -242,10 +248,7 @@ def logout():
# main to be called via Flask/Gunicorn
###############################################################################
def main():
if hostname == PROD_HOST:
app.run(ssl_context=('/etc/letsencrypt/live/pa.depaoli.id.au/cert.pem', '/etc/letsencrypt/live/pa.depaoli.id.au/privkey.pem'), host="0.0.0.0", debug=False)
else:
app.run(host="0.0.0.0", debug=True)
app.run(host="0.0.0.0", debug=True)
###############################################################################
# This func creates a new filter in jinja2 to test to hand back the username

View File

@@ -24,7 +24,6 @@ class PA:
hostname = socket.gethostname()
PROD_HOST="pa_web"
# dict to store name of icon in icons.svg so we can use by referece in html
ICON={}
@@ -43,7 +42,7 @@ if hostname == "lappy":
PA_EXIF_AUTOROTATE = './utils/pa_exifautotran'
PA_EXIF_ROTATER = './utils/pa_rotate'
# if we dont set the env or we are explicitly DEV, run web server on localhost & db on mara (port 65432)
elif 'ENV' not in os.environ or os.environ['ENV'] == "development":
elif 'ENV' not in os.environ or os.environ['ENV'] == "development" or os.environ['ENV'] == "container":
PA_JOB_MANAGER_HOST="localhost"
DB_URL = 'postgresql+psycopg2://pa:for_now_pa@mara.ddp.net:65432/pa'
PA_EXIF_AUTOROTATE = './utils/pa_exifautotran'
@@ -56,6 +55,10 @@ elif os.environ['ENV'] == "production":
PA_EXIF_ROTATER = '/code/utils/pa_rotate'
else:
print( "ERROR: I do not know which environment (development, etc.) and which DB (on which host to use)" )
if 'ENV' not in os.environ:
print( f"ERROR: no ENV variable set in the environment" )
else:
print( f"ERROR: ENV is {os.environ['ENV']}" )
exit( -1 )
# PORT number we connect to the pa_job_manager on - by default it runs on the

View File

@@ -2,8 +2,19 @@
echo "ENV is set to: $ENV" &> /var/log/pa_job_manager.out &
su mythtv -g mythtv -c 'ENV="production" python3 -u /code/pa_job_manager.py' &> /var/log/pa_job_manager.out &
gunicorn --bind=0.0.0.0:80 --workers=4 --threads=16 main:app --env ENV="production" --error-logfile gunicorn.error.log --access-logfile gunicorn.log --capture-output
if [ "$ENV" == "production" ]; then
su mythtv -g mythtv -c 'ENV="production" python3 -u /code/pa_job_manager.py' &> /var/log/pa_job_manager.out &
gunicorn --bind=0.0.0.0:80 --workers=4 --threads=16 main:app --env ENV="production" --error-logfile gunicorn.error.log --access-logfile gunicorn.log --capture-output
elif [ "$ENV" == "container" ]; then
cd /home/ddp/src/photoassistant/
# add ddp quickly to container so we can run the job manager as ddp and write to the files
echo "ddp:x:1000:1000:Damien De Paoli,,,:/home/ddp:/bin/bash" >> /etc/passwd
ENV="container" sudo -u ddp python3 -u pa_job_manager.py &
gunicorn --bind=0.0.0.0:80 --workers=1 --threads=1 main:app --env ENV="container" --reload --capture-output
else
echo "Not sure which ENV ($ENV) we are running, set up for DEV and dont run job manager (jic)"
gunicorn --bind=0.0.0.0:80 --workers=1 --threads=1 main:app --env ENV="development" --error-logfile gunicorn.error.log --access-logfile gunicorn.log --capture-output --enable-stdio-inheritance --reload
fi
# this should never be invoked unless gunicorn fails -- in that case, at least
# we will keep the container can login by hand and check the issue/error