Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
3136f32
ci: add Dockerfile and action to build celery worker image
jennifer-richards May 4, 2022
e5edba7
ci: build celery worker on push to jennifer/celery branch
jennifer-richards May 4, 2022
3e0d9bc
ci: also build celery worker for main branch
jennifer-richards May 4, 2022
a3fa424
ci: Add comment to celery Dockerfile
jennifer-richards May 4, 2022
6c77c54
chore: first stab at a celery/rabbitmq docker-compose
jennifer-richards May 5, 2022
048ca85
feat: add celery configuration and test task / endpoint
jennifer-richards May 5, 2022
1797206
chore: run mq/celery containers for dev work
jennifer-richards May 5, 2022
aa18578
chore: point to ghcr.io image for celery worker
jennifer-richards May 5, 2022
7012bed
refactor: move XML parsing duties into XMLDraft
jennifer-richards May 9, 2022
2cc91c0
feat: add api_upload endpoint and beginnings of async processing
jennifer-richards May 9, 2022
94be264
perf: index Submission table on submission_date
jennifer-richards May 9, 2022
1e065a4
feat: remove existing files when accepting a new submission
jennifer-richards May 9, 2022
9dd7b5f
refactor: make clear that deduce_group() uses only the draft name
jennifer-richards May 10, 2022
bcfc85e
refactor: extract only draft name/revision in clean() method
jennifer-richards May 10, 2022
52c0864
refactor: minimize checks and data extraction in api_upload() view
jennifer-richards May 10, 2022
553720c
ci: fix dockerfiles to match sandbox testing
jennifer-richards May 12, 2022
caae932
ci: tweak celery container docker-compose settings
jennifer-richards May 17, 2022
517cf21
refactor: clean up Draft parsing API and usage
jennifer-richards May 17, 2022
f9cd8cf
feat: flesh out async submission processing
jennifer-richards May 17, 2022
071e30f
feat: add state name for submission being validated asynchronously
jennifer-richards May 17, 2022
9d77822
feat: cancel submissions that async processing can't handle
jennifer-richards May 18, 2022
4a0fbcb
refactor: simplify/consolidate async tasks and improve error handling
jennifer-richards May 18, 2022
21588cd
feat: add api_submission_status endpoint
jennifer-richards May 19, 2022
5dbb46d
refactor: return JSON from submission api endpoints
jennifer-richards May 19, 2022
25b2c47
refactor: reuse cancel_submission method
jennifer-richards May 19, 2022
afbae64
refactor: clean up error reporting a bit
jennifer-richards May 19, 2022
b23b016
feat: guard against cancellation of a submission while validating
jennifer-richards May 19, 2022
608af25
feat: indicate that a submission is still being validated
jennifer-richards May 19, 2022
9cdcdb7
fix: do not delete submission files after creating them
jennifer-richards May 20, 2022
1353bcb
chore: remove debug statement
jennifer-richards May 20, 2022
bdeab69
test: add tests of the api_upload and api_submission_status endpoints
jennifer-richards May 20, 2022
50ec286
test: add tests and stubs for async side of submission handling
jennifer-richards May 24, 2022
21a96ee
fix: gracefully handle (ignore) invalid IDs in async submit task
jennifer-richards May 24, 2022
f77cb1d
test: test process_uploaded_submission method
jennifer-richards May 24, 2022
d279827
fix: fix failures of new tests
jennifer-richards May 24, 2022
7f63f99
refactor: fix type checker complaints
jennifer-richards May 25, 2022
162b7f1
test: test submission_status view of submission in "validating" state
jennifer-richards May 25, 2022
191d5e3
Merge remote-tracking branch 'origin/main' into jennifer/submit-async
jennifer-richards May 25, 2022
ee11c5b
fix: fix up migrations
jennifer-richards May 26, 2022
5533d36
fix: use the streamlined SubmissionBaseUploadForm for api_upload
jennifer-richards May 26, 2022
9b82a3d
feat: show submission history event timestamp as mouse-over text
jennifer-richards May 26, 2022
93f5a5f
fix: remove 'manual' as next state for 'validating' submission state
jennifer-richards May 26, 2022
993606f
refactor: share SubmissionBaseUploadForm code with Deprecated version
jennifer-richards May 26, 2022
4a44bdb
fix: validate text submission title, update a couple comments
jennifer-richards May 27, 2022
4c0ed30
chore: disable requirements updating when celery dev container starts
jennifer-richards May 27, 2022
4fa4287
feat: log traceback on unexpected error during submission processing
jennifer-richards May 27, 2022
9836b3c
feat: allow secretariat to cancel "validating" submission
jennifer-richards May 27, 2022
8d4358e
feat: indicate time since submission on the status page
jennifer-richards May 27, 2022
2ef3ec2
perf: check submission rate thresholds earlier when possible
jennifer-richards May 27, 2022
e3428f0
fix: create Submission before saving to reduce race condition window
jennifer-richards May 30, 2022
118770a
Merge remote-tracking branch 'origin/main' into jennifer/submit-async
jennifer-richards May 30, 2022
3ad6dc5
fix: call deduce_group() with filename
jennifer-richards May 30, 2022
83166c9
refactor: remove code lint
jennifer-richards May 30, 2022
a941bc3
refactor: change the api_upload URL to api/submission
jennifer-richards May 31, 2022
6be7250
docs: update submission API documentation
jennifer-richards May 31, 2022
f7792d9
test: add tests of api_submission's text draft consistency checks
jennifer-richards May 31, 2022
5b2760b
refactor: rename api_upload to api_submission to agree with new URL
jennifer-richards May 31, 2022
ad6a96f
test: test API documentation and submission thresholds
jennifer-richards May 31, 2022
fb132ee
fix: fix a couple api_submission view renames missed in templates
jennifer-richards May 31, 2022
41149b5
chore: use base image + add arm64 support
NGPixel May 31, 2022
bd53162
Merge remote-tracking branch 'origin/main' into jennifer/submit-async
jennifer-richards Jun 1, 2022
46949ca
ci: try to fix workflow_dispatch for celery worker
jennifer-richards Jun 1, 2022
9300382
ci: another attempt to fix workflow_dispatch
jennifer-richards Jun 1, 2022
234b7d4
ci: build celery image for submit-async branch
jennifer-richards Jun 1, 2022
ea21743
ci: fix typo
jennifer-richards Jun 1, 2022
cd0227c
Merge remote-tracking branch 'NGPixel/patch-1' into jennifer/submit-a…
jennifer-richards Jun 1, 2022
86f039e
ci: publish celery worker to ghcr.io/painless-security
jennifer-richards Jun 1, 2022
86d4772
ci: install python requirements in celery image
jennifer-richards Jun 2, 2022
2cfcae2
ci: fix up requirements install on celery image
jennifer-richards Jun 2, 2022
a22ac89
Merge branch 'main' into jennifer/submit-async
jennifer-richards Jun 30, 2022
ae826ef
chore: remove XML_LIBRARY references that crept back in
jennifer-richards Jun 30, 2022
5d95b1f
feat: accept 'replaces' field in api_submission
jennifer-richards Jun 30, 2022
de46d1e
docs: update api_submission documentation
jennifer-richards Jun 30, 2022
783fa11
fix: remove unused import
jennifer-richards Jun 30, 2022
b682d71
test: test "replaces" validation for submission API
jennifer-richards Jun 30, 2022
60a6ef6
test: test that "replaces" is set by api_submission
jennifer-richards Jun 30, 2022
6219412
feat: trap TERM to gracefully stop celery container
jennifer-richards Jul 5, 2022
a31767b
chore: tweak celery/mq settings
jennifer-richards Jul 7, 2022
d2e3acd
docs: update installation instructions
jennifer-richards Jul 7, 2022
df10bc0
ci: adjust paths that trigger celery worker image build
jennifer-richards Jul 7, 2022
7167d9c
Merge branch 'ietf-tools:main' into jennifer/submit-async
jennifer-richards Jul 7, 2022
7a7a575
ci: fix branches/repo names left over from dev
jennifer-richards Jul 13, 2022
e99f2c3
ci: run manage.py check when initializing celery container
jennifer-richards Jul 13, 2022
dbdf092
docs: revise INSTALL instructions
jennifer-richards Jul 13, 2022
a048fff
ci: pass filename to pip update in celery container
jennifer-richards Jul 14, 2022
22e8280
docs: update INSTALL to include freezing pip versions
jennifer-richards Jul 14, 2022
128e9db
Merge branch 'main' into jennifer/submit-async
jennifer-richards Aug 2, 2022
18f2341
docs: add explanation of frozen-requirements.txt
jennifer-richards Aug 2, 2022
a48f582
ci: build image for sandbox deployment
jennifer-richards Aug 3, 2022
2d43316
ci: add additional build trigger path
jennifer-richards Aug 3, 2022
40f01a3
docs: tweak INSTALL
jennifer-richards Aug 3, 2022
bec798c
fix: change INSTALL process to stop datatracker before running migrat…
rjsparks Aug 3, 2022
ce94785
chore: use ietf.settings for manage.py check in celery container
jennifer-richards Aug 4, 2022
5c13ad1
Merge remote-tracking branch 'origin/jennifer/submit-async' into jenn…
jennifer-richards Aug 4, 2022
e74cbc5
chore: set uid/gid for celery worker
jennifer-richards Aug 4, 2022
cdac495
chore: create user/group in celery container if needed
jennifer-richards Aug 4, 2022
c56168c
chore: tweak docker compose/init so celery container works in dev
jennifer-richards Aug 4, 2022
26980e9
ci: build mq docker image
jennifer-richards Aug 5, 2022
0727a9c
fix: move rabbitmq.pid to writeable location
jennifer-richards Aug 5, 2022
e7949d0
fix: clear password when CELERY_PASSWORD is empty
jennifer-richards Aug 5, 2022
d63ad34
chore: add shutdown debugging option to celery image
jennifer-richards Aug 18, 2022
89ac7d0
Merge branch 'main' into jennifer/submit-async
jennifer-richards Aug 18, 2022
352cd2b
chore: add django-celery-beat package
jennifer-richards Aug 19, 2022
dbabe82
chore: run "celery beat" in datatracker-celery image
jennifer-richards Aug 19, 2022
de863d9
chore: fix docker image name
jennifer-richards Aug 19, 2022
e96ddd2
feat: add task to cancel stale submissions
jennifer-richards Aug 19, 2022
e5f1ab5
test: test the cancel_stale_submissions task
jennifer-richards Aug 19, 2022
f9da62c
chore: make f-string with no interpolation a plain string
jennifer-richards Aug 22, 2022
be36010
Merge branch 'main' into jennifer/submit-async
jennifer-richards Aug 22, 2022
cef725f
Merge branch 'main' into jennifer/submit-async
jennifer-richards Aug 22, 2022
f66d181
Merge branch 'main' into jennifer/submit-async
jennifer-richards Aug 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/build-celery-worker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Build Celery Worker Docker Image

on:
push:
branches:
- 'main'
- 'jennifer/submit-async'
paths:
- 'requirements.txt'
- 'dev/celery/**'
- '.github/workflows/build-celery-worker.yml'

workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker Build & Push
uses: docker/build-push-action@v3
with:
context: .
file: dev/celery/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
# tags: ghcr.io/ietf-tools/datatracker-celery:latest
tags: ghcr.io/painless-security/datatracker-celery:latest

46 changes: 46 additions & 0 deletions .github/workflows/build-mq-broker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Build MQ Broker Docker Image

on:
push:
branches:
- 'main'
- 'jennifer/submit-async'
paths:
- 'dev/mq/**'
- '.github/workflows/build-mq-worker.yml'

workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker Build & Push
uses: docker/build-push-action@v3
with:
context: .
file: dev/mq/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
# tags: ghcr.io/ietf-tools/datatracker-mq:latest
tags: ghcr.io/painless-security/datatracker-mq:latest

69 changes: 59 additions & 10 deletions dev/INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -29,38 +29,78 @@ General Instructions for Deployment of a New Release
python3.9 -mvenv env
source env/bin/activate
pip install -r requirements.txt
pip freeze > frozen-requirements.txt

(The pip freeze command records the exact versions of the Python libraries that pip installed.
This is used by the celery docker container to ensure it uses the same library versions as
the datatracker service.)

5. Move static files into place for CDN (/a/www/www6s/lib/dt):

ietf/manage.py collectstatic

6. Run system checks (which patches the just installed modules)::

ietf/manage.py check
ietf/manage.py check

7. Switch to the docker directory and update images:

cd /a/docker/datatracker-cel
docker image tag ghcr.io/ietf-tools/datatracker-celery:latest datatracker-celery-fallback
docker image tag ghcr.io/ietf-tools/datatracker-mq:latest datatracker-mq-fallback
docker-compose pull

8. Stop and remove the async task containers:
Wait for this to finish cleanly. It may take up to about 10 minutes for the 'stop' command to
complete if a long-running task is in progress.

docker-compose down

9. Stop the datatracker
(consider doing this with a second shell at ietfa to avoid the exit and shift back to wwwrun)

exit
sudo systemctl stop datatracker.socket datatracker.service
sudo su - -s /bin/bash wwwrun

7. Run migrations:
10. Return to the release directory and run migrations:

cd /a/www/ietf-datatracker/${releasenumber}
ietf/manage.py migrate

Take note if any migrations were executed.

8. Back out one directory level, then re-point the 'web' symlink::
11. Back out one directory level, then re-point the 'web' symlink::

cd ..
rm ./web; ln -s ${releasenumber} web

9. Reload the datatracker service (it is no longer necessary to restart apache) ::
12. Start the datatracker service (it is no longer necessary to restart apache) ::

exit # or CTRL-D, back to root level shell
systemctl restart datatracker
sudo systemctl start datatracker.service datatracker.socket

13. Start async task worker and message broker:

10. Verify operation:
cd /a/docker/datatracker-cel
bash startcommand

14. Verify operation:

http://datatracker.ietf.org/

11. If install failed and there were no migrations at step 7, revert web symlink and repeat the restart in step 9.
If there were migrations at step 7, they will need to be reversed before the restart at step 9. If it's not obvious
what to do to reverse the migrations, contact the dev team.
15. If install failed and there were no migrations at step 9, revert web symlink and docker update and repeat the
restart in steps 11 and 12. To revert the docker update:

cd /a/docker/datatracker-cel
docker-compose down
docker image rm ghcr.io/ietf-tools/datatracker-celery:latest ghcr.io/ietf-tools/datatracker-mq:latest
docker image tag datatracker-celery-fallback ghcr.io/ietf-tools/datatracker-celery:latest
docker image tag datatracker-mq-fallback ghcr.io/ietf-tools/datatracker-mq:latest
cd -

If there were migrations at step 10, they will need to be reversed before the restart at step 12.
If it's not obvious what to do to reverse the migrations, contact the dev team.


Patching a Production Release
Expand Down Expand Up @@ -95,8 +135,17 @@ The following process should be used:
6. Edit ``.../ietf/__init__.py`` in the new patched release to indicate the patch
version in the ``__patch__`` string.

7. Change the 'web' symlink, reload etc. as described in
7. Stop the async task container (this may take a few minutes if tasks are in progress):

cd /a/docker/datatracker-cel
docker-compose stop celery

8. Change the 'web' symlink, reload etc. as described in
`General Instructions for Deployment of a New Release`_.

9. Start async task worker:

cd /a/docker/datatracker-cel
bash startcommand


20 changes: 20 additions & 0 deletions dev/celery/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Dockerfile for celery worker
#
FROM ghcr.io/ietf-tools/datatracker-app-base:latest
LABEL maintainer="IETF Tools Team <tools-discuss@ietf.org>"

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get purge -y imagemagick imagemagick-6-common

# Copy the startup file
COPY dev/celery/docker-init.sh /docker-init.sh
RUN sed -i 's/\r$//' /docker-init.sh && \
chmod +x /docker-init.sh

# Install current datatracker python dependencies
COPY requirements.txt /tmp/pip-tmp/
RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt
RUN rm -rf /tmp/pip-tmp

ENTRYPOINT [ "/docker-init.sh" ]
75 changes: 75 additions & 0 deletions dev/celery/docker-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash
#
# Environment parameters:
#
# CELERY_APP - name of application to pass to celery (defaults to ietf)
#
# CELERY_ROLE - 'worker' or 'beat' (defaults to 'worker')
#
# CELERY_UID - numeric uid for the celery worker process
#
# CELERY_GID - numeric gid for the celery worker process
#
# UPDATES_REQUIREMENTS_FROM - path, relative to /workspace mount, to a pip requirements
# file that should be installed at container startup. Default is no package install/update.
#
# DEBUG_TERM_TIMING - if non-empty, writes debug messages during shutdown after a TERM signal
#
WORKSPACEDIR="/workspace"
CELERY_ROLE="${CELERY_ROLE:-worker}"

cd "$WORKSPACEDIR" || exit 255

if [[ -n "${UPDATE_REQUIREMENTS_FROM}" ]]; then
reqs_file="${WORKSPACEDIR}/${UPDATE_REQUIREMENTS_FROM}"
echo "Updating requirements from ${reqs_file}..."
pip install --upgrade -r "${reqs_file}"
fi

if [[ "${CELERY_ROLE}" == "worker" ]]; then
echo "Running initial checks..."
/usr/local/bin/python $WORKSPACEDIR/ietf/manage.py check
fi

CELERY_OPTS=( "${CELERY_ROLE}" )
if [[ -n "${CELERY_UID}" ]]; then
# ensure that some group with the necessary GID exists in container
if ! id "${CELERY_UID}" ; then
adduser --system --uid "${CELERY_UID}" --no-create-home --disabled-login "celery-user-${CELERY_UID}"
fi
CELERY_OPTS+=("--uid=${CELERY_UID}")
fi

if [[ -n "${CELERY_GID}" ]]; then
# ensure that some group with the necessary GID exists in container
if ! getent group "${CELERY_GID}" ; then
addgroup --gid "${CELERY_GID}" "celery-group-${CELERY_GID}"
fi
CELERY_OPTS+=("--gid=${CELERY_GID}")
fi

log_term_timing_msgs () {
# output periodic debug message
while true; do
echo "Waiting for celery worker shutdown ($(date --utc --iso-8601=ns))"
sleep 0.5s
done
}

cleanup () {
# Cleanly terminate the celery app by sending it a TERM, then waiting for it to exit.
if [[ -n "${celery_pid}" ]]; then
echo "Gracefully terminating celery worker. This may take a few minutes if tasks are in progress..."
kill -TERM "${celery_pid}"
if [[ -n "${DEBUG_TERM_TIMING}" ]]; then
log_term_timing_msgs &
fi
wait "${celery_pid}"
fi
}

trap 'trap "" TERM; cleanup' TERM
# start celery in the background so we can trap the TERM signal
celery --app="${CELERY_APP:-ietf}" "${CELERY_OPTS[@]}" "$@" &
celery_pid=$!
wait "${celery_pid}"
17 changes: 17 additions & 0 deletions dev/mq/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Dockerfile for RabbitMQ worker
#
FROM rabbitmq:3-alpine
LABEL maintainer="IETF Tools Team <tools-discuss@ietf.org>"

# Copy the startup file
COPY dev/mq/ietf-rabbitmq-server.bash /ietf-rabbitmq-server.bash
RUN sed -i 's/\r$//' /ietf-rabbitmq-server.bash && \
chmod +x /ietf-rabbitmq-server.bash

# Put the rabbitmq.conf in the conf.d so it runs after 10-defaults.conf.
# Can override this for an individual container by mounting additional
# config files in /etc/rabbitmq/conf.d.
COPY dev/mq/rabbitmq.conf /etc/rabbitmq/conf.d/20-ietf-config.conf
COPY dev/mq/definitions.json /definitions.json

CMD ["/ietf-rabbitmq-server.bash"]
30 changes: 30 additions & 0 deletions dev/mq/definitions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"permissions": [
{
"configure": ".*",
"read": ".*",
"user": "datatracker",
"vhost": "dt",
"write": ".*"
}
],
"users": [
{
"hashing_algorithm": "rabbit_password_hashing_sha256",
"limits": {},
"name": "datatracker",
"password_hash": "",
"tags": []
}
],
"vhosts": [
{
"limits": [],
"metadata": {
"description": "",
"tags": []
},
"name": "dt"
}
]
}
22 changes: 22 additions & 0 deletions dev/mq/ietf-rabbitmq-server.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash -x
#
# Environment parameters:
#
# CELERY_PASSWORD - password for the datatracker celery user
#
export RABBITMQ_PID_FILE=/tmp/rabbitmq.pid

update_celery_password () {
rabbitmqctl wait "${RABBITMQ_PID_FILE}" --timeout 300
rabbitmqctl await_startup --timeout 300
if [[ -n "${CELERY_PASSWORD}" ]]; then
rabbitmqctl change_password datatracker <<END
${CELERY_PASSWORD}
END
else
rabbitmqctl clear_password datatracker
fi
}

update_celery_password &
exec rabbitmq-server "$@"
18 changes: 18 additions & 0 deletions dev/mq/rabbitmq.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# prevent guest from logging in over tcp
loopback_users.guest = true

# load saved definitions
load_definitions = /definitions.json

# Ensure that enough disk is available to flush to disk. To do this, need to limit the
# memory available to the container to something reasonable. See
# https://www.rabbitmq.com/production-checklist.html#monitoring-and-resource-usage
# for recommendations.

# 1-1.5 times the memory available to the container is adequate for disk limit
disk_free_limit.absolute = 6000MB

# This should be ~40% of the memory available to the container. Use an
# absolute number because relative will be proprtional to the full machine
# memory.
vm_memory_high_watermark.absolute = 1600MB
Loading