Skip to content

Commit 7dcc333

Browse files
authored
Merge pull request #18 from abikouo/dispatcherd_1
Set up docker with dispatcherd for local development
2 parents afee16a + 97b1847 commit 7dcc333

26 files changed

+522
-38
lines changed

.dockerignore

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Virtual environment
38+
.venv/
39+
venv/
40+
env/
41+
42+
# IDE and Editor files
43+
.vscode/
44+
.idea/
45+
*.swp
46+
*.bak
47+
*.swo
48+
49+
# Gitignore and other version control files
50+
.git/
51+
.gitignore
52+
.gitmodules
53+
54+
# Environment variables
55+
.env
56+
.env.*
57+
*.env
58+
59+
# Logs and temporary files
60+
*.log
61+
tmp/
62+
temp/
63+
64+
# Database files
65+
*.sqlite3
66+
*.db
67+
68+
# Testing
69+
.cache
70+
.coverage
71+
.tox
72+
coverage.xml
73+
htmlcov
74+
pep8.txt
75+
scratch
76+
testem.log
77+
.pytest_cache/
78+
79+
# Mac OS X
80+
*.DS_Store
81+
82+
# VSCode
83+
.vscode/

.github/workflows/tests.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
env:
1919
DJANGO_SETTINGS_MODULE: pattern_service.settings
20+
COMPOSE_COMMAND: docker compose
2021

2122
steps:
2223
- name: Checkout code
@@ -32,5 +33,8 @@ jobs:
3233
python -m pip install --upgrade pip
3334
python -m pip install tox
3435
36+
- name: Set up Docker Compose
37+
uses: docker/setup-compose-action@v1
38+
3539
- name: Run unit tests
36-
run: tox -e test
40+
run: make test

CONTRIBUTING.md

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@ Hi there! We're excited to have you as a contributor.
1111
- [Clone the repo](#clone-the-repo)
1212
- [Configure Python environment](#configure-python-environment)
1313
- [Set env variables for development](#set-env-variables-for-development)
14+
- [Configure postgres and run the dispatcher service](#configure-postgres-and-run-the-dispatcher-service)
1415
- [Configure and run the application](#configure-and-run-the-application)
1516
- [Updating dependencies](#updating-dependencies)
16-
- [Running tests, linters, and code checks](#running-tests-linters-and-code-checks)
17+
- [Running linters and code checks](#running-linters-and-code-checks)
18+
- [Running tests](#running-tests)
1719

1820
## Things to know prior to submitting code
1921

2022
- All code submissions are done through pull requests against the `main` branch.
2123
- Take care to make sure no merge commits are in the submission, and use `git rebase` vs `git merge` for this reason.
2224
- If collaborating with someone else on the same branch, consider using `--force-with-lease` instead of `--force`. This will prevent you from accidentally overwriting commits pushed by someone else. For more information, see [git push docs](https://git-scm.com/docs/git-push#git-push---force-with-leaseltrefnamegt).
2325
- We ask all of our community members and contributors to adhere to the [Ansible code of conduct](http://docs.ansible.com/ansible/latest/community/code_of_conduct.html). If you have questions, or need assistance, please reach out to our community team at [[email protected]](mailto:[email protected])
24-
- This repository uses a`pre-commit`, configuration, so ensure that you install pre-commit globally for your user, or by using pipx.
2526

2627
## Build and Run the Development Environment
2728

@@ -47,6 +48,8 @@ Install required python modules for development
4748

4849
`pip install -r requirements/requirements-dev.txt`
4950

51+
For standalone development tools written in Python, such as `pre-commit` and `pip-tools`, we recommend using your system package manager, `pipx` tool or `pip` user install mode (`pip install --user`), in decreasing order of preference.
52+
5053
### Set env variables for development
5154

5255
Either create a .env file in the project root containing the following env variables, or export them to your shell env:
@@ -55,8 +58,29 @@ Either create a .env file in the project root containing the following env varia
5558
PATTERN_SERVICE_MODE=development
5659
```
5760

61+
### Configure postgres and run the dispatcher service
62+
63+
Several endpoints in the pattern service rely on asynchronous tasks that are handled by a separate running service, the dispatcher service. This uses [PostgreSQL's](https://www.postgresql.org/) `pg_notify` ability to send asyncronous tasks from the django application to the dispatcher service. For more details, see the [dispatcherd documentation](https://github.com/ansible/dispatcherd/blob/main/README.md).
64+
65+
To make use of the dispatcher, you will need to ensure that both postgres and the dispatcher service are running. _The easiest way to do this is via [docker-compose](./tools/container/README.md)_, however it is also possible to do this manually as follows:
66+
67+
- Install postgres locally and create a database for the service.
68+
- Update your local .env file to reference your postgres server and database details (these can also be exported to your shell env):
69+
70+
```bash
71+
PATTERN_SERVICE_DB_NAME=<your database name>
72+
PATTERN_SERVICE_DB_USER=<your database user>
73+
PATTERN_SERVICE_DB_PASSWORD=<your database user password>
74+
PATTERN_SERVICE_DB_HOST=localhost
75+
PATTERN_SERVICE_DB_PORT="5432 (or your postgres port)"
76+
```
77+
78+
- Run the dispatcherd service from the root pattern service directory with `python manage.py worker`
79+
5880
### Configure and run the application
5981

82+
In a separate terminal window, run:
83+
6084
`python manage.py migrate && python manage.py runserver`
6185

6286
The application can be reached in your browser at `https://localhost:8000/`. The Django admin UI is accessible at `https://localhost:8000/admin` and the available API endpoints will be listed in the 404 information at `http://localhost:8000/api/pattern-service/v1/`.
@@ -67,13 +91,22 @@ Project dependencies for all environments are specified in the [pyproject.toml f
6791

6892
To add a new dependency:
6993

70-
1. Add the package to the appropriate project or optional dependencies section of the pyproject.toml file, using dependency specifiers to constrain versions.
71-
2. Update the requirements files with the command `make requirements`. This should update the relevant requirements.txt files in the project's requirements directory.
94+
1. Ensure you have `pip-tools` installed by running either `pipx install pip-tools` or `pip install -u pip-tools`.
95+
2. Add the package to the appropriate project or optional dependencies section of the pyproject.toml file, using dependency specifiers to constrain versions.
96+
3. Update the requirements files with the command `make requirements`. This should update the relevant requirements.txt files in the project's requirements directory.
97+
98+
## Running linters and code checks
99+
100+
Linters, type checks, and other checks can all be run via `tox`. To see the available `tox` commands for this project, run `tox list`.
72101

73-
## Running tests, linters, and code checks
102+
To run an individual tox command use the `-e` flag to specify the environment, for example: `tox -e lint` to run the linters.
74103

75-
Unit tests, linters, type checks, and other checks can all be run via `tox`. To see the available `tox` commands for this project, run `tox list`.
104+
To run all checks, simply run `tox` with no options.
76105

77-
To run an individual tox command use the `-e` flag to specify the environment, for example: `tox -e test` to run tests with all supported python versions.
78-
s
79-
To run all tests and checks, simply run `tox` with no options.
106+
## Running tests
107+
108+
Running the tests requires a postgres connection. The easiest way to do this is with the [test compose file](./tools/podman/compose-test.yaml), and there is a `make` command to simplify starting the postgres container and running the tests:
109+
110+
```bash
111+
make test
112+
```

Dockerfile.dev

Lines changed: 0 additions & 21 deletions
This file was deleted.

Makefile

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ help: ## Show this help message
1212
# -------------------------------------
1313

1414
CONTAINER_RUNTIME ?= podman
15+
COMPOSE_COMMAND ?= podman compose
1516
IMAGE_NAME ?= pattern-service
1617
IMAGE_TAG ?= latest
18+
QUAY_NAMESPACE ?= ansible
19+
BUILD_ARGS ?= --arch amd64
1720

1821
ensure-namespace:
1922
@test -n "$$QUAY_NAMESPACE" || (echo "Error: QUAY_NAMESPACE is required to push quay.io" && exit 1)
2023

2124
.PHONY: build
2225
build: ## Build the container image
2326
@echo "Building container image..."
24-
$(CONTAINER_RUNTIME) build -t $(IMAGE_NAME):$(IMAGE_TAG) -f Dockerfile.dev --arch amd64 .
27+
$(CONTAINER_RUNTIME) build -t $(IMAGE_NAME):$(IMAGE_TAG) -f tools/podman/Containerfile.dev $(BUILD_ARGS) .
2528

2629
.PHONY: clean
2730
clean: ## Remove container image
@@ -34,6 +37,24 @@ push: ensure-namespace build ## Tag and push container image to Quay.io
3437
$(CONTAINER_RUNTIME) tag $(IMAGE_NAME):$(IMAGE_TAG) quay.io/$(QUAY_NAMESPACE)/$(IMAGE_NAME):$(IMAGE_TAG)
3538
$(CONTAINER_RUNTIME) push quay.io/$(QUAY_NAMESPACE)/$(IMAGE_NAME):$(IMAGE_TAG)
3639

40+
#--------------------------------------
41+
# Compose
42+
# -------------------------------------
43+
.PHONY: compose-build
44+
compose-build: ## Build the containers images for the services
45+
$(COMPOSE_COMMAND) -f tools/podman/compose.yaml $(COMPOSE_OPTS) build
46+
47+
.PHONY: compose-up ## Build and start the containers for the services
48+
compose-up:
49+
$(COMPOSE_COMMAND) -f tools/podman/compose.yaml $(COMPOSE_OPTS) up $(COMPOSE_UP_OPTS) --remove-orphans
50+
51+
.PHONY: compose-down
52+
compose-down: ## Stop containers and remove containers, network, images and volumes created by compose-up
53+
$(COMPOSE_COMMAND) -f tools/podman/compose.yaml $(COMPOSE_OPTS) down --remove-orphans
54+
55+
.PHONY: compose-restart
56+
compose-restart: compose-down compose-up ## Stop and remove existing infrastructure and start a new one
57+
3758
# -------------------------------------
3859
# Dependencies
3960
# -------------------------------------
@@ -43,3 +64,13 @@ requirements: ## Generate requirements.txt files from pyproject.toml
4364
pip-compile -o requirements/requirements.txt pyproject.toml
4465
pip-compile --extra dev --extra test -o requirements/requirements-dev.txt pyproject.toml
4566
pip-compile --extra test -o requirements/requirements-test.txt pyproject.toml
67+
68+
# -------------------------------------
69+
# Test
70+
# -------------------------------------
71+
72+
.PHONY: test
73+
test: ## Run tests with a postgres database using docker-compose
74+
$(COMPOSE_COMMAND) -f tools/podman/compose-test.yaml $(COMPOSE_OPTS) up -d
75+
-tox -e test
76+
$(COMPOSE_COMMAND) -f tools/podman/compose-test.yaml $(COMPOSE_OPTS) down

core/apps.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
import logging
2+
3+
from dispatcherd.config import setup as dispatcher_setup
14
from django.apps import AppConfig
5+
from django.conf import settings
6+
7+
logger = logging.getLogger(__name__)
28

39

410
class CoreConfig(AppConfig):
511
default_auto_field = "django.db.models.BigAutoField"
612
name = "core"
13+
14+
def ready(self) -> None:
15+
# Configure dispatcher
16+
dispatcher_setup(config=settings.DISPATCHER_CONFIG)

core/management/__init__.py

Whitespace-only changes.

core/management/commands/__init__.py

Whitespace-only changes.

core/management/commands/worker.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import logging
2+
3+
from dispatcherd import run_service
4+
from django.core.management.base import BaseCommand
5+
6+
logger = logging.getLogger(__name__)
7+
8+
9+
class Command(BaseCommand):
10+
"""Wrapper for worker command."""
11+
12+
def handle(self, *args: tuple, **options: dict) -> None:
13+
logger.info("Starting Pattern service dispatcherd worker.")
14+
run_service()

core/tasks/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)