Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,17 @@ jobs:
self-hosted-runner-image: "noble"
working-directory: ${{ matrix.charm.working-directory }}
with-uv: true
build-snap-haproxy-route-policy:
name: Build Snap
runs-on: ubuntu-latest
steps:
- name: Build Snap
id: snapcraft
uses: snapcore/action-build@v1
with:
path: ./haproxy-route-policy
- name: Upload Snap Artifact
uses: actions/upload-artifact@v4
with:
name: snap
path: ${{ steps.snapcraft.outputs.snap }}
20 changes: 20 additions & 0 deletions docs/release-notes/artifacts/pr0415.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version_schema: 2

changes:
- title: Added snap packaging and runtime scripts for haproxy-route-policy
author: tphan025
type: minor
description: >
Added snap packaging for the haproxy-route-policy app, including
`snap/snapcraft.yaml`, install/configure hooks, and helper scripts to run
Gunicorn and Django management commands with snap configuration values.
Added Gunicorn as a dependency and configured uv build metadata in
`pyproject.toml` for packaging. Updated the app README with a basic setup
flow for PostgreSQL and snap configuration.
urls:
pr:
- https://github.com/canonical/haproxy-operator/pull/415
related_doc:
related_issue:
visibility: public
highlight: false
24 changes: 24 additions & 0 deletions haproxy-route-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#### Basic setup

Start a PostgreSQL database:

```
docker run -d --name postgres -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USERNAME=postgres postgres:latest
```

Basic snap configurations:

```
sudo snap set haproxy-route-policy database-password=postgres
sudo snap set haproxy-route-policy database-host=localhost
sudo snap set haproxy-route-policy database-port=5432
sudo snap set haproxy-route-policy database-user=postgres
sudo snap set haproxy-route-policy database-name=postgres
```

## Learn more
* [Read more](https://charmhub.io/haproxy-operator/docs)

## Project and community
* [Issues](https://github.com/canonical/haproxy-operator/issues)
* [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com)
9 changes: 9 additions & 0 deletions haproxy-route-policy/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,20 @@ dependencies = [
"django>=6.0.3",
"djangorestframework>=3.16.1",
"djangorestframework-simplejwt>=5.5.1",
"gunicorn>=23.0.0",
"psycopg2-binary>=2.9.11",
"validators>=0.35.0",
"whitenoise>=6.12.0",
]

[build-system]
requires = ["uv_build>=0.7.2,<1"]
build-backend = "uv_build"

[tool.uv.build-backend]
module-root = ""
module-name = ["haproxy_route_policy", "policy"]

[dependency-groups]
auth = [
"djangorestframework-simplejwt>=5.5.1",
Expand Down
52 changes: 52 additions & 0 deletions haproxy-route-policy/snap/hooks/configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/sh

# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

DJANGO_DEBUG="$(snapctl get debug)"
export DJANGO_DEBUG

case "$DJANGO_DEBUG" in
"true") ;;
"false") ;;
*)
>&2 echo "'$DJANGO_DEBUG is not a supported value for django_debug. Possible values are true, false"
return 1
;;
esac

DJANGO_LOG_LEVEL="$(snapctl get log-level)"
export DJANGO_LOG_LEVEL

case "$DJANGO_LOG_LEVEL" in
"debug") ;;
"info") ;;
"warning") ;;
"error") ;;
"critical") ;;
"DEBUG") ;;
"INFO") ;;
"WARNING") ;;
"ERROR") ;;
"CRITICAL") ;;
*)
>&2 echo "'$DJANGO_LOG_LEVEL is not a supported value for debug. Possible values are debug, info, warning, error, critical"
return 1
;;
esac

DJANGO_ALLOWED_HOSTS="$(snapctl get allowed-hosts)"
export DJANGO_ALLOWED_HOSTS
DJANGO_DATABASE_PASSWORD="$(snapctl get database-password)"
export DJANGO_DATABASE_PASSWORD
DJANGO_DATABASE_HOST="$(snapctl get database-host)"
export DJANGO_DATABASE_HOST
DJANGO_DATABASE_PORT="$(snapctl get database-port)"
export DJANGO_DATABASE_PORT
DJANGO_DATABASE_USER="$(snapctl get database-user)"
export DJANGO_DATABASE_USER
DJANGO_DATABASE_NAME="$(snapctl get database-name)"
export DJANGO_DATABASE_NAME

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider failing fast = not starting the snap if we're missing some variables.

snapctl stop "$SNAP_INSTANCE_NAME"
snapctl start "$SNAP_INSTANCE_NAME"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we run the migrations here?

13 changes: 13 additions & 0 deletions haproxy-route-policy/snap/hooks/install
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh

# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

set -xe

# set default configuration values
snapctl set debug='false'
snapctl set log-level='INFO'
snapctl set allowed-hosts='["*"]'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default to 127.0.01 and let the charm update when related with haproxy.

SECRET_KEY="$(tr -dc a-zA-Z0-9 < /dev/urandom | head -c 50)"
snapctl set secret-key="$SECRET_KEY"
33 changes: 33 additions & 0 deletions haproxy-route-policy/snap/scripts/bin/gunicorn-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh

# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

set -xe

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider failing fast = not starting if some mandatory variables are missing.

DJANGO_SECRET_KEY="$(snapctl get secret-key)"
export DJANGO_SECRET_KEY
DJANGO_DEBUG="$(snapctl get debug)"
export DJANGO_DEBUG
DJANGO_ALLOWED_HOSTS="$(snapctl get allowed-hosts)"
export DJANGO_ALLOWED_HOSTS
DJANGO_LOG_LEVEL="$(snapctl get log-level)"
export DJANGO_LOG_LEVEL
DJANGO_DATABASE_PASSWORD="$(snapctl get database-password)"
export DJANGO_DATABASE_PASSWORD
DJANGO_DATABASE_HOST="$(snapctl get database-host)"
export DJANGO_DATABASE_HOST
DJANGO_DATABASE_PORT="$(snapctl get database-port)"
export DJANGO_DATABASE_PORT
DJANGO_DATABASE_USER="$(snapctl get database-user)"
export DJANGO_DATABASE_USER
DJANGO_DATABASE_NAME="$(snapctl get database-name)"
export DJANGO_DATABASE_NAME

LOG_LEVEL="info"
if [ "$DJANGO_DEBUG" = "true" ]; then
LOG_LEVEL="debug"
fi

exec gunicorn --bind 0.0.0.0:8080 haproxy_route_policy.wsgi \
--capture-output --log-level="$LOG_LEVEL"
30 changes: 30 additions & 0 deletions haproxy-route-policy/snap/scripts/bin/manage
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh

# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

set -e

DJANGO_SECRET_KEY="$(snapctl get secret-key)"
export DJANGO_SECRET_KEY
DJANGO_DEBUG="$(snapctl get debug)"
export DJANGO_DEBUG
DJANGO_ALLOWED_HOSTS="$(snapctl get allowed-hosts)"
if [ -z "$DJANGO_ALLOWED_HOSTS" ]; then
DJANGO_ALLOWED_HOSTS="[]"
fi
export DJANGO_ALLOWED_HOSTS
DJANGO_LOG_LEVEL="$(snapctl get log-level)"
export DJANGO_LOG_LEVEL
DJANGO_DATABASE_PASSWORD="$(snapctl get database-password)"
export DJANGO_DATABASE_PASSWORD
DJANGO_DATABASE_HOST="$(snapctl get database-host)"
export DJANGO_DATABASE_HOST
DJANGO_DATABASE_PORT="$(snapctl get database-port)"
export DJANGO_DATABASE_PORT
DJANGO_DATABASE_USER="$(snapctl get database-user)"
export DJANGO_DATABASE_USER
DJANGO_DATABASE_NAME="$(snapctl get database-name)"
export DJANGO_DATABASE_NAME

exec $SNAP/bin/uv run $SNAP/app/manage.py "$@" --settings=haproxy_route_policy.settings
54 changes: 54 additions & 0 deletions haproxy-route-policy/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

name: haproxy-route-policy
base: core24
version: "0.1"
license: Apache-2.0
summary: HAProxy Route Policy API
description: |
This snap bundles the HAProxy Route Policy Django application to be included in the haproxy-route-policy-operator.
confinement: strict
platforms:
amd64:
build-on: [amd64]
build-for: [amd64]

system-usernames:
_daemon_: shared

parts:
haproxy-route-policy:
plugin: uv
source: .
build-snaps:
- astral-uv
stage-snaps:
- astral-uv
override-build: |
# Also copy the source code to the install directory for the manage.py script
cp -r . $SNAPCRAFT_PART_INSTALL/app
chown -R 584792:584792 $SNAPCRAFT_PART_INSTALL/app
craftctl default

scripts:
plugin: dump
source: ./snap/scripts
override-prime: |
craftctl default
chmod -R +rx $CRAFT_PRIME/bin

apps:
gunicorn:
command: bin/gunicorn-start
daemon: simple
restart-condition: always
plugs:
- network
- network-bind

manage:
command: bin/manage
plugs:
- network
- network-bind
25 changes: 24 additions & 1 deletion haproxy-route-policy/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading