From 95b1acb69a2cd0b843dd98f7b6e6be889674dbb9 Mon Sep 17 00:00:00 2001 From: jerabekjiri Date: Fri, 24 Jan 2025 16:17:45 +0100 Subject: [PATCH] init 4.9 docker compose standalone profile with CI --- .../ci-docker-compose-integration.yml | 85 +++++ .github/workflows/ci_oci-env-integration.yml | 2 +- dev/compose/Dockerfile.dev | 24 ++ dev/compose/README.md | 263 +++++++++++++++ dev/compose/bin/README.md | 48 +++ dev/compose/bin/devinstall | 24 ++ dev/compose/bin/entr | Bin 0 -> 41760 bytes dev/compose/bin/pulpcore-api | 32 ++ dev/compose/bin/pulpcore-content | 20 ++ dev/compose/bin/reloader | 10 + dev/compose/bin/wait | 6 + dev/compose/database/README.md | 21 ++ .../database/database_fields.symmetric.key | 1 + dev/compose/signing/README.md | 181 ++++++++++ dev/compose/signing/collection_sign.sh | 17 + dev/compose/signing/container_sign.sh | 11 + dev/compose/signing/setup_gpg_keys.sh | 10 + dev/compose/signing/setup_gpg_workarounds.sh | 10 + dev/compose/signing/setup_repo_keyring.sh | 6 + dev/compose/signing/setup_signing_services.sh | 17 + dev/compose/signing/signing-public.key | 18 + dev/compose/signing/signing-secret.key | 33 ++ .../signing/signing-secret.key.password.txt | 1 + dev/compose/standalone.yaml | 309 ++++++++++++++++++ dev/nginx/nginx.conf | 92 ++++++ 25 files changed, 1240 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-docker-compose-integration.yml create mode 100644 dev/compose/Dockerfile.dev create mode 100644 dev/compose/README.md create mode 100755 dev/compose/bin/README.md create mode 100755 dev/compose/bin/devinstall create mode 100755 dev/compose/bin/entr create mode 100755 dev/compose/bin/pulpcore-api create mode 100755 dev/compose/bin/pulpcore-content create mode 100755 dev/compose/bin/reloader create mode 100755 dev/compose/bin/wait create mode 100644 dev/compose/database/README.md create mode 100644 dev/compose/database/database_fields.symmetric.key create mode 100644 dev/compose/signing/README.md create mode 100755 dev/compose/signing/collection_sign.sh create mode 100755 dev/compose/signing/container_sign.sh create mode 100755 dev/compose/signing/setup_gpg_keys.sh create mode 100755 dev/compose/signing/setup_gpg_workarounds.sh create mode 100755 dev/compose/signing/setup_repo_keyring.sh create mode 100755 dev/compose/signing/setup_signing_services.sh create mode 100644 dev/compose/signing/signing-public.key create mode 100644 dev/compose/signing/signing-secret.key create mode 100644 dev/compose/signing/signing-secret.key.password.txt create mode 100644 dev/compose/standalone.yaml create mode 100644 dev/nginx/nginx.conf diff --git a/.github/workflows/ci-docker-compose-integration.yml b/.github/workflows/ci-docker-compose-integration.yml new file mode 100644 index 0000000000..1bba4267c4 --- /dev/null +++ b/.github/workflows/ci-docker-compose-integration.yml @@ -0,0 +1,85 @@ +--- +name: Docker Compose Integration +on: + pull_request: + branches: + - '**' + push: + branches: + - '**' + workflow_dispatch: + +jobs: + integration: + strategy: + fail-fast: false + matrix: + env: + - { TEST_PROFILE: standalone, HUB_TEST_MARKS: "deployment_standalone or all" } + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: (Linux) Install docker compose + run: | + curl -L -o /tmp/docker-compose https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-linux-x86_64 + install /tmp/docker-compose /usr/local/bin/ + + - name: sudo apt update + run: | + sudo apt update + + - name: Install python requirements and podman + run: | + sudo apt-get install -y libsasl2-dev python-dev-is-python3 libldap2-dev libssl-dev podman + + - name: Spin up dev/compose/${{ matrix.env.TEST_PROFILE }}.yaml + run: | + docker compose -f dev/compose/${{ matrix.env.TEST_PROFILE }}.yaml up --detach + + - name: Export environment variables to host + if: ${{ matrix.env.TEST_PROFILE != 'certified-sync' }} + run: | + docker compose -f dev/compose/${{ matrix.env.TEST_PROFILE }}.yaml exec manager /bin/bash -c 'env | grep -v -w "HOME"' >> $GITHUB_ENV + + - name: Export environment variables to host (certified-sync) + if: ${{ matrix.env.TEST_PROFILE == 'certified-sync' }} + run: | + docker compose -f dev/compose/${{ matrix.env.TEST_PROFILE }}.yaml exec standalone-manager /bin/bash -c 'env | grep -v -w "HOME"' >> $GITHUB_ENV + + - run: cat $GITHUB_ENV + + - name: Wait for API online status + run: | + max_runs=10 + for i in $(seq 1 $max_runs); do + echo "$i: checking api status..." + RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -u "${{ env.DJANGO_SUPERUSER_USERNAME }}:${{ env.DJANGO_SUPERUSER_PASSWORD }}" -LI http://localhost:5001/api/galaxy/pulp/api/v3/status/) + if [ "$RESPONSE" -ne 200 ]; then + echo "API is down. Retrying in 10 seconds..." + sleep 10 + else + echo "API online." + exit 0 + fi + done + + - name: Install integration requirements + run: | + pip install -r integration_requirements.txt + + - name: Run integration tests + run: | + pytest -v -r sx --color=yes -m '${{ matrix.env.HUB_TEST_MARKS }}' galaxy_ng/tests/integration + env: + GALAXYKIT_SLEEP_SECONDS_POLLING: ".5" + GALAXYKIT_SLEEP_SECONDS_ONETIME: ".5" + GALAXYKIT_POLLING_MAX_ATTEMPTS: "50" + GALAXY_SLEEP_SECONDS_POLLING: ".5" + GALAXY_SLEEP_SECONDS_ONETIME: ".5" + GALAXY_POLLING_MAX_ATTEMPTS: "50" \ No newline at end of file diff --git a/.github/workflows/ci_oci-env-integration.yml b/.github/workflows/ci_oci-env-integration.yml index 045ae54fef..9030c72a90 100644 --- a/.github/workflows/ci_oci-env-integration.yml +++ b/.github/workflows/ci_oci-env-integration.yml @@ -17,7 +17,7 @@ jobs: env: - TEST_PROFILE: ldap - TEST_PROFILE: keycloak - - TEST_PROFILE: standalone + # - TEST_PROFILE: standalone - TEST_PROFILE: rbac - TEST_PROFILE: certified-sync - TEST_PROFILE: insights diff --git a/dev/compose/Dockerfile.dev b/dev/compose/Dockerfile.dev new file mode 100644 index 0000000000..5a54e8f018 --- /dev/null +++ b/dev/compose/Dockerfile.dev @@ -0,0 +1,24 @@ +# This Dockerfile is meant to extend the main Dockerfile.rhel8 +# Moving files to the required places +# Installing extra development libraries and tools +FROM localhost/galaxy_ng/galaxy_ng:base + +ARG GNUPGHOME +ENV GNUPGHOME $GNUPGHOME + +USER root + +RUN /app/dev/compose/signing/setup_gpg_workarounds.sh + +RUN set -ex; \ + install -Dm 0775 /app/dev/compose/database/database_fields.symmetric.key /etc/pulp/certs/database_fields.symmetric.key && \ + install -Dm 0775 /app/dev/compose/signing/signing-secret.key /etc/pulp/certs/signing-secret.key && \ + install -Dm 0775 /app/dev/compose/signing/signing-secret.key.password.txt /etc/pulp/certs/signing-secret.key.password.txt && \ + install -Dm 0775 /app/dev/compose/signing/signing-secret.key /etc/pulp/certs/signing-public.key && \ + install -Dm 0775 /app/dev/compose/signing/collection_sign.sh /var/lib/pulp/scripts/collection_sign.sh && \ + install -Dm 0775 /app/dev/compose/signing/container_sign.sh /var/lib/pulp/scripts/container_sign.sh && \ + chmod +x /var/lib/pulp/scripts/*_sign.sh + +RUN /app/dev/compose/signing/setup_gpg_keys.sh + +RUN ${VIRTUAL_ENV}/bin/python3 -m pip install ipython ipdb django-extensions diff --git a/dev/compose/README.md b/dev/compose/README.md new file mode 100644 index 0000000000..99dea4b24e --- /dev/null +++ b/dev/compose/README.md @@ -0,0 +1,263 @@ +# Galaxy Simplified Compose Stack + +Profiles: + +- `standalone` - Run galaxy_ng for integration with Ansible Automation Platform + +## Requirements + +- `docker compose` version `>=2` + +## Usage + +Pick a profile as needed and on the root of `galaxy_ng` repository. + +> Examples assumes `standalone` as the profile, change as needed. + +Build images +```bash +docker compose -f dev/compose/standalone.yaml build +``` + +Run the stack +```bash +docker compose -f dev/compose/standalone.yaml up +# optionally pass `-d` to release the terminal +``` + +Exec commands on the `manager` service + +Bash +```console +$ docker compose -f dev/compose/standalone.yaml exec manager /bin/bash +bash-4.4# +``` +Django Admin +```console +$ docker compose -f dev/compose/standalone.yaml exec manager pulpcore-manager +Type 'pulpcore-manager help ' for help on a specific subcommand. + +Available subcommands: + +[app] + add-signing-service + analyze-publication +... +``` + +Settings +```console +$ docker compose -f dev/compose/standalone.yaml exec manager dynaconf get DATABASES | python -m json.tool +{ + "default": { + "ENGINE": "django.db.backends.postgresql", + "HOST": "postgres", + "NAME": "galaxy_ng", + "PASSWORD": "galaxy_ng", + "PORT": 5432, + "USER": "galaxy_ng" + } +} +``` +```console +$ docker compose -f dev/compose/standalone.yaml exec manager dynaconf list +CONTENT_ORIGIN 'https://localhost' +CACHE_ENABLED False +CACHE_SETTINGS {'EXPIRES_TTL': 600} +ALLOWED_CONTENT_CHECKSUMS ['sha224', 'sha256', 'sha384', 'sha512'] +... +``` + +Stopping +```console +$ docker compose -f dev/compose/standalone.yaml down +# add -v to stop and remove volumes +``` + +> [!TIP] +> Stop with Ctrl + C if running without `-d` and then execute the `down` command. + +## API Access + +Galaxy API is available on: + +[http://localhost:5001/api/galaxy/v3/swagger-ui/](http://localhost:5001/api/galaxy/v3/swagger-ui/) + +AAP UI and API will be available only if started separately on: + +[https://localhost](https://localhost) + + +## Running UI for standalone development + +Ansible Hub UI can be started separately as a standalone `npm` run. + +```console +# Assuming galaxy_ng is running on standalone compose. + +$ git clone https://github.com/ansible/ansible-hub-ui ~/projects/ansible-hub-ui +$ git clone https://github.com/ansible/galaxy_ng ~/projects/galaxy_ng +``` +Open 2 terminals: + +On the first terminal: + +```console +$ cd galaxy_ng +$ docker compose -f dev/compose/standalone.yaml up +``` + +On the second terminal: + +```console +cd ansible-hub-ui +npm install +npm run start-standalone +``` + +UI will be available on http://localhost:8002 and API on http://localhost:5001 + + +## Auto Reload and Local Checkouts + +To have the services `api`, `worker` and `content` to automatically reload when +source code changes it is required to set which paths the `reloader` must watch for changes. + +Set the variable `DEV_SOURCE_PATH` with the packages you want to add to the reloader list. + +Those repositories must be local checkouts located on the same level of the `galaxy_ng` repository. + +Example: + +Get the repositories locally in the same root path. +```console +$ git clone https://github.com/dynaconf/dynaconf ~/projects/dynaconf +$ git clone https://github.com/pulp/pulp_ansible ~/projects/pulp_ansible +$ git clone https://github.com/ansible/galaxy_ng ~/projects/galaxy_ng +``` + +> **IMPORTANT** Ensure all the repos are checked out to compatible branches. +> for example. you may be on galaxy_ng:master and reading `setup.py` you +> see that it requires `pulp_ansible>2.10,<3` then ensure you checkout `pulp_ansible` +> to a compatible branch. + +Start the compose setting the desired editable paths. + +```console +$ cd ~/projects/galaxy_ng +$ export DEV_SOURCE_PATH="dynaconf:pulp_ansible:galaxy_ng" +$ docker compose -f dev/compose/standalone.yaml up --build +``` + +Optionally it can be informed in a single line: + +```console +$ DEV_SOURCE_PATH="dynaconf:pulp_ansible:galaxy_ng" docker compose -f dev/compose/app.yaml up --build +``` + +> [!NOTE] +> if passing on the call line, remember to repass the same variable every time you interact with +>`docker compose` using the `run` command, usually `exec,logs,stats` doesn't require, but commands +> that starts the service container from scratch needs the variables. + +Now when changes are detected on `.py` and `.yaml` files on any of the `DEV_SOURCE_PATH` +directories it will trigger reload of `api`, `worker`, and `content` services. + + +## Troubleshooting + +### VersionConflict error + +Example: +```bash +api-1 | raise VersionConflict(dist, req).with_context(dependent_req) +api-1 | pkg_resources.VersionConflict: (pkg_foo 3.2.6 (/venv/lib/python3.11/site-packages), Requirement.parse('pkg_foo<3.1.13,>=3.1.12')) +``` + +Solution 1: +Clean up local build files: + +```bash +cd ~/projects/galaxy_ng +rm -rf .eggs +rm -rf build +rm -rf galaxy_ng.egg-info +``` + +Solution 2: + +- Ensure `LOCK_REQUIREMENTS` is set to `0` +- Ensure all your local checkouts are checked out to compatible branches + +### LLB definition error + +```bash +failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to do request: Head "http://localhost/v2/galaxy_ng/galaxy_ng/manifests/base": dial tcp [::1]:80: connect: connection refused +``` + +Solution + +```bash +export DOCKER_BUILDKIT=0 +export COMPOSE_DOCKER_CLI_BUILD=0 +``` + +## Tests + +### Unit tests +Run unit tests with docker compose [Running unit tests](../../galaxy_ng//tests/unit/README.md) + +### Integration tests +Run integration tests with docker compose, check the [Running integration tests](../../galaxy_ng/tests/integration/README.md) + +Run with legacy oci-env, check the [Running oci-env integration tests](../../docs/dev/integration_tests.md) + +## Tips and Tricks. + +--- + +### Debugging + +#### Step 1 - Add the breakpoint + +Edit the file you want to debug and add a breakpoint + +```python +__import__("ipdb").set_trace() +``` + +> [!TIP] +> Replace if you are using a different debugger, however the images has only **pdb** and **ipdb** installed. + +If you discover other ways of debugging, like connecting dap protocol or vscode debugger, please update this file! + +#### Step 2 - Now execute your stack or just the container you are trying to debug. + +Example: + +```bash +$ export DEV_SOURCE_PATH=galaxy_ng +$ docker compose -f dev/compose/standalone.yaml up migrations +# The container will keep running stopped on the breakpoint. +``` + +#### Step 3 - Attach + +```bash +$ docker compose -f dev/compose/standalone.yaml attach migrations +ipdb> +``` + +> [!IMPORTANT] +> To detach from the container DO NOT use Ctrl+c, +> instead, use Ctrl-p Ctrl-q + +--- + +**TBD** + +### Connecting to Database + +### Dumping and restoring the database + +### Populating testing data diff --git a/dev/compose/bin/README.md b/dev/compose/bin/README.md new file mode 100755 index 0000000000..b447b359d2 --- /dev/null +++ b/dev/compose/bin/README.md @@ -0,0 +1,48 @@ +# Dev Binary Tools + +## Reloader + +A Script that splits `DEV_SOURCE_PATH` variable and list all files on its directories, +then omit some unwanted files watching for `.py|yaml` only for changes. + +Then it calls `entr` to reload the passed command. + +## entr + +A tool to watch files for changes and reload +This file is compiled specifically for the container in use. + +LINK: https://eradman.com/entrproject/ + +In case recompilation is needed, run inside the container. + +```bash +# Install entr so we can have reload on worker processes +# the checkout is to fix a compilation error caused by this commit +# https://github.com/eradman/entr/commit/f9ac92d17e42236fe6b5e8492e087620173c7b24 +RUN git clone https://github.com/eradman/entr && \ + cd entr && \ + git checkout 0d2d92d6052624a1e03a2a654e98e1c49f9955d9 && \ + cp Makefile.linux Makefile && \ + make +``` + +Then copy the generated `entr` binary. + +## devinstall + +Install all paths listed on `DEV_SOURCE_PATH` as editable every time the compose starts. + +## wait + +Wait until a file is present on the shared volumes, + +```console +$ wait /etc/pulp/certs/filename; +Waiting for /etc/pulp/certs/filename ... +# sleep 2 secs +Waiting for /etc/pulp/certs/filename ... +# sleep 2 secs +Waiting for /etc/pulp/certs/filename ... +... +``` diff --git a/dev/compose/bin/devinstall b/dev/compose/bin/devinstall new file mode 100755 index 0000000000..79167d1eea --- /dev/null +++ b/dev/compose/bin/devinstall @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +if [ -z "${DEV_SOURCE_PATH}" ]; then + echo "DEV_SOURCE_PATH is not defined, skipping editable installs." + exit 0 +fi + +IFS=':' read -ra SRC_PATH_LIST <<< "$DEV_SOURCE_PATH" + +for item in "${SRC_PATH_LIST[@]}"; do + src_path="/src/${item}" + if [[ -d "$src_path" ]]; then + echo "Installing path ${item} in editable mode." + + if [[ "${LOCK_REQUIREMENTS}" -eq "1" ]]; then + pip3.11 install --no-cache-dir --no-deps --editable "$src_path" >/dev/null + else + pip3.11 install --no-cache-dir --editable "$src_path" >/dev/null + fi + + else + echo "WARNING: Source path ${item} is not a directory." + fi +done + diff --git a/dev/compose/bin/entr b/dev/compose/bin/entr new file mode 100755 index 0000000000000000000000000000000000000000..b9b3c55826a27c5ccbc9c1ce3812d3afe04e639c GIT binary patch literal 41760 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 b1C(}4S?VUF?<7X_4r NOTE: For development it is better to use a persistent key, so database dumps +> can be easily restored across dev environments. + +## Generating a new key + +```bash +rpm -q openssl || dnf -y install openssl; +mkdir -p /etc/pulp/certs/; +openssl rand -base64 32 > /etc/pulp/certs/database_fields.symmetric.key; +chmod 640 /etc/pulp/certs/database_fields.symmetric.key; +``` diff --git a/dev/compose/database/database_fields.symmetric.key b/dev/compose/database/database_fields.symmetric.key new file mode 100644 index 0000000000..14697a0310 --- /dev/null +++ b/dev/compose/database/database_fields.symmetric.key @@ -0,0 +1 @@ +DNmNdwgyZugTax9S64J0FITTr9IHPxbuoF1F1CGPr68= diff --git a/dev/compose/signing/README.md b/dev/compose/signing/README.md new file mode 100644 index 0000000000..5341520bda --- /dev/null +++ b/dev/compose/signing/README.md @@ -0,0 +1,181 @@ +# Node Setup + +Requirements: + +- system has a running `gpg-agent` +- required files are in place + +```bash +# Keys +/etc/pulp/certs/signing-secret.key +/etc/pulp/certs/signing-secret.key.password.tx +/etc/pulp/certs/signing-public.key + +# Scripts +/var/lib/pulp/scripts/collection_sign.sh +/var/lib/pulp/scripts/container_sign.sh + +# Workarounds for Pulp envvar limitation. +# required only if GPGHOME differs from running user HOME +# ./setup_gpg_workarounds.sh +/etc/pulp/certs/HOME.workaround.txt +/etc/pulp/certs/GNUPGHOME.workaround.txt +``` + +## Workers + +```bash +./setup_gpg_keys.sh +``` + +## Run once, on any node, after workers are alive + +```bash +./setup_gpg_keys.sh +./setup_signing_services.sh +./setup_repo_keyring.sh +``` + +--- + +# How Signing Works + +## 1. GPG and keys + +System needs a GPGHOME and a KEYRING + +Usually: + +```bash +~/.gnupg/pubring.kbx +``` + +> NOTE: If `GNUPGHOME` differs from the current user `HOME`, then it is required to save the path to `/etc/pulp/certs/HOME.workaround.txt` and `/etc/pulp/certs/GNUPGHOME.workaround.txt` as a workaround due to a limitation on Pulp SigningService that cannot access external environment variables. + +The keyring must have the secret-key for signing and public key for verification. +The files are located on this directory and must be copied to `/etc/pulp/certs` + +> These keys are for development purposes only! NEVER USE THOSE IN PRODUCTION! + +- cp `signing-secret.key` -> `/etc/pulp/certs/signing-secret.key` +- cp `signing-public.key` -> `/etc/pulp/certs/signing-public.key` + +Key information: + +- fingerprint is `FB8B3F2D24BCAF7EFDF793A9F37575C52D4F16F3` +- short id `F37575C52D4F16F3` +- admin ID `galaxydev@ansible.com` +- passphrase `Galaxy2024` + +The passphrase must be added to a file named `/etc/pulp/certs/signing-secret.key.password.txt` + +```bash +echo "Galaxy2024" > /etc/pulp/certs/signing-secret.key.password.txt +``` + +To add both keys to the keyring start the agent and run: + +```bash +gpgconf --kill gpg-agent && gpg --batch --no-default-keyring --import /etc/pulp/certs/signing-secret.key; +``` + +it is also require to adjust the key trust level: + +```bash +(echo 5; echo y; echo save) | gpg --command-fd 0 --no-tty --no-greeting -q --edit-key 'FB8B3F2D24BCAF7EFDF793A9F37575C52D4F16F3' +``` + +Ensure key is added and trusted + +```bash +gpg --list-secret-keys +``` + +Must output a `[ultimate]` trust level key. + + +## 2. Signing Scripts and Signing Service + +> For collection the script is `collection_sign.sh` and for containers `container_sign.sh`, both +> located on this directory, the files must be copied to `/var/lib/pulp/scripts/` + +- cp `collection_sign.sh` -> `/var/lib/pulp/scripts/collection_sign.sh` +- cp `container_sign.sh` -> `/var/lib/pulp/scripts/container_sign.sh` + +> NOTE: The path for the signing service can be any path, `/var/lib/pulp/script` is just a convention. + +Use `pulpcore-manager add-signing-service` to register the signing service. + +- name: container-default | ansible-default +- script: path/to/executable that can access the GPG keyring +- key: fingerprint_of_gpg_key that lives on the keyring + +Examples: + +For collections: + +```bash +pulpcore-manager add-signing-service ansible-default /var/lib/pulp/scripts/collection_sign.sh F37575C52D4F16F3 +``` + +For containers: + +```bash +pulpcore-manager add-signing-service container-default /var/lib/pulp/scripts/container_sign.sh F37575C52D4F16F3 --class container:ManifestSigningService; +``` + +> NOTE: The command above will actually try to sign an arbitrary artifact in order to validate the key. + +## 3. Signing Collections and Containers + +Galaxy will call the `sign` endpoint passing the following information: + +- content unit id: +- signing_service: foo +- repository: + +Then: + +Signature content is created based on artifact and added to the same +repo as the content and contains a foreign_key to the content signed. + +## 5. Public keys and Validation + +### Collection + +Galaxy exposes collection signature on UI and API. + +### Container + +For Containers the signature is added to the registry extended API so usually +clients such as `podman` will automatically fetch and validate the signature +if configured with a proper `policies.json` file. + +### Public Key + +When validating a signature the client `ansible-galaxy` will needs to have +the public key on a local keyring, there are 2 ways to get the public key. + +- On Galaxy UI there is a menu on sidebar `Signature Keys` that exposes +the public keys and user can download it. + +- On API there is the `/signing-services` API to expose the same information. + +> NOTE: User needs to create the keyring locally and import the key manually. + +## 6. Signature Upload + +Galaxy can be alternatively configured to accept signature upload instead +of relying on a local GPG keyring and SigningService to generate it. + +In this case the artifact can be externally signed (e.g using a hardware token) +and then signature uploaded during the approval dashboard process. + +1. Repository needs a `gpgkey` field containing a public key. + * `pulpcore-manager set-repo-keyring --repository staging --publickeypath /etc/pulp/certs/signing-public.key -y;` + * OR + * `pulpcore-manager set-repo-keyring --repository staging --keyring ~/.gnupg/pubring.kbx -y;` +2. CollectionVersion is uploaded to the repo and ends in `pending` state on approval dashboard when system has `REQUIRE_SIGNATURE_FOR_APPROVAL` +3. Signature is uploaded to the same repo, file matches the collectionversion (e.g `namespace-collection-1.2.3.asc`) name and repo uses `gpgkey` to verify the signature is valid. + +In this case there is no signing service involved, no need for GPG keyrings. diff --git a/dev/compose/signing/collection_sign.sh b/dev/compose/signing/collection_sign.sh new file mode 100755 index 0000000000..685309ad50 --- /dev/null +++ b/dev/compose/signing/collection_sign.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +GNUPGHOME=$(cat /etc/pulp/certs/GNUPGHOME.workaround.txt) + +gpg --lock-never \ + --quiet \ + --batch \ + --pinentry-mode loopback \ + --yes \ + --passphrase $(cat /etc/pulp/certs/signing-secret.key.password.txt) \ + --homedir "$GNUPGHOME" \ + --detach-sign \ + --default-key $PULP_SIGNING_KEY_FINGERPRINT \ + --armor \ + --output $1.asc \ + $1 + +[ $? -eq 0 ] && echo {\"file\": \"$1\", \"signature\": \"$1.asc\"} || exit $? diff --git a/dev/compose/signing/container_sign.sh b/dev/compose/signing/container_sign.sh new file mode 100755 index 0000000000..160a1d6b2b --- /dev/null +++ b/dev/compose/signing/container_sign.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +MANIFEST_PATH=$1 +HOME=$(cat /etc/pulp/certs/HOME.workaround.txt) + +skopeo standalone-sign \ + --passphrase-file /etc/pulp/certs/signing-secret.key.password.txt \ + --output $SIG_PATH \ + $MANIFEST_PATH $REFERENCE $PULP_SIGNING_KEY_FINGERPRINT + +[ $? -eq 0 ] && echo {\"signature_path\": \"$SIG_PATH\"} || exit $? diff --git a/dev/compose/signing/setup_gpg_keys.sh b/dev/compose/signing/setup_gpg_keys.sh new file mode 100755 index 0000000000..d20d018301 --- /dev/null +++ b/dev/compose/signing/setup_gpg_keys.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# ensure agent is running +gpgconf --kill gpg-agent + +# Import the key +gpg --batch --no-default-keyring --import /etc/pulp/certs/signing-secret.key; + +# Set the key trust level +(echo 5; echo y; echo save) | gpg --command-fd 0 --no-tty --no-greeting -q --edit-key 'FB8B3F2D24BCAF7EFDF793A9F37575C52D4F16F3' trust; diff --git a/dev/compose/signing/setup_gpg_workarounds.sh b/dev/compose/signing/setup_gpg_workarounds.sh new file mode 100755 index 0000000000..59a068d824 --- /dev/null +++ b/dev/compose/signing/setup_gpg_workarounds.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +DEFAULT_GNUPGHOME="$HOME/.gnupg" +CURRENT_GNUPGHOME="${GNUPGHOME:-$DEFAULT_GNUPGHOME}" + +# Remove both `.gnupg` and potential trailing `/` after `.gnupg` +CURRENT_HOME="${CURRENT_GNUPGHOME%/.gnupg/}" +CURRENT_HOME="${CURRENT_HOME%/.gnupg}" + +echo "$CURRENT_GNUPGHOME" > /etc/pulp/certs/GNUPGHOME.workaround.txt +echo "$CURRENT_HOME" > /etc/pulp/certs/HOME.workaround.txt diff --git a/dev/compose/signing/setup_repo_keyring.sh b/dev/compose/signing/setup_repo_keyring.sh new file mode 100755 index 0000000000..7eefc10b46 --- /dev/null +++ b/dev/compose/signing/setup_repo_keyring.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +for repo in staging published; do + pulpcore-manager set-repo-keyring --repository $repo --keyring /root/.gnupg/pubring.kbx -y; +done + diff --git a/dev/compose/signing/setup_signing_services.sh b/dev/compose/signing/setup_signing_services.sh new file mode 100755 index 0000000000..9de430badf --- /dev/null +++ b/dev/compose/signing/setup_signing_services.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# Collection +HAS_COLLECTION_SIGNING=$(pulpcore-manager shell -c 'from pulpcore.app.models import SigningService;print(SigningService.objects.filter(name="ansible-default").count())' 2>/dev/null || true) +if [[ "$HAS_COLLECTION_SIGNING" -eq "0" ]]; then + pulpcore-manager add-signing-service ansible-default /var/lib/pulp/scripts/collection_sign.sh F37575C52D4F16F3 +else + echo "Collection Signing Service Already exists" +fi + +# Container +HAS_CONTAINER_SIGNING=$(pulpcore-manager shell -c 'from pulpcore.app.models import SigningService;print(SigningService.objects.filter(name="container-default").count())' 2>/dev/null || true) +if [[ "$HAS_CONTAINER_SIGNING" -eq "0" ]]; then + pulpcore-manager add-signing-service container-default /var/lib/pulp/scripts/container_sign.sh F37575C52D4F16F3 --class container:ManifestSigningService +else + echo "Container Signing Service Already exists" +fi diff --git a/dev/compose/signing/signing-public.key b/dev/compose/signing/signing-public.key new file mode 100644 index 0000000000..5a27c5c58d --- /dev/null +++ b/dev/compose/signing/signing-public.key @@ -0,0 +1,18 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBGcBkDMBCADcXzLFpIHjlPSNtNsQBvtnRCcqBUKUk7Xz8eZIHVIOt6lF3TPN +ZMfyyPhaihLlKzJQdhzDoc3/hdTKRxfBltrff9nYx5dHWegomVL1i/S0HAB7MOqn +Sj1dErkQEPhYbno1VI5ml71LMeu/anDmEkEhtvkVcqWnXs6DiiudU0Tmc4W/+lVH +Cluk+ISkg1/3pxLAQjSiPpWg/YB/cNDcuuHxueC0KqIHgGIrx0iDI8Tq7KlNbcOV +Cyj0Xpcv653dDlJZAA9O/ljfleNa08NxspRBEoMXhIKuOL/owVY65ZDCBBgg5GGH +uKGnFBITmKd9dWUVRezj7sKu5p4ErATgRi7lABEBAAG0JkdhbGF4eSBEZXYgS2V5 +IDxnYWxheHlkZXZAYW5zaWJsZS5jb20+iQFRBBMBCAA7FiEE+4s/LSS8r37995Op +83V1xS1PFvMFAmcBkDMCGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQ +83V1xS1PFvPDmAgAwJJ/TPDrW9clGbObG6d3RTzM08R1Hvx1xRhpeWGB3uPag+zS +LmmgSHUskWWChRr1mcdIfH60HgdhR1PIk9sjKsTWorzS0Polit7Dd7pS+e1sFdGe +MFGX0ljDYF558yaX5NCVBstIaqxTuHc+SGOYT8/7w5P7/y7Li9OBO4vpPx6gq/RV +J1x6GnDELphGeyzAlPzevRwVr7h27kfIidI8vD2LYs3qV7scnOcW+hFcJ5utLee4 +4ia1BDCYDRgOgz4kMoz/rGQ4rR15aTclihc0+puZJrvsUQMPS1+q9XoJPJs+s+Gr +kY24YID/BNUXy0j/BR5vQQvCSCaWdBDGyFvV7A== +=0hZK +-----END PGP PUBLIC KEY BLOCK----- diff --git a/dev/compose/signing/signing-secret.key b/dev/compose/signing/signing-secret.key new file mode 100644 index 0000000000..3408182cc6 --- /dev/null +++ b/dev/compose/signing/signing-secret.key @@ -0,0 +1,33 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQPGBGcBkDMBCADcXzLFpIHjlPSNtNsQBvtnRCcqBUKUk7Xz8eZIHVIOt6lF3TPN +ZMfyyPhaihLlKzJQdhzDoc3/hdTKRxfBltrff9nYx5dHWegomVL1i/S0HAB7MOqn +Sj1dErkQEPhYbno1VI5ml71LMeu/anDmEkEhtvkVcqWnXs6DiiudU0Tmc4W/+lVH +Cluk+ISkg1/3pxLAQjSiPpWg/YB/cNDcuuHxueC0KqIHgGIrx0iDI8Tq7KlNbcOV +Cyj0Xpcv653dDlJZAA9O/ljfleNa08NxspRBEoMXhIKuOL/owVY65ZDCBBgg5GGH +uKGnFBITmKd9dWUVRezj7sKu5p4ErATgRi7lABEBAAH+BwMCHPHopLXNy/H5x9sv +w+Ca3lAqKjqFX0MTJElj5dOndRgdUh3oUAoYfSB6/F3OHGIl3zlKhh5QrP8UUFjb +PFZjJYVoEU+ymBNucXMLBAymRAb8FxsDD94G75TYZxg+PXjQCnUbBxeeFoYl5vA2 +35KMZpGAIzhhNAjZlyFoX7GiMqdWxaKuUkR+NAi7cEWjhrgTE8gTtPfDl8aWN0if +2b2Jl8YXXlG32P+YN4qn0P91Z/nRAHPnrm0wGbDtcFCPGLGl2wXtoY2eb/2gwruU +r0uh3LEXq/27G6EfgX5ADikmXI4W6VdyCkkIRjbAv7jfou3jEseiy1jI2oGCvWVn +k0y79g04oTSjDGadW0gvZbGA87HndnS7p7S0oVmPVuhzKot894VH3TCCr1V3nO+Z +y7FfjdCDkN9bZ4ijoI0aXdOGZD1lbRHlq2UCaCe9ZKy27xFpqnkqlfuk59wjmcVJ +xv+w11kPh1QW51xY5quv+CXKFd3DF1L9auRvRBJP+UZa6Qq/2w5YZVPKLj9VF5oS +4iQON3l/4casojT/s3F7N1+HfsSZH6y3+WFr9up806GUte8eQUiqHxAnKfKdoUC9 +6izFeGWi6AL57vEiLp939RWh5AERnLHHAp4KpR4fDbwoBREbgqtBe2FHCJCnhqVl +/E/1Ydle1bXV/swpPI5lsKqjf2EhKK2hFUTmBlDkQjfN4tVU1BvC6s7HGD/F0OQu +loZghUisN66t9cA0rZHYzvd0yIknglDXfjgzj+rdXaMoaqOKV8IgEa/SwdNjLw5A +m/dFXCfz3AuezjHrdAw8y1+F/wRlezySFRmd6REStMgHtWJeRgJiv42ZgktBJziL +a671wp6c8bV0Ataa43WIBu7KZbq6NuiJnkZHNI7BILpENA98yV6WNetCb7SsZ6OQ +lPdzW0wp9BILtCZHYWxheHkgRGV2IEtleSA8Z2FsYXh5ZGV2QGFuc2libGUuY29t +PokBUQQTAQgAOxYhBPuLPy0kvK9+/feTqfN1dcUtTxbzBQJnAZAzAhsDBQsJCAcC +AiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEPN1dcUtTxbzw5gIAMCSf0zw61vXJRmz +mxund0U8zNPEdR78dcUYaXlhgd7j2oPs0i5poEh1LJFlgoUa9ZnHSHx+tB4HYUdT +yJPbIyrE1qK80tD6JYrew3e6UvntbBXRnjBRl9JYw2BeefMml+TQlQbLSGqsU7h3 +PkhjmE/P+8OT+/8uy4vTgTuL6T8eoKv0VSdcehpwxC6YRnsswJT83r0cFa+4du5H +yInSPLw9i2LN6le7HJznFvoRXCebrS3nuOImtQQwmA0YDoM+JDKM/6xkOK0deWk3 +JYoXNPqbmSa77FEDD0tfqvV6CTybPrPhq5GNuGCA/wTVF8tI/wUeb0ELwkgmlnQQ +xshb1ew= +=hw1Q +-----END PGP PRIVATE KEY BLOCK----- diff --git a/dev/compose/signing/signing-secret.key.password.txt b/dev/compose/signing/signing-secret.key.password.txt new file mode 100644 index 0000000000..7e0c21b8b5 --- /dev/null +++ b/dev/compose/signing/signing-secret.key.password.txt @@ -0,0 +1 @@ +Galaxy2024 diff --git a/dev/compose/standalone.yaml b/dev/compose/standalone.yaml new file mode 100644 index 0000000000..d1b5685268 --- /dev/null +++ b/dev/compose/standalone.yaml @@ -0,0 +1,309 @@ +x-common-env: &common-env + + GNUPGHOME: /root/.gnupg/ + + DJANGO_SUPERUSER_USERNAME: admin + DJANGO_SUPERUSER_EMAIL: admin@example.com + DJANGO_SUPERUSER_PASSWORD: admin + + POSTGRES_USER: galaxy_ng + POSTGRES_PASSWORD: galaxy_ng + POSTGRES_DB: galaxy_ng + + # no spying + PULP_ANALYTICS: 'false' + + # normally goes into settings.py ... + PULP_DATABASES__default__ENGINE: django.db.backends.postgresql + PULP_DATABASES__default__NAME: galaxy_ng + PULP_DATABASES__default__USER: galaxy_ng + PULP_DATABASES__default__PASSWORD: galaxy_ng + PULP_DATABASES__default__HOST: postgres + PULP_DATABASES__default__PORT: 5432 + + PULP_DEBUG: 1 + PULP_GALAXY_DEPLOYMENT_MODE: 'standalone' + PULP_DEFAULT_FILE_STORAGE: "pulpcore.app.models.storage.FileSystem" + PULP_REDIRECT_TO_OBJECT_STORAGE: 'false' + + # Hostname and prefix has to be correct + PULP_GALAXY_API_PATH_PREFIX: '/api/galaxy/' + PULP_CONTENT_PATH_PREFIX: '/pulp/content/' + PULP_ANSIBLE_API_HOSTNAME: 'http://localhost:5001' + PULP_ANSIBLE_CONTENT_HOSTNAME: "http://localhost:5001" + PULP_CONTENT_ORIGIN: "http://localhost:5001" + PULP_CSRF_TRUSTED_ORIGINS: "['http://localhost']" + + # signing ... + PULP_GALAXY_AUTO_SIGN_COLLECTIONS: 'false' + PULP_GALAXY_REQUIRE_CONTENT_APPROVAL: 'true' + PULP_GALAXY_REQUIRE_SIGNATURE_FOR_APPROVAL: 'false' + PULP_GALAXY_COLLECTION_SIGNING_SERVICE: 'ansible-default' + PULP_GALAXY_CONTAINER_SIGNING_SERVICE: 'container-default' + + # pulp container ... + PULP_TOKEN_AUTH_DISABLED: 'false' + PULP_TOKEN_SERVER: 'http://localhost:5001/token/' + PULP_TOKEN_SIGNATURE_ALGORITHM: 'ES256' + PULP_PUBLIC_KEY_PATH: '/src/galaxy_ng/dev/common/container_auth_public_key.pem' + PULP_PRIVATE_KEY_PATH: '/src/galaxy_ng/dev/common/container_auth_private_key.pem' + + # auth ... + PULP_GALAXY_AUTHENTICATION_CLASSES: "['rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.BasicAuthentication']" + PULP_ANSIBLE_BASE_JWT_VALIDATE_CERT: 'false' + PULP_ANSIBLE_BASE_JWT_KEY: 'https://localhost' + PULP_GALAXY_FEATURE_FLAGS__external_authentication: 'true' + + # disable user/group modifications + PULP_ALLOW_LOCAL_RESOURCE_MANAGEMENT: 'true' + + # role content workaround .. + PULP_ANSIBLE_BASE_ROLES_REQUIRE_VIEW: 'false' + + # Resource server + # This disables the attempt for resource syncing + PULP_RESOURCE_SERVER_SYNC_ENABLED: 'false' + # Set above to 'true' if/when RESOURCE_SERVER is configured + # The next variables must be configured to enable resource sync + # PULP_RESOURCE_SERVER__URL='https://localhost' + # PULP_RESOURCE_SERVER__SECRET_KEY='?' + # PULP_RESOURCE_SERVER__VALIDATE_HTTPS='false' + + # Integration test settings + HUB_API_ROOT: 'http://localhost:5001/api/galaxy/' + HUB_TEST_MARKS: deployment_standalone or all + HUB_USE_MOVE_ENDPOINT: 'true' + CONTAINER_REGISTRY: 'localhost:5001' + + # Unpin dependencies on setup.py if set to 0 + LOCK_REQUIREMENTS: 0 + + # DEV EDITABLE STUFF + # To enable editable installs of local checkouts set DEV_SOURCE_PATH keeping the ordering as follows: + # "dynaconf:pulpcore:galaxy_importer:pulp_ansible:pulp_container:galaxy_ng:django-ansible-base" + # This can be done as part of the `docker compose` call: + # $ DEV_SOURCE_PATH="pulp_container:galaxy_ng" docker compose -f dev/compose/standalone.yaml up + DEV_SOURCE_PATH: + +# allow attaching to the running container +x-debugging: &debugging + stdin_open: true + tty: true + +services: + base_img: + build: + context: ../../ + dockerfile: Dockerfile + image: "localhost/galaxy_ng/galaxy_ng:base" + + base_img_dev: # Extends base_img with extra files and dev tools + depends_on: + - base_img + build: + context: . + dockerfile: Dockerfile.dev + args: + <<: *common-env + image: "localhost/galaxy_ng/galaxy_ng:dev" + + redis: + image: "redis:5" + + postgres: + image: "postgres:13" + ports: + - '5433:5432' + environment: + <<: *common-env + healthcheck: + test: ["CMD", "pg_isready", "-U", "galaxy_ng"] + interval: 10s + retries: 5 + # Uncomment below to spam out every DB statement to the service stderr + # WARNING: enabling log_statement=all makes database slower + # command: ["postgres", "-c", "log_statement=ddl", "-c", "log_destination=stderr"] + + migrations: + image: "localhost/galaxy_ng/galaxy_ng:dev" + depends_on: + - base_img_dev + - postgres + volumes: + - "etc_pulp_certs:/etc/pulp/certs" + - "var_lib_pulp_standalone:/var/lib/pulp" + - "../../../:/src" + - "../../:/app" + environment: + <<: *common-env + user: root + <<: *debugging + command: | + bash -c " + set -e; + rm -rf /var/lib/pulp/.migrated; + /src/galaxy_ng/dev/compose/bin/devinstall; + + pulpcore-manager check --database default; + pulpcore-manager migrate; + pulpcore-manager shell < /src/galaxy_ng/dev/common/setup_test_data.py; + pulpcore-manager createsuperuser --noinput || true; + + touch /var/lib/pulp/.migrated; + " + + api: + image: "localhost/galaxy_ng/galaxy_ng:dev" + depends_on: + - base_img_dev + - postgres + - migrations + volumes: + - "etc_pulp_certs:/etc/pulp/certs" + - "var_lib_pulp_standalone:/var/lib/pulp" + - "../../../:/src" + - "../../:/app" + environment: + <<: *common-env + extra_hosts: + localhost: "host-gateway" + networks: + - default + - service-mesh + user: root + <<: *debugging + command: | + bash -c " + /src/galaxy_ng/dev/compose/bin/devinstall; + /src/galaxy_ng/dev/compose/bin/wait /var/lib/pulp/.migrated; + + /src/galaxy_ng/dev/compose/bin/reloader /src/galaxy_ng/dev/compose/bin/pulpcore-api + " + + content: + image: "localhost/galaxy_ng/galaxy_ng:dev" + depends_on: + - base_img_dev + - postgres + - migrations + volumes: + - "etc_pulp_certs:/etc/pulp/certs" + - "var_lib_pulp_standalone:/var/lib/pulp" + - "../../../:/src" + - "../../:/app" + environment: + <<: *common-env + extra_hosts: + localhost: "host-gateway" + networks: + - default + - service-mesh + user: root + <<: *debugging + command: | + bash -c " + /src/galaxy_ng/dev/compose/bin/devinstall; + /src/galaxy_ng/dev/compose/bin/wait /var/lib/pulp/.migrated; + + /src/galaxy_ng/dev/compose/bin/reloader /src/galaxy_ng/dev/compose/bin/pulpcore-content + " + + worker: + image: "localhost/galaxy_ng/galaxy_ng:dev" + depends_on: + - base_img_dev + - postgres + - migrations + volumes: + - "etc_pulp_certs:/etc/pulp/certs" + - "var_lib_pulp_standalone:/var/lib/pulp" + - "../../../:/src" + - "../../:/app" + environment: + <<: *common-env + user: root + <<: *debugging + command: | + bash -c " + /src/galaxy_ng/dev/compose/bin/devinstall; + /src/galaxy_ng/dev/compose/bin/wait /var/lib/pulp/.migrated; + + # Worker needs gpg in order to consume signing tasks; + gpg --list-secret-keys; + + /src/galaxy_ng/dev/compose/bin/reloader /venv/bin/pulpcore-worker + " + + manager: + image: "localhost/galaxy_ng/galaxy_ng:dev" + depends_on: + - base_img_dev + - postgres + - migrations + - worker + volumes: + - "etc_pulp_certs:/etc/pulp/certs" + - "var_lib_pulp_standalone:/var/lib/pulp" + - "../../../:/src" + - "../../:/app" + environment: + <<: *common-env + user: root + <<: *debugging + command: | + bash -c " + /src/galaxy_ng/dev/compose/bin/devinstall; + /src/galaxy_ng/dev/compose/bin/wait /var/lib/pulp/.migrated; + + # Give some time for API to start; + sleep 5; + + # Setup signing services; + gpg --list-secret-keys; + /src/galaxy_ng/dev/compose/signing/setup_signing_services.sh; + echo 'Signing Services'; + curl -s -u $$DJANGO_SUPERUSER_USERNAME:$$DJANGO_SUPERUSER_PASSWORD http://api:24817/api/galaxy/pulp/api/v3/signing-services/?fields=name,script,pubkey_fingerprint | python -m json.tool; + + # Setup repository gpgkey for upload verification; + /src/galaxy_ng/dev/compose/signing/setup_repo_keyring.sh; + + echo ' '; + echo '###################### API ROOT ##############################'; + curl -s -u $$DJANGO_SUPERUSER_USERNAME:$$DJANGO_SUPERUSER_PASSWORD http://api:24817/api/galaxy/ | python -m json.tool; + echo '################### DEV_SOURCE_PATH ##########################'; + echo $$DEV_SOURCE_PATH; + echo ' '; + echo '######################## READY ###############################'; + echo ' '; + echo 'Credentials: ' $$DJANGO_SUPERUSER_USERNAME:$$DJANGO_SUPERUSER_PASSWORD; + echo 'API Spec: http://localhost:5001/api/galaxy/v3/swagger-ui/'; + echo 'Django Admin: docker compose -f dev/compose/standalone.yaml exec manager pulpcore-manager'; + echo 'Settings list: docker compose -f dev/compose/standalone.yaml exec manager dynaconf list'; + echo 'Docs: https://github.com/ansible/galaxy_ng/blob/master/dev/compose/README.md'; + echo '##############################################################'; + + # Keep it running indefinitely to enable `docker compose -f ... exec manager /bin/bash`; + tail -f /dev/null + " + + nginx: + image: "nginx:latest" + depends_on: + - postgres + - migrations + - api + - content + ports: + - '5001:5001' + volumes: + - '../nginx/nginx.conf:/etc/nginx/nginx.conf:ro' + +volumes: + var_lib_pulp_standalone: + name: var_lib_pulp_standalone + etc_pulp_certs: + name: etc_pulp_certs + +networks: + service-mesh: + name: service-mesh diff --git a/dev/nginx/nginx.conf b/dev/nginx/nginx.conf new file mode 100644 index 0000000000..73f91b11d4 --- /dev/null +++ b/dev/nginx/nginx.conf @@ -0,0 +1,92 @@ +# TODO: Support IPv6. +# TODO: Maybe serve multiple `location`s, not just one. + +# The "nginx" package on fedora creates this user and group. +# user nginx nginx; + +# Gunicorn docs suggest this value. +worker_processes 1; +# daemon off; +events { + worker_connections 1024; # increase if you have lots of clients + accept_mutex off; # set to 'on' if nginx worker_processes > 1 +} + +http { + include mime.types; + # fallback in case we can't determine a type + default_type application/octet-stream; + sendfile on; + + # If left at the default of 1024, nginx emits a warning about being unable + # to build optimal hash types. + types_hash_max_size 4096; + + upstream pulp-content { + server content:24816; + } + + upstream pulp-api { + server api:24817; + } + + server { + # Gunicorn docs suggest the use of the "deferred" directive on Linux. + listen 5001 default_server deferred; + server_name $hostname; + + # The default client_max_body_size is 1m. Clients uploading + # files larger than this will need to chunk said files. + client_max_body_size 10m; + + # Gunicorn docs suggest this value. + keepalive_timeout 5; + + location /pulp/content/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + # we don't want nginx trying to do something clever with + # redirects, we set the Host: header above already. + proxy_redirect off; + proxy_pass http://pulp-content; + } + + location /api/galaxy/api/v3/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + # we don't want nginx trying to do something clever with + # redirects, we set the Host: header above already. + proxy_redirect off; + proxy_pass http://pulp-api; + client_max_body_size 0; + } + + location /auth/login/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + # we don't want nginx trying to do something clever with + # redirects, we set the Host: header above already. + proxy_redirect off; + proxy_pass http://pulp-api; + } + + # include pulp/*.conf; + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + # we don't want nginx trying to do something clever with + # redirects, we set the Host: header above already. + proxy_redirect off; + proxy_pass http://pulp-api; + # most pulp static files are served through whitenoise + # http://whitenoise.evans.io/en/stable/ + } + + } +} +