diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3a63fe09..be852702 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ before_script: pre-commit-check: <<: *only-default stage: pre-commit - image: python:3.11-bullseye + image: python:3.11-bookworm # variables: # PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit # cache: @@ -53,7 +53,7 @@ secret_detection: test-3.10-core: <<: *only-default - image: python:3.10-bullseye + image: python:3.10-bookworm script: - tox -e py310-core artifacts: @@ -65,7 +65,7 @@ test-3.10-core: test-3.11-core: <<: *only-default - image: python:3.11-bullseye + image: python:3.11-bookworm script: - tox -e py311-core artifacts: @@ -77,7 +77,7 @@ test-3.11-core: test-3.12-core: <<: *only-default - image: python:3.12-bullseye + image: python:3.12-bookworm script: - tox -e py312-core artifacts: @@ -89,7 +89,7 @@ test-3.12-core: test-3.10-all: <<: *only-default - image: python:3.10-bullseye + image: python:3.10-bookworm script: - tox -e py310-all artifacts: @@ -101,7 +101,7 @@ test-3.10-all: test-3.11-all: <<: *only-default - image: python:3.11-bullseye + image: python:3.11-bookworm script: - tox -e py311-all artifacts: @@ -114,7 +114,7 @@ test-3.11-all: test-3.12-all: <<: *only-default - image: python:3.12-bullseye + image: python:3.12-bookworm script: - tox -e py312-all artifacts: @@ -126,7 +126,7 @@ test-3.12-all: build-test: stage: test - image: python:3.12-bullseye + image: python:3.12-bookworm before_script: - python -m pip install --upgrade pip @@ -145,13 +145,13 @@ build-test: test-docs: <<: *only-default - image: python:3.12-bullseye + image: python:3.12-bookworm script: - tox -e docs deploy_production: stage: deploy - image: python:3.12-bullseye + image: python:3.12-bookworm before_script: - python -m pip install --upgrade pip diff --git a/allianceauth/__init__.py b/allianceauth/__init__.py index ee05a338..4edd6674 100644 --- a/allianceauth/__init__.py +++ b/allianceauth/__init__.py @@ -5,7 +5,7 @@ manage online service access. # This will make sure the app is always imported when # Django starts so that shared_task will use this app. -__version__ = '4.1.0' +__version__ = '4.2.2' __title__ = 'Alliance Auth' __url__ = 'https://gitlab.com/allianceauth/allianceauth' NAME = f'{__title__} v{__version__}' diff --git a/allianceauth/analytics/tasks.py b/allianceauth/analytics/tasks.py index 02a812a7..cc9ef160 100644 --- a/allianceauth/analytics/tasks.py +++ b/allianceauth/analytics/tasks.py @@ -101,11 +101,38 @@ def analytics_daily_stats(): event_type='Stats') for appconfig in apps.get_app_configs(): - analytics_event(namespace='allianceauth.analytics', - task='send_extension_stats', - label=appconfig.label, - value=1, - event_type='Stats') + if appconfig.label in [ + "django_celery_beat", + "bootstrapform", + "messages", + "sessions", + "auth", + "staticfiles", + "users", + "addons", + "admin", + "humanize", + "contenttypes", + "sortedm2m", + "django_bootstrap5", + "tokens", + "authentication", + "services", + "framework", + "notifications" + "eveonline", + "navhelper", + "analytics", + "menu", + "theme" + ]: + pass + else: + analytics_event(namespace='allianceauth.analytics', + task='send_extension_stats', + label=appconfig.label, + value=1, + event_type='Stats') @shared_task() diff --git a/allianceauth/apps.py b/allianceauth/apps.py index 053f71f8..098f50ba 100644 --- a/allianceauth/apps.py +++ b/allianceauth/apps.py @@ -5,26 +5,5 @@ from django.core.checks import Warning, Error, register class AllianceAuthConfig(AppConfig): name = 'allianceauth' - -@register() -def check_settings(app_configs, **kwargs): - from django.conf import settings - - errors = [] - if hasattr(settings, "SITE_URL"): - if settings.SITE_URL[-1] == "/": - errors.append(Warning( - "'SITE_URL' Has a trailing slash. This may lead to incorrect links being generated by Auth.")) - else: - errors.append(Error( - "No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules.")) - if hasattr(settings, "CSRF_TRUSTED_ORIGINS"): - if hasattr(settings, "SITE_URL"): - if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS: - errors.append(Warning( - "'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified.")) - else: - errors.append(Error( - "No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified")) - - return errors + def ready(self) -> None: + import allianceauth.checks # noqa diff --git a/allianceauth/authentication/templates/authentication/dashboard.html b/allianceauth/authentication/templates/authentication/dashboard.html index af1ece0d..640f2691 100644 --- a/allianceauth/authentication/templates/authentication/dashboard.html +++ b/allianceauth/authentication/templates/authentication/dashboard.html @@ -7,7 +7,7 @@ {% translate "Dashboard" %} {% endblock %} {% block content %} -
+
{% for dash in views %} {{ dash | safe }} {% endfor %} diff --git a/allianceauth/authentication/templates/authentication/dashboard_characters.html b/allianceauth/authentication/templates/authentication/dashboard_characters.html index 7021ba46..3560210f 100644 --- a/allianceauth/authentication/templates/authentication/dashboard_characters.html +++ b/allianceauth/authentication/templates/authentication/dashboard_characters.html @@ -1,5 +1,5 @@ {% load i18n %} -
+
{% translate "Characters" as widget_title %} diff --git a/allianceauth/authentication/templates/authentication/dashboard_groups.html b/allianceauth/authentication/templates/authentication/dashboard_groups.html index 270fcb76..d7d3c3b7 100644 --- a/allianceauth/authentication/templates/authentication/dashboard_groups.html +++ b/allianceauth/authentication/templates/authentication/dashboard_groups.html @@ -1,5 +1,5 @@ {% load i18n %} -
+
{% translate "Membership" as widget_title %} diff --git a/allianceauth/checks.py b/allianceauth/checks.py new file mode 100644 index 00000000..19b0adec --- /dev/null +++ b/allianceauth/checks.py @@ -0,0 +1,187 @@ +from typing import List +from django import db +from django.core.checks import CheckMessage, Error, register, Warning +from allianceauth.utils.cache import get_redis_client +from django.utils import timezone +from packaging.version import InvalidVersion, Version as Pep440Version +from celery import current_app +from django.conf import settings +from sqlite3.dbapi2 import sqlite_version_info + +""" +A = System Packages +B = Configuration +""" + + +@register() +def django_settings(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + if hasattr(settings, "SITE_URL"): + if settings.SITE_URL[-1] == "/": + errors.append(Warning("'SITE_URL' Has a trailing slash. This may lead to incorrect links being generated by Auth.", hint="", id="allianceauth.checks.B005")) + else: + errors.append(Error("No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules.", hint="", id="allianceauth.checks.B006")) + + if hasattr(settings, "CSRF_TRUSTED_ORIGINS") and hasattr(settings, "SITE_URL"): + if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS: + errors.append(Warning("'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified.", hint="", id="allianceauth.checks.B007")) + else: + errors.append(Error("No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified", hint="", id="allianceauth.checks.B008")) + + return errors + + +@register() +def system_package_redis(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + try: + redis_version = Pep440Version(get_redis_client().info()['redis_version']) + except InvalidVersion: + errors.append(Warning("Unable to confirm Redis Version")) + return errors + + if redis_version.major == 7 and redis_version.minor == 2 and timezone.now() > timezone.datetime(year=2025, month=8, day=31, tzinfo=timezone.utc): + errors.append(Error(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A001")) + elif redis_version.major == 7 and redis_version.minor == 0: + errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A002")) + elif redis_version.major == 6 and redis_version.minor == 2: + errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A018")) + elif redis_version.major in [6, 5]: + errors.append(Error(f"Redis {redis_version.public} EOL", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A003")) + + return errors + + +@register() +def system_package_mysql(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + + for connection in db.connections.all(): + if connection.vendor == "mysql": + try: + mysql_version = Pep440Version(".".join(str(i) for i in connection.mysql_version)) + except InvalidVersion: + errors.append(Warning("Unable to confirm MySQL Version")) + return errors + + # MySQL 8 + if mysql_version.major == 8 and mysql_version.minor == 4 and timezone.now() > timezone.datetime(year=2032, month=4, day=30, tzinfo=timezone.utc): + errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A004")) + elif mysql_version.major == 8 and mysql_version.minor == 3: + errors.append(Warning(f"MySQL {mysql_version.public} Non LTS", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A005")) + elif mysql_version.major == 8 and mysql_version.minor == 2: + errors.append(Warning(f"MySQL {mysql_version.public} Non LTS", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A006")) + elif mysql_version.major == 8 and mysql_version.minor == 1: + errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A007")) + elif mysql_version.major == 8 and mysql_version.minor == 0 and timezone.now() > timezone.datetime(year=2026, month=4, day=30, tzinfo=timezone.utc): + errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A008")) + elif mysql_version.major < 8: # This will also catch Mariadb 5.x + errors.append(Error(f"MySQL or MariaDB {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A009")) + return errors + + +@register() +def system_package_mariadb(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + + for connection in db.connections.all(): + if connection.vendor == "mysql": # Still to find a way to determine MySQL vs MariaDB + try: + mariadb_version = Pep440Version(".".join(str(i) for i in connection.mysql_version)) + except InvalidVersion: + errors.append(Warning("Unable to confirm MariaDB Version")) + return errors + + # MariaDB 11 + if mariadb_version.major == 11 and mariadb_version.minor == 4 and timezone.now() > timezone.datetime(year=2029, month=5, day=19, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A010")) + elif mariadb_version.major == 11 and mariadb_version.minor == 2: + errors.append(Warning(f"MariaDB {mariadb_version.public} Non LTS", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A018")) + if timezone.now() > timezone.datetime(year=2024, month=11, day=21, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A011")) + elif mariadb_version.major == 11 and mariadb_version.minor == 1: + errors.append(Warning(f"MariaDB {mariadb_version.public} Non LTS", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A019")) + if timezone.now() > timezone.datetime(year=2024, month=8, day=21, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A012")) + elif mariadb_version.major == 11 and mariadb_version.minor in [0, 3]: # Demote versions down here once EOL + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config.", id="allianceauth.checks.A013")) + + # MariaDB 10 + elif mariadb_version.major == 10 and mariadb_version.minor == 11 and timezone.now() > timezone.datetime(year=2028, month=2, day=10, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config.", id="allianceauth.checks.A014")) + elif mariadb_version.major == 10 and mariadb_version.minor == 6 and timezone.now() > timezone.datetime(year=2026, month=7, day=6, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A0015")) + elif mariadb_version.major == 10 and mariadb_version.minor == 5 and timezone.now() > timezone.datetime(year=2025, month=6, day=24, tzinfo=timezone.utc): + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A016")) + elif mariadb_version.major == 10 and mariadb_version.minor in [0, 1, 2, 3, 4, 7, 9, 10]: # Demote versions down here once EOL + errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A017")) + + return errors + + +@register() +def system_package_sqlite(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + for connection in db.connections.all(): + if connection.vendor == "sqlite": + try: + sqlite_version = Pep440Version(".".join(str(i) for i in sqlite_version_info)) + except InvalidVersion: + errors.append(Warning("Unable to confirm SQLite Version")) + return errors + if sqlite_version.major == 3 and sqlite_version.minor < 27: + errors.append(Error(f"SQLite {sqlite_version.public} Unsupported by Django", hint="https://pkgs.org/download/sqlite3", id="allianceauth.checks.A020")) + return errors + + +@register() +def sql_settings(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + for connection in db.connections.all(): + if connection.vendor == "mysql": + try: + if connection.settings_dict["OPTIONS"]["charset"] != "utf8mb4": + errors.append(Error(f"SQL Charset is not set to utf8mb4 DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001")) + except KeyError: + errors.append(Error(f"SQL Charset is not set to utf8mb4 DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001")) + + # This hasn't actually been set on AA yet + # try: + # if connection.settings_dict["OPTIONS"]["collation"] != "utf8mb4_unicode_ci": + # errors.append(Error(f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001")) + # except KeyError: + # errors.append(Error(f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001")) + + # if connection.vendor == "sqlite": + + return errors + + +@register() +def celery_settings(app_configs, **kwargs) -> List[CheckMessage]: + errors: List[CheckMessage] = [] + + try: + if current_app.conf.broker_transport_options != {'priority_steps': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'queue_order_strategy': 'priority'}: + errors.append(Error("Celery Priorities are not set correctly", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc", id="allianceauth.checks.B003")) + except KeyError: + errors.append(Error("Celery Priorities are not set", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc", id="allianceauth.checks.B003")) + + try: + if current_app.conf.broker_connection_retry_on_startup != True: + errors.append(Error("Celery broker_connection_retry_on_startup not set correctly", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280", id="allianceauth.checks.B004")) + except KeyError: + errors.append(Error("Celery broker_connection_retry_on_startup not set", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280", id="allianceauth.checks.B004")) + + return errors + + +# IDEAS + +# Any other celery things weve manually changed over the years +# I'd be happy to add Community App checks, old versions the owners dont want to support etc. + + +# Check Default Collation on DB +# Check Charset Collation on all tables diff --git a/allianceauth/framework/templates/framework/dashboard/widget-title.html b/allianceauth/framework/templates/framework/dashboard/widget-title.html index fdc11845..f6c0c855 100644 --- a/allianceauth/framework/templates/framework/dashboard/widget-title.html +++ b/allianceauth/framework/templates/framework/dashboard/widget-title.html @@ -1,7 +1,7 @@ {#Usage:#} {# {% include "framework/dashboard/widget-title.html" with title="Foobar" %}#} -
+

{{ title }}

diff --git a/allianceauth/optimer/templates/optimer/dashboard.ops.html b/allianceauth/optimer/templates/optimer/dashboard.ops.html index cf990ec4..b9e1d418 100644 --- a/allianceauth/optimer/templates/optimer/dashboard.ops.html +++ b/allianceauth/optimer/templates/optimer/dashboard.ops.html @@ -1,7 +1,7 @@ {% load i18n %} {% load evelinks %} -
+
{% translate "Upcoming Fleets" as widget_title %} diff --git a/allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html b/allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html index ef70a136..e140ee7c 100644 --- a/allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html +++ b/allianceauth/services/modules/mumble/templates/services/mumble/mumble_service_ctrl.html @@ -7,7 +7,9 @@ {% endblock %} {% block url %} - {{ service_url }} + {% if username != '' %} + {{ service_url }} + {% endif %} {% endblock %} {% block user %} diff --git a/allianceauth/templates/allianceauth/admin-status/esi_check.html b/allianceauth/templates/allianceauth/admin-status/esi_check.html index 3b8393b9..9c7f1605 100644 --- a/allianceauth/templates/allianceauth/admin-status/esi_check.html +++ b/allianceauth/templates/allianceauth/admin-status/esi_check.html @@ -1,5 +1,5 @@ {% load i18n %} -
+

{% translate 'Your Server received an ESI error response code of ' %}?


@@ -23,7 +23,7 @@ console.log("ESI Check: ", JSON.stringify(responseJson, null, 2)); const status = responseJson.status; - if (status != 200) { + if (status !== 200) { elemCode.textContent = status elemMessage.textContent = responseJson.data.error; new bootstrap.Collapse(elemCard, { diff --git a/allianceauth/templates/allianceauth/admin-status/overview.html b/allianceauth/templates/allianceauth/admin-status/overview.html index 23e4c026..47484a57 100644 --- a/allianceauth/templates/allianceauth/admin-status/overview.html +++ b/allianceauth/templates/allianceauth/admin-status/overview.html @@ -2,7 +2,7 @@ {% load humanize %} {% if notifications %} -
+
{% translate "Alliance Auth Notifications" as widget_title %} @@ -13,9 +13,9 @@ {% for notif in notifications %}
  • {% if notif.state == 'opened' %} - {% translate "Open" %} + {% translate "Open" %} {% else %} - {% translate "Closed" %} + {% translate "Closed" %} {% endif %} #{{ notif.iid }} {{ notif.title }}
  • @@ -46,7 +46,7 @@
    {% endif %} -
    +
    diff --git a/allianceauth/templates/allianceauth/error.html b/allianceauth/templates/allianceauth/error.html index 5d65c676..3c2280ea 100644 --- a/allianceauth/templates/allianceauth/error.html +++ b/allianceauth/templates/allianceauth/error.html @@ -1,31 +1,37 @@ {% extends "allianceauth/base-bs5.html" %} +{% load theme_tags %} + {% block page_title %} {{ error_title }} {% endblock page_title %} {% block content %} -
    - {% include "framework/header/page-header.html" with title=error_title %} +
    +
    +
    + {% include "framework/header/page-header.html" with title=error_title %} -
    - - - - +
    + + + + +
    + +

    {{ error_message }}

    +
    - -

    {{ error_message }}

    {% endblock content %} diff --git a/allianceauth/timerboard/templates/timerboard/dashboard.timers.html b/allianceauth/timerboard/templates/timerboard/dashboard.timers.html index d512e483..4b6d9a5a 100644 --- a/allianceauth/timerboard/templates/timerboard/dashboard.timers.html +++ b/allianceauth/timerboard/templates/timerboard/dashboard.timers.html @@ -1,7 +1,7 @@ {% load i18n %} {% load evelinks %} -
    +
    {% translate "Upcoming Timers" as widget_title %} diff --git a/docker/.env.example b/docker/.env.example index ea7373ea..24c7c446 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -1,7 +1,7 @@ PROTOCOL=https:// AUTH_SUBDOMAIN=%AUTH_SUBDOMAIN% DOMAIN=%DOMAIN% -AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v4.1.0 +AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v4.2.2 # Nginx Proxy Manager PROXY_HTTP_PORT=80 diff --git a/docker/Dockerfile b/docker/Dockerfile index 8ae60b06..2f4d70e3 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ FROM python:3.11-slim -ARG AUTH_VERSION=v4.1.0 +ARG AUTH_VERSION=v4.2.2 ARG AUTH_PACKAGE=allianceauth==${AUTH_VERSION} ENV AUTH_USER=allianceauth ENV AUTH_GROUP=allianceauth @@ -9,21 +9,21 @@ ENV AUTH_HOME=/home/allianceauth # Setup user and directory permissions SHELL ["/bin/bash", "-c"] -RUN groupadd -g 61000 ${AUTH_GROUP} -RUN useradd -g 61000 -l -M -s /bin/false -u 61000 ${AUTH_USER} -RUN mkdir -p ${STATIC_BASE} \ - && chown ${AUTH_USERGROUP} ${STATIC_BASE} \ - && mkdir -p ${AUTH_HOME} \ - && chown ${AUTH_USERGROUP} ${AUTH_HOME} +RUN groupadd -g 61000 ${AUTH_GROUP} && \ + useradd -g 61000 -l -m -s /bin/false -u 61000 ${AUTH_USER} -# Install build dependencies -RUN apt-get update && apt-get upgrade -y && apt-get install -y \ - libmariadb-dev gcc git pkg-config +RUN mkdir -p ${STATIC_BASE}/myauth/static \ + && chown ${AUTH_USERGROUP} ${STATIC_BASE}/myauth/static -# Install python dependencies -RUN pip install --upgrade pip -RUN pip install wheel gunicorn -RUN pip install ${AUTH_PACKAGE} +# Install Build Dependencies +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends libmariadb-dev gcc git pkg-config \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install AA and Dependencies +RUN pip install --no-cache-dir ${AUTH_PACKAGE} gunicorn # Switch to non-root user USER ${AUTH_USER} @@ -33,7 +33,6 @@ WORKDIR ${AUTH_HOME} RUN allianceauth start myauth COPY /allianceauth/project_template/project_name/settings/local.py ${AUTH_HOME}/myauth/myauth/settings/local.py RUN allianceauth update myauth -RUN mkdir -p ${STATIC_BASE}/myauth/static RUN echo 'alias auth="python $AUTH_HOME/myauth/manage.py"' >> ~/.bashrc && \ source ~/.bashrc diff --git a/docker/conf/celery.py b/docker/conf/celery.py index f8eb9a86..5129f00a 100644 --- a/docker/conf/celery.py +++ b/docker/conf/celery.py @@ -9,6 +9,10 @@ from django.conf import settings # noqa app = Celery('myauth') +# Automatically try to establish the connection to the AMQP broker on +# Celery startup if it is unavailable. +app.conf.broker_connection_retry_on_startup = True + # Using a string here means the worker don't have to serialize # the configuration object to child processes. app.config_from_object('django.conf:settings') diff --git a/docker/custom.dockerfile b/docker/custom.dockerfile index 99d11d1b..458ff724 100644 --- a/docker/custom.dockerfile +++ b/docker/custom.dockerfile @@ -1,6 +1,8 @@ ARG AA_DOCKER_TAG FROM $AA_DOCKER_TAG -RUN cd /home/allianceauth +WORKDIR ${AUTH_HOME} + COPY /conf/requirements.txt requirements.txt -RUN pip install -r requirements.txt +RUN --mount=type=cache,target=~/.cache \ + pip install -r requirements.txt diff --git a/docs/development/custom/framework/templates.md b/docs/development/custom/framework/templates.md index b7581a8c..c989e53e 100644 --- a/docs/development/custom/framework/templates.md +++ b/docs/development/custom/framework/templates.md @@ -35,7 +35,7 @@ To ensure the dashboard widgets have a unified style, we provide a template part To use it, you can use the following code in your dashboard widget template: ```django -
    +
    {% translate "My Widget Title" as widget_title %} diff --git a/docs/features/services/mumble-docker.md b/docs/features/services/mumble-docker.md index 36fa52b3..09df8458 100644 --- a/docs/features/services/mumble-docker.md +++ b/docs/features/services/mumble-docker.md @@ -1,4 +1,4 @@ -# Mumble +# Mumble (Docker) An alternate install guide for Mumble using Docker, better suited to an Alliance Auth Docker install diff --git a/docs/features/services/openfire-docker.md b/docs/features/services/openfire-docker.md index f2ecc217..e2947f24 100644 --- a/docs/features/services/openfire-docker.md +++ b/docs/features/services/openfire-docker.md @@ -1,4 +1,4 @@ -# Openfire +# Openfire (Docker) An alternate install guide for Openfire using Docker, better suited to an Alliance Auth Docker install diff --git a/docs/features/services/teamspeak3-docker.md b/docs/features/services/teamspeak3-docker.md index 4bccdfcd..81c2f24d 100644 --- a/docs/features/services/teamspeak3-docker.md +++ b/docs/features/services/teamspeak3-docker.md @@ -1,4 +1,4 @@ -# TeamSpeak 3 +# TeamSpeak 3 (Docker) ## Overview diff --git a/docs/installation/allianceauth.md b/docs/installation/allianceauth.md index 9ebae33b..117b8fd7 100644 --- a/docs/installation/allianceauth.md +++ b/docs/installation/allianceauth.md @@ -181,13 +181,17 @@ If you don't plan on running the database on the same server as auth you still n ### Redis and Other Tools -A few extra utilities are also required for installation of packages. +A few extra utilities are also required for the installation of packages. ::::{tabs} :::{group-tab} Ubuntu 2004, 2204 ```shell +curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg +sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg +echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list +sudo apt-get update sudo apt-get install unzip git redis-server curl libssl-dev libbz2-dev libffi-dev build-essential pkg-config ``` diff --git a/pyproject.toml b/pyproject.toml index 41b1f34f..b0f25b08 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ authors = [ requires-python = ">=3.10" classifiers = [ "Environment :: Web Environment", + "Framework :: Celery", "Framework :: Django", "Framework :: Django :: 4.2", "Intended Audience :: Developers",