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" was received"
investigate this (possible I'm calling check_for_jobs and maybe not doing the async right?) 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? 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? 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_UID=500
ENV PJM_GID=500 ENV PJM_GID=500
RUN groupadd -g ${PJM_GID} mythtv && useradd -r -u ${PJM_UID} -g ${PJM_GID} mythtv 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 . . COPY . .
RUN pip3 install -r requirements.txt RUN pip3 install -r requirements.txt
RUN pip3 install --upgrade pillow --user RUN pip3 install --upgrade pillow --user
EXPOSE 80 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 chmod 600 .sk
RUN date > internal/build-date.txt RUN date > internal/build-date.txt
RUN git log -n 15 > internal/git-log.txt RUN git log -n 15 > internal/git-log.txt

11
main.py
View File

@@ -11,7 +11,7 @@ from datetime import datetime
import os import os
import re import re
import socket 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 # for ldap auth
from flask_ldap3_login import LDAP3LoginManager from flask_ldap3_login import LDAP3LoginManager
@@ -86,6 +86,7 @@ from files import Entry
from person import Person from person import Person
from settings import Settings from settings import Settings
from user import PAUser from user import PAUser
from states import PA_UserState
####################################### GLOBALS ####################################### ####################################### GLOBALS #######################################
# allow jinja2 to call these python functions directly # 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. # 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. login_user(form.user, remember=True) # Tell flask-login to log them in.
next = request.args.get("next") 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: if next:
return redirect(next) # Send them back where they came from return redirect(next) # Send them back where they came from
else: else:
@@ -242,9 +248,6 @@ def logout():
# main to be called via Flask/Gunicorn # main to be called via Flask/Gunicorn
############################################################################### ###############################################################################
def main(): 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)
############################################################################### ###############################################################################

View File

@@ -24,7 +24,6 @@ class PA:
hostname = socket.gethostname() hostname = socket.gethostname()
PROD_HOST="pa_web"
# dict to store name of icon in icons.svg so we can use by referece in html # dict to store name of icon in icons.svg so we can use by referece in html
ICON={} ICON={}
@@ -43,7 +42,7 @@ if hostname == "lappy":
PA_EXIF_AUTOROTATE = './utils/pa_exifautotran' PA_EXIF_AUTOROTATE = './utils/pa_exifautotran'
PA_EXIF_ROTATER = './utils/pa_rotate' 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) # 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" PA_JOB_MANAGER_HOST="localhost"
DB_URL = 'postgresql+psycopg2://pa:for_now_pa@mara.ddp.net:65432/pa' DB_URL = 'postgresql+psycopg2://pa:for_now_pa@mara.ddp.net:65432/pa'
PA_EXIF_AUTOROTATE = './utils/pa_exifautotran' PA_EXIF_AUTOROTATE = './utils/pa_exifautotran'
@@ -56,6 +55,10 @@ elif os.environ['ENV'] == "production":
PA_EXIF_ROTATER = '/code/utils/pa_rotate' PA_EXIF_ROTATER = '/code/utils/pa_rotate'
else: else:
print( "ERROR: I do not know which environment (development, etc.) and which DB (on which host to use)" ) 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 ) exit( -1 )
# PORT number we connect to the pa_job_manager on - by default it runs on the # 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 & echo "ENV is set to: $ENV" &> /var/log/pa_job_manager.out &
if [ "$ENV" == "production" ]; then
su mythtv -g mythtv -c 'ENV="production" python3 -u /code/pa_job_manager.py' &> /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 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 # 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 # we will keep the container can login by hand and check the issue/error