Skip to content

Commit 7cb3bc8

Browse files
Run without docker (#649)
* Remove unused docker stacks Update dev stacks to silence warnings * Add start-bare-metal command to corgi cli Effectively runs the same command as docker entrypoint * Add build-frontend command; update fronted packages Add python version and nvmrc * Make environ optional for start-bare-metal Easier to test this way * Check python version matches docker version * Add install script and source .env before start * Add script to install secrets with aws ssm For launch template Add secrets spec; update install_secrets For more information about how this secrets spec works, see openstax/aws-ruby repository Turns out top_key is not optional in secrets spec That README in openstax/aws-ruby should really be updated When the secrets factory is being created, `.to_sym` is called on the top_key That means it cannot be nil Then top_key is used as a key for the secrets spec, even if it is an empty string Consequently, top_key is required * Support url-safe base64 encoding for session secret * Add gunicorn logging configuration options * Remove unused scripts * Add .poetry-version file We have had problems with poetry lock file compatibility in the past This file will be read by the ansible playbook to determine which version of poetry to install * Remove hotdog README section This will need to work differently in the future if it's ever revived Leaving the scripts for now as they might still be useful * install_secrets: Ensure secret_name and secret_value have values for each secret * Small update to corgi cli and ci tests * Bump version for rollup-plugin-css-only This version should be idempotent (hopefully) * Get session secret from substitution
1 parent 3449831 commit 7cb3bc8

33 files changed

+742
-753
lines changed

.github/workflows/test.yml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,24 @@ jobs:
5656
- name: Frontend Unit Tests
5757
run: |
5858
set -e
59-
docker compose -f docker-compose.stack.dev.yml exec frontend npm run test:unit
60-
docker compose -f docker-compose.stack.dev.yml exec frontend npm run lint
59+
./corgi compose-do dev exec frontend npm run test:unit
60+
./corgi compose-do dev exec frontend npm run lint
6161
6262
- name: Backend Unit Tests
6363
run: |
6464
set -e
65-
docker compose -f docker-compose.stack.dev.yml exec backend pytest -vvv ./tests/unit
66-
docker compose -f docker-compose.stack.dev.yml exec backend ruff check
67-
docker compose -f docker-compose.stack.dev.yml exec backend ruff format --check
65+
# We ignore patch version for this comparison
66+
python_version_docker="$(./corgi compose-do dev exec backend python --version | cut -d' ' -f2 | cut -d. -f-2)"
67+
python_version_repo="$(< .python-version)"
68+
if [[ "$python_version_repo" != "$python_version_docker" ]]; then
69+
echo "Python version mismatch:"
70+
echo "Repo: $python_version_repo"
71+
echo "Docker: $python_version_docker"
72+
exit 1
73+
fi
74+
./corgi compose-do dev exec backend pytest -vvv ./tests/unit
75+
./corgi compose-do dev exec backend ruff check
76+
./corgi compose-do dev exec backend ruff format --check
6877
6978
- name: Test database
7079
run: |
@@ -78,6 +87,6 @@ jobs:
7887
fi
7988
# Ensure the latest migration works backwards and forwards with
8089
# existing job data
81-
docker compose -f docker-compose.stack.dev.yml exec backend alembic downgrade -1
82-
docker compose -f docker-compose.stack.dev.yml exec backend alembic upgrade head
90+
./corgi compose-do dev exec backend alembic downgrade -1
91+
./corgi compose-do dev exec backend alembic upgrade head
8392
./corgi stop

.poetry-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.8.3

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

README.md

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -307,43 +307,6 @@ with requests.session() as session:
307307
print(jobs.json())
308308
```
309309

310-
## Testing Unmerged CORGI & Enki Changes in Concourse
311-
312-
[CORGI Hotdog](https://corgi-hotdog.ce.openstax.org/) is a testing environment for experimenting with changes before they go to staging.
313-
314-
URL: https://corgi-hotdog.ce.openstax.org/
315-
316-
### Use cases for hotdog
317-
- Catching issues that do not appear on Enki GitHub actions but does error in Concourse
318-
- Experimenting with changes that would be difficult/tedious to test locally (changes to concourse resource, upload steps, etc.)
319-
320-
### Deploy Porcess
321-
322-
- Two ways to deploy changes
323-
- https://corgi-hotdog.ce.openstax.org/hotdog
324-
* Enter the ref for one or both repos into the fields (ref can be commit sha or branch name)
325-
- There is a script in [ce-scripts](https://github.com/openstax/ce-scripts/blob/c6c2e63d8941392003a4462c8a73e86aa06a598e/bash/hotdog)
326-
* Run this script in Enki or CORGI.
327-
* You can either specify a ref as an argument to the script or use your current ref by omitting this argument.
328-
- At this point, the two ways converge and the following occurs
329-
- Success message
330-
- On concourse, corgi-hotdog, wait for hotdog-head to get new checked out version, this triggers a concourse build pipeline is set in build-deploy-Enki
331-
- See api call: `corgi-hotdog.openstax.org/hotdog/head` if you would like more details
332-
- Since concourse depends on production Enki tags on dockerhub, there isn’t a way to do concourse + dev Enki tag — except thru hotdog
333-
- Hotdog tag on dockerhub: corgi-hotdog rebuild as whatever dev ref you give it, then rebuilds the docker image for Enki.
334-
- Rebuild triggered by submitting a new ref.
335-
- Wait to build hotdog tag and push to dockerhub. At this point, you can create a job. still have to wait for concourse (steps: corgi-git-pdf & corgi-resource) to fetch the tag. then eventually the job will run.
336-
- Some additional details are
337-
- If you checkout a branch, you will need to checkout the branch again if you want to pull the latest changes from the branch
338-
- Jobs run on concourse. See logging & progress details on concourse/CORGI.
339-
- In hotdog corgi ui: worker-version tells you what Enki ref it is & a timestamp
340-
- Only one corgi-hotdog tag at a time
341-
342-
### Hotdog TODO
343-
1. Automatically pull changes from branches
344-
1. Automatically redeploy the stack if python dependencies change (maybe add a field to corgi refs that, when set, will trigger deploy on checkout?)
345-
1. Consider creating a hybrid of PR pipeline so each PR can have a hotdog stack
346-
347310
## Generating an ERD
348311

349312
The corgi CLI supports generating an ERD from database data. The auto-generated ERD, as well as a small description, replaces the README section labeled `## CORGI ERD`.

backend/app/app/core/auth.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from base64 import b64decode, b64encode
1+
import binascii
2+
from base64 import b64decode, b64encode, urlsafe_b64decode, urlsafe_b64encode
23
from datetime import datetime, timedelta, timezone
34
from typing import List, Optional, cast
45

@@ -15,10 +16,21 @@
1516
COOKIE_NAME = "user"
1617

1718

19+
def new_fernet_key(secret: str | None):
20+
assert secret is not None, "Expected base64 encoded secret, got None"
21+
try:
22+
decoded = b64decode(secret)
23+
except binascii.Error:
24+
decoded = urlsafe_b64decode(secret)
25+
assert len(decoded) >= 32, "Secret should be at least 32 bytes long"
26+
# Fernet key must be 32 url-safe base64-encoded bytes.
27+
return urlsafe_b64encode(decoded[:32])
28+
29+
1830
class Crypto:
1931
"""Simple delegate class to simplify to encrypting/decrypting strings"""
2032

21-
f = Fernet(b64encode(b64decode(cast(str, SESSION_SECRET))[:32]))
33+
f = Fernet(new_fernet_key(SESSION_SECRET))
2234

2335
@staticmethod
2436
def encrypt(msg: str, encoding: str = "utf-8") -> str:

backend/app/bin/live-reload.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ CALLABLE_NAME=${CALLABLE_NAME:-server}
77
SESSION_SECRET="$(dd if=/dev/urandom bs=1024 count=1 2>/dev/null | base64)"
88
export SESSION_SECRET
99

10-
uvicorn "${MODULE_NAME}:${CALLABLE_NAME}" --host 0.0.0.0 --port 80 --debug
10+
if [[ -z "${GUNICORN_CONF:-}" ]]; then
11+
exec uvicorn "${MODULE_NAME}:${CALLABLE_NAME}" --host 0.0.0.0 --port 80 --debug
12+
else
13+
exec gunicorn -k uvicorn.workers.UvicornWorker -c "$GUNICORN_CONF" "${MODULE_NAME}:${CALLABLE_NAME}"
14+
fi

backend/backend.dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ ENV PYTHONPATH="/app:$PYTHONPATH"
5353
COPY ./docker/start.sh /start.sh
5454
RUN chmod +x /start.sh
5555

56-
COPY ./docker/gunicorn.conf /gunicorn.conf
56+
COPY ./docker/gunicorn.conf.py /gunicorn.conf.py
5757

5858
COPY ./app /app
5959
WORKDIR /app
@@ -83,7 +83,7 @@ ENV PYTHONPATH="/app:$PYTHONPATH"
8383
COPY ./docker/start.sh /start.sh
8484
RUN chmod +x /start.sh
8585

86-
COPY ./docker/gunicorn.conf /gunicorn.conf
86+
COPY ./docker/gunicorn.conf.py /gunicorn.conf.py
8787

8888
COPY ./app /app
8989
WORKDIR /app
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
port = os.getenv("PORT", "80")
99
bind_env = os.getenv("BIND", None)
1010
use_loglevel = os.getenv("LOG_LEVEL", "info")
11-
if bind_env:
12-
use_bind = bind_env
13-
else:
14-
use_bind = f"{host}:{port}"
11+
error_log_file = os.getenv("ERROR_LOG_FILE") or "-"
12+
access_log_file = os.getenv("ACCESS_LOG_FILE") or None
13+
syslog_conf = os.getenv("SYSLOG_ADDR") or None
14+
use_bind = bind_env if bind_env else f"{host}:{port}"
1515

1616
cores = multiprocessing.cpu_count()
1717
workers_per_core = float(workers_per_core_str)
@@ -22,12 +22,22 @@
2222
else:
2323
web_concurrency = max(int(default_web_concurrency), 2)
2424

25+
if syslog_conf and not (
26+
syslog_conf.startswith("unix://")
27+
or syslog_conf.startswith("udp://")
28+
or syslog_conf.startswith("tcp://")
29+
):
30+
raise ValueError(f"Invalid syslog address: {syslog_conf}")
31+
2532
# Gunicorn config variables
2633
loglevel = use_loglevel
2734
workers = web_concurrency
2835
bind = use_bind
2936
keepalive = 120
30-
errorlog = "-"
37+
errorlog = error_log_file
38+
accesslog = access_log_file
39+
syslog = syslog_conf is not None
40+
syslog_addr = syslog_conf
3141
timeout = 120
3242

3343
# For debugging and testing

backend/docker/start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -e
44

55
MODULE_NAME=${MODULE_NAME:-app.main}
66
CALLABLE_NAME=${CALLABLE_NAME:-server}
7-
GUNICORN_CONF=${GUNICORN_CONF:-/gunicorn.conf}
7+
GUNICORN_CONF=${GUNICORN_CONF:-/gunicorn.conf.py}
88
PRE_START_PATH=${PRE_START_PATH:-/app/bin/prestart.sh}
99

1010
export APP_MODULE=${APP_MODULE:-"$MODULE_NAME:$CALLABLE_NAME"}

0 commit comments

Comments
 (0)