diff --git a/Dockerfile.rhel8 b/Dockerfile.rhel8 index 3684933c72..b56716eeeb 100644 --- a/Dockerfile.rhel8 +++ b/Dockerfile.rhel8 @@ -22,7 +22,7 @@ COPY requirements/requirements.insights.txt /tmp/requirements.txt # NOTE: en_US.UTF-8 locale is provided by glibc-langpack-en RUN set -ex; \ DNF="dnf -y --disableplugin=subscription-manager" && \ - INSTALL_PKGS="glibc-langpack-en git-core libpq python3.11 python3.11-pip" && \ + INSTALL_PKGS="glibc-langpack-en git-core libpq python3.11 python3.11-pip skopeo" && \ INSTALL_PKGS_BUILD="gcc libpq-devel python3.11-devel openldap-devel" && \ LANG=C ${DNF} install ${INSTALL_PKGS} ${INSTALL_PKGS_BUILD} && \ python3.11 -m venv "${VIRTUAL_ENV}" && \ @@ -44,20 +44,22 @@ RUN chgrp -R 0 $HOME && \ chmod -R g=u $HOME RUN set -ex; \ - install -dm 0775 -o galaxy /var/lib/pulp/artifact \ - /var/lib/pulp/tmp \ - /etc/pulp/certs \ + install -dm 0775 -o galaxy \ + /var/lib/pulp/{artifact,media,scripts,tmp} \ + /etc/pulp/{certs,keys} \ /tmp/ansible && \ pip3.11 install --no-deps --editable /app && \ PULP_CONTENT_ORIGIN=x django-admin collectstatic && \ install -Dm 0644 /app/ansible.cfg /etc/ansible/ansible.cfg && \ install -Dm 0644 /app/docker/etc/settings.py /etc/pulp/settings.py && \ install -Dm 0755 /app/docker/entrypoint.sh /entrypoint.sh && \ - install -Dm 0755 /app/docker/bin/* /usr/local/bin/ + install -Dm 0755 /app/docker/bin/* /usr/local/bin/ && \ + install -Dm 0775 /app/galaxy-operator/bin/* /usr/bin/ USER galaxy -WORKDIR /app +ENV HOME="/var/lib/pulp" +WORKDIR /var/lib/pulp VOLUME [ "/var/lib/pulp/artifact", \ - "/var/lib/pulp/tmp", \ + "/var/lib/pulp/tmp", \ "/tmp/ansible" ] -ENTRYPOINT [ "/entrypoint.sh" ] +ENTRYPOINT [ "/entrypoint.sh" ] \ No newline at end of file diff --git a/docker/bin/start-api b/docker/bin/start-api index e5ef33ccc2..0824a9202a 100755 --- a/docker/bin/start-api +++ b/docker/bin/start-api @@ -31,4 +31,7 @@ if [[ -n "${GUNICORN_LOGGER_CLASS}" ]]; then GUNICORN_OPTIONS+=(--logger-class "${GUNICORN_LOGGER_CLASS}") fi -exec "${GUNICORN}" "${GUNICORN_OPTIONS[@]}" "${APP_MODULE}" + +mkdir -p /var/lib/pulp/{assets,media,scripts,tmp} + +exec "${GUNICORN}" "${GUNICORN_OPTIONS[@]}" "${APP_MODULE}" \ No newline at end of file diff --git a/docker/bin/start-content-app b/docker/bin/start-content-app index f0d43f1784..ad47f6f029 100755 --- a/docker/bin/start-content-app +++ b/docker/bin/start-content-app @@ -11,10 +11,11 @@ readonly BIND_PORT="${GUNICORN_PORT:-24816}" readonly WORKER_CLASS='aiohttp.GunicornWebWorker' readonly APP_MODULE='pulpcore.content:server' +mkdir -p /var/lib/pulp/{assets,media,scripts,tmp} exec gunicorn \ --bind "${BIND_HOST}:${BIND_PORT}" \ --worker-class "${WORKER_CLASS}" \ --workers "${GUNICORN_WORKERS}" \ --access-logfile - \ - "${APP_MODULE}" + "${APP_MODULE}" \ No newline at end of file diff --git a/galaxy-operator/bin/readyz.py b/galaxy-operator/bin/readyz.py new file mode 100644 index 0000000000..c7269f74b7 --- /dev/null +++ b/galaxy-operator/bin/readyz.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +import os +import sys +import requests + +from requests.packages.urllib3.util.connection import HAS_IPV6 + + +def is_api_healthy(path): + """ + Checks if API is healthy + """ + address = "[::1]" if HAS_IPV6 else "127.0.0.1" + url = f"http://{address}:8000{path}" + print(f"Readiness probe: checking {url}") + response = requests.get(url, allow_redirects=True) + data = response.json() + + if not data["database_connection"]["connected"]: + print("Readiness probe: database issue") + sys.exit(3) + + if os.getenv("REDIS_SERVICE_HOST") and not data["redis_connection"]["connected"]: + print("Readiness probe: cache issue") + sys.exit(4) + + print("Readiness probe: ready!") + sys.exit(0) + + +def is_content_healthy(path): + """ + Checks if Content is healthy + """ + address = "[::1]" if HAS_IPV6 else "127.0.0.1" + url = f"http://{address}:24816{path}" + print(f"Readiness probe checking {url}") + response = requests.head(url) + response.raise_for_status() + + print("Readiness probe: ready!") + sys.exit(0) + + +""" +PID 1 value (/proc/1/cmdline) may vary based on the gunicorn install method (RPM vs pip) +The cmdline value for this PID looks like: +``` +# pip installation +gunicorn: master \[pulp-{content,api}\] +``` +OR +``` +# RPM installation +/usr/bin/python3.9/usr/bin/gunicorn--bind[::]:2481{6,7}pulpcore.app.wsgi:application--namepulp-{api,content}--timeout90--workers2 +``` +""" +with open("/proc/1/cmdline", "r") as f: + cmdline = f.readline() + +if "pulp-api" in cmdline: + is_api_healthy(sys.argv[1]) + +elif "pulp-content" in cmdline: + is_content_healthy(sys.argv[1]) diff --git a/galaxy-operator/bin/wait_on_postgres.py b/galaxy-operator/bin/wait_on_postgres.py new file mode 100644 index 0000000000..6b34b2f8d8 --- /dev/null +++ b/galaxy-operator/bin/wait_on_postgres.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import sys +import time +from django.db import connection, utils + +if __name__ == "__main__": + + print("Waiting on postgresql to start...") + for dummy in range(100): + try: + connection.ensure_connection() + break + except utils.OperationalError: + time.sleep(3) + + else: + print("Unable to reach postgres.") + sys.exit(1) + + print("Postgres started.") + sys.exit(0)