diff --git a/BUGs b/BUGs index e1dbec2..88ce433 100644 --- a/BUGs +++ b/BUGs @@ -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? diff --git a/Dockerfile b/Dockerfile index e9ce761..7272e12 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/main.py b/main.py index ad496e5..7004cc9 100644 --- a/main.py +++ b/main.py @@ -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 diff --git a/shared.py b/shared.py index 4c7e580..619ac19 100644 --- a/shared.py +++ b/shared.py @@ -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 diff --git a/wrapper.sh b/wrapper.sh index 9b56ca4..e4a2f25 100755 --- a/wrapper.sh +++ b/wrapper.sh @@ -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