From 0b830f34cc5d500e02099b9fd5d9655bf5e1cdd7 Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Thu, 20 Apr 2023 00:15:08 -0400 Subject: [PATCH 1/5] Improve local development experience - Adds a Python REPL container, which has the profile 'dev' to avoid being run in production - Uses YAML anchors where possible to reuse docker compose config - Separates out building config from the entrypoint command to a script that can be run at-will to update local config to match config in git - Adds instructions to docker-compose.override.yml.template --- .pythonstartup.py | 47 ++++++++++++++++++++++++++ Dockerfile | 2 ++ docker-compose.override.yml.template | 49 ++++++++++++++++++---------- docker-compose.yml | 35 +++++++++----------- rebuild-config.sh | 12 +++++++ uber-wrapper.sh | 16 --------- 6 files changed, 109 insertions(+), 52 deletions(-) create mode 100644 .pythonstartup.py create mode 100644 rebuild-config.sh diff --git a/.pythonstartup.py b/.pythonstartup.py new file mode 100644 index 000000000..717cffd9f --- /dev/null +++ b/.pythonstartup.py @@ -0,0 +1,47 @@ +import os +import sys +import atexit +import readline +import rlcompleter +import traceback +from pprint import pprint + + +readline.parse_and_bind('tab: complete') +history_path = os.path.expanduser('~/.pyhistory') + + +@atexit.register +def save_history(): + readline.write_history_file(history_path) + + +if os.path.exists(history_path): + readline.read_history_file(history_path) + +try: + import cherrypy + import sideboard + from uber.config import c + from uber.models import AdminAccount, Attendee, initialize_db, Session + + initialize_db() + + # Make it easier to do session stuff at the command line + session = Session().session + + admin = session.query(AdminAccount).filter( + AdminAccount.attendee_id == Attendee.id, + Attendee.email == 'magfest@example.com' + ).order_by(AdminAccount.id).first() + + if admin: + # Make it easier to do site section testing at the command line + cherrypy.session = {'account_id': admin.id} + print('Logged in as {} <{}>'.format(admin.attendee.full_name, admin.attendee.email)) + else: + print('INFO: Could not find Test Developer admin account') + +except Exception as ex: + print('ERROR: Could not initialize ubersystem environment') + traceback.print_exc() \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9c0a7adb6..26e6efd06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ ADD uber-development.ini.template ./uber-development.ini.template ADD sideboard-development.ini.template ./sideboard-development.ini.template ADD uber-wrapper.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/uber-wrapper.sh +ADD rebuild-config.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/rebuild-config.sh ADD . plugins/uber/ diff --git a/docker-compose.override.yml.template b/docker-compose.override.yml.template index 32b6c3938..a794f4637 100644 --- a/docker-compose.override.yml.template +++ b/docker-compose.override.yml.template @@ -3,40 +3,55 @@ # 1. Download all plugins into one root directory; multiple event plugins can live side-by-side # 2. For each event you want to develop for, create `development-EVENTNAME.ini` in this directory # where EVENTNAME matches the name of the event plugin. The new file does not need to contain anything. -# 3. Copy this file to docker-compose.override.yml -# 4. Run `docker-compose -p EVENTNAME up -d` -# 5. Run `docker exec EVENTNAME-web-1 /app/env/bin/python /app/plugins/uber/make_config.py --repo https://github.com/magfest/terraform-aws-magfest.git --paths uber_config/environments/dev uber_config/events/EVENT/YEAR` +# 3. Copy this template file to docker-compose.override.yml +# 4. Run `docker compose -p EVENTNAME --profile dev up -d` +# 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git EVENT YEAR" bash -c 'docker compose -p EVENTNAME exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` # where EVENT is the config folder name (e.g., `stock` not `magstock`) and year is the config year (e.g., 2023) # -# Repeat step 5 whenever you want to reset your config to the git repo +# Repeat step 5 whenever you want to reset your config; it will pull from uber-development.ini.template, then the git repo +# When you want into the Python REPL, run `docker-compose -p EVENTNAME restart python-repl && docker attach EVENTNAME-python-repl` + +x-dev-volumes: + volumes: + - &extra-plugin-1 + $PWD/../covid:/app/plugins/covid + - &extra-plugin-2 + $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} services: + python-repl: + container_name: ${COMPOSE_PROJECT_NAME}-python-repl + build: . + volumes: + - *extra-plugin-1 + - *extra-plugin-2 + - $PWD/.pythonstartup.py:/app/.pythonstartup.py + stdin_open: true + tty: true + environment: + - DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db + - PYTHONSTARTUP=/app/.pythonstartup.py + command: ['/app/env/bin/python3'] + profiles: ["dev"] web: extends: file: docker-compose.yml service: web - # Uncomment the environment settings below to automatically pull config from a git repo - # This will ALWAYS UNDO any local changes you make to development.ini - # Be sure to set your UBER_CONFIG_EVENT and UBER_CONFIG_YEAR env variables to match the folders in your git repo - # - #environment: - # - UBERSYSTEM_GIT_CONFIG=https://github.com/magfest/terraform-aws-magfest.git - # - UBERSYSTEM_GIT_CONFIG_PATHS=uber_config/environments/dev uber_config/events/${UBER_CONFIG_EVENT:-super}/${UBER_CONFIG_YEAR:-2024} volumes: - - $PWD/../covid:/app/plugins/covid - - $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} + - *extra-plugin-1 + - *extra-plugin-2 - $PWD/development-${COMPOSE_PROJECT_NAME}.ini:/app/plugins/uber/development.ini celery-beat: extends: file: docker-compose.yml service: celery-beat volumes: - - $PWD/../covid:/app/plugins/covid - - $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} + - *extra-plugin-1 + - *extra-plugin-2 celery-worker: extends: file: docker-compose.yml service: celery-worker volumes: - - $PWD/../covid:/app/plugins/covid - - $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} \ No newline at end of file + - *extra-plugin-1 + - *extra-plugin-2 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 9df7d5cfd..547660ffa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,26 @@ # docker-compose for development of ubersystem +x-uber: &uber + build: . + environment: + - &uber-db-connect # This anchor ONLY supports one value, YAML does not support properly merging sequences + DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db + volumes: + - $PWD:/app/plugins/uber services: web: - build: . + <<: *uber ports: - 80:80 environment: - - DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db + - *uber-db-connect - PORT=80 - volumes: - - $PWD:/app/plugins/uber + celery-beat: + <<: *uber + command: ['celery-beat'] + celery-worker: + <<: *uber + command: ['celery-worker'] db: image: postgres environment: @@ -25,18 +36,4 @@ services: environment: - RABBITMQ_DEFAULT_USER=celery - RABBITMQ_DEFAULT_PASS=celery - - RABBITMQ_DEFAULT_VHOST=uber - celery-beat: - build: . - command: ['celery-beat'] - environment: - - DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db - volumes: - - $PWD:/app/plugins/uber - celery-worker: - build: . - command: ['celery-worker'] - environment: - - DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db - volumes: - - $PWD:/app/plugins/uber \ No newline at end of file + - RABBITMQ_DEFAULT_VHOST=uber \ No newline at end of file diff --git a/rebuild-config.sh b/rebuild-config.sh new file mode 100644 index 000000000..882ab60d1 --- /dev/null +++ b/rebuild-config.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +# This will replace any variable references in these files +# If you want to add any additional settings here just add +# the variables to the environment when running this. +envsubst < "uber-development.ini.template" > /app/plugins/uber/development.ini +envsubst < "sideboard-development.ini.template" > /app/development.ini + +if [ "$1" = 'git' ]; then +/app/env/bin/python /app/plugins/uber/make_config.py --repo https://github.com/magfest/terraform-aws-magfest.git --paths uber_config/environments/dev uber_config/events/$2 uber_config/events/$2/$3 +fi \ No newline at end of file diff --git a/uber-wrapper.sh b/uber-wrapper.sh index 1bd8b9b23..25a2a4bc8 100644 --- a/uber-wrapper.sh +++ b/uber-wrapper.sh @@ -1,22 +1,6 @@ #!/bin/bash set -e -# This will replace any variable references in these files -# If you want to add any additional settings here just add -# the variables to the environment when running this. -envsubst < "uber-development.ini.template" > /app/plugins/uber/development.ini -envsubst < "sideboard-development.ini.template" > /app/development.ini - -if [ -n "${UBERSYSTEM_GIT_CONFIG}" ]; then - echo "Loading UBERSYSTEM_CONFIG from git repo ${UBERSYSTEM_GIT_CONFIG}" - /app/env/bin/python /app/plugins/uber/make_config.py --repo "${UBERSYSTEM_GIT_CONFIG}" --paths ${UBERSYSTEM_GIT_CONFIG_PATHS} -fi - -if [ -n "${UBERSYSTEM_CONFIG}" ]; then - echo "Parsing config from environment" - /app/env/bin/python /app/plugins/uber/make_config.py -fi - if [ "$1" = 'uber' ]; then echo "If this is the first time starting this server go to the following URL to create an account:" echo "http://${HOSTNAME}:${PORT}${DEFAULT_URL}/accounts/insert_test_admin" From c6caaa0cce96ed5a23c61888ad69afea57e338ee Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Thu, 20 Apr 2023 20:39:35 -0400 Subject: [PATCH 2/5] Put single-variable anchors on one line --- docker-compose.override.yml.template | 8 +++----- docker-compose.yml | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docker-compose.override.yml.template b/docker-compose.override.yml.template index a794f4637..12012091a 100644 --- a/docker-compose.override.yml.template +++ b/docker-compose.override.yml.template @@ -5,7 +5,7 @@ # where EVENTNAME matches the name of the event plugin. The new file does not need to contain anything. # 3. Copy this template file to docker-compose.override.yml # 4. Run `docker compose -p EVENTNAME --profile dev up -d` -# 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git EVENT YEAR" bash -c 'docker compose -p EVENTNAME exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` +# 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git stock 2023" bash -c 'docker compose -p magstock exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` # where EVENT is the config folder name (e.g., `stock` not `magstock`) and year is the config year (e.g., 2023) # # Repeat step 5 whenever you want to reset your config; it will pull from uber-development.ini.template, then the git repo @@ -13,10 +13,8 @@ x-dev-volumes: volumes: - - &extra-plugin-1 - $PWD/../covid:/app/plugins/covid - - &extra-plugin-2 - $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} + - &extra-plugin-1 $PWD/../covid:/app/plugins/covid + - &extra-plugin-2 $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} services: python-repl: diff --git a/docker-compose.yml b/docker-compose.yml index 547660ffa..085f5596b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,8 +2,7 @@ x-uber: &uber build: . environment: - - &uber-db-connect # This anchor ONLY supports one value, YAML does not support properly merging sequences - DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db + - &uber-db-connect DB_CONNECTION_STRING=postgresql://uber_db:uber_db@db:5432/uber_db volumes: - $PWD:/app/plugins/uber From 20b038325917e47bbc50c4be66de74e74cefe306 Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Thu, 20 Apr 2023 20:41:56 -0400 Subject: [PATCH 3/5] Fix hardcoded event names --- docker-compose.override.yml.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.override.yml.template b/docker-compose.override.yml.template index 12012091a..39df555e7 100644 --- a/docker-compose.override.yml.template +++ b/docker-compose.override.yml.template @@ -5,7 +5,7 @@ # where EVENTNAME matches the name of the event plugin. The new file does not need to contain anything. # 3. Copy this template file to docker-compose.override.yml # 4. Run `docker compose -p EVENTNAME --profile dev up -d` -# 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git stock 2023" bash -c 'docker compose -p magstock exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` +# 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git EVENT YEAR" bash -c 'docker compose -p EVENTNAME exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` # where EVENT is the config folder name (e.g., `stock` not `magstock`) and year is the config year (e.g., 2023) # # Repeat step 5 whenever you want to reset your config; it will pull from uber-development.ini.template, then the git repo From cbcb908d0500bb45f389bdd00fc982db8ff2468b Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Thu, 20 Apr 2023 20:49:15 -0400 Subject: [PATCH 4/5] Add restart after config Apparently this is needed for the system to work after it first stands up config --- docker-compose.override.yml.template | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.override.yml.template b/docker-compose.override.yml.template index 39df555e7..110d1f2b1 100644 --- a/docker-compose.override.yml.template +++ b/docker-compose.override.yml.template @@ -7,6 +7,7 @@ # 4. Run `docker compose -p EVENTNAME --profile dev up -d` # 5. Run `env CONFIG_CMD="/usr/local/bin/rebuild-config.sh git EVENT YEAR" bash -c 'docker compose -p EVENTNAME exec web $CONFIG_CMD exec celery-worker $CONFIG_CMD exec celery-beat $CONFIG_CMD'` # where EVENT is the config folder name (e.g., `stock` not `magstock`) and year is the config year (e.g., 2023) +# 6. Run `docker compose -p EVENTNAME restart` # # Repeat step 5 whenever you want to reset your config; it will pull from uber-development.ini.template, then the git repo # When you want into the Python REPL, run `docker-compose -p EVENTNAME restart python-repl && docker attach EVENTNAME-python-repl` @@ -31,6 +32,7 @@ services: - PYTHONSTARTUP=/app/.pythonstartup.py command: ['/app/env/bin/python3'] profiles: ["dev"] + stop_grace_period: 1s web: extends: file: docker-compose.yml From 072dda79b6703502ab1fe15e7e9183bd5d31c560 Mon Sep 17 00:00:00 2001 From: Victoria Earl Date: Wed, 3 May 2023 14:14:41 -0400 Subject: [PATCH 5/5] Add more volume mounts The Python REPL wasn't mounting the uber plugin, which would Cause Problems. Also mounts the config file to the celery containers, although this hasn't quite had the results I wanted. --- docker-compose.override.yml.template | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docker-compose.override.yml.template b/docker-compose.override.yml.template index 110d1f2b1..3f6cfa2a9 100644 --- a/docker-compose.override.yml.template +++ b/docker-compose.override.yml.template @@ -16,14 +16,17 @@ x-dev-volumes: volumes: - &extra-plugin-1 $PWD/../covid:/app/plugins/covid - &extra-plugin-2 $PWD/../${COMPOSE_PROJECT_NAME}/:/app/plugins/${COMPOSE_PROJECT_NAME} + - &config-file $PWD/development-${COMPOSE_PROJECT_NAME}.ini:/app/plugins/uber/development.ini services: python-repl: container_name: ${COMPOSE_PROJECT_NAME}-python-repl build: . volumes: + - $PWD:/app/plugins/uber - *extra-plugin-1 - *extra-plugin-2 + - *config-file - $PWD/.pythonstartup.py:/app/.pythonstartup.py stdin_open: true tty: true @@ -40,7 +43,7 @@ services: volumes: - *extra-plugin-1 - *extra-plugin-2 - - $PWD/development-${COMPOSE_PROJECT_NAME}.ini:/app/plugins/uber/development.ini + - *config-file celery-beat: extends: file: docker-compose.yml @@ -48,10 +51,12 @@ services: volumes: - *extra-plugin-1 - *extra-plugin-2 + - *config-file celery-worker: extends: file: docker-compose.yml service: celery-worker volumes: - *extra-plugin-1 - - *extra-plugin-2 \ No newline at end of file + - *extra-plugin-2 + - *config-file