diff --git a/.github/skills/dev/git-workflow/release-new-version/skill.md b/.github/skills/dev/git-workflow/release-new-version/skill.md index 48e99b5e9..410b225ee 100644 --- a/.github/skills/dev/git-workflow/release-new-version/skill.md +++ b/.github/skills/dev/git-workflow/release-new-version/skill.md @@ -40,22 +40,35 @@ Before starting: - [ ] Clean working tree (`git status`) - [ ] Up to date with `origin/main` - [ ] GitHub environment `dockerhub-torrust` configured -- [ ] GitHub environment `crates-io` configured with `CARGO_REGISTRY_TOKEN` +- [ ] GitHub environment `crates-io` configured with `CARGO_REGISTRY_TOKEN` scoped to + **all four** crate names (`torrust-tracker-deployer-types`, + `torrust-tracker-deployer-dependency-installer`, `torrust-tracker-deployer`, + `torrust-tracker-deployer-sdk`) β€” a token scoped to only one will cause 403 on the others - [ ] Releaser has permissions for `main`, tags, and release branches +- [ ] All four `Cargo.toml` files have `description`, `license`, `repository`, `readme` +- [ ] Every internal path dependency also declares an explicit `version` constraint +- [ ] `Cargo.lock` is committed and up to date ## Commands ### 1) Update versions -Update `version` in: +Update `version` in all four manifests, and update the `version` constraint on every +internal path dependency in each file: - `Cargo.toml` +- `packages/deployer-types/Cargo.toml` +- `packages/dependency-installer/Cargo.toml` - `packages/sdk/Cargo.toml` ### 2) Commit and push ```bash -git add Cargo.toml packages/sdk/Cargo.toml +git add Cargo.toml \ + packages/deployer-types/Cargo.toml \ + packages/dependency-installer/Cargo.toml \ + packages/sdk/Cargo.toml \ + Cargo.lock git commit -S -m "release: version vX.Y.Z" git push origin main ``` @@ -72,8 +85,15 @@ git push origin releases/vX.Y.Z ### 4) Verify workflows -- Container workflow: publishes Docker image from release branch -- Publish Crate workflow: publishes `torrust-tracker-deployer-sdk` +- **Container** workflow: publishes Docker image from release branch +- **Publish Crate** workflow: publishes all four crates in dependency order: + 1. `torrust-tracker-deployer-types` + 2. `torrust-tracker-deployer-dependency-installer` + 3. `torrust-tracker-deployer` + 4. `torrust-tracker-deployer-sdk` + + Each crate's dry-run runs only after its prerequisites are indexed on crates.io. + Do not attempt to publish out of order. Workflow files: diff --git a/.github/skills/dev/testing/run-local-e2e-test/skill.md b/.github/skills/dev/testing/run-local-e2e-test/skill.md index aed47156d..af0329e63 100644 --- a/.github/skills/dev/testing/run-local-e2e-test/skill.md +++ b/.github/skills/dev/testing/run-local-e2e-test/skill.md @@ -21,13 +21,13 @@ This skill walks you through a complete manual end-to-end test of the deployer u ```bash # Verify all required tools are installed -cargo run -p torrust-dependency-installer --bin dependency-installer -- check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- check # Install missing tools (LXD, OpenTofu, Ansible, Docker) -cargo run -p torrust-dependency-installer --bin dependency-installer -- install +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install ``` -> **Note**: `cargo run --bin dependency-installer` does not work from the workspace root because the binary lives in a sub-package. Always use `-p torrust-dependency-installer`. +> **Note**: `cargo run --bin dependency-installer` does not work from the workspace root because the binary lives in a sub-package. Always use `-p torrust-tracker-deployer-dependency-installer`. ## Complete Workflow diff --git a/.github/skills/usage/operations/check-system-dependencies/skill.md b/.github/skills/usage/operations/check-system-dependencies/skill.md index a8f8f9f29..e89f8ed85 100644 --- a/.github/skills/usage/operations/check-system-dependencies/skill.md +++ b/.github/skills/usage/operations/check-system-dependencies/skill.md @@ -14,16 +14,16 @@ Use the built-in `dependency-installer` package to verify all required tools are ```bash # Check all dependencies -cargo run -p torrust-dependency-installer --bin dependency-installer check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check # Check a specific dependency -cargo run -p torrust-dependency-installer --bin dependency-installer check --dependency opentofu +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check --dependency opentofu # List all dependencies with status -cargo run -p torrust-dependency-installer --bin dependency-installer list +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer list # Install all missing dependencies -cargo run -p torrust-dependency-installer --bin dependency-installer install +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer install ``` ## Required Dependencies @@ -60,7 +60,7 @@ ERROR ... dependency is not installed dependency="opentofu" - In CI/CD pipelines use `--log-level off` to suppress output and rely on exit code only: ```bash - cargo run -p torrust-dependency-installer --bin dependency-installer check --log-level off + cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check --log-level off ``` - To install missing tools automatically, use the `install` subcommand (requires system package manager access) diff --git a/.github/skills/usage/operations/install-system-dependencies/skill.md b/.github/skills/usage/operations/install-system-dependencies/skill.md index 2a3791b7f..ddb5c966b 100644 --- a/.github/skills/usage/operations/install-system-dependencies/skill.md +++ b/.github/skills/usage/operations/install-system-dependencies/skill.md @@ -14,26 +14,26 @@ Use the built-in `dependency-installer` package to install all tools required to ```bash # 1. Check what is already installed -cargo run -p torrust-dependency-installer --bin dependency-installer check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check # 2. Install everything missing in one command -cargo run -p torrust-dependency-installer --bin dependency-installer install +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer install # 3. Verify all dependencies are now present -cargo run -p torrust-dependency-installer --bin dependency-installer check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check ``` ## Commands ```bash # Install all missing dependencies -cargo run -p torrust-dependency-installer --bin dependency-installer install +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer install # Install a specific dependency -cargo run -p torrust-dependency-installer --bin dependency-installer install --dependency opentofu +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer install --dependency opentofu # Install with verbose output (shows download/install steps) -cargo run -p torrust-dependency-installer --bin dependency-installer install --verbose +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer install --verbose ``` ## Dependencies Installed diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..c1a60f39c --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,91 @@ +name: "CodeQL Advanced" + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + schedule: + - cron: "24 23 * * 5" + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + include: + - language: actions + build-mode: none + - language: rust + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Add any setup steps before running the `github/codeql-action/init` action. + # This includes steps like installing compilers or runtimes (`actions/setup-node` + # or others). This is typically only required for manual builds. + # - name: Setup runtime (example) + # uses: actions/setup-example@v1 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: + # https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # ℹ️ Command-line programs to run using the OS shell. + # πŸ“š See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - name: Run manual build steps + if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/container.yaml b/.github/workflows/container.yaml index 45884475d..83704aabe 100644 --- a/.github/workflows/container.yaml +++ b/.github/workflows/container.yaml @@ -10,7 +10,7 @@ # # Publishing: # - Images are pushed to Docker Hub on push to main/develop/release branches (not PRs) -# - Release branches (releases/vX.Y.Z) publish versioned Docker tags (X.Y.Z) +# - Release branches (releases/vX.Y.Z or releases/vX.Y.Z-pre.N) publish versioned Docker tags # - Release Docker tags use bare semver without the v prefix # - Requires Docker Hub credentials in the dockerhub-torrust GitHub Environment @@ -22,12 +22,6 @@ on: - "develop" - "main" - "releases/**/*" - paths: - - "src/**" - - "Cargo.toml" - - "Cargo.lock" - - "docker/deployer/**" - - ".github/workflows/container.yaml" pull_request: branches: @@ -117,7 +111,7 @@ jobs: elif [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then echo "type=develop" >> $GITHUB_OUTPUT echo "continue=true" >> $GITHUB_OUTPUT - elif [[ $(echo "${{ github.ref }}" | grep -P '^refs/heads/releases/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$') ]]; then + elif [[ $(echo "${{ github.ref }}" | grep -P '^refs/heads/releases/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[a-zA-Z0-9][a-zA-Z0-9.-]*)?$') ]]; then version=$(echo "${{ github.ref }}" | sed -n -E 's/^refs\/heads\/releases\///p') echo "version=$version" >> $GITHUB_OUTPUT echo "type=release" >> $GITHUB_OUTPUT @@ -132,7 +126,7 @@ jobs: fi publish: - name: Publish (${{ needs.context.outputs.type }}) + name: Publish Image environment: dockerhub-torrust needs: context if: needs.context.outputs.continue == 'true' diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 42e20526b..adb340182 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -35,7 +35,7 @@ jobs: - name: Build dependency-installer binary run: | - cargo build --release -p torrust-dependency-installer --bin dependency-installer + cargo build --release -p torrust-tracker-deployer-dependency-installer --bin dependency-installer - name: Install all development dependencies run: | diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 359aac390..ed75d1fa2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -38,7 +38,7 @@ jobs: name: Build All Binaries run: | cargo build --bins - cargo build -p torrust-dependency-installer --bin dependency-installer + cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer - id: coverage-text name: Generate Text Coverage Summary diff --git a/.github/workflows/docker-security-scan.yml b/.github/workflows/docker-security-scan.yml index e79662594..c592eae56 100644 --- a/.github/workflows/docker-security-scan.yml +++ b/.github/workflows/docker-security-scan.yml @@ -101,7 +101,7 @@ jobs: timeout-minutes: 10 outputs: # JSON array of Docker image references for use in scan matrix - # Example: ["torrust/tracker:develop","mysql:8.4","prom/prometheus:v3.5.1","grafana/grafana:12.4.2","caddy:2.10.2"] + # Example: ["torrust/tracker:develop","mysql:8.4","prom/prometheus:v3.11.2","grafana/grafana:13.0.0","caddy:2.11.2"] images: ${{ steps.extract.outputs.images }} steps: @@ -182,7 +182,7 @@ jobs: .docker_images.mysql, .docker_images.prometheus, .docker_images.grafana - ] | map(select(. != null)) + ["caddy:2.10.2"]') + ] | map(select(. != null)) + ["caddy:2.11.2"]') echo "Detected images: $images" echo "images=$images" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/publish-crate.yaml b/.github/workflows/publish-crate.yaml index 6a5da8ce6..eb736ebe5 100644 --- a/.github/workflows/publish-crate.yaml +++ b/.github/workflows/publish-crate.yaml @@ -1,7 +1,12 @@ -# Crate publication workflow for Torrust Tracker Deployer SDK +# Crate publication workflow for Torrust Tracker Deployer # -# This workflow publishes the SDK crate when a release branch is pushed. -# Trigger branch format: releases/vX.Y.Z +# Publishes all four workspace crates in dependency order when a release branch is pushed: +# 1. torrust-tracker-deployer-types (no internal deps) +# 2. torrust-tracker-deployer-dependency-installer (no internal deps) +# 3. torrust-tracker-deployer (depends on 1 and 2) +# 4. torrust-tracker-deployer-sdk (depends on 1 and 3) +# +# Trigger branch format: releases/vX.Y.Z or releases/vX.Y.Z-pre.N (pre-release) name: Publish Crate @@ -9,23 +14,21 @@ on: push: branches: - "releases/**/*" - paths: - - "Cargo.toml" - - "Cargo.lock" - - "packages/sdk/**" - - ".github/workflows/publish-crate.yaml" workflow_dispatch: env: CARGO_TERM_COLOR: always - CRATE_NAME: torrust-tracker-deployer-sdk + DEPLOYER_TYPES_CRATE: torrust-tracker-deployer-types + DEPENDENCY_INSTALLER_CRATE: torrust-tracker-deployer-dependency-installer + MAIN_CRATE: torrust-tracker-deployer + SDK_CRATE: torrust-tracker-deployer-sdk jobs: - publish_sdk: - name: Publish SDK Crate + publish_all: + name: Publish All Crates environment: crates-io runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 60 steps: - name: Checkout Repository @@ -42,87 +45,178 @@ jobs: - name: Extract Release Version id: release run: | - if [[ "${{ github.ref_name }}" =~ ^releases/v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then + if [[ "${{ github.ref_name }}" =~ ^releases/v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[a-zA-Z0-9][a-zA-Z0-9.-]*)?$ ]]; then version="${GITHUB_REF_NAME#releases/v}" echo "version=$version" >> "$GITHUB_OUTPUT" else echo "Invalid release branch name: ${{ github.ref_name }}" >&2 - echo "Expected format: releases/vX.Y.Z" >&2 + echo "Expected format: releases/vX.Y.Z or releases/vX.Y.Z-pre.N" >&2 exit 1 fi - - name: Verify Release Version Matches Cargo Manifests + - name: Verify Release Version Matches All Cargo Manifests run: | + release_version="${{ steps.release.outputs.version }}" + root_version=$(grep '^version = ' Cargo.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/') sdk_version=$(grep '^version = ' packages/sdk/Cargo.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/') - release_version="${{ steps.release.outputs.version }}" + types_version=$(grep '^version = ' packages/deployer-types/Cargo.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/') + installer_version=$(grep '^version = ' packages/dependency-installer/Cargo.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/') + + for pair in "Root:$root_version" "SDK:$sdk_version" "DeployerTypes:$types_version" "DependencyInstaller:$installer_version"; do + label="${pair%%:*}" + version="${pair#*:}" + if [[ "$version" != "$release_version" ]]; then + echo "$label Cargo.toml version mismatch: $version != $release_version" >&2 + exit 1 + fi + done - if [[ "$root_version" != "$release_version" ]]; then - echo "Root Cargo.toml version mismatch: $root_version != $release_version" >&2 - exit 1 - fi + - name: Verify Crates.io Metadata for All Crates + run: | + for manifest in Cargo.toml packages/sdk/Cargo.toml packages/deployer-types/Cargo.toml packages/dependency-installer/Cargo.toml; do + for field in description license repository readme; do + if ! grep -q "^$field = " "$manifest"; then + echo "Missing required field '$field' in $manifest" >&2 + exit 1 + fi + done + done - if [[ "$sdk_version" != "$release_version" ]]; then - echo "SDK Cargo.toml version mismatch: $sdk_version != $release_version" >&2 - exit 1 - fi + - name: Run All Tests + run: cargo test - - name: Verify SDK Metadata + - name: Inspect Packaged Files run: | - for field in description license repository readme; do - if ! grep -q "^$field = " packages/sdk/Cargo.toml; then - echo "Missing required field in packages/sdk/Cargo.toml: $field" >&2 + for crate in \ + "${{ env.DEPLOYER_TYPES_CRATE }}" \ + "${{ env.DEPENDENCY_INSTALLER_CRATE }}" \ + "${{ env.MAIN_CRATE }}" \ + "${{ env.SDK_CRATE }}"; do + echo "=== Packaged files for $crate ===" + cargo package --list -p "$crate" + done + + - name: Dry Run Publish torrust-tracker-deployer-types + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish --dry-run -p ${{ env.DEPLOYER_TYPES_CRATE }} + + - name: Check If Versions Already Published + run: | + release_version="${{ steps.release.outputs.version }}" + for crate in \ + "${{ env.DEPLOYER_TYPES_CRATE }}" \ + "${{ env.DEPENDENCY_INSTALLER_CRATE }}" \ + "${{ env.MAIN_CRATE }}" \ + "${{ env.SDK_CRATE }}"; do + set +e + http_status=$(curl -s -o /tmp/crate-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/$crate/$release_version") + set -e + if [[ "$http_status" == "200" ]]; then + echo "Already published: $crate $release_version β€” do not republish, cut a patch release instead." >&2 exit 1 fi done - - name: Run SDK Tests - run: cargo test -p ${{ env.CRATE_NAME }} + - name: Publish torrust-tracker-deployer-types + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish -p ${{ env.DEPLOYER_TYPES_CRATE }} - - name: Inspect Packaged Files - run: cargo package --list -p ${{ env.CRATE_NAME }} + - name: Wait for torrust-tracker-deployer-types to Be Indexed + run: | + release_version="${{ steps.release.outputs.version }}" + for attempt in $(seq 1 10); do + status=$(curl -s -o /tmp/crate-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.DEPLOYER_TYPES_CRATE }}/$release_version") + if [[ "$status" == "200" ]]; then + echo "${{ env.DEPLOYER_TYPES_CRATE }} $release_version is indexed on crates.io" + break + fi + echo "Waiting for crates.io index (attempt $attempt/10)..." + sleep 20 + done + + - name: Dry Run Publish torrust-tracker-deployer-dependency-installer + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish --dry-run -p ${{ env.DEPENDENCY_INSTALLER_CRATE }} - - name: Dry Run Publish + - name: Publish torrust-tracker-deployer-dependency-installer env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish --dry-run -p ${{ env.CRATE_NAME }} + run: cargo publish -p ${{ env.DEPENDENCY_INSTALLER_CRATE }} - - name: Check If Version Already Published + - name: Wait for torrust-tracker-deployer-dependency-installer to Be Indexed run: | - set +e - http_status=$(curl -s -o /tmp/crate-version.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.CRATE_NAME }}/${{ steps.release.outputs.version }}") - set -e + release_version="${{ steps.release.outputs.version }}" + for attempt in $(seq 1 10); do + status=$(curl -s -o /tmp/crate-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.DEPENDENCY_INSTALLER_CRATE }}/$release_version") + if [[ "$status" == "200" ]]; then + echo "${{ env.DEPENDENCY_INSTALLER_CRATE }} $release_version is indexed on crates.io" + break + fi + echo "Waiting for crates.io index update (attempt $attempt/10)..." + sleep 20 + done - if [[ "$http_status" == "200" ]]; then - echo "Crate version already published: ${{ env.CRATE_NAME }} ${{ steps.release.outputs.version }}" >&2 - echo "Do not republish. Cut a follow-up patch release instead." >&2 - exit 1 - fi + - name: Dry Run Publish torrust-tracker-deployer + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish --dry-run -p ${{ env.MAIN_CRATE }} + + - name: Publish torrust-tracker-deployer + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish -p ${{ env.MAIN_CRATE }} + + - name: Wait for torrust-tracker-deployer to Be Indexed + run: | + release_version="${{ steps.release.outputs.version }}" + for attempt in $(seq 1 10); do + status=$(curl -s -o /tmp/crate-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.MAIN_CRATE }}/$release_version") + if [[ "$status" == "200" ]]; then + echo "${{ env.MAIN_CRATE }} $release_version is indexed on crates.io" + break + fi + echo "Waiting for crates.io index update (attempt $attempt/10)..." + sleep 20 + done - - name: Publish Crate + - name: Dry Run Publish torrust-tracker-deployer-sdk env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish -p ${{ env.CRATE_NAME }} + run: cargo publish --dry-run -p ${{ env.SDK_CRATE }} - - name: Verify Crate Is Available + - name: Publish torrust-tracker-deployer-sdk + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish -p ${{ env.SDK_CRATE }} + + - name: Verify SDK Is Available on crates.io run: | - for attempt in 1 2 3 4 5; do - status=$(curl -s -o /tmp/crate-publish-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.CRATE_NAME }}/${{ steps.release.outputs.version }}") + release_version="${{ steps.release.outputs.version }}" + for attempt in $(seq 1 30); do + status=$(curl -s -o /tmp/crate-publish-check.json -w "%{http_code}" "https://crates.io/api/v1/crates/${{ env.SDK_CRATE }}/$release_version") if [[ "$status" == "200" ]]; then - echo "Crate is available on crates.io" + echo "SDK crate is available on crates.io" exit 0 fi - echo "Waiting for crates.io index update (attempt $attempt/5)..." - sleep 10 + echo "Waiting for crates.io index update (attempt $attempt/30)..." + sleep 20 done - echo "Crate was published but not visible yet. Check crates.io manually." >&2 - exit 1 + # crates.io indexing can be slow under load. The cargo publish step above + # already returned zero β€” the crate is published. This check is best-effort. + echo "SDK crate not yet visible after 10 minutes β€” verify manually:" >&2 + echo " https://crates.io/crates/${{ env.SDK_CRATE }}/$release_version" >&2 + echo "This is expected on slow crates.io days; it does not mean the publish failed." + exit 0 - - name: Verify docs.rs Build + - name: Verify docs.rs Build for SDK run: | - docs_url="https://docs.rs/${{ env.CRATE_NAME }}/${{ steps.release.outputs.version }}" - for attempt in 1 2 3 4 5 6; do + docs_url="https://docs.rs/${{ env.SDK_CRATE }}/${{ steps.release.outputs.version }}" + for attempt in $(seq 1 6); do status=$(curl -s -o /tmp/docs-rs-check.html -w "%{http_code}" "$docs_url") if [[ "$status" == "200" ]]; then echo "docs.rs page is available: $docs_url" @@ -134,4 +228,5 @@ jobs: echo "docs.rs page is not available yet: $docs_url" >&2 echo "The crate may still be building on docs.rs; verify manually later." >&2 - exit 1 + echo "This is expected shortly after a first publish. Verify manually: $docs_url" + exit 0 diff --git a/.github/workflows/test-dependency-installer.yml b/.github/workflows/test-dependency-installer.yml index e23b76c5e..54d12334d 100644 --- a/.github/workflows/test-dependency-installer.yml +++ b/.github/workflows/test-dependency-installer.yml @@ -48,7 +48,7 @@ jobs: - name: Build dependency-installer binary run: | echo "πŸ”¨ Building dependency-installer binary..." - cargo build --release -p torrust-dependency-installer --bin dependency-installer + cargo build --release -p torrust-tracker-deployer-dependency-installer --bin dependency-installer echo "βœ… Binary built successfully" - name: Install all development dependencies diff --git a/.github/workflows/test-e2e-deployment.yml b/.github/workflows/test-e2e-deployment.yml index b3d0e2e18..9c8df0f17 100644 --- a/.github/workflows/test-e2e-deployment.yml +++ b/.github/workflows/test-e2e-deployment.yml @@ -43,8 +43,8 @@ jobs: - name: Install dependencies run: | - cargo build -p torrust-dependency-installer --bin dependency-installer - cargo run -p torrust-dependency-installer --bin dependency-installer -- install + cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer + cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install - name: Setup Docker uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/test-e2e-infrastructure.yml b/.github/workflows/test-e2e-infrastructure.yml index 8d870715f..0b949d84b 100644 --- a/.github/workflows/test-e2e-infrastructure.yml +++ b/.github/workflows/test-e2e-infrastructure.yml @@ -39,8 +39,8 @@ jobs: - name: Install dependencies run: | - cargo build -p torrust-dependency-installer --bin dependency-installer - cargo run -p torrust-dependency-installer --bin dependency-installer -- install + cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer + cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install - name: Verify installations run: | diff --git a/.github/workflows/test-lxd-provision.yml b/.github/workflows/test-lxd-provision.yml index ab6661bf5..0f405cbd6 100644 --- a/.github/workflows/test-lxd-provision.yml +++ b/.github/workflows/test-lxd-provision.yml @@ -54,8 +54,8 @@ jobs: - name: Install dependencies run: | - cargo build -p torrust-dependency-installer --bin dependency-installer - cargo run -p torrust-dependency-installer --bin dependency-installer -- install + cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer + cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install - name: Render template configurations run: | diff --git a/Cargo.lock b/Cargo.lock index 497fcc69e..cb655d1fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,9 +148,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "bytes", @@ -203,9 +203,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" @@ -242,7 +242,7 @@ dependencies = [ "log", "num", "pin-project-lite", - "rand 0.9.3", + "rand 0.9.4", "rustls", "rustls-native-certs", "rustls-pki-types", @@ -678,7 +678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb330bbd4cb7a5b9f559427f06f98a4f853a137c8298f3bd3f8ca57663e21986" dependencies = [ "portable-atomic", - "rand 0.9.3", + "rand 0.9.4", "web-time", ] @@ -1072,9 +1072,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.8" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", @@ -1395,9 +1395,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" [[package]] name = "libm" @@ -1949,9 +1949,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2251,9 +2251,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.11" +version = "0.103.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20a6af516fea4b20eccceaf166e8aa666ac996208e8a644ce3ef5aa783bc7cd4" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" dependencies = [ "ring", "rustls-pki-types", @@ -2805,9 +2805,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" dependencies = [ "bytes", "libc", @@ -2945,34 +2945,6 @@ dependencies = [ "tonic", ] -[[package]] -name = "torrust-dependency-installer" -version = "0.1.0" -dependencies = [ - "async-trait", - "clap", - "testcontainers", - "thiserror 1.0.69", - "tokio", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "torrust-deployer-types" -version = "0.1.0" -dependencies = [ - "chrono", - "email_address", - "schemars 1.2.1", - "secrecy", - "serde", - "serde_json", - "thiserror 2.0.18", - "tracing", - "url", -] - [[package]] name = "torrust-linting" version = "0.1.0" @@ -2997,7 +2969,7 @@ dependencies = [ "figment", "parking_lot", "percent-encoding", - "rand 0.9.3", + "rand 0.9.4", "regex", "reqwest", "rstest", @@ -3011,9 +2983,9 @@ dependencies = [ "testcontainers", "thiserror 2.0.18", "tokio", - "torrust-dependency-installer", - "torrust-deployer-types", "torrust-linting", + "torrust-tracker-deployer-dependency-installer", + "torrust-tracker-deployer-types", "tracing", "tracing-appender", "tracing-subscriber", @@ -3022,6 +2994,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "torrust-tracker-deployer-dependency-installer" +version = "0.1.0" +dependencies = [ + "async-trait", + "clap", + "testcontainers", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "torrust-tracker-deployer-sdk" version = "0.1.0" @@ -3029,8 +3014,23 @@ dependencies = [ "tempfile", "thiserror 2.0.18", "tokio", - "torrust-deployer-types", "torrust-tracker-deployer", + "torrust-tracker-deployer-types", +] + +[[package]] +name = "torrust-tracker-deployer-types" +version = "0.1.0" +dependencies = [ + "chrono", + "email_address", + "schemars 1.2.1", + "secrecy", + "serde", + "serde_json", + "thiserror 2.0.18", + "tracing", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0f70cf6e5..7197c37e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,12 @@ resolver = "2" [package] name = "torrust-tracker-deployer" -version = "0.1.0-beta.1" +version = "0.1.0" edition = "2021" description = "Torrust Tracker Deployer - Deployment Infrastructure with Ansible and OpenTofu" license = "MIT" +repository = "https://github.com/torrust/torrust-tracker-deployer" +readme = "README.md" default-run = "torrust-tracker-deployer" [lib] @@ -62,8 +64,8 @@ tempfile = "3.0" tera = "1.0" testcontainers = { version = "0.27", features = [ "blocking" ] } thiserror = "2.0" -torrust-dependency-installer = { path = "packages/dependency-installer" } -torrust-deployer-types = { path = "packages/deployer-types" } +torrust-tracker-deployer-dependency-installer = { path = "packages/dependency-installer", version = "0.1.0" } +torrust-tracker-deployer-types = { path = "packages/deployer-types", version = "0.1.0" } torrust-linting = "0.1.0" tracing = { version = "0.1", features = [ "attributes" ] } tracing-appender = "0.2" diff --git a/docs/ai-training/dataset/rendered-templates/03-minimal-hetzner/tofu/hetzner/main.tf b/docs/ai-training/dataset/rendered-templates/03-minimal-hetzner/tofu/hetzner/main.tf index b78486960..2f88f9cbb 100644 --- a/docs/ai-training/dataset/rendered-templates/03-minimal-hetzner/tofu/hetzner/main.tf +++ b/docs/ai-training/dataset/rendered-templates/03-minimal-hetzner/tofu/hetzner/main.tf @@ -107,7 +107,7 @@ variable "server_labels" { # Root SSH provides a recovery/debugging path. # # SECURITY NOTE: For production deployments, consider disabling root SSH access -# after verifying deployment succeeded. See docs/security/ssh-root-access-hetzner.md +# after verifying deployment succeeded. See docs/security/user-security/ssh-root-access-hetzner.md # # This key will appear in Hetzner Console β†’ Security β†’ SSH Keys. resource "hcloud_ssh_key" "torrust" { diff --git a/docs/ai-training/dataset/rendered-templates/04-full-stack-hetzner/tofu/hetzner/main.tf b/docs/ai-training/dataset/rendered-templates/04-full-stack-hetzner/tofu/hetzner/main.tf index b78486960..2f88f9cbb 100644 --- a/docs/ai-training/dataset/rendered-templates/04-full-stack-hetzner/tofu/hetzner/main.tf +++ b/docs/ai-training/dataset/rendered-templates/04-full-stack-hetzner/tofu/hetzner/main.tf @@ -107,7 +107,7 @@ variable "server_labels" { # Root SSH provides a recovery/debugging path. # # SECURITY NOTE: For production deployments, consider disabling root SSH access -# after verifying deployment succeeded. See docs/security/ssh-root-access-hetzner.md +# after verifying deployment succeeded. See docs/security/user-security/ssh-root-access-hetzner.md # # This key will appear in Hetzner Console β†’ Security β†’ SSH Keys. resource "hcloud_ssh_key" "torrust" { diff --git a/docs/ai-training/dataset/rendered-templates/12-high-availability/tofu/hetzner/main.tf b/docs/ai-training/dataset/rendered-templates/12-high-availability/tofu/hetzner/main.tf index b78486960..2f88f9cbb 100644 --- a/docs/ai-training/dataset/rendered-templates/12-high-availability/tofu/hetzner/main.tf +++ b/docs/ai-training/dataset/rendered-templates/12-high-availability/tofu/hetzner/main.tf @@ -107,7 +107,7 @@ variable "server_labels" { # Root SSH provides a recovery/debugging path. # # SECURITY NOTE: For production deployments, consider disabling root SSH access -# after verifying deployment succeeded. See docs/security/ssh-root-access-hetzner.md +# after verifying deployment succeeded. See docs/security/user-security/ssh-root-access-hetzner.md # # This key will appear in Hetzner Console β†’ Security β†’ SSH Keys. resource "hcloud_ssh_key" "torrust" { diff --git a/docs/ai-training/dataset/rendered-templates/14-lightweight-production/tofu/hetzner/main.tf b/docs/ai-training/dataset/rendered-templates/14-lightweight-production/tofu/hetzner/main.tf index b78486960..2f88f9cbb 100644 --- a/docs/ai-training/dataset/rendered-templates/14-lightweight-production/tofu/hetzner/main.tf +++ b/docs/ai-training/dataset/rendered-templates/14-lightweight-production/tofu/hetzner/main.tf @@ -107,7 +107,7 @@ variable "server_labels" { # Root SSH provides a recovery/debugging path. # # SECURITY NOTE: For production deployments, consider disabling root SSH access -# after verifying deployment succeeded. See docs/security/ssh-root-access-hetzner.md +# after verifying deployment succeeded. See docs/security/user-security/ssh-root-access-hetzner.md # # This key will appear in Hetzner Console β†’ Security β†’ SSH Keys. resource "hcloud_ssh_key" "torrust" { diff --git a/docs/codebase-architecture.md b/docs/codebase-architecture.md index 5ca8c226d..9aae4d292 100644 --- a/docs/codebase-architecture.md +++ b/docs/codebase-architecture.md @@ -219,7 +219,7 @@ Independently versioned Cargo workspace packages in `packages/`: - βœ… [`torrust-linting`](https://crates.io/crates/torrust-linting) (external crate) - Unified linting framework (runs markdownlint, yamllint, taplo, cspell, clippy, rustfmt, shellcheck) - βœ… `packages/dependency-installer/` - Dependency detection and installation for development setup (OpenTofu, Ansible, LXD, cargo-machete) -- βœ… `packages/deployer-types/` - Shared value objects and traits (`torrust-deployer-types`) β€” cross-cutting foundational types (e.g., `EnvironmentName`, `DomainName`, `Username`, `Clock`, `ErrorKind`) shared by the root crate and SDK +- βœ… `packages/deployer-types/` - Shared value objects and traits (`torrust-tracker-deployer-types`) β€” cross-cutting foundational types (e.g., `EnvironmentName`, `DomainName`, `Username`, `Clock`, `ErrorKind`) shared by the root crate and SDK - βœ… `packages/sdk/` - Programmatic SDK (`torrust-tracker-deployer-sdk`) β€” independently consumable Rust crate for deploying Torrust Tracker instances without the CLI ### Presentation Layer diff --git a/docs/deployments/hetzner-demo-tracker/prerequisites.md b/docs/deployments/hetzner-demo-tracker/prerequisites.md index 7b4e55868..f875991c2 100644 --- a/docs/deployments/hetzner-demo-tracker/prerequisites.md +++ b/docs/deployments/hetzner-demo-tracker/prerequisites.md @@ -86,7 +86,7 @@ The image starts, prints tool versions, and shows the CLI help. Tool versions in All dependencies verified with: ```bash -cargo run -p torrust-dependency-installer --bin dependency-installer check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer check ``` - [x] **Rust toolchain** β€” `rustc 1.96.0-nightly (ec818fda3 2026-03-02)` diff --git a/docs/issues/429-deployer-cves.md b/docs/issues/429-deployer-cves.md new file mode 100644 index 000000000..ed769e34f --- /dev/null +++ b/docs/issues/429-deployer-cves.md @@ -0,0 +1,70 @@ +# Issue #429: Deployer Image CVEs after Remediation Pass 1 + +**GitHub**: +**Image**: `torrust/tracker-deployer:local` +**Dockerfile**: `docker/deployer/Dockerfile` + +--- + +## Context + +After PR #436 removed `gnupg` from the runtime layer: + +| Pass | HIGH | CRITICAL | +| ------------------ | ---- | -------- | +| Before remediation | 49 | 1 | +| After pass 1 | 44 | 1 | + +Remaining findings split into two areas: + +1. **Debian 13.4 (trixie) base packages** β€” HIGH, blocked on upstream patches +2. **OpenTofu binary** β€” 2 HIGH + 1 CRITICAL, blocked on OpenTofu release + +## Decision + +**Re-scan and check OpenTofu release, then decide**: + +- If a newer OpenTofu release clears the CRITICAL: update the pinned version, + rebuild, re-scan, update scan doc, close #429 +- If Debian packages are now patched: `docker build --no-cache` will pick them up; + re-scan, update scan doc, re-evaluate #429 +- If nothing has changed: post comment documenting current state and accepted risk; + leave open with revisit note + +## Steps + +- [x] Check current OpenTofu version pinned in the Dockerfile: + `grep -i opentofu docker/deployer/Dockerfile` +- [x] Check latest OpenTofu release: + +- [x] Rebuild and re-scan: + + ```bash + docker build --no-cache -t torrust/tracker-deployer:local docker/deployer/ + trivy image --severity HIGH,CRITICAL torrust/tracker-deployer:local + ``` + +- [x] Compare against the pass-1 baseline in + `docs/security/deployer/docker/scans/torrust-tracker-deployer.md` +- [x] For Debian base package CVEs, check fix availability: + +- [x] Update `docs/security/deployer/docker/scans/torrust-tracker-deployer.md` with new + scan results +- [ ] **If CRITICAL is cleared**: update Dockerfile OpenTofu version; post results + comment; close #429 +- [ ] **If only Debian packages improved**: post results comment; re-evaluate open + status +- [x] **If no change**: post comment with accepted risk rationale for remaining + CVEs; label `accepted-risk`; leave open with revisit note + +## Outcome + +- Date: Apr 15, 2026 +- Current OpenTofu version in Dockerfile: installed via script (no pinned version) +- Latest OpenTofu release: v1.11.6 (2026-04-08) β€” installed in rebuilt image +- Findings after rebuild (HIGH / CRITICAL): 46 HIGH / 1 CRITICAL + - Debian OS: 42 HIGH, 0 CRITICAL + - `usr/bin/tofu` (v1.11.6): 4 HIGH, 1 CRITICAL +- Decision: **leave open** β€” CRITICAL CVE-2026-33186 (grpc-go gRPC auth bypass) remains in tofu binary; requires OpenTofu upstream to bump grpc-go to v1.79.3+ +- Comment/PR: PR #458, comment on #429 +- Revisit: when OpenTofu ships v1.11.7+ or v1.12.x with updated grpc-go dependency diff --git a/docs/issues/432-caddy-cves.md b/docs/issues/432-caddy-cves.md new file mode 100644 index 000000000..3ffc7c4f0 --- /dev/null +++ b/docs/issues/432-caddy-cves.md @@ -0,0 +1,75 @@ +# Issue #432: Caddy CVEs after upgrade to 2.10.2 + +**GitHub**: +**Image**: `caddy:2.10.2` +**Template**: `templates/docker-compose/docker-compose.yml.tera` + +--- + +## Context + +After PR #436 upgraded Caddy from `2.10` to `2.10.2`: + +| Version | HIGH | CRITICAL | +| -------- | ---- | -------- | +| `2.10` | 18 | 6 | +| `2.10.2` | 14 | 4 | + +4 CRITICAL remain in upstream Caddy binary dependencies. + +## Decision + +**Re-scan with latest Caddy tag, then decide**: + +- If a newer tag clears CRITICALs: upgrade, update scan doc, close #432 +- If not: post comment with scan results, document accepted risk, leave open with + revisit note + +## Steps + +- [x] Check the latest Caddy release: + and +- [x] Run Trivy against the latest tag: + `trivy image --severity HIGH,CRITICAL caddy:LATEST_TAG` +- [x] Compare results against the 2.10.2 baseline in + `docs/security/production/scans/caddy.md` +- [x] **If CRITICALs are cleared (or HIGH count drops meaningfully)**: update + `templates/docker-compose/docker-compose.yml.tera` and the CI scan matrix; + update the scan doc; post results comment; close #432 +- [ ] **If CRITICALs remain**: post comment documenting which CVEs remain and why + they cannot be fixed (upstream binary); add revisit note to #432; leave open + +## Outcome + +- Date: 2026-04-15 +- Latest Caddy tag tested: `2.11.2` (released 2026-04-14) +- Decision: **upgrade to `caddy:2.11.2`** β€” HIGH count dropped meaningfully (14β†’10), CRITICAL halved (4β†’2) +- Action: updated `templates/docker-compose/docker-compose.yml.tera` and CI scan matrix +- Issue: **left open** β€” 2 CRITICAL CVEs remain in upstream binary dependencies +- PR: opened against `main` on branch `432-caddy-cves` + +### Scan details β€” `caddy:2.11.2` (Trivy v0.69.3, 2026-04-15) + +**Version comparison:** + +| Version | HIGH | CRITICAL | +| -------- | ---- | -------- | +| `2.10` | 18 | 6 | +| `2.10.2` | 14 | 4 | +| `2.11.2` | 10 | 2 | + +**Target breakdown:** + +| Target | HIGH | CRITICAL | +| -------------- | ---- | -------- | +| caddy (alpine) | 3 | 0 | +| usr/bin/caddy | 7 | 2 | + +**Remaining CRITICAL CVEs (upstream binary, cannot be fixed without Caddy release):** + +| CVE | Library | Fix | Notes | +| -------------- | ---------------------- | ------ | ---------------------------------------------------------- | +| CVE-2026-30836 | smallstep/certificates | 0.30.0 | Unauthenticated SCEP cert issuance | +| CVE-2026-33186 | google.golang.org/grpc | 1.79.3 | Authorization bypass via HTTP/2 path ⚠️ network-accessible | + +**Revisit**: when Caddy ships updated grpc-go (β‰₯1.79.3) and smallstep/certificates (β‰₯0.30.0). diff --git a/docs/issues/443-rand-0.8.5-rustsec.md b/docs/issues/443-rand-0.8.5-rustsec.md new file mode 100644 index 000000000..891fc3437 --- /dev/null +++ b/docs/issues/443-rand-0.8.5-rustsec.md @@ -0,0 +1,73 @@ +# Issue #443: RUSTSEC-2026-0097 β€” `rand 0.8.5` unsound (transitive) + +**GitHub**: +**Advisory**: +**Affected**: `rand >= 0.7, < 0.9.3` and `0.10.0` +**Reported version**: `0.8.5` + +--- + +## Context + +`rand 0.8.5` is a transitive dependency via `tera v1.20.1`. It cannot be +directly upgraded β€” only a new `tera` release that bumps its own rand dependency +will clear it. + +Current dependency paths (`cargo tree -i rand@0.8.5`): + +```text +rand v0.8.5 +└── tera v1.20.1 + └── torrust-tracker-deployer v0.1.0 + +rand v0.8.5 +└── phf_generator v0.11.3 + └── phf_codegen v0.11.3 + └── chrono-tz-build v0.3.0 + [build-dependencies] + └── chrono-tz v0.9.0 + └── tera v1.20.1 (*) +``` + +## Risk Assessment + +The unsoundness requires **all** of the following conditions simultaneously: + +1. The `log` and `thread_rng` features of `rand 0.8.5` are both enabled +2. A custom logger is registered +3. The custom logger calls `rand::rng()` inside its logging code +4. `ThreadRng` attempts to reseed (every 64 kB of random output) +5. Trace-level or warn-level (with getrandom failure) logging is active + +This application does **not** implement a custom logger that calls back into rand. +Only `tera` uses `rand 0.8.5` for template rendering β€” it does not trigger the +logging path. + +**Conclusion**: Low practical risk β€” the conditions for unsoundness are not met. + +## Decision + +**Post a comment with the risk assessment, then leave open** until `tera` releases +a version using `rand >= 0.9.3`. + +## Steps + +- [x] Run `cargo audit` to confirm RUSTSEC-2026-0097 is still reported for rand 0.8.5 +- [x] Run `cargo tree -i rand@0.8.5` to confirm `tera` is still the only consumer +- [x] Check whether `tera` has released a version with `rand >= 0.9.3`: + +- [x] **`tera` has not updated yet** β€” latest stable is `1.20.1` (released ~6 months + ago). A `2.0.0-alpha.2` pre-release exists (~1 month ago) but is not production + ready. + - [x] Post a comment on #443 with the risk assessment and cargo tree output + - Leave the issue open β€” revisit when `tera` releases a new stable version + +## Outcome + +- Date: 2026-04-14 +- tera latest stable version: `1.20.1` (no fix available yet) +- Result: **Cannot fix.** `rand 0.8.5` is pulled in solely by `tera 1.20.1`. No + stable `tera` release uses `rand >= 0.9.3`. Practical risk is low β€” the + unsoundness conditions are not met in this application (no custom logger calling + back into rand). Risk assessment posted as comment on #443; issue left open. +- Comment/PR: https://github.com/torrust/torrust-tracker-deployer/issues/443#issuecomment-4246102278 diff --git a/docs/issues/448-release-process-branch-tag-docker-crate.md b/docs/issues/448-release-process-branch-tag-docker-crate.md deleted file mode 100644 index 723ac23e3..000000000 --- a/docs/issues/448-release-process-branch-tag-docker-crate.md +++ /dev/null @@ -1,296 +0,0 @@ -# Define a Standard Release Process (Branch, Tag, Docker Image, Crate) - -**Issue**: #448 -**Parent Epic**: N/A (standalone release process task) -**Related**: - -- `docs/contributing/roadmap-issues.md` -- `docs/contributing/commit-process.md` -- `docs/roadmap.md` - -## Overview - -Define and document a repeatable release process for this repository so releases are -predictable, auditable, and less error-prone. - -This repository already has a container workflow in `.github/workflows/container.yaml` -that publishes Docker images for `main` and `develop`. The new release process should -extend that model to support release branches, while keeping the overall process much -simpler than the Torrust Tracker release process. - -The initial release process should include these mandatory steps in order: - -1. Update the version in the relevant `Cargo.toml` files -2. Commit the release version -3. Push the release commit to `main` -4. Create the release tag and push it -5. Create the release branch and push it -6. Let GitHub Actions publish release artifacts: - - Docker image for the release branch - - Crate for the release branch -7. Create the GitHub release from the tag - -## Goals - -- [x] Define a single documented release workflow with explicit step order -- [x] Make branch and tag conventions consistent across releases -- [x] Ensure Docker image publication is triggered from release branches -- [x] Ensure crate publication is triggered from release branches -- [x] Define validation and rollback guidance for failed release steps -- [x] Keep the first version of the process intentionally simpler than the tracker repository -- [x] Avoid duplicate Docker release tags for the same version - -## πŸ—οΈ Architecture Requirements - -**DDD Layer**: Infrastructure (CI/CD and release automation), Documentation -**Module Path**: `docs/`, `.github/workflows/`, and release-related scripts if needed -**Pattern**: Release workflow and operational guide - -### Module Structure Requirements - -- [x] Keep process documentation in `docs/` -- [x] Keep automation in `.github/workflows/` and/or `scripts/` -- [x] Keep branch and tag naming rules explicit and testable -- [x] Keep artifact version alignment across Git tag, Docker image tag, and crate version - -### Architectural Constraints - -- [x] Release order must be deterministic and documented -- [x] Tag format must be clearly defined as `vX.Y.Z` -- [x] Release branch format must be clearly defined and compatible with workflow triggers -- [x] Docker publish step must support reproducible release tagging without overloading `main` publish behavior -- [x] Docker release tags must not include the Git tag `v` prefix -- [x] Crate publish step must define pre-checks and ownership requirements -- [x] Docker Hub credentials must separate secrets from non-sensitive variables -- [x] Workflow triggers and branch protections must align with allowed branches (`develop`, `main`, `releases/**/*`) - -### Anti-Patterns to Avoid - -- ❌ Manual ad-hoc release steps without a checklist -- ❌ Tagging and artifact versions drifting from each other -- ❌ Publishing the same Docker release twice with both `vX.Y.Z` and `X.Y.Z` tags -- ❌ Publishing artifacts without verification or rollback notes -- ❌ Coupling release steps to undocumented local machine state - -## Specifications - -### 1. Release Branch Strategy - -Define how release branches are created, named, and finalized. - -- Naming convention: `releases/vX.Y.Z` -- Source branch: create the release branch from the same commit that was pushed to `main` -- The release branch is a publication trigger, not a long-lived development branch -- The release branch name must be parseable by GitHub Actions so release version metadata can be extracted - -### 2. Version Update and Release Commit - -Define which manifests are updated before the release commit. - -- Root `Cargo.toml` version must be updated from the current development version to the release version -- Publishable package versions must also be updated in their own manifests -- The likely first publishable crate is `packages/sdk/Cargo.toml` (`torrust-tracker-deployer-sdk`) -- The release commit should be explicit and traceable, for example: `release: version vX.Y.Z` -- Verify release metadata quality for publishable crates (`description`, `license`, `repository`, `readme`) before publishing - -### 3. Tagging Strategy - -Define release tag rules and when tags are created. - -- Tag format: `vX.Y.Z` -- Annotated and signed tag requirements -- Tag is created from the release commit already pushed to `main` -- Tag, release branch, Docker tags, and crate versions must all refer to the same semantic version -- Git tags keep the `v` prefix, but Docker release tags must use bare semver (`X.Y.Z`) - -### 4. Docker Image Publication - -Extend `.github/workflows/container.yaml` so release branches also publish Docker images. - -- Keep existing behavior for `main` and `develop` -- Add support for `releases/**/*` branch pushes -- Follow the tracker repository pattern for deriving release image tags from the release branch version -- Release branch publication should push versioned tags, not `latest` -- Release branch publication must publish only canonical semver Docker tags such as `1.2.3` -- Do not publish duplicate release image tags with both `v1.2.3` and `1.2.3` -- Verify the image can be pulled and inspected after publication - -Environment configuration for Docker publish: - -- Use GitHub Environment: `dockerhub-torrust` -- Keep `DOCKER_HUB_ACCESS_TOKEN` as a secret -- Keep `DOCKER_HUB_USERNAME` as a normal environment variable (already set to `torrust` in deployer) -- Do not store `DOCKER_HUB_USERNAME` or `DOCKER_HUB_REPOSITORY_NAME` as secrets -- Repository name can be hardcoded for this repo (`tracker-deployer`) or stored as a non-secret variable - -### 5. Library Crate Publication - -Add a dedicated workflow for publishing crates from release branches. - -- Preferred initial target crate: `torrust-tracker-deployer-sdk` -- Trigger on push to `releases/**/*` -- Run tests and release pre-checks before publication -- Verify packaged contents before publishing (`cargo package --list`) to avoid shipping unintended files -- `cargo publish --dry-run` before real publish -- Post-publish verification (crate visible in registry and installable) -- Verify docs.rs build status for the published version -- Avoid mixing Docker-specific logic into the crate publication workflow - -Environment configuration for crate publish: - -- Use a dedicated GitHub Environment for crate publication (for example `deployment`) -- Store cargo registry token as a secret only in that environment -- Keep non-sensitive crate metadata as normal variables when needed - -### 6. GitHub Release Creation - -Define how the GitHub release is created from the pushed tag. - -- Keep this step simple for now: create the GitHub release manually from the tag -- Attach release notes manually or with a minimal template -- Do not block Docker or crate publication on a more complex release-notes automation flow - -Release finalization gate order: - -- Confirm the release commit is pushed to `main` -- Confirm tag `vX.Y.Z` is pushed -- Confirm branch `releases/vX.Y.Z` is pushed -- Confirm Docker release workflow passed -- Confirm crate release workflow passed -- Create/publish GitHub release as final step - -### 7. Workflow Separation Strategy - -Prefer independent workflows instead of one workflow that publishes all release artifacts. - -- Keep Docker publication in `container.yaml` because it already owns Docker build/test/publish logic -- Add a separate release-oriented workflow for crate publication; `deployment.yaml` is probably too vague in this repository -- Prefer a name that reveals the artifact, for example `publish-crate.yaml` or `release-crate.yaml` -- Keep GitHub release creation outside the artifact publication workflows for the first iteration - -Reasoning: - -- Docker and crate publishing have different credentials, failure modes, and verification steps -- Separate workflows reduce accidental coupling and make reruns more targeted -- The simpler process is easier to debug than one orchestrator workflow with multiple artifact paths - -### 8. Failure Handling and Recovery - -Define how to proceed when a step fails. - -- If Docker publication fails, the release branch can be re-pushed or the workflow can be re-run without changing the tag -- If crate publication fails after tag and branch creation, document whether a version must be abandoned or publication can be retried safely -- Branch/tag rollback guidance -- Docker publish retry policy -- Crate publish partial-failure guidance -- Operator-facing troubleshooting notes - -Partial-failure action matrix: - -- Docker failed, crate not started: fix Docker workflow and re-run publication on the same release branch -- Docker passed, crate failed before upload: fix issue and re-run crate workflow on the same release branch -- Crate published, later step failed: do not republish same crate version; proceed with follow-up patch release if needed - -Idempotency and re-run rules: - -- Docker release publication must be safely re-runnable for the same release branch/version -- Crate workflow must detect already-published versions and fail with clear guidance instead of ambiguous errors -- Tag and branch creation steps must check for existing refs and stop with actionable output if refs already exist - -Crate rollback/yank policy: - -- Never delete published versions (not possible on crates.io); use `cargo yank` only when necessary -- Prefer yanking only for severe release defects (broken build, critical security issue, unusable package) -- After yanking, cut a patch release with a higher version and document remediation in release notes - -### 9. Pre-Flight Checks - -Define mandatory checks before starting any release actions. - -- Verify required GitHub environments exist (`dockerhub-torrust` and crate publish environment) -- Verify required secrets and variables exist in those environments -- Verify the releaser has permission to access protected environments and push required refs -- Verify local workspace is clean and on the expected source branch before version bump/tagging - -### 10. Repository Settings Alignment - -Define repository settings expectations that release automation depends on. - -- Allowed branches for release-related workflows: `develop`, `main`, `releases/**/*` -- Release workflows must be trigger-scoped to those branches; avoid broad wildcard triggers -- Current tracker policy (`10` branches and `0` tags allowed) should be documented as reference, and deployer should adopt equivalent branch scoping for release workflows where applicable - -## Implementation Plan - -### Phase 1: Define the Manual Release Sequence (estimated time: 2-3 hours) - -- [x] Task 1.1: Document the simplified release steps from version bump through GitHub release creation -- [x] Task 1.2: Define version, tag, and release branch naming conventions -- [x] Task 1.3: Specify which `Cargo.toml` files must be updated for each release -- [x] Task 1.4: Add a pre-flight checklist for environments, permissions, and clean git state - -### Phase 2: Docker Release Branch Publishing (estimated time: 1-2 hours) - -- [x] Task 2.1: Extend `container.yaml` to trigger on `releases/**/*` -- [x] Task 2.2: Add release branch context detection and release image tags -- [x] Task 2.3: Define image verification, credential, and rerun requirements -- [x] Task 2.4: Ensure Docker Hub username/repository are configured as non-secret variables (token remains secret) - -### Phase 3: Crate Publishing Workflow (estimated time: 1-2 hours) - -- [x] Task 3.1: Create a dedicated workflow for publishing the SDK crate from `releases/**/*` -- [x] Task 3.2: Define package inspection, dry-run, publish, and post-publish verification steps -- [x] Task 3.3: Define dedicated environment and document cargo registry credentials and failure recovery rules -- [x] Task 3.4: Add docs.rs post-publish verification guidance - -### Phase 4: Validation and Operational Guidance (estimated time: 2-4 hours) - -- [ ] Task 4.1: Validate the end-to-end release flow against a test version -- [x] Task 4.2: Document how maintainers verify Docker image, crate publication, and GitHub release creation -- [x] Task 4.3: Add troubleshooting notes for partial publication failures -- [x] Task 4.4: Add explicit idempotency/re-run guidance and crate yank policy - -> Note: The practical end-to-end validation for Task 4.1 is planned as the -> post-merge `0.1.0-beta` release run. - -## Acceptance Criteria - -> **Note for Contributors**: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations. - -**Quality Checks**: - -- [x] Pre-commit checks pass: `./scripts/pre-commit.sh` - -**Task-Specific Criteria**: - -- [x] The documented release process follows this order: version update, release commit, push to `main`, tag push, release branch push, workflow-driven artifact publication, GitHub release creation -- [x] The spec defines explicit finalization gates (main push, tag push, release branch push, Docker pass, crate pass, GitHub release) -- [x] Branch naming and tag naming conventions are documented as `releases/vX.Y.Z` and `vX.Y.Z` -- [x] `container.yaml` is specified to publish Docker images for release branches in addition to existing `main` and `develop` behavior -- [x] The spec explicitly requires Docker release tags to use `X.Y.Z` and forbids `vX.Y.Z` image tags -- [x] A separate crate publication workflow is specified for the SDK crate on `releases/**/*` -- [x] The spec explicitly records the decision to keep Docker and crate publication in independent workflows -- [x] Docker Hub configuration policy is explicit: token is secret, username/repository are variables -- [x] Release workflow branch scope is explicit and aligned with `develop`, `main`, and `releases/**/*` -- [x] Docker publish procedure includes verification and failure handling -- [x] Crate publish procedure includes dry-run and post-publish verification -- [x] Crate publish procedure includes package content inspection before publish -- [x] Crate publish procedure includes docs.rs build verification after publish -- [x] Pre-flight checks are documented for environments, secrets/variables, permissions, and git state -- [x] Partial-failure and re-run rules are documented for Docker and crate workflows -- [x] Crate rollback policy includes explicit yank criteria and patch-release follow-up -- [x] Version consistency rules are documented across Git tags, Docker tags, and crate versions - -## Related Documentation - -- `docs/contributing/roadmap-issues.md` -- `docs/contributing/commit-process.md` -- `docs/roadmap.md` -- https://raw.githubusercontent.com/torrust/torrust-linting/refs/heads/main/skills/publish-rust-crate/SKILL.md - -## Notes - -- Keep the first iteration focused on one release path that can be executed by maintainers without additional assumptions. -- Start with the SDK crate only unless additional crates are explicitly marked for publication. -- Do not import the tracker repository's full staging and develop branch merge-back process into this repository yet. -- Guard against the tracker bug described in `torrust/torrust-tracker#1029`: Docker release tags should not be published with the `v` prefix. diff --git a/docs/issues/450-release-v0-1-0-beta-end-to-end-validation.md b/docs/issues/450-release-v0-1-0-beta-end-to-end-validation.md deleted file mode 100644 index c20f94e6b..000000000 --- a/docs/issues/450-release-v0-1-0-beta-end-to-end-validation.md +++ /dev/null @@ -1,225 +0,0 @@ -# Release v0.1.0-beta.1: End-to-End Process Validation - -**Issue**: #450 -**Parent Epic**: N/A (standalone release task) -**Related**: - -- `docs/release-process.md` -- `.github/skills/dev/git-workflow/release-new-version/skill.md` -- Issue #448 β€” Define release process (merged) - -## Overview - -Execute the first real end-to-end release of the Torrust Tracker Deployer following -the release process defined in issue #448. Version `0.1.0-beta.1` is the first -pre-release version and serves as the practical validation of the entire release -workflow β€” from version bump to artifact verification. - -This task is intentionally broader than a normal release. It treats the release -itself as an audit surface: every step where the documentation is inaccurate, -incomplete, or misleading must be captured and fixed before closing the issue. -The goal is a release process that is fully trustworthy for future stable releases. - -## Goals - -- [ ] Execute the complete release process for `v0.1.0-beta.1` -- [ ] Verify Docker image is published and pullable from Docker Hub -- [ ] Verify SDK crate is published and visible on crates.io -- [ ] Verify docs.rs builds the published crate -- [ ] Verify GitHub release is created and accessible -- [ ] Document every friction point, error, or inconsistency encountered -- [ ] Fix any release-process issues or documentation gaps found during execution -- [ ] Leave `docs/release-process.md` accurate for future releases - -## πŸ—οΈ Architecture Requirements - -**DDD Layer**: Infrastructure (CI/CD, release automation), Documentation -**Module Path**: `docs/`, `.github/workflows/`, `Cargo.toml` manifests -**Pattern**: Release workflow and operational guide - -### Module Structure Requirements - -- [ ] Version updates limited to `Cargo.toml` and `packages/sdk/Cargo.toml` -- [ ] Any documentation fixes go in `docs/release-process.md` or the release skill - -### Architectural Constraints - -- [ ] Release order from `docs/release-process.md` must be followed exactly -- [ ] Tag and branch naming must follow established conventions (`vX.Y.Z`, `releases/vX.Y.Z`) -- [ ] Docker tag must use bare semver (`0.1.0-beta.1`, no `v` prefix) -- [ ] Pre-release versions are valid on both crates.io and Docker Hub -- [ ] Any workflow fix must not break existing `main` or `develop` behavior - -### Anti-Patterns to Avoid - -- ❌ Skipping artifact verification and declaring the release done on tag push alone -- ❌ Silently skipping problems found during the release without filing follow-up issues -- ❌ Making workflow changes without verifying the full release pipeline -- ❌ Bumping past `0.1.0-beta.1` to cover up issues instead of documenting them - -## Specifications - -### 1. Version to Release - -- **Version string**: `0.1.0-beta.1` -- **Git tag**: `v0.1.0-beta.1` -- **Release branch**: `releases/v0.1.0-beta.1` -- **Docker tag**: `0.1.0-beta.1` (no `v` prefix) -- **Crate version**: `0.1.0-beta.1` - -Pre-release suffixes (`-beta.1`) are valid semver and supported by crates.io and Docker Hub. - -### 2. Pre-Flight Checks - -Before executing any release step, the following must be confirmed: - -**Git state:** - -- Clean working tree on `main` that is up to date with `torrust/main` -- The merge commit of PR #448 must be on `main` - -**GitHub Environments:** - -- `dockerhub-torrust` environment exists with correct credentials: - - `DOCKER_HUB_ACCESS_TOKEN` (secret) - - `DOCKER_HUB_USERNAME` (variable = `torrust`) -- `crates-io` environment exists with: - - `CARGO_REGISTRY_TOKEN` (secret) - -**Permissions:** - -- Releaser can push to `torrust/main`, tags, and release branches - -### 3. Release Execution Steps - -Follow `docs/release-process.md` exactly: - -1. Update `version` in `Cargo.toml` and `packages/sdk/Cargo.toml` to `0.1.0-beta.1` -2. Run `cargo build && cargo test` to verify workspace health -3. Commit: `git commit -S -m "release: version v0.1.0-beta.1"` -4. Push to `main`: `git push origin main` -5. Create annotated signed tag: `git tag -s -a v0.1.0-beta.1 -m "Release v0.1.0-beta.1"` -6. Push tag: `git push origin v0.1.0-beta.1` -7. Create release branch: `git checkout -b releases/v0.1.0-beta.1` -8. Push release branch: `git push origin releases/v0.1.0-beta.1` -9. Monitor Container and Publish Crate workflows -10. Create GitHub release from tag `v0.1.0-beta.1` - -### 4. Artifact Verification - -Artifacts must be verified after CI completes, not assumed: - -**Docker image:** - -```bash -docker pull torrust/tracker-deployer:0.1.0-beta.1 -docker image inspect torrust/tracker-deployer:0.1.0-beta.1 -docker run --rm --entrypoint tofu torrust/tracker-deployer:0.1.0-beta.1 version -``` - -**Crate:** - -```bash -curl -sf "https://crates.io/api/v1/crates/torrust-tracker-deployer-sdk/0.1.0-beta.1" | jq '.version.num' -``` - -**docs.rs:** - -- Confirm build passes at: `https://docs.rs/torrust-tracker-deployer-sdk/0.1.0-beta.1` - -**GitHub release:** - -- Confirm it exists and is published (not draft) at `https://github.com/torrust/torrust-tracker-deployer/releases/tag/v0.1.0-beta.1` - -### 5. Process Review and Improvement - -During execution, document all friction points, errors, and documentation gaps in -a dedicated section of this issue or directly in `docs/release-process.md`. - -Categories to watch for: - -- Missing or inaccurate steps in the release guide -- Workflow failures due to incorrect configuration -- Environment/permission issues not covered by the pre-flight checklist -- Timing issues (e.g., crates.io indexing delay, docs.rs build delay) -- Any step that required improvising beyond what the docs describe - -For each issue found: fix it inline if small (typo, clarification), or file a -follow-up issue if it requires non-trivial work. - -## Implementation Plan - -### Phase 1: Pre-Flight and Setup (estimated time: 30 minutes) - -- [ ] Task 1.1: Verify local workspace is clean and on `torrust/main` -- [ ] Task 1.2: Verify GitHub environments `dockerhub-torrust` and `crates-io` are configured -- [ ] Task 1.3: Confirm releaser has required push permissions -- [ ] Task 1.4: Document any pre-flight issues found - -### Phase 2: Execute the Release (estimated time: 1-2 hours) - -- [ ] Task 2.1: Update `version` to `0.1.0-beta.1` in both `Cargo.toml` files -- [ ] Task 2.2: Run `cargo build && cargo test` and verify they pass -- [ ] Task 2.3: Create and push the signed release commit to `main` -- [ ] Task 2.4: Create and push annotated signed tag `v0.1.0-beta.1` -- [ ] Task 2.5: Create and push release branch `releases/v0.1.0-beta.1` -- [ ] Task 2.6: Monitor Container and Publish Crate workflows to completion - -### Phase 3: Artifact Verification (estimated time: 30 minutes) - -- [ ] Task 3.1: Pull and inspect Docker image `torrust/tracker-deployer:0.1.0-beta.1` -- [ ] Task 3.2: Verify crate `torrust-tracker-deployer-sdk@0.1.0-beta.1` is on crates.io -- [ ] Task 3.3: Verify docs.rs build for the published crate version -- [ ] Task 3.4: Create GitHub release from tag `v0.1.0-beta.1` - -### Phase 4: Process Review and Cleanup (estimated time: 1 hour) - -- [ ] Task 4.1: Collect all issues and friction points encountered during execution -- [ ] Task 4.2: Fix small documentation inconsistencies in `docs/release-process.md` -- [ ] Task 4.3: Fix small skill inaccuracies in `release-new-version/skill.md` -- [ ] Task 4.4: File follow-up issues for any non-trivial problems found -- [ ] Task 4.5: Update release finalization gates to confirm all pass - -## Acceptance Criteria - -> **Note for Contributors**: These criteria define what the PR reviewer will check. - -**Quality Checks**: - -- [ ] Pre-commit checks pass: `./scripts/pre-commit.sh` - -**Release Execution**: - -- [ ] Version `0.1.0-beta.1` is committed and present in both `Cargo.toml` files on `main` -- [ ] Tag `v0.1.0-beta.1` exists and is signed -- [ ] Branch `releases/v0.1.0-beta.1` exists -- [ ] Container workflow completed successfully -- [ ] Publish Crate workflow completed successfully -- [ ] GitHub release `v0.1.0-beta.1` is published (not draft) - -**Artifact Verification**: - -- [ ] Docker image `torrust/tracker-deployer:0.1.0-beta.1` can be pulled and run -- [ ] Crate `torrust-tracker-deployer-sdk@0.1.0-beta.1` is visible on crates.io -- [ ] docs.rs build page loads for the published version - -**Process Quality**: - -- [ ] All issues found during the release are documented (inline or filed as follow-ups) -- [ ] `docs/release-process.md` reflects any corrections made -- [ ] No step was silently skipped or improvised without documentation - -## Related Documentation - -- `docs/release-process.md` -- `.github/workflows/container.yaml` -- `.github/workflows/publish-crate.yaml` -- `.github/skills/dev/git-workflow/release-new-version/skill.md` -- Issue #448 β€” release process definition (merged) - -## Notes - -- This is the first real execution of the release process. Treat it as an audit. -- Pre-release semver (`0.1.0-beta.1`) is valid for crates.io and Docker Hub. -- If a blocking issue is found that cannot be fixed quickly, pause the release, file an issue, and continue when resolved β€” do not rush past it. -- The next release after this will be a stable `0.1.0` once the process is validated. diff --git a/docs/issues/460-node-24-action-deprecation-warnings.md b/docs/issues/460-node-24-action-deprecation-warnings.md new file mode 100644 index 000000000..d474f6a7d --- /dev/null +++ b/docs/issues/460-node-24-action-deprecation-warnings.md @@ -0,0 +1,131 @@ +# Update GitHub Actions to Node.js 24 Compatible Versions + +**Issue**: #460 +**Parent Epic**: N/A +**Related**: N/A + +## Overview + +Several GitHub Actions workflows produce deprecation warnings because some actions +still run on Node.js 20. Starting **June 2nd, 2026**, GitHub will force all actions +to run with Node.js 24 by default, and Node.js 20 will be removed from runners on +**September 16th, 2026**. + +Each affected action needs to be reviewed: in some cases a newer version with +Node.js 24 support exists and can be adopted; in other cases no compatible release +exists yet and the issue must be tracked until one does. + +Reference: + +## Goals + +- [ ] Identify which affected actions have Node.js 24-compatible releases available +- [ ] Update workflow files to use compatible versions where possible +- [ ] Track actions that have no compatible release yet, and re-check periodically +- [ ] Eliminate all Node.js 20 deprecation warnings from CI runs + +## Affected Actions by Workflow + +### `backup-container.yaml` β€” Backup Container + +| Action | Current Version | Node.js 24? | +| ---------------------------- | --------------- | ----------- | +| `docker/setup-buildx-action` | `@v3` | TBD | +| `docker/build-push-action` | `@v6` | TBD | +| `docker/login-action` | `@v3` | TBD | +| `docker/metadata-action` | `@v5` | TBD | + +### `container.yaml` β€” Container + +| Action | Current Version | Node.js 24? | +| ---------------------------- | --------------- | ----------- | +| `docker/setup-buildx-action` | `@v3` | TBD | +| `docker/build-push-action` | `@v6` | TBD | +| `docker/login-action` | `@v3` | TBD | +| `docker/metadata-action` | `@v5` | TBD | + +### `cargo-security-audit.yml` β€” Cargo Security Audit + +| Action | Current Version | Node.js 24? | +| --------------------- | --------------- | ----------- | +| `rustsec/audit-check` | `@v2.0.0` | TBD | + +### `docker-security-scan.yml` β€” Docker Security Scan + +| Action | Current Version | Node.js 24? | +| --------------------------- | --------------- | ----------- | +| `aquasecurity/trivy-action` | `@0.35.0` | TBD | + +> **Note**: The warning in this workflow shows `actions/cache@0400d5f...` running on +> Node.js 20. This is a **transitive dependency** used internally by +> `aquasecurity/trivy-action`. Updating Trivy to a newer release should resolve it. + +### `test-e2e-deployment.yml` β€” E2E Deployment Workflow Tests + +| Action | Current Version | Node.js 24? | +| ---------------------------- | --------------- | ----------- | +| `docker/setup-buildx-action` | `@v3` | TBD | + +### `dependabot-updates` β€” Dependabot (GitHub-managed) + +| Action | Current Version | Node.js 24? | +| -------------------------- | --------------- | ----------- | +| `github/dependabot-action` | `@main` | TBD | + +> **Note**: This workflow is **managed entirely by GitHub** and is not present in +> this repository. We cannot update it directly. The warning may resolve +> automatically when GitHub updates their internal Dependabot runner, or it may +> require a GitHub support request. + +## Implementation Plan + +### Phase 1: Research available updates + +- [ ] Check latest releases of `docker/setup-buildx-action`, `docker/build-push-action`, `docker/login-action`, `docker/metadata-action` for Node.js 24 support +- [ ] Check latest release of `rustsec/audit-check` for Node.js 24 support +- [ ] Check latest release of `aquasecurity/trivy-action` for Node.js 24 support (resolves transitive `actions/cache` warning) +- [ ] Investigate `github/dependabot-action` β€” determine if this is fully GitHub-managed and no action is needed from our side + +### Phase 2: Apply available updates + +- [ ] Update all docker action versions in `backup-container.yaml` where newer Node.js 24 compatible versions are available +- [ ] Update all docker action versions in `container.yaml` where newer Node.js 24 compatible versions are available +- [ ] Update `docker/setup-buildx-action` in `test-e2e-deployment.yml` +- [ ] Update `rustsec/audit-check` in `cargo-security-audit.yml` +- [ ] Update `aquasecurity/trivy-action` in `docker-security-scan.yml` + +### Phase 3: Handle actions with no available update + +- [ ] For any action without a Node.js 24-compatible release, open a follow-up tracking note or issue +- [ ] Document the status and re-check schedule + +## Acceptance Criteria + +> **Note for Contributors**: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations. + +**Quality Checks**: + +- [ ] Pre-commit checks pass: `./scripts/pre-commit.sh` + +**Task-Specific Criteria**: + +- [ ] No Node.js 20 deprecation warnings appear in any of the affected workflow runs +- [ ] All updated action versions are pinned correctly and tested +- [ ] Any action that cannot be updated is documented with a follow-up plan + +## Related Documentation + +- [GitHub blog: Deprecation of Node 20 on Actions Runners](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/) +- Affected workflow runs: + - [backup-container.yaml run #24191868780](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24191868780) + - [cargo-security-audit.yml run #24455465380](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24455465380) + - [container.yaml run #24455465394](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24455465394) + - [dependabot-updates run #24389583837](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24389583837) + - [docker-security-scan.yml run #24445697392](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24445697392) + - [test-e2e-deployment.yml run #24455481734](https://github.com/torrust/torrust-tracker-deployer/actions/runs/24455481734) + +## Notes + +- The `docker/*` actions appear in both `backup-container.yaml` and `container.yaml` with the same versions. They should be updated together. +- The `dependabot-updates` warning may resolve itself without any action on our part β€” GitHub is likely already working on updating the internal runner. +- Setting `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true` in the workflow environment is available as a temporary opt-in to test compatibility before the forced migration. diff --git a/docs/issues/462-release-v0-1-0-stable-end-to-end-execution.md b/docs/issues/462-release-v0-1-0-stable-end-to-end-execution.md new file mode 100644 index 000000000..e7240867b --- /dev/null +++ b/docs/issues/462-release-v0-1-0-stable-end-to-end-execution.md @@ -0,0 +1,148 @@ +# Release v0.1.0: Stable End-to-End Execution + +**Issue**: #462 +**Parent Epic**: N/A +**Related**: [#459](https://github.com/torrust/torrust-tracker-deployer/issues/459) (beta.2 release validation), +[#450](https://github.com/torrust/torrust-tracker-deployer/issues/450) (beta.1 release validation), +[#448](https://github.com/torrust/torrust-tracker-deployer/issues/448) (release process definition), +[#452](https://github.com/torrust/torrust-tracker-deployer/pull/452) (crate rename to tracker-deployer namespace) + +## Overview + +Execute the first stable release of the Torrust Tracker Deployer (`v0.1.0`), +validating the full release workflow from version bump through release publication. + +This release is the GA cut after beta validation. The objective is to execute the +canonical process cleanly, ensure all release artifacts are published and verifiable, +and capture any friction that still exists in the release workflow documentation, +skill instructions, or CI automation. + +## Goals + +- [ ] Version `0.1.0` is reflected in all four `Cargo.toml` files on `main` +- [ ] Signed tag `v0.1.0` and release branch `releases/v0.1.0` exist +- [ ] Docker image `torrust/tracker-deployer:0.1.0` is published to Docker Hub +- [ ] All four crates are published to crates.io at version `0.1.0` +- [ ] GitHub release `v0.1.0` is published (not draft) +- [ ] Any new friction points discovered are documented and filed as follow-ups + +## Specifications + +### Version Bump Scope + +Update `version` field to `0.1.0` in all four manifests: + +| File | Crate | +| ------------------------------------------ | ----------------------------------------------- | +| `Cargo.toml` (workspace root) | `torrust-tracker-deployer` | +| `packages/deployer-types/Cargo.toml` | `torrust-tracker-deployer-types` | +| `packages/dependency-installer/Cargo.toml` | `torrust-tracker-deployer-dependency-installer` | +| `packages/sdk/Cargo.toml` | `torrust-tracker-deployer-sdk` | + +Also update every internal path dependency `version` constraint to `0.1.0`. + +### Publish Order (crates.io dependency order) + +1. `torrust-tracker-deployer-types` +2. `torrust-tracker-deployer-dependency-installer` +3. `torrust-tracker-deployer` +4. `torrust-tracker-deployer-sdk` + +Each crate's dry-run step in CI runs only after its prerequisites are indexed on +crates.io - do not attempt to publish out of order. + +## Implementation Plan + +### Phase 1: Pre-Flight and Setup + +- [ ] Task 1.1: Verify local workspace is clean and on `torrust/main` up-to-date + with `origin/main` (`git status`, `git pull --ff-only`) +- [ ] Task 1.2: Confirm GitHub environments `dockerhub-torrust` and `crates-io` are + correctly configured for stable release publication +- [ ] Task 1.3: Confirm releaser has push access to `main`, tags, and release branches +- [ ] Task 1.4: Document any pre-flight issues found + +### Phase 2: Execute the Release + +- [ ] Task 2.1: Update `version` to `0.1.0` in all four `Cargo.toml` files + and in every internal path dependency constraint +- [ ] Task 2.2: Run `cargo build && cargo test` and verify they pass +- [ ] Task 2.3: Run `./scripts/pre-commit.sh` and verify all checks pass +- [ ] Task 2.4: Create and push the signed release commit to `main` + (`git commit -S -m "release: version v0.1.0"`) +- [ ] Task 2.5: Create and push annotated signed tag `v0.1.0` +- [ ] Task 2.6: Create and push release branch `releases/v0.1.0` +- [ ] Task 2.7: Monitor Container and Publish Crate workflows to completion + +### Phase 3: Artifact Verification + +- [ ] Task 3.1: Pull and inspect Docker image `torrust/tracker-deployer:0.1.0` +- [ ] Task 3.2: Verify all four crates at `0.1.0` are visible on crates.io +- [ ] Task 3.3: Verify docs.rs build for the published crate versions +- [ ] Task 3.4: Create GitHub release from tag `v0.1.0` + +### Phase 4: Process Review and Fixes + +- [ ] Task 4.1: Collect every friction point, error, or unexpected step encountered + during the release - no matter how small +- [ ] Task 4.2: For each issue found, fix the root cause immediately in the relevant + artifact: + - `docs/release-process.md` - if a step was wrong, missing, or misleading + - `.github/skills/dev/git-workflow/release-new-version/skill.md` - if the skill + diverged from reality + - `scripts/` - if a helper script failed or was absent + - CI workflow files (`.github/workflows/`) - if a workflow behaved unexpectedly + - Any other documentation, template, or configuration that contributed to the + friction +- [ ] Task 4.3: File follow-up issues for any non-trivial problems that cannot be + fixed inline (e.g., upstream blockers, larger refactors) +- [ ] Task 4.4: Re-run `./scripts/pre-commit.sh` after any fixes to confirm nothing + was broken +- [ ] Task 4.5: Confirm all finalization gates below are met + +## Acceptance Criteria + +**Quality Checks**: + +- [ ] Pre-commit checks pass: `./scripts/pre-commit.sh` + +**Release Execution**: + +- [ ] Version `0.1.0` is committed and present in all four `Cargo.toml` files on `main` +- [ ] Tag `v0.1.0` exists and is signed +- [ ] Branch `releases/v0.1.0` exists +- [ ] Container workflow completed successfully +- [ ] Publish Crate workflow completed successfully +- [ ] GitHub release `v0.1.0` is published (not draft) + +**Artifact Verification**: + +- [ ] Docker image `torrust/tracker-deployer:0.1.0` can be pulled and run +- [ ] All four crates at `0.1.0` are visible on crates.io: + - [ ] `torrust-tracker-deployer-types@0.1.0` + - [ ] `torrust-tracker-deployer-dependency-installer@0.1.0` + - [ ] `torrust-tracker-deployer@0.1.0` + - [ ] `torrust-tracker-deployer-sdk@0.1.0` +- [ ] docs.rs build page loads for the published versions + +**Process Quality**: + +- [ ] Every friction point or error encountered is documented (inline comment or + filed follow-up issue) +- [ ] Every fixable problem is fixed in the relevant artifact - documentation, + skill, script, or workflow - not just noted +- [ ] No step was silently skipped or improvised without documentation +- [ ] `docs/release-process.md` and the release skill accurately reflect how the + release was actually executed + +## Related Documentation + +- [Release Process](../release-process.md) +- [Release Skill](../../.github/skills/dev/git-workflow/release-new-version/skill.md) +- [beta.2 release issue #459](https://github.com/torrust/torrust-tracker-deployer/issues/459) + +## Notes + +This is a stable release (`0.1.0`), not a pre-release. Cargo users should receive +this version by default through normal semver resolution, and release notes should +highlight upgrade guidance from `0.1.0-beta.2` where relevant. diff --git a/docs/refactors/completed-refactorings.md b/docs/refactors/completed-refactorings.md index ee709f543..d3576d47a 100644 --- a/docs/refactors/completed-refactorings.md +++ b/docs/refactors/completed-refactorings.md @@ -4,7 +4,7 @@ | --------------------------------------------------- | ------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Standardize JsonView Render API | Feb 28, 2026 | Consistent `render()` return type + `Render` trait for all views | See git history at `docs/refactors/plans/standardize-json-view-render-api.md` - Introduced `ViewRenderError` + `Render` trait; removed inherent `render()` from all 26 view structs (13 `JsonView` + 13 `TextView`); eliminated dead fallback code; propagated errors through all handler chains with new `OutputFormatting` variant on 11 command error types; removed asymmetry between text and JSON renderers (3 phases, final commit `221c998a`, PR #402, 750 additions / 1528 deletions) | | SDK DDD Layer Boundary Fixes | Feb 25, 2026 | Remove DDD violations from SDK public surface | See git history at `docs/refactors/plans/sdk-ddd-layer-boundary-fixes.md` - Introduced `PersistenceError`, `InvalidStateError`, `ReleaseWorkflowStep` application-layer wrappers; updated all 9 command handler error enums; added `RepositoryProvider` trait; moved infra wiring to bootstrap; deleted orphaned `src/presentation/sdk/`; renamed `RepositoryFactory` β†’ `FileRepositoryFactory` (commits `6f3028f4`, `52628329`, PR #381) | -| Extract Shared Types Package | Feb 25, 2026 | Extract shared value objects and traits into packages/deployer-types/ | See git history at `docs/refactors/plans/extract-shared-types-package.md` - Created `packages/deployer-types/` (`torrust-deployer-types`) with all shared value objects and traits from `src/shared/` and `EnvironmentName` from `src/domain/`; root crate and SDK now depend on the types package, backward-compat re-exports maintained, PR #381 | +| Extract Shared Types Package | Feb 25, 2026 | Extract shared value objects and traits into packages/deployer-types/ | See git history at `docs/refactors/plans/extract-shared-types-package.md` - Created `packages/deployer-types/` (`torrust-tracker-deployer-types`) with all shared value objects and traits from `src/shared/` and `EnvironmentName` from `src/domain/`; root crate and SDK now depend on the types package, backward-compat re-exports maintained, PR #381 | | Extract SDK Workspace Package | Feb 25, 2026 | Create packages/sdk/ as independently consumable workspace package | See git history at `docs/refactors/plans/extract-sdk-workspace-package.md` - Created `packages/sdk/` (`torrust-tracker-deployer-sdk`) with SDK source, README, and examples moved from root `examples/sdk/`; backward compat deferred (cyclic dep resolved in Plan 3), PR #381 | | Presentation CLI/SDK Separation | Feb 25, 2026 | Separate CLI and SDK in presentation layer | See git history at `docs/refactors/plans/presentation-cli-sdk-separation.md` - Moved all CLI-specific modules (controllers, dispatch, input, views, error, errors, tests) under `src/presentation/cli/`, updated 160 files, SDK confirmed zero CLI imports (commit f02024f6, PR #381) | | E2E Test Isolation - Complete Log Directory Support | Feb 18, 2026 | Add log_dir to all E2E tests | See git history at `docs/refactors/plans/e2e-test-isolation-log-dir.md` - Added `.log_dir()` to 45 ProcessRunner calls across 6 E2E test files (validate, create, list, show, destroy, purge commands); all tests produce zero production `data/` pollution (6 phases, commits 1d576a5aβ†’1c437d80, Issue [#365](https://github.com/torrust/torrust-tracker-deployer/issues/365)) | diff --git a/docs/release-process.md b/docs/release-process.md index dbaa34ea1..7731773fd 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -32,12 +32,26 @@ Do not skip or reorder steps. Each step is a prerequisite for the next. ## Files to Update for Each Release -Update the `version` field in both files: +Update the `version` field in all four manifests: -- `Cargo.toml` (workspace root) β€” deployer binary version -- `packages/sdk/Cargo.toml` β€” `torrust-tracker-deployer-sdk` crate version +| File | Crate | +| ------------------------------------------ | ----------------------------------------------- | +| `Cargo.toml` (workspace root) | `torrust-tracker-deployer` | +| `packages/deployer-types/Cargo.toml` | `torrust-tracker-deployer-types` | +| `packages/dependency-installer/Cargo.toml` | `torrust-tracker-deployer-dependency-installer` | +| `packages/sdk/Cargo.toml` | `torrust-tracker-deployer-sdk` | -Both files must contain the same non-prefixed semver version (e.g., `1.2.3`). +All four must carry the same non-prefixed semver version string (e.g., `1.2.3`). + +Also ensure that every internal path dependency in each manifest declares an explicit +`version` constraint that matches the release version, for example: + +```toml +torrust-tracker-deployer-types = { path = "packages/deployer-types", version = "1.2.3" } +``` + +crates.io rejects packages with path-only dependencies (no `version` field) because +consumers resolving the crate from the registry cannot follow local paths. ## Pre-Flight Checklist @@ -54,27 +68,50 @@ Run these checks before starting any release actions: - `DOCKER_HUB_ACCESS_TOKEN` β€” secret - `DOCKER_HUB_USERNAME` β€” variable (value: `torrust`) - [ ] GitHub Environment `crates-io` exists and contains: - - `CARGO_REGISTRY_TOKEN` β€” secret + - `CARGO_REGISTRY_TOKEN` β€” secret with `publish-new` and `publish-update` scopes + for **all four** crate names: + - `torrust-tracker-deployer-types` + - `torrust-tracker-deployer-dependency-installer` + - `torrust-tracker-deployer` + - `torrust-tracker-deployer-sdk` + + > A token scoped to only one crate name will cause HTTP 403 Forbidden for all + > others. Create a single token covering all four names. **Permissions:** - [ ] You have push access to `main`, and can push tags and release branches - [ ] You have access to the `dockerhub-torrust` and `crates-io` environments -**Crate metadata** (before first publish of each crate): +**Crate metadata** (verify for all four crates before first publish, or whenever +adding a new publishable crate): -- [ ] `packages/sdk/Cargo.toml` has `description`, `license`, `repository`, and `readme` +- [ ] Each `Cargo.toml` has `description`, `license`, `repository`, and `readme` +- [ ] Each internal path dependency also declares an explicit `version` constraint +- [ ] All four crate names follow the `torrust-tracker-deployer-*` namespace + (crate names are permanent on crates.io β€” audit before first publish) +- [ ] `Cargo.lock` is committed and up to date ## Release Steps ### Step 1 β€” Update Versions -Edit the `version` field in both Cargo.toml files: +Edit the `version` field in all four `Cargo.toml` files. Also update the `version` +constraint on every internal path dependency in each manifest to match the new +release version: ```bash -# Edit Cargo.toml and packages/sdk/Cargo.toml -# Change: version = "X.Y.Z-dev" (or current dev version) -# To: version = "X.Y.Z" +# Edit these four files: +# Cargo.toml +# packages/deployer-types/Cargo.toml +# packages/dependency-installer/Cargo.toml +# packages/sdk/Cargo.toml +# +# In each, change: version = "X.Y.Z-dev" (or current dev version) +# to: version = "X.Y.Z" +# +# Also update the version constraint on internal path deps, for example: +# torrust-tracker-deployer-types = { path = "...", version = "X.Y.Z" } ``` Verify the workspace compiles and tests pass after the version change: @@ -86,10 +123,14 @@ cargo test ### Step 2 β€” Create the Release Commit -Stage only the version changes and create a signed commit: +Stage all four manifests **and `Cargo.lock`**, then create a signed commit: ```bash -git add Cargo.toml packages/sdk/Cargo.toml +git add Cargo.toml \ + packages/deployer-types/Cargo.toml \ + packages/dependency-installer/Cargo.toml \ + packages/sdk/Cargo.toml \ + Cargo.lock git commit -S -m "release: version vX.Y.Z" ``` @@ -136,7 +177,15 @@ the crate. Monitor the following workflows in GitHub Actions: - **Container** workflow β€” publishes the Docker image tagged `X.Y.Z` to Docker Hub -- **Publish Crate** workflow β€” publishes `torrust-tracker-deployer-sdk` to crates.io +- **Publish Crate** workflow β€” publishes all four crates to crates.io in dependency + order: + 1. `torrust-tracker-deployer-types` + 2. `torrust-tracker-deployer-dependency-installer` + 3. `torrust-tracker-deployer` + 4. `torrust-tracker-deployer-sdk` + + Each crate's dry-run step runs only after its prerequisites are available on + crates.io. Do not attempt to manually publish out of order. Both workflows must succeed before moving to step 7. See [Finalization Gates](#finalization-gates) below. @@ -177,19 +226,34 @@ docker run --rm --entrypoint tofu torrust/tracker-deployer:X.Y.Z version ## Crate Verification -After the Publish Crate workflow completes: +After the Publish Crate workflow completes, verify all four crates are indexed +(crates.io indexing may take a few minutes after publish): ```bash -# Verify the crate is visible on crates.io -# (indexing may take a few minutes after publish) -curl -sf "https://crates.io/api/v1/crates/torrust-tracker-deployer-sdk/X.Y.Z" | jq '.version.num' - -# Verify docs.rs build -# https://docs.rs/torrust-tracker-deployer-sdk/X.Y.Z +for crate in \ + torrust-tracker-deployer-types \ + torrust-tracker-deployer-dependency-installer \ + torrust-tracker-deployer \ + torrust-tracker-deployer-sdk; do + status=$(curl -s -o /dev/null -w "%{http_code}" \ + "https://crates.io/api/v1/crates/$crate/X.Y.Z") + echo "$crate: HTTP $status" +done ``` -It is normal for the crates.io index and docs.rs build to take a few minutes. -Check the GitHub release notes for links once propagation is complete. +All four should return `HTTP 200`. If any return 404, wait a few minutes and retry. + +**docs.rs** pages may take minutes to hours to become available after a first +publish, especially for a new crate. The Publish Crate workflow prints the URLs +as informational output. Verify them manually when convenient: + +- `https://docs.rs/torrust-tracker-deployer-types/X.Y.Z` +- `https://docs.rs/torrust-tracker-deployer-dependency-installer/X.Y.Z` +- `https://docs.rs/torrust-tracker-deployer/X.Y.Z` +- `https://docs.rs/torrust-tracker-deployer-sdk/X.Y.Z` + +A 404 on docs.rs is **not** a release failure. The crate is published; docs.rs +builds in its own queue. ## Failure Handling and Recovery diff --git a/docs/research/caddy-tls-proxy-evaluation/security-scan.md b/docs/research/caddy-tls-proxy-evaluation/security-scan.md index fb1521508..6a9ba7dfe 100644 --- a/docs/research/caddy-tls-proxy-evaluation/security-scan.md +++ b/docs/research/caddy-tls-proxy-evaluation/security-scan.md @@ -28,7 +28,6 @@ ### HIGH Severity 1. **CVE-2025-59530** - Crash in github.com/quic-go/quic-go - - **Component**: `github.com/quic-go/quic-go` - **Installed Version**: v0.54.0 - **Fixed Version**: 0.49.1, 0.54.1 @@ -36,7 +35,6 @@ - **Reference**: https://avd.aquasec.com/nvd/cve-2025-59530 2. **CVE-2025-58183** - Unbounded allocation in Go stdlib - - **Component**: `stdlib` - **Installed Version**: v1.25.0 - **Fixed Version**: 1.24.8, 1.25.2 @@ -55,13 +53,11 @@ ### Risk Assessment 1. **CVE-2025-44005 (CRITICAL)**: - - **Impact**: Authorization bypass in certificate creation - **Mitigation**: This affects the `smallstep/certificates` library, which is used by Caddy for certificate management - **Action Required**: Monitor for Caddy v2.11 release with updated dependencies 2. **CVE-2025-59530 (HIGH)**: - - **Impact**: QUIC protocol crash vulnerability - **Mitigation**: Affects HTTP/3 (QUIC) support; HTTP/2 and HTTP/1.1 not affected - **Action Required**: Monitor for Caddy release with patched QUIC library @@ -106,14 +102,12 @@ Caddy's vulnerability count is within normal range for Go-based proxies. When Caddy is officially integrated into the deployer (new issue), the following workflow updates will be required: 1. **Update `.github/workflows/docker-security-scan.yml`**: - - Add `caddy:2.10` (or latest version) to the third-party images matrix - This ensures automated security scanning in CI/CD pipeline 2. **Add to security scan documentation**: - - - Create `docs/security/docker/scans/caddy.md` with scan history - - Update summary table in `docs/security/docker/scans/README.md` + - Create `docs/security/production/scans/caddy.md` with scan history + - Update summary table in `docs/security/production/scans/README.md` 3. **Set up GitHub Security monitoring**: - SARIF results will automatically upload to GitHub Security tab diff --git a/docs/security/README.md b/docs/security/README.md new file mode 100644 index 000000000..a85d4f6e9 --- /dev/null +++ b/docs/security/README.md @@ -0,0 +1,111 @@ +# Security Overview + +This directory documents security considerations for the Torrust Tracker Deployer project, organized by priority level. + +## Priority Levels + +Security effort should be distributed according to exposure and risk. The highest-priority areas are those that directly affect end users in production. + +### Priority 1 β€” Production Environment (Critical) + +**Directory**: [`production/`](production/) + +The most critical security surface: the Docker images, OS packages, system dependencies, and server configuration that the deployer deploys to production. + +These are exposed to the internet and run continuously. Any vulnerability here directly affects tracker users. + +**Scope**: + +- Service container images: `caddy`, `prom/prometheus`, `grafana/grafana`, `mysql` +- Backup service container: `torrust/tracker-backup` +- OS base layers of the provisioned VM +- Server configuration (TLS, SSH access policies) + +**Scan history**: [`production/scans/`](production/scans/) + +--- + +### Priority 2 β€” User Workflow Security (Important) + +**Directory**: [`user-security/`](user-security/) + +How users interact with the deployer affects the security of their deployments. Mistakes here can expose secrets or production credentials. + +**Scope**: + +- Sharing secrets with AI coding agents during deployment +- SSH access controls and key management +- Safe handling of deployment credentials (`envs/*.json`) + +**Documents**: + +- [AI Agents and Secrets](user-security/ai-agents-and-secrets.md) β€” risks when using cloud-based AI agents during deployments +- [SSH Root Access on Hetzner](user-security/ssh-root-access-hetzner.md) β€” SSH key behavior and hardening guidance + +--- + +### Priority 3 β€” Deployer Tooling Security (Standard) + +**Directory**: [`deployer/`](deployer/) + +The deployer itself β€” its Rust binary, container images, and bundled tools (OpenTofu, Ansible). This is a **lower-risk surface** because: + +- Users run the deployer locally for minutes at a time +- It is not exposed to the internet during normal use +- It runs in a controlled local or CI environment + +This priority increases if the deployer is ever embedded in a long-running service (e.g., a web application that calls the deployer on demand). + +**Scope**: + +- The deployer container image: `torrust/tracker-deployer` (Rust binary + OpenTofu + Ansible) +- Rust dependency vulnerabilities (`cargo audit` / RustSec) +- Bundled tool vulnerabilities: OpenTofu, Ansible + +**Subdirectories**: + +- [`deployer/docker/`](deployer/docker/) β€” Docker image scans +- [`deployer/dependencies/`](deployer/dependencies/) β€” Rust dependency audits + +--- + +### Priority 4 β€” Testing Artifacts (Low) + +**Directory**: [`testing/`](testing/) + +Docker images and other artifacts used only in automated tests or local development. These never run in production and have a minimal attack surface. + +**Scope**: + +- `torrust/tracker-ssh-server` β€” SSH server used in E2E integration tests +- `torrust/tracker-provisioned-instance` β€” Ubuntu VM simulation used in E2E deployment workflow tests + +**Scan history**: [`testing/scans/`](testing/scans/) + +--- + +## Scan Tooling + +| Tool | Purpose | Run Command | +| ----------- | ------------------------- | ---------------------------------------------- | +| Trivy | Docker image CVE scanning | `trivy image --severity HIGH,CRITICAL ` | +| cargo-audit | Rust dependency audits | `cargo audit` | + +## Current Security Status + +### Production Images + +See [`production/scans/README.md`](production/scans/README.md) for the latest status of all production-deployed images. + +### Deployer Images + +See [`deployer/docker/scans/README.md`](deployer/docker/scans/README.md) for the latest status of deployer-internal images. + +### Rust Dependencies + +See [`deployer/dependencies/README.md`](deployer/dependencies/README.md) for the latest cargo-audit report. + +## Related Documentation + +- [Docker Image Scanning Guide](production/README.md) +- [Dependency Security Reports](deployer/dependencies/README.md) diff --git a/docs/security/deployer/README.md b/docs/security/deployer/README.md new file mode 100644 index 000000000..2cd35576d --- /dev/null +++ b/docs/security/deployer/README.md @@ -0,0 +1,30 @@ +# Deployer Tooling Security + +This directory covers security for the deployer's own tools and container images. +These are [Priority 3](../README.md) β€” a lower-risk surface because the deployer runs locally for minutes at a time and is not exposed to the internet. + +> **Note**: This priority increases if the deployer is ever embedded in a long-running service +> (e.g., a web application that provisions environments on demand). + +## Subdirectories + +### [`docker/`](docker/) + +Security scans for Docker images used by the deployer itself: + +- `torrust/tracker-deployer` β€” the deployer container (Rust binary + OpenTofu + Ansible) +- `torrust/tracker-backup` β€” backup helper container +- `torrust/tracker-ssh-server` β€” SSH server used in local testing + +### [`dependencies/`](dependencies/) + +Rust dependency security audits via `cargo audit`: + +- Tracks RustSec advisories for the deployer's Cargo.lock +- Records remediation actions and accepted risks + +## Relationship to Priority 1 + +Vulnerabilities in deployer tooling are less urgent than production image vulnerabilities +because the deployer is a short-lived local tool. However, CRITICAL CVEs in tools like +OpenTofu or Ansible should still be tracked and addressed when upstream fixes are available. diff --git a/docs/security/dependencies/README.md b/docs/security/deployer/dependencies/README.md similarity index 100% rename from docs/security/dependencies/README.md rename to docs/security/deployer/dependencies/README.md diff --git a/docs/security/dependencies/scans/2026-04-10-cargo-audit.md b/docs/security/deployer/dependencies/scans/2026-04-10-cargo-audit.md similarity index 95% rename from docs/security/dependencies/scans/2026-04-10-cargo-audit.md rename to docs/security/deployer/dependencies/scans/2026-04-10-cargo-audit.md index 47a60be10..f6f09c9e2 100644 --- a/docs/security/dependencies/scans/2026-04-10-cargo-audit.md +++ b/docs/security/deployer/dependencies/scans/2026-04-10-cargo-audit.md @@ -69,4 +69,4 @@ No follow-up issue was required for this scan because all reported vulnerabiliti - Main task: - Workflow: `.github/workflows/cargo-security-audit.yml` -- Dependency report index: `docs/security/dependencies/README.md` +- Dependency report index: `docs/security/deployer/dependencies/README.md` diff --git a/docs/security/docker/README.md b/docs/security/deployer/docker/README.md similarity index 83% rename from docs/security/docker/README.md rename to docs/security/deployer/docker/README.md index e4ef218e0..b5a0b8a2b 100644 --- a/docs/security/docker/README.md +++ b/docs/security/deployer/docker/README.md @@ -1,15 +1,21 @@ -# Docker Image Security Scanning Guide +# Deployer Docker Image Security -This document explains how to perform security scans on Docker images used in the deployer. +This directory covers security scanning for Docker images used by the deployer tooling. +These are [Priority 3](../../README.md) images β€” they run locally for minutes during deployment +and are not exposed to the internet. + +For production image security, see [`../../production/`](../../production/). ## Purpose -Regular security scanning ensures that Docker images used in production deployments are free from known vulnerabilities. This documentation provides: +Regular security scanning ensures that deployer tool images are free from known vulnerabilities. This documentation provides: -- Instructions for running security scans +- Instructions for running security scans on deployer images - Configuration guidelines - Best practices for vulnerability management +See [`../../production/`](../../production/) for scanning guidance on production-deployed images. + ## Automated Scanning For ongoing security monitoring, see [Issue #250: Implement periodic security vulnerability scanning workflow](https://github.com/torrust/torrust-tracker-deployer/issues/250). @@ -121,13 +127,8 @@ trivy image --severity HIGH,CRITICAL prom/prometheus:v3.5.0 See the [scans/](scans/) directory for historical security scan results: - [Torrust Tracker Deployer](scans/torrust-tracker-deployer.md) -- [Torrust Tracker Backup](scans/tracker-backup.md) -- [Prometheus](scans/prometheus.md) -- [Grafana](scans/grafana.md) -- [MySQL](scans/mysql.md) ## References - [Trivy Documentation](https://aquasecurity.github.io/trivy/) - [Issue #250: Automated Security Scanning](https://github.com/torrust/torrust-tracker-deployer/issues/250) -- [Issue #253: Docker Image Updates](https://github.com/torrust/torrust-tracker-deployer/issues/253) diff --git a/docs/security/deployer/docker/scans/README.md b/docs/security/deployer/docker/scans/README.md new file mode 100644 index 000000000..b4efce9f8 --- /dev/null +++ b/docs/security/deployer/docker/scans/README.md @@ -0,0 +1,31 @@ +# Deployer Docker Image Scan Results + +Historical security scan results for Docker images used by the deployer itself. +These are [Priority 3](../../README.md) images β€” lower risk, short-lived, not internet-exposed. + +For production image scans, see [`../../../production/scans/`](../../../production/scans/). + +## Current Status Summary + +| Image | Version | HIGH | CRITICAL | Status | Last Scan | Details | +| -------------------------- | ------- | ---- | -------- | -------------------------------------- | ------------ | ----------------------------------- | +| `torrust/tracker-deployer` | trixie | 46 | 1 | ⚠️ CRITICAL blocked (OpenTofu grpc-go) | Apr 15, 2026 | [View](torrust-tracker-deployer.md) | + +## Scan Archives + +- [torrust-tracker-deployer.md](torrust-tracker-deployer.md) β€” Deployer (base: rust:trixie) + +For backup service scans (production container), see [`../../../production/scans/torrust-tracker-backup.md`](../../../production/scans/torrust-tracker-backup.md). +For SSH server and provisioned-instance scans (testing only), see [`../../../testing/scans/`](../../../testing/scans/). + +## Build and Scan + +```bash +# Build deployer image +docker build --target release --tag torrust/tracker-deployer:local --file docker/deployer/Dockerfile . + +# Scan +trivy image --severity HIGH,CRITICAL torrust/tracker-deployer:local +``` + +See [`../README.md`](../README.md) for detailed scanning instructions. diff --git a/docs/security/docker/scans/torrust-tracker-deployer.md b/docs/security/deployer/docker/scans/torrust-tracker-deployer.md similarity index 75% rename from docs/security/docker/scans/torrust-tracker-deployer.md rename to docs/security/deployer/docker/scans/torrust-tracker-deployer.md index 32706615c..dcc27b3da 100644 --- a/docs/security/docker/scans/torrust-tracker-deployer.md +++ b/docs/security/deployer/docker/scans/torrust-tracker-deployer.md @@ -4,9 +4,9 @@ Security scan history for the `torrust/tracker-deployer` Docker image. ## Current Status -| Version | HIGH | CRITICAL | Status | Last Scan | -| ------- | ---- | -------- | ------------------------------------------ | ----------- | -| trixie | 44 | 1 | ⚠️ Improved after remediation (still open) | Apr 8, 2026 | +| Version | HIGH | CRITICAL | Status | Last Scan | +| ------- | ---- | -------- | -------------------------------------------------- | ------------ | +| trixie | 46 | 1 | ⚠️ CRITICAL blocked on OpenTofu upstream (grpc-go) | Apr 15, 2026 | ## Build & Scan Commands @@ -24,6 +24,76 @@ trivy image --severity HIGH,CRITICAL torrust/tracker-deployer:local ## Scan History +### April 15, 2026 - Remediation Pass 2 (Issue #429) + +**Image**: `torrust/tracker-deployer:local` +**OpenTofu version**: v1.11.6 (latest, released 2026-04-08) +**Trivy Version**: 0.69.3 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Base OS**: Debian 13.4 (trixie) +**Status**: ⚠️ **1 CRITICAL remains** (blocked on OpenTofu upstream) β€” 46 HIGH, 1 CRITICAL + +#### Summary + +Image rebuilt from scratch with `--no-cache`. OpenTofu v1.11.6 (latest) was installed. +CRITICAL in `usr/bin/tofu` (CVE-2026-33186, grpc-go) **remains unresolved** β€” needs +OpenTofu to upgrade `google.golang.org/grpc` to v1.79.3+. + +#### Target breakdown + +| Target | HIGH | CRITICAL | +| ---------------------------------------------- | ------ | -------- | +| `torrust/tracker-deployer:local` (debian 13.4) | 42 | 0 | +| `usr/bin/tofu` | 4 | 1 | +| **Total** | **46** | **1** | + +#### Comparison vs pass 1 (Apr 8) + +| Target | Apr 8 (HIGH / CRITICAL) | Apr 15 (HIGH / CRITICAL) | Delta | +| -------------- | ----------------------- | ------------------------ | ------------------------------------------ | +| Debian OS | 42 / 0 | 42 / 0 | no change (same Debian state) | +| `usr/bin/tofu` | 2 / 1 | 4 / 1 | +2 HIGH (Trivy DB update) | +| **Total** | **44 / 1** | **46 / 1** | **+2 HIGH (Trivy DB), CRITICAL unchanged** | + +#### `usr/bin/tofu` CVE details (OpenTofu v1.11.6) + +| CVE | Library | Severity | Status | Installed | Fixed | Title | +| -------------- | ------------------------------ | -------- | ------ | --------- | ------ | ----------------------------------------------- | +| CVE-2026-33186 | google.golang.org/grpc | CRITICAL | fixed | v1.76.0 | 1.79.3 | gRPC-Go: Authorization bypass via HTTP/2 path | +| CVE-2026-34986 | github.com/go-jose/go-jose/v4 | HIGH | fixed | v4.1.2 | 4.1.4 | JOSE: DoS via crafted JSON Web Encryption | +| CVE-2026-4660 | github.com/hashicorp/go-getter | HIGH | fixed | v1.8.2 | 1.8.6 | go-getter: Arbitrary file reads via crafted URL | +| CVE-2026-24051 | go.opentelemetry.io/otel/sdk | HIGH | fixed | v1.38.0 | 1.40.0 | OTel Go SDK: Arbitrary code execution via PATH | +| CVE-2026-39883 | go.opentelemetry.io/otel/sdk | HIGH | fixed | v1.38.0 | 1.43.0 | OTel Go SDK: BSD kenv PATH hijacking | + +All `usr/bin/tofu` CVEs have fixes available in their respective upstream libraries but +require OpenTofu to update its Go module dependencies and ship a new release. + +#### Notable Debian OS CVEs (selected new or notable HIGH, all `affected` / no fix in trixie) + +| CVE | Package | Title | +| -------------- | -------------- | ----------------------------------------------------------- | +| CVE-2025-13836 | python3.13 | cpython: Excessive read buffering DoS in http.client | +| CVE-2025-15366 | python3.13 | cpython: IMAP command injection (`will_not_fix`) | +| CVE-2025-15367 | python3.13 | cpython: POP3 command injection (`will_not_fix`) | +| CVE-2026-25210 | libexpat1 | libexpat: Integer overflow β€” data integrity issues | +| CVE-2026-29111 | libsystemd0 | systemd: Assert/freeze via spurious IPC (``) | +| CVE-2026-35385 | openssh-client | OpenSSH: Priv escalation via scp legacy protocol | +| CVE-2026-35414 | openssh-client | OpenSSH: Security bypass via authorized_keys principals | +| CVE-2026-35535 | sudo | Sudo: Privilege escalation via failed privilege drop | +| CVE-2025-69720 | ncurses | ncurses: Buffer overflow in `infocmp` CLI tool (``) | + +#### Decision + +**Leave issue #429 open β€” CRITICAL unresolved.** + +- CRITICAL CVE-2026-33186 (grpc-go, gRPC authorization bypass) remains in `usr/bin/tofu` v1.11.6 +- Fix requires OpenTofu to bump `google.golang.org/grpc` to v1.79.3+ and ship a new release +- Debian OS CVEs are all `affected`/`will_not_fix`/`` with no trixie backports available + +**Revisit**: When OpenTofu releases v1.11.7+ or v1.12.x with updated `grpc-go` dependency. + +--- + ### April 8, 2026 - Remediation Pass 1 (Issue #428) **Image**: `torrust/tracker-deployer:local` diff --git a/docs/security/docker/scans/README.md b/docs/security/docker/scans/README.md deleted file mode 100644 index 1d176fbcc..000000000 --- a/docs/security/docker/scans/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# Security Scan Results - -This directory contains historical security scan results for Docker images used in the deployer. - -## Current Status Summary - -| Image | Version | HIGH | CRITICAL | Status | Last Scan | Details | -| -------------------------------------- | ------- | ---- | -------- | ------------------------- | ----------- | ----------------------------------------------- | -| `torrust/tracker-deployer` | trixie | 44 | 1 | ⚠️ Partial remediation | Apr 8, 2026 | [View](torrust-tracker-deployer.md) | -| `torrust/tracker-backup` | trixie | 6 | 0 | ℹ️ Remediation no change | Apr 8, 2026 | [View](torrust-tracker-backup.md) | -| `torrust/tracker-ssh-server` | 3.23.3 | 0 | 0 | βœ… Remediated (vuln scan) | Apr 8, 2026 | [View](torrust-ssh-server.md) | -| `torrust/tracker-provisioned-instance` | 24.04 | 0 | 0 | βœ… Remediated (vuln scan) | Apr 8, 2026 | [View](torrust-tracker-provisioned-instance.md) | -| `caddy` | 2.10.2 | 14 | 4 | ⚠️ Partial remediation | Apr 8, 2026 | [View](caddy.md) | -| `prom/prometheus` | v3.5.1 | 6 | 4 | ⚠️ Partial remediation | Apr 8, 2026 | [View](prometheus.md) | -| `grafana/grafana` | 12.4.2 | 4 | 0 | ⚠️ Partial remediation | Apr 8, 2026 | [View](grafana.md) | -| `mysql` | 8.4 | 7 | 1 | ⚠️ Monitored | Apr 8, 2026 | [View](mysql.md) | - -**Overall Status**: ⚠️ **CVE database update detected** - Most images still show increased vulnerability counts from previous scans (Feb-Dec 2025). Deployer has a first remediation pass applied (49 HIGH -> 44 HIGH, with 1 CRITICAL still open). - -## Scan Archives - -Each file contains the complete scan history for a service: - -- [torrust-tracker-deployer.md](torrust-tracker-deployer.md) - Deployer (base: rust:trixie, **updated from bookworm**) -- [torrust-tracker-backup.md](torrust-tracker-backup.md) - Backup container (base: debian:trixie-slim, **updated**) -- [torrust-ssh-server.md](torrust-ssh-server.md) - SSH test server (base: alpine:3.23.3, **new**) -- [torrust-tracker-provisioned-instance.md](torrust-tracker-provisioned-instance.md) - Ubuntu VM simulation (base: ubuntu:24.04, **new**) -- [caddy.md](caddy.md) - Caddy TLS termination proxy -- [prometheus.md](prometheus.md) - Prometheus monitoring -- [grafana.md](grafana.md) - Grafana dashboards -- [mysql.md](mysql.md) - MySQL database - -## Build & Scan All Images - -To build and scan all Torrust Tracker Deployer images: - -```bash -# Build all images -docker build --target release --tag torrust/tracker-deployer:local --file docker/deployer/Dockerfile . -docker build --tag torrust/tracker-backup:local docker/backup/ -docker build --tag torrust/tracker-ssh-server:local docker/ssh-server/ -docker build --tag torrust/tracker-provisioned-instance:local docker/provisioned-instance/ - -# Run scans on all images -trivy image --severity HIGH,CRITICAL torrust/tracker-deployer:local -trivy image --severity HIGH,CRITICAL torrust/tracker-backup:local -trivy image --severity HIGH,CRITICAL torrust/tracker-ssh-server:local -trivy image --severity HIGH,CRITICAL torrust/tracker-provisioned-instance:local -``` - -## Scanning Standards - -All scans use: - -- **Tool**: Trivy (latest) -- **Severity Filter**: HIGH and CRITICAL only (MEDIUM and LOW omitted for brevity) -- **Update Frequency**: On every push (GitHub Actions), weekly schedules, and manual verification -- **Documentation**: Each scan includes context on image purpose, vulnerability analysis, and mitigation strategies - -## How to Add New Scans - -1. Build image: `docker build --tag :local ` -2. Run Trivy scan: `trivy image --severity HIGH,CRITICAL :local` -3. Create or update scan file in this directory -4. Update the summary table above -5. Commit with message: `docs: add security scan for ()` or `docs: [#] update security scans` - -See [../README.md](../README.md) for detailed scanning instructions and best practices. - -## Image Purpose & Risk Context - -Each image serves a different purpose with different security contexts: - -| Image | Purpose | Runtime | Network Exposure | Data Access | Risk Level | -| ------------------------ | ---------------------------------------- | ------------------- | ----------------- | ------------------ | ---------- | -| **Deployer** | CLI tool for infrastructure provisioning | User's machine / CI | None | SSH keys only | LOW | -| **Backup** | Database backup container | Controlled schedule | Internal only | Read access to DB | MEDIUM | -| **SSH Server** | E2E testing SSH connectivity | CI test environment | Test network only | Test data only | NEGLIGIBLE | -| **Provisioned Instance** | E2E deployment workflow testing | CI test environment | Test network only | Test data only | NEGLIGIBLE | -| **Caddy** | TLS termination and reverse proxy | Production optional | Public internet | Configuration only | MEDIUM | -| **Prometheus** | Metrics collection | Infrastructure | Internal network | Metrics only | LOW | -| **Grafana** | Metrics visualization | Infrastructure | Internal network | Read-only graphs | LOW | -| **MySQL** | Database storage | Infrastructure | Internal network | Application data | HIGH | - -## Security Updates Schedule - -- **Deployer image**: Rebuilt whenever Rust or Debian releases updates (typically monthly) -- **Backup image**: Rebuilt with base OS updates (tied to Debian release cycle) -- **SSH/Provisioned**: Rebuilt on every CI run (via GitHub Actions) -- **Monitoring images**: Scanned weekly, rebuilt when security advisories issued - -## References - -- [Trivy Documentation](https://aquasecurity.github.io/trivy/) -- [OWASP Docker Security](https://owasp.org/www-community/attacks/Docker_Escapes) -- [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker) -- [GitHub Actions Docker Security](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions) diff --git a/docs/security/docker/scans/caddy.md b/docs/security/docker/scans/caddy.md deleted file mode 100644 index f2b6fe78e..000000000 --- a/docs/security/docker/scans/caddy.md +++ /dev/null @@ -1,94 +0,0 @@ -# Caddy Security Scan History - -**Image**: `caddy:2.10.2` -**Purpose**: TLS termination proxy for HTTPS support -**Documentation**: [Caddy TLS Proxy Evaluation](../../research/caddy-tls-proxy-evaluation/README.md) - -## Current Status - -| Version | HIGH | CRITICAL | Status | Scan Date | -| ------- | ---- | -------- | ------------------------------------ | ----------- | -| 2.10.2 | 14 | 4 | ⚠️ Partial improvement after upgrade | Apr 8, 2026 | - -**Deployment Status**: ⚠️ Requires follow-up - upgrading from `2.10` to `2.10.2` reduced findings, but HIGH/CRITICAL issues remain in Caddy binary dependencies - -## Vulnerability Summary - -The Caddy 2.10 image has: - -- **Alpine base image**: Clean (0 vulnerabilities) -- **Caddy binary (Go)**: 4 vulnerabilities in dependencies (not Caddy core) - -All vulnerabilities have fixed versions available upstream and are expected to be resolved in the next Caddy release. - -## Scan History - -### April 8, 2026 - Remediation Pass 1 (Issue #428) - -**Scanner**: Trivy v0.68.2 -**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` -**Image**: `caddy:2.10.2` -**Status**: ⚠️ **18 vulnerabilities** (14 HIGH, 4 CRITICAL) - -#### Summary - -Easy remediation applied by upgrading Caddy image tag from `2.10` to `2.10.2`. - -Vulnerability comparison: - -- Previous (`2.10`): 18 HIGH, 6 CRITICAL -- Current (`2.10.2`): 14 HIGH, 4 CRITICAL - -Improvement: -4 HIGH, -2 CRITICAL - -#### Target Breakdown (`2.10.2`) - -| Target | Type | HIGH | CRITICAL | -| ------------- | -------- | ---- | -------- | -| usr/bin/caddy | gobinary | 14 | 4 | - -Remaining issues are in upstream Caddy binary dependencies and require vendor/upstream updates. - -### January 13, 2026 - caddy:2.10 - -**Scanner**: Trivy v0.68 - -| Target | Type | HIGH | CRITICAL | -| -------------------------- | -------- | ---- | -------- | -| caddy:2.10 (alpine 3.22.2) | alpine | 0 | 0 | -| usr/bin/caddy | gobinary | 3 | 1 | - -**Vulnerabilities Found**: - -| CVE | Severity | Component | Fixed Version | -| -------------- | -------- | --------------------------------- | --------------- | -| CVE-2025-44005 | CRITICAL | github.com/smallstep/certificates | 0.29.0 | -| CVE-2025-59530 | HIGH | github.com/quic-go/quic-go | 0.49.1, 0.54.1 | -| CVE-2025-58183 | HIGH | stdlib (archive/tar) | 1.24.8, 1.25.2 | -| CVE-2025-61729 | HIGH | stdlib (crypto/x509) | 1.24.11, 1.25.5 | - -**Risk Assessment**: - -1. **CVE-2025-44005**: Authorization bypass in certificate creation (smallstep library) -2. **CVE-2025-59530**: QUIC protocol crash (affects HTTP/3 only) -3. **CVE-2025-58183**: Unbounded allocation in tar parsing -4. **CVE-2025-61729**: Resource consumption in x509 certificate validation - -**Recommendation**: Deploy with monitoring. Update to patched version when Caddy v2.11 releases. - -## Related Documentation - -- [Full Security Analysis](../../../research/caddy-tls-proxy-evaluation/security-scan.md) -- [Caddy Evaluation Summary](../../../research/caddy-tls-proxy-evaluation/README.md) -- [HTTPS Implementation](../../../issues/272-add-https-support-with-caddy.md) - -## How to Rescan - -```bash -trivy image --severity HIGH,CRITICAL caddy:2.10.2 -``` - -## Security Advisories - -- **Caddy**: -- **Alpine Linux**: diff --git a/docs/security/docker/scans/mysql.md b/docs/security/docker/scans/mysql.md deleted file mode 100644 index 821116dc8..000000000 --- a/docs/security/docker/scans/mysql.md +++ /dev/null @@ -1,97 +0,0 @@ -# MySQL - Security Scans - -Security scan history for the `mysql` Docker image. - -## Current Status - -| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | -| ------- | ---- | -------- | ------------------------------------ | ----------- | ------------ | -| 8.4 | 7 | 1 | ⚠️ Monitored (no safer easy upgrade) | Apr 8, 2026 | Apr 30, 2032 | - -## Scan History - -### April 8, 2026 - Remediation Pass 1 (Issue #428) - -**Image**: `mysql:8.4` -**Trivy Version**: 0.68.2 -**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` -**Status**: ⚠️ **8 vulnerabilities** (7 HIGH, 1 CRITICAL) - -#### Summary - -Findings are concentrated in helper components, not MySQL server core: - -- Python packages: 2 HIGH -- `gosu` Go stdlib dependencies: 5 HIGH, 1 CRITICAL - -Tag comparison for easy remediation was performed (`8.4.1`, `8.4.2`, `8.4.3`, `9.0`, `9.1`, `latest`). -No safer drop-in tag with lower overall risk profile was identified for immediate adoption in this pass. - -#### Decision - -- Keep `mysql:8.4` for now (validated runtime and LTS alignment) -- Track unresolved CVEs in follow-up issue for deeper investigation - -### April 8, 2026 - -**Image**: `mysql:8.4` -**Trivy Version**: 0.68.2 -**Status**: ⚠️ **8 vulnerabilities** (8 HIGH, 0 CRITICAL) - Increase from Dec scan - -#### Summary - -Vulnerability count increased from 0 to 8 HIGH. Breakdown: - -- Python libraries: 2 HIGH -- `/usr/local/bin/gosu`: 6 HIGH - -This increase suggests Trivy database update rather than actual MySQL regression. - -#### Changes Since December - -- December scan: 0 vulnerabilities -- April scan: 8 HIGH -- MySQL server binary itself appears unaffected - -**Recommended Action**: Most concerns are in helper binaries (gosu) and Python tools, not MySQL core. Verify with MySQL security advisories: https://www.mysql.com/support/security/ - -### December 29, 2025 - -**Image**: `mysql:8.4` -**Trivy Version**: 0.68.2 -**Status**: βœ… SECURE - 0 HIGH/CRITICAL vulnerabilities - -#### Results - -```text -mysql:8.4 (oracle 9.7) -====================== -Total: 0 (HIGH: 0, CRITICAL: 0) - -MySQL server core: 0 vulnerabilities -``` - -#### Notes - -- MySQL 8.4 is an LTS release with extended support -- Oracle Linux 9.7 base has no HIGH/CRITICAL vulnerabilities -- MySQL server itself has 0 vulnerabilities -- LTS release designed for production stability - -#### Support Status - -- Release: April 10, 2024 -- Premier Support: Until April 30, 2029 (3+ years remaining) -- Extended Support: Until April 30, 2032 (6+ years remaining) -- LTS Release: Designed for production stability - ---- - -### Previous Scans - -#### December 23, 2025 (Pre-Update Baseline) - -**Image**: `mysql:8.0` -**Status**: Preliminary scan - 0 HIGH/CRITICAL (informal assessment) - -**Note**: December 23 scan was a preliminary assessment before formal documentation was established. diff --git a/docs/security/production/README.md b/docs/security/production/README.md new file mode 100644 index 000000000..921e82cee --- /dev/null +++ b/docs/security/production/README.md @@ -0,0 +1,59 @@ +# Production Image Security + +This directory covers security scanning for Docker images that the deployer **deploys to production**. +These are [Priority 1](../README.md) β€” the highest-risk surface because they run continuously and are exposed to the internet. + +## Images Covered + +| Image | Role | +| ------------------------ | ------------------------------------------------------------------- | +| `caddy` | TLS termination proxy β€” public-facing | +| `prom/prometheus` | Metrics collection | +| `grafana/grafana` | Metrics dashboards | +| `mysql` | Tracker database | +| `torrust/tracker-backup` | Backup service β€” runs on a schedule inside the deployed environment | + +## Scanning with Trivy + +```bash +# Scan a production image +trivy image --severity HIGH,CRITICAL caddy:2.11.2 + +# Scan and output JSON +trivy image --format json --output report.json caddy:2.11.2 + +# Scan all severities for a full report +trivy image caddy:2.11.2 +``` + +## When to Act on Findings + +**CRITICAL severity**: + +1. Check whether the upstream vendor has released a patched image +2. Update the image version in `templates/docker-compose/docker-compose.yml.tera` +3. Re-scan the updated image to confirm the fix +4. Update scan history in `scans/.md` + +**HIGH severity**: + +1. Check Debian/Alpine security tracker for fix availability +2. If a fix exists, update the image as above +3. If no fix exists (`affected` / `will_not_fix` / ``), document the accepted risk + +## Best Practices + +- Pin to specific versions, never `latest`, in production templates +- Prefer official vendor images (`prom`, `grafana`, `mysql`) +- Re-scan after every image version bump +- Monitor vendor security advisories + +## Scan History + +See [`scans/`](scans/) for per-image scan history and current status. + +## References + +- [Trivy Documentation](https://aquasecurity.github.io/trivy/) +- [Debian Security Tracker](https://security-tracker.debian.org/tracker/) +- [Issue #250: Automated Security Scanning](https://github.com/torrust/torrust-tracker-deployer/issues/250) diff --git a/docs/security/production/scans/README.md b/docs/security/production/scans/README.md new file mode 100644 index 000000000..c5064ab22 --- /dev/null +++ b/docs/security/production/scans/README.md @@ -0,0 +1,27 @@ +# Production Image Scan Results + +Historical security scan results for Docker images deployed to production by the deployer. + +## Current Status Summary + +| Image | Version | HIGH | CRITICAL | Status | Last Scan | Details | +| ------------------------ | ------- | ---- | -------- | ----------------------------------------- | ------------ | --------------------------------- | +| `caddy` | 2.11.2 | 10 | 2 | ⚠️ CRITICAL pending upstream | Apr 15, 2026 | [View](caddy.md) | +| `prom/prometheus` | v3.11.2 | 4 | 0 | βœ… Remediated | Apr 14, 2026 | [View](prometheus.md) | +| `grafana/grafana` | 12.4.2 | 4 | 0 | ⚠️ Accepted risk (OS ``) | Apr 8, 2026 | [View](grafana.md) | +| `mysql` | 8.4 | 9 | 1 | ⚠️ Accepted risk (gosu/mysqlsh, not core) | Apr 15, 2026 | [View](mysql.md) | +| `torrust/tracker-backup` | trixie | 6 | 0 | ⚠️ Accepted risk (Debian ``) | Apr 15, 2026 | [View](torrust-tracker-backup.md) | + +## Scanning Instructions + +See [`../README.md`](../README.md) for Trivy usage and remediation workflow. + +## Scan Archives + +Each file contains the complete scan history for a service: + +- [caddy.md](caddy.md) β€” Caddy TLS termination proxy +- [prometheus.md](prometheus.md) β€” Prometheus monitoring +- [grafana.md](grafana.md) β€” Grafana dashboards +- [mysql.md](mysql.md) β€” MySQL tracker database +- [torrust-tracker-backup.md](torrust-tracker-backup.md) β€” Backup service container diff --git a/docs/security/production/scans/caddy.md b/docs/security/production/scans/caddy.md new file mode 100644 index 000000000..27b33654d --- /dev/null +++ b/docs/security/production/scans/caddy.md @@ -0,0 +1,151 @@ +# Caddy Security Scan History + +**Image**: `caddy:2.11.2` +**Purpose**: TLS termination proxy for HTTPS support +**Documentation**: [Caddy TLS Proxy Evaluation](../../research/caddy-tls-proxy-evaluation/README.md) + +## Current Status + +| Version | HIGH | CRITICAL | Status | Scan Date | +| ------- | ---- | -------- | ------------------------------------ | ------------ | +| 2.11.2 | 10 | 2 | ⚠️ Partial improvement after upgrade | Apr 15, 2026 | + +**Deployment Status**: ⚠️ Requires follow-up β€” 2 CRITICAL CVEs remain in upstream Caddy binary dependencies (smallstep/certificates, grpc-go). Fixes require upstream Caddy releases. + +## Vulnerability Summary + +The Caddy 2.11.2 image has: + +- **Alpine base image**: 3 HIGH, 0 CRITICAL (libcrypto3/libssl3, zlib β€” fixed versions available) +- **Caddy binary (Go)**: 7 HIGH, 2 CRITICAL in dependencies (not Caddy core) + +The 2 CRITICAL CVEs are in upstream Caddy binary dependencies and require Caddy to update its vendored modules. + +## Scan History + +### April 15, 2026 - Remediation Pass 2 (Issue #432) + +**Scanner**: Trivy v0.69.3 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Image**: `caddy:2.11.2` +**Status**: ⚠️ **12 vulnerabilities** (10 HIGH, 2 CRITICAL) + +#### Summary + +Upgraded Caddy from `2.10.2` to `2.11.2` (latest as of 2026-04-14). Meaningful reduction in findings but 2 CRITICAL CVEs remain in upstream binary dependencies. + +Vulnerability comparison: + +| Version | HIGH | CRITICAL | +| -------- | ---- | -------- | +| `2.10` | 18 | 6 | +| `2.10.2` | 14 | 4 | +| `2.11.2` | 10 | 2 | + +Issue left open β€” CRITICALs not fully cleared. + +#### Target Breakdown (`2.11.2`) + +| Target | Type | HIGH | CRITICAL | +| -------------- | -------- | ---- | -------- | +| caddy (alpine) | alpine | 3 | 0 | +| usr/bin/caddy | gobinary | 7 | 2 | + +#### CVE Details + +**Alpine OS layer:** + +| CVE | Library | Severity | Fixed In | Notes | +| -------------- | ------------------- | -------- | -------- | -------------------------- | +| CVE-2026-28390 | libcrypto3, libssl3 | HIGH | 3.5.6-r0 | OpenSSL DoS via NULL deref | +| CVE-2026-22184 | zlib | HIGH | 1.3.2-r0 | Buffer overflow in untgz | + +**Caddy binary (Go):** + +| CVE | Library | Severity | Fixed In | Notes | +| -------------- | ---------------------- | -------- | ------------- | ------------------------------------------- | +| CVE-2026-34986 | go-jose/go-jose v3+v4 | HIGH | 3.0.5 / 4.1.4 | DoS via crafted JWE | +| CVE-2026-30836 | smallstep/certificates | CRITICAL | 0.30.0 | Unauthenticated SCEP cert issuance | +| CVE-2026-39883 | otel/sdk | HIGH | 1.43.0 | Local PATH hijack (no remote path) | +| CVE-2026-33186 | google.golang.org/grpc | CRITICAL | 1.79.3 | Authorization bypass via HTTP/2 path | +| CVE-2026-25679 | stdlib | HIGH | 1.26.1 | Incorrect IPv6 parsing in net/url | +| CVE-2026-27137 | stdlib | HIGH | 1.26.1 | Email constraint enforcement in crypto/x509 | +| CVE-2026-32280 | stdlib | HIGH | 1.26.2 | Excessive work during chain building | +| CVE-2026-32282 | stdlib | HIGH | 1.26.2 | Root.Chmod follows symlinks out of root | + +**Overall risk**: The 2 CRITICAL CVEs (CVE-2026-30836, CVE-2026-33186) are in upstream +Caddy binary dependencies and require a new Caddy release to fix. CVE-2026-33186 +(gRPC authorization bypass) has a network-accessible attack path. Revisit when +Caddy ships the updated grpc-go and smallstep dependencies. + +--- + +### April 8, 2026 - Remediation Pass 1 (Issue #428) + +**Scanner**: Trivy v0.68.2 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Image**: `caddy:2.10.2` +**Status**: ⚠️ **18 vulnerabilities** (14 HIGH, 4 CRITICAL) + +#### Summary + +Easy remediation applied by upgrading Caddy image tag from `2.10` to `2.10.2`. + +Vulnerability comparison: + +- Previous (`2.10`): 18 HIGH, 6 CRITICAL +- Current (`2.10.2`): 14 HIGH, 4 CRITICAL + +Improvement: -4 HIGH, -2 CRITICAL + +#### Target Breakdown (`2.10.2`) + +| Target | Type | HIGH | CRITICAL | +| ------------- | -------- | ---- | -------- | +| usr/bin/caddy | gobinary | 14 | 4 | + +Remaining issues are in upstream Caddy binary dependencies and require vendor/upstream updates. + +### January 13, 2026 - caddy:2.10 + +**Scanner**: Trivy v0.68 + +| Target | Type | HIGH | CRITICAL | +| -------------------------- | -------- | ---- | -------- | +| caddy:2.10 (alpine 3.22.2) | alpine | 0 | 0 | +| usr/bin/caddy | gobinary | 3 | 1 | + +**Vulnerabilities Found**: + +| CVE | Severity | Component | Fixed Version | +| -------------- | -------- | --------------------------------- | --------------- | +| CVE-2025-44005 | CRITICAL | github.com/smallstep/certificates | 0.29.0 | +| CVE-2025-59530 | HIGH | github.com/quic-go/quic-go | 0.49.1, 0.54.1 | +| CVE-2025-58183 | HIGH | stdlib (archive/tar) | 1.24.8, 1.25.2 | +| CVE-2025-61729 | HIGH | stdlib (crypto/x509) | 1.24.11, 1.25.5 | + +**Risk Assessment**: + +1. **CVE-2025-44005**: Authorization bypass in certificate creation (smallstep library) +2. **CVE-2025-59530**: QUIC protocol crash (affects HTTP/3 only) +3. **CVE-2025-58183**: Unbounded allocation in tar parsing +4. **CVE-2025-61729**: Resource consumption in x509 certificate validation + +**Recommendation**: Deploy with monitoring. Update to patched version when Caddy v2.11 releases. + +## Related Documentation + +- [Full Security Analysis](../../../research/caddy-tls-proxy-evaluation/security-scan.md) +- [Caddy Evaluation Summary](../../../research/caddy-tls-proxy-evaluation/README.md) +- [HTTPS Implementation](../../../issues/272-add-https-support-with-caddy.md) + +## How to Rescan + +```bash +trivy image --severity HIGH,CRITICAL caddy:2.11.2 +``` + +## Security Advisories + +- **Caddy**: +- **Alpine Linux**: diff --git a/docs/security/docker/scans/grafana.md b/docs/security/production/scans/grafana.md similarity index 50% rename from docs/security/docker/scans/grafana.md rename to docs/security/production/scans/grafana.md index 0b998824f..8da2c76ed 100644 --- a/docs/security/docker/scans/grafana.md +++ b/docs/security/production/scans/grafana.md @@ -4,13 +4,65 @@ Security scan history for the `grafana/grafana` Docker image. ## Current Status -| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | -| ------- | ---- | -------- | ------------------------------------ | ----------- | ----------- | -| 12.4.2 | 4 | 0 | ⚠️ Partial improvement after upgrade | Apr 8, 2026 | Unknown | +| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | +| ------- | ---- | -------- | ------------------------------------- | ------------ | ----------- | +| 13.0.0 | 10 | 0 | ⚠️ Accepted risk (no remote exposure) | Apr 14, 2026 | Unknown | +| 12.4.2 | 13 | 0 | βœ… Replaced by 13.0.0 | Apr 14, 2026 | Unknown | ## Scan History -### April 8, 2026 - Remediation Pass 1 (Issue #428) +### April 14, 2026 - CVE-2026-34986 remediation (Issue #434) + +**Image**: `grafana/grafana:13.0.0` +**Trivy Version**: 0.68.2 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Status**: ⚠️ **10 HIGH, 0 CRITICAL** β€” CVE-2026-34986 (remote DoS) eliminated + +#### Summary + +Full re-scan revealed 13 HIGH in `grafana/grafana:12.4.2` including CVE-2026-34986, +an unauthenticated remote DoS via a crafted JWE bearer token (CVSS 7.5, +AV:N/AC:L/PR:N/UI:N). The fix (bumping `go-jose/v4` to `4.1.4`) was merged in +[grafana/grafana#121830](https://github.com/grafana/grafana/pull/121830) with label +`no-backport` β€” no 12.x patch will be issued. Upgraded to `13.0.0`. + +Vulnerability comparison: + +- `12.4.2`: 13 HIGH, 0 CRITICAL (CVE-2026-34986 present) +- `13.0.0`: 10 HIGH, 0 CRITICAL (CVE-2026-34986 **absent**) + +Improvement: -3 HIGH; remote DoS eliminated. + +Detail by target in 13.0.0: + +- Alpine 3.23.3 base: 3 HIGH (openssl + zlib β€” same as 12.4.2, blocked on Alpine rebuild) +- grafana binary: 2 HIGH (moby/moby CVE-2026-34040, otel/sdk CVE-2026-39883) +- grafana-cli binary: 0 HIGH βœ… +- grafana-server binary: 0 HIGH βœ… +- elasticsearch plugin (new bundled binary): 5 HIGH (otel + stdlib, all local-only) + +### April 14, 2026 - Full scan (Issue #434) + +**Image**: `grafana/grafana:12.4.2` +**Trivy Version**: 0.68.2 (updated DB) +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Status**: ⚠️ **13 HIGH, 0 CRITICAL** β€” includes remote-exploitable CVE-2026-34986 + +#### Summary + +Re-scan with updated Trivy DB (April 14) revealed 13 HIGH in `12.4.2`, significantly +more than the 4 HIGH found in the April 8 scan due to new CVE entries added to the +vulnerability database. CVE-2026-34986 (`go-jose/v4`, CVSS 7.5) is the only +finding with a remote attack path. + +Breakdown: + +- Alpine 3.23.3 base: 3 HIGH (openssl + zlib) +- grafana binary: 6 HIGH (go-jose, moby, otel Γ— 2, stdlib Γ— 2) +- grafana-cli binary: 2 HIGH (moby + otel) +- grafana-server binary: 2 HIGH (moby + otel) + +### April 8, 2026 β€” Remediation Pass 1 (Issue #428) **Image**: `grafana/grafana:12.4.2` **Trivy Version**: 0.68.2 @@ -26,15 +78,13 @@ Vulnerability comparison: - Previous (`12.3.1`): 18 HIGH, 6 CRITICAL - Current (`12.4.2`): 4 HIGH, 0 CRITICAL -Improvement: -14 HIGH, -6 CRITICAL - -This is a strong reduction and clears all CRITICAL findings. +Improvement: -14 HIGH, -6 CRITICAL. All CRITICAL findings cleared. -### April 8, 2026 +### April 8, 2026 β€” Prior scan pre-upgrade (12.3.1) **Image**: `grafana/grafana:12.3.1` **Trivy Version**: 0.68.2 -**Status**: ⚠️ **24 vulnerabilities** (24 HIGH, 0 CRITICAL) - Significant increase from Dec scan +**Status**: ⚠️ **24 vulnerabilities** (24 HIGH, 0 CRITICAL) β€” significant increase from Dec scan #### Summary diff --git a/docs/security/production/scans/mysql.md b/docs/security/production/scans/mysql.md new file mode 100644 index 000000000..098e5e90b --- /dev/null +++ b/docs/security/production/scans/mysql.md @@ -0,0 +1,163 @@ +# MySQL - Security Scans + +Security scan history for the `mysql` Docker image. + +## Current Status + +| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | +| ------- | ---- | -------- | ----------------------- | ------------ | ------------ | +| 8.4 | 9 | 1 | ⚠️ Accepted risk (gosu) | Apr 15, 2026 | Apr 30, 2032 | + +## Scan History + +### April 15, 2026 - Remediation Pass 2 / Accepted Risk (Issue #435) + +**Image**: `mysql:8.4` (resolves to `8.4.8`) +**Trivy Version**: 0.69.3 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Status**: ⚠️ **10 vulnerabilities** (9 HIGH, 1 CRITICAL) + +#### Summary + +Floating tag still resolves to `8.4.8` (unchanged from Apr 8 baseline). Vulnerability count +increased from 7 HIGH + 1 CRITICAL to 9 HIGH + 1 CRITICAL due to Trivy DB updates only; +no new MySQL release shipped. + +A comparison scan of `mysql:9.6` (latest Innovation Release, shipped 2026-04-14) shows an +**identical CVE profile** β€” same `gosu v1.24.6` Go binary and same Python packages: + +| Version | HIGH | CRITICAL | Notes | +| ------- | ---- | -------- | ------------------------------------- | +| `8.4.8` | 9 | 1 | LTS, support EOL Apr 2032 | +| `9.6` | 9 | 1 | Innovation Release, shorter lifecycle | + +All CVEs are in helper components only: + +| Target | HIGH | CRITICAL | +| ------------------------- | ----- | -------- | +| `mysql:8.4` (oracle 9.7) | 0 | 0 | +| Python packages (mysqlsh) | 2 | 0 | +| `usr/local/bin/gosu` | 7 | 1 | +| **Total** | **9** | **1** | + +**CVE details β€” Python packages (`cryptography 45.0.7`, `pyOpenSSL 25.1.0`):** + +| CVE | Library | Severity | Status | Fixed Version | Title | +| -------------- | ------------ | -------- | ------ | ------------- | ---------------------------------------------- | +| CVE-2026-26007 | cryptography | HIGH | fixed | 46.0.5 | Subgroup attack due to missing SECT validation | +| CVE-2026-27459 | pyOpenSSL | HIGH | fixed | 26.0.0 | DTLS cookie callback buffer overflow | + +**CVE details β€” `gosu` (`stdlib v1.24.6`):** + +| CVE | Severity | Status | Fixed Version | Title | +| -------------- | -------- | ------ | --------------- | ------------------------------------------------------------- | +| CVE-2025-68121 | CRITICAL | fixed | 1.24.13, 1.25.7 | crypto/tls: Incorrect certificate validation (TLS resumption) | +| CVE-2025-58183 | HIGH | fixed | 1.24.8, 1.25.2 | archive/tar: Unbounded allocation in GNU sparse map | +| CVE-2025-61726 | HIGH | fixed | 1.24.12, 1.25.6 | net/url: Memory exhaustion in query parameter parsing | +| CVE-2025-61728 | HIGH | fixed | 1.24.12, 1.25.6 | archive/zip: Excessive CPU - building archive index | +| CVE-2025-61729 | HIGH | fixed | 1.24.11, 1.25.5 | crypto/x509: DoS via excessive resource consumption | +| CVE-2026-25679 | HIGH | fixed | 1.25.8, 1.26.1 | net/url: Incorrect parsing of IPv6 host literals | +| CVE-2026-32280 | HIGH | fixed | 1.25.9, 1.26.2 | chain building: unbounded work amount | +| CVE-2026-32282 | HIGH | fixed | 1.25.9, 1.26.2 | internal/syscall/unix: Root.Chmod can follow symlinks | + +#### Decision + +**Accepted risk β€” close issue #435.** + +- No viable upgrade path: `mysql:9.6` (latest) has an identical CVE profile +- All CVEs are in `gosu` (process privilege helper) and MySQL Shell Python packages β€” + **not MySQL Server itself** +- The CRITICAL (CVE-2025-68121, crypto/tls cert validation) is in `gosu`, not in any + MySQL network-facing code path +- `mysql:8.4` remains the correct choice: LTS with support until Apr 30, 2032 +- Fix requires MySQL upstream to release a new image with `gosu` rebuilt on Go β‰₯ 1.24.13 + +**Revisit**: When MySQL upstream ships `8.4.9` or later with updated `gosu`. + +--- + +### April 8, 2026 - Remediation Pass 1 (Issue #428) + +**Image**: `mysql:8.4` +**Trivy Version**: 0.68.2 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Status**: ⚠️ **8 vulnerabilities** (7 HIGH, 1 CRITICAL) + +#### Summary + +Findings are concentrated in helper components, not MySQL server core: + +- Python packages: 2 HIGH +- `gosu` Go stdlib dependencies: 5 HIGH, 1 CRITICAL + +Tag comparison for easy remediation was performed (`8.4.1`, `8.4.2`, `8.4.3`, `9.0`, `9.1`, `latest`). +No safer drop-in tag with lower overall risk profile was identified for immediate adoption in this pass. + +#### Decision + +- Keep `mysql:8.4` for now (validated runtime and LTS alignment) +- Track unresolved CVEs in follow-up issue for deeper investigation + +### April 8, 2026 + +**Image**: `mysql:8.4` +**Trivy Version**: 0.68.2 +**Status**: ⚠️ **8 vulnerabilities** (8 HIGH, 0 CRITICAL) - Increase from Dec scan + +#### Summary + +Vulnerability count increased from 0 to 8 HIGH. Breakdown: + +- Python libraries: 2 HIGH +- `/usr/local/bin/gosu`: 6 HIGH + +This increase suggests Trivy database update rather than actual MySQL regression. + +#### Changes Since December + +- December scan: 0 vulnerabilities +- April scan: 8 HIGH +- MySQL server binary itself appears unaffected + +**Recommended Action**: Most concerns are in helper binaries (gosu) and Python tools, not MySQL core. Verify with MySQL security advisories: https://www.mysql.com/support/security/ + +### December 29, 2025 + +**Image**: `mysql:8.4` +**Trivy Version**: 0.68.2 +**Status**: βœ… SECURE - 0 HIGH/CRITICAL vulnerabilities + +#### Results + +```text +mysql:8.4 (oracle 9.7) +====================== +Total: 0 (HIGH: 0, CRITICAL: 0) + +MySQL server core: 0 vulnerabilities +``` + +#### Notes + +- MySQL 8.4 is an LTS release with extended support +- Oracle Linux 9.7 base has no HIGH/CRITICAL vulnerabilities +- MySQL server itself has 0 vulnerabilities +- LTS release designed for production stability + +#### Support Status + +- Release: April 10, 2024 +- Premier Support: Until April 30, 2029 (3+ years remaining) +- Extended Support: Until April 30, 2032 (6+ years remaining) +- LTS Release: Designed for production stability + +--- + +### Previous Scans + +#### December 23, 2025 (Pre-Update Baseline) + +**Image**: `mysql:8.0` +**Status**: Preliminary scan - 0 HIGH/CRITICAL (informal assessment) + +**Note**: December 23 scan was a preliminary assessment before formal documentation was established. diff --git a/docs/security/docker/scans/prometheus.md b/docs/security/production/scans/prometheus.md similarity index 57% rename from docs/security/docker/scans/prometheus.md rename to docs/security/production/scans/prometheus.md index 746503bd4..20aaa1744 100644 --- a/docs/security/docker/scans/prometheus.md +++ b/docs/security/production/scans/prometheus.md @@ -4,12 +4,56 @@ Security scan history for the `prom/prometheus` Docker image. ## Current Status -| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | -| ------- | ---- | -------- | ------------------------------------ | ----------- | ------------ | -| v3.5.1 | 6 | 4 | ⚠️ Partial improvement after upgrade | Apr 8, 2026 | Jul 31, 2026 | +| Version | HIGH | CRITICAL | Status | Last Scan | Support EOL | +| ------- | ---- | -------- | ----------------------------- | ------------ | ----------- | +| v3.11.2 | 4 | 0 | βœ… No CRITICALs after upgrade | Apr 14, 2026 | TBD | ## Scan History +### April 14, 2026 - Remediation Pass 2 (Issue #433) + +**Image**: `prom/prometheus:v3.11.2` +**Trivy Version**: 0.68.2 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Status**: βœ… **4 vulnerabilities** (4 HIGH, 0 CRITICAL) + +#### Summary + +Upgraded Prometheus from `v3.5.1` to `v3.11.2` (latest as of 2026-04-13). All +CRITICAL vulnerabilities eliminated. Four HIGH findings remain in upstream +binary dependencies; all are local-only (no remote attack path). + +Vulnerability comparison: + +| Version | HIGH | CRITICAL | +| ------- | ---- | -------- | +| v3.5.0 | 16 | 4 | +| v3.5.1 | 6 | 2 | +| v3.11.2 | 4 | 0 | + +#### Target Breakdown (`v3.11.2`) + +| Target | HIGH | CRITICAL | +| ---------------- | ---- | -------- | +| `bin/prometheus` | 3 | 0 | +| `bin/promtool` | 1 | 0 | + +No OS layer β€” pure Go binaries, no Alpine/Debian base image. + +#### Remaining CVEs + +| CVE | Library | Installed | Fixed In | Severity | Notes | +| -------------- | ---------------- | --------- | -------- | -------- | ----------------------------------------- | +| CVE-2026-32285 | buger/jsonparser | v1.1.1 | 1.1.2 | HIGH | DoS via malformed JSON; internal use only | +| CVE-2026-34040 | moby/docker | v28.5.2 | 29.3.1 | HIGH | Auth bypass; Docker-client code path | +| CVE-2026-39883 | otel/sdk | v1.42.0 | 1.43.0 | HIGH | Local PATH hijack; no remote path | + +All remaining findings are in upstream Prometheus binary dependencies. No +remote attack path exists for any of the three CVE types, and fixes are +pending upstream Prometheus releases. + +--- + ### April 8, 2026 - Remediation Pass 1 (Issue #428) **Image**: `prom/prometheus:v3.5.1` diff --git a/docs/security/docker/scans/torrust-tracker-backup.md b/docs/security/production/scans/torrust-tracker-backup.md similarity index 70% rename from docs/security/docker/scans/torrust-tracker-backup.md rename to docs/security/production/scans/torrust-tracker-backup.md index 44f8b54cc..44098841d 100644 --- a/docs/security/docker/scans/torrust-tracker-backup.md +++ b/docs/security/production/scans/torrust-tracker-backup.md @@ -4,9 +4,9 @@ Security scan history for the `torrust/tracker-backup` Docker image. ## Current Status -| Version | HIGH | CRITICAL | Status | Last Scan | -| ------- | ---- | -------- | -------------------- | ----------- | -| trixie | 6 | 0 | ℹ️ Base OS Monitored | Apr 8, 2026 | +| Version | HIGH | CRITICAL | Status | Last Scan | +| ------- | ---- | -------- | ------------------------------------ | ------------ | +| trixie | 6 | 0 | ⚠️ Accepted risk (Debian ``) | Apr 15, 2026 | ## Build & Scan Commands @@ -24,6 +24,56 @@ trivy image --severity HIGH,CRITICAL torrust/tracker-backup:local ## Scan History +### April 15, 2026 - Remediation Pass 2 / Accepted Risk (Issue #431) + +**Image**: `torrust/tracker-backup:local` +**Trivy Version**: 0.69.3 +**Scan Mode**: `--scanners vuln --severity HIGH,CRITICAL` +**Base OS**: Debian 13.4 (trixie-slim) +**Status**: ⚠️ **No change** β€” 6 HIGH, 0 CRITICAL + +#### Summary + +Image rebuilt from scratch with `--no-cache`. All Debian packages updated to latest trixie +repository state. Vulnerability count unchanged: **6 HIGH, 0 CRITICAL**. + +| Target | HIGH | CRITICAL | +| -------------------------------------------- | ---- | -------- | +| `torrust/tracker-backup:local` (debian 13.4) | 6 | 0 | + +| CVE | Library | Severity | Status | Fixed Version | Title | +| -------------- | ------------------------------------------------- | -------- | -------- | ------------- | --------------------------------------------------------- | +| CVE-2025-69720 | libncurses6, libtinfo6, ncurses-base, ncurses-bin | HIGH | affected | β€” | ncurses: Buffer overflow in `infocmp` CLI tool | +| CVE-2026-29111 | libsystemd0, libudev1 | HIGH | affected | β€” | systemd: Assert/freeze via spurious unprivileged IPC call | + +#### Debian Security Tracker Status + +Both CVEs confirmed as `` (minor issue) for trixie β€” Debian Security Team will not +issue a DSA for stable trixie: + +- **CVE-2025-69720**: Fixed only in `forky/sid` (`ncurses 6.6+20251231-1`). Affects the + `infocmp` CLI tool (`progs/infocmp.c`) β€” **not the ncurses library itself**. Our backup + container never invokes `infocmp`. +- **CVE-2026-29111**: Fixed only in `forky/sid` (`systemd 260.1-1`). Affects systemd when + running as PID 1 and receiving a spurious unprivileged IPC call. Our container runs a bash + script as entrypoint β€” **systemd is not PID 1**; `libsystemd0`/`libudev1` are installed as + transitive dependencies of other packages but the daemon is never started. + +#### Decision + +**Accepted risk β€” close issue #431.** + +- No fixes available in Debian trixie for either CVE +- Both CVEs are marked `` minor issues by Debian Security Team +- Neither CVE is reachable in our container's runtime behaviour: + - `infocmp` is never called + - systemd is not running as PID 1 +- The backup container has a minimal footprint, runs non-root, and is not network-accessible + +**Revisit**: When Debian trixie backports fixes for `ncurses` or `systemd`. + +--- + ### April 8, 2026 - Remediation Pass 1 (Issue #428) **Image**: `torrust/tracker-backup:local` diff --git a/docs/security/testing/README.md b/docs/security/testing/README.md new file mode 100644 index 000000000..6547c00b8 --- /dev/null +++ b/docs/security/testing/README.md @@ -0,0 +1,21 @@ +# Testing Artifacts Security + +This directory covers security for Docker images used only in automated tests or local development. +These are [Priority 4](../README.md) β€” the lowest-risk surface, as they never run in production. + +## Scope + +- `torrust/tracker-ssh-server` β€” SSH server used in E2E integration tests +- `torrust/tracker-provisioned-instance` β€” Ubuntu VM simulation used in E2E deployment workflow tests + +## Scan History + +See [`scans/`](scans/) for historical scan results. + +## When to Re-scan + +Scan testing artifacts when: + +- A test image uses a base image with known CRITICALs +- An artifact is promoted to be used in the deployer itself (moves to Priority 3) +- An artifact is deployed to production (moves to Priority 1) diff --git a/docs/security/testing/scans/README.md b/docs/security/testing/scans/README.md new file mode 100644 index 000000000..5526a5a7d --- /dev/null +++ b/docs/security/testing/scans/README.md @@ -0,0 +1,28 @@ +# Testing Image Scan Results + +Historical security scan results for Docker images used only in automated tests or local development. +These are [Priority 4](../../README.md) images β€” they never run in production. + +## Current Status Summary + +| Image | Version | HIGH | CRITICAL | Status | Last Scan | Details | +| -------------------------------------- | ------- | ---- | -------- | ------------------------- | ----------- | ----------------------------------------------- | +| `torrust/tracker-ssh-server` | 3.23.3 | 0 | 0 | βœ… Remediated (vuln scan) | Apr 8, 2026 | [View](torrust-ssh-server.md) | +| `torrust/tracker-provisioned-instance` | 24.04 | 0 | 0 | βœ… Remediated (vuln scan) | Apr 8, 2026 | [View](torrust-tracker-provisioned-instance.md) | + +## Scan Archives + +- [torrust-ssh-server.md](torrust-ssh-server.md) β€” SSH test server (base: alpine:3.23.3), used for E2E integration tests +- [torrust-tracker-provisioned-instance.md](torrust-tracker-provisioned-instance.md) β€” Ubuntu VM simulation (base: ubuntu:24.04), used for E2E deployment workflow tests + +## Build and Scan + +```bash +# Build testing images +docker build --tag torrust/tracker-ssh-server:local docker/ssh-server/ +docker build --tag torrust/tracker-provisioned-instance:local docker/provisioned-instance/ + +# Scan +trivy image --severity HIGH,CRITICAL torrust/tracker-ssh-server:local +trivy image --severity HIGH,CRITICAL torrust/tracker-provisioned-instance:local +``` diff --git a/docs/security/docker/scans/torrust-ssh-server.md b/docs/security/testing/scans/torrust-ssh-server.md similarity index 100% rename from docs/security/docker/scans/torrust-ssh-server.md rename to docs/security/testing/scans/torrust-ssh-server.md diff --git a/docs/security/docker/scans/torrust-tracker-provisioned-instance.md b/docs/security/testing/scans/torrust-tracker-provisioned-instance.md similarity index 100% rename from docs/security/docker/scans/torrust-tracker-provisioned-instance.md rename to docs/security/testing/scans/torrust-tracker-provisioned-instance.md diff --git a/docs/security/ai-agents-and-secrets.md b/docs/security/user-security/ai-agents-and-secrets.md similarity index 100% rename from docs/security/ai-agents-and-secrets.md rename to docs/security/user-security/ai-agents-and-secrets.md diff --git a/docs/security/ssh-root-access-hetzner.md b/docs/security/user-security/ssh-root-access-hetzner.md similarity index 100% rename from docs/security/ssh-root-access-hetzner.md rename to docs/security/user-security/ssh-root-access-hetzner.md diff --git a/packages/README.md b/packages/README.md index 9f91a498a..ca2544ccf 100644 --- a/packages/README.md +++ b/packages/README.md @@ -88,8 +88,8 @@ All packages in this directory: ```rust // Add to your Cargo.toml [dependencies] -torrust-linting = "0.1.0" # external crate: https://crates.io/crates/torrust-linting -torrust-dependency-installer = { path = "packages/dependency-installer" } +torrust-tracker-deployer-types = { path = "packages/deployer-types" } +torrust-tracker-deployer-dependency-installer = { path = "packages/dependency-installer" } torrust-tracker-deployer-sdk = { path = "packages/sdk" } ``` diff --git a/packages/dependency-installer/Cargo.toml b/packages/dependency-installer/Cargo.toml index e344b622e..b33e2aeb1 100644 --- a/packages/dependency-installer/Cargo.toml +++ b/packages/dependency-installer/Cargo.toml @@ -1,12 +1,14 @@ [package] -name = "torrust-dependency-installer" +name = "torrust-tracker-deployer-dependency-installer" version = "0.1.0" edition = "2021" description = "Dependency detection and installation utilities for the Torrust Tracker Deployer project" license = "MIT" +repository = "https://github.com/torrust/torrust-tracker-deployer" +readme = "README.md" [lib] -name = "torrust_dependency_installer" +name = "torrust_tracker_deployer_dependency_installer" path = "src/lib.rs" [[bin]] diff --git a/packages/dependency-installer/README.md b/packages/dependency-installer/README.md index 74dac7bda..2c8a24fc0 100644 --- a/packages/dependency-installer/README.md +++ b/packages/dependency-installer/README.md @@ -1,4 +1,4 @@ -# Torrust Dependency Installer Package +# Torrust Tracker Deployer Dependency Installer This package provides dependency detection and installation utilities for the Torrust Tracker Deployer project. @@ -125,51 +125,51 @@ This output is designed for human reading, **not for parsing by scripts**. ```bash # Check all dependencies (default log level shows INFO and above) $ dependency-installer check -2025-11-04T17:33:20.959847Z INFO torrust_dependency_installer::handlers::check: Checking all dependencies -2025-11-04T17:33:20.960126Z INFO torrust_dependency_installer::handlers::check: Dependency check result dependency="cargo-machete" status="installed" -2025-11-04T17:33:20.960131Z INFO torrust_dependency_installer::handlers::check: Dependency check result dependency="OpenTofu" status="not installed" -2025-11-04T17:33:20.960136Z INFO torrust_dependency_installer::handlers::check: Dependency check result dependency="Ansible" status="not installed" -2025-11-04T17:33:20.960139Z INFO torrust_dependency_installer::handlers::check: Dependency check result dependency="LXD" status="installed" -2025-11-04T17:33:20.960144Z INFO torrust_dependency_installer::handlers::check: Missing dependencies missing_count=2 total_count=4 +2025-11-04T17:33:20.959847Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Checking all dependencies +2025-11-04T17:33:20.960126Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Dependency check result dependency="cargo-machete" status="installed" +2025-11-04T17:33:20.960131Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Dependency check result dependency="OpenTofu" status="not installed" +2025-11-04T17:33:20.960136Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Dependency check result dependency="Ansible" status="not installed" +2025-11-04T17:33:20.960139Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Dependency check result dependency="LXD" status="installed" +2025-11-04T17:33:20.960144Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Missing dependencies missing_count=2 total_count=4 Error: Check command failed: Failed to check all dependencies: Missing 2 out of 4 required dependencies # Check specific dependency $ dependency-installer check --dependency opentofu -2025-11-04T17:33:20.959855Z INFO torrust_dependency_installer::handlers::check: Checking specific dependency dependency=opentofu -2025-11-04T17:33:20.960473Z INFO torrust_dependency_installer::detector::opentofu: OpenTofu is not installed dependency="opentofu" -2025-11-04T17:33:20.960482Z INFO torrust_dependency_installer::handlers::check: Dependency is not installed dependency="OpenTofu" status="not installed" +2025-11-04T17:33:20.959855Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Checking specific dependency dependency=opentofu +2025-11-04T17:33:20.960473Z INFO torrust_tracker_deployer_dependency_installer::detector::opentofu: OpenTofu is not installed dependency="opentofu" +2025-11-04T17:33:20.960482Z INFO torrust_tracker_deployer_dependency_installer::handlers::check: Dependency is not installed dependency="OpenTofu" status="not installed" Error: Check command failed: Failed to check specific dependency: opentofu: not installed # Install all dependencies $ dependency-installer install -2025-11-04T19:30:10.000000Z INFO torrust_dependency_installer::handlers::install: Installing all dependencies -2025-11-04T19:30:10.100000Z INFO torrust_dependency_installer::installer::cargo_machete: Installing cargo-machete dependency="cargo-machete" -2025-11-04T19:30:25.000000Z INFO torrust_dependency_installer::handlers::install: Dependency installation result dependency="cargo-machete" status="installed" -2025-11-04T19:30:25.100000Z INFO torrust_dependency_installer::installer::opentofu: Installing OpenTofu dependency="opentofu" -2025-11-04T19:30:40.000000Z INFO torrust_dependency_installer::handlers::install: Dependency installation result dependency="OpenTofu" status="installed" +2025-11-04T19:30:10.000000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: Installing all dependencies +2025-11-04T19:30:10.100000Z INFO torrust_tracker_deployer_dependency_installer::installer::cargo_machete: Installing cargo-machete dependency="cargo-machete" +2025-11-04T19:30:25.000000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: Dependency installation result dependency="cargo-machete" status="installed" +2025-11-04T19:30:25.100000Z INFO torrust_tracker_deployer_dependency_installer::installer::opentofu: Installing OpenTofu dependency="opentofu" +2025-11-04T19:30:40.000000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: Dependency installation result dependency="OpenTofu" status="installed" ... -2025-11-04T19:31:00.000000Z INFO torrust_dependency_installer::handlers::install: All dependencies installed successfully +2025-11-04T19:31:00.000000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: All dependencies installed successfully # Install specific dependency with verbose logging $ dependency-installer install --dependency opentofu --verbose -2025-11-04T19:30:10.000000Z INFO torrust_dependency_installer::handlers::install: Installing specific dependency dependency=opentofu -2025-11-04T19:30:10.100000Z INFO torrust_dependency_installer::installer::opentofu: Installing OpenTofu dependency="opentofu" -2025-11-04T19:30:10.200000Z DEBUG torrust_dependency_installer::installer::opentofu: Downloading OpenTofu installer script -2025-11-04T19:30:12.000000Z DEBUG torrust_dependency_installer::installer::opentofu: Making installer script executable -2025-11-04T19:30:12.100000Z DEBUG torrust_dependency_installer::installer::opentofu: Running OpenTofu installer with sudo -2025-11-04T19:30:25.000000Z DEBUG torrust_dependency_installer::installer::opentofu: Cleaning up installer script -2025-11-04T19:30:25.100000Z INFO torrust_dependency_installer::handlers::install: Dependency installation completed dependency="OpenTofu" status="installed" +2025-11-04T19:30:10.000000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: Installing specific dependency dependency=opentofu +2025-11-04T19:30:10.100000Z INFO torrust_tracker_deployer_dependency_installer::installer::opentofu: Installing OpenTofu dependency="opentofu" +2025-11-04T19:30:10.200000Z DEBUG torrust_tracker_deployer_dependency_installer::installer::opentofu: Downloading OpenTofu installer script +2025-11-04T19:30:12.000000Z DEBUG torrust_tracker_deployer_dependency_installer::installer::opentofu: Making installer script executable +2025-11-04T19:30:12.100000Z DEBUG torrust_tracker_deployer_dependency_installer::installer::opentofu: Running OpenTofu installer with sudo +2025-11-04T19:30:25.000000Z DEBUG torrust_tracker_deployer_dependency_installer::installer::opentofu: Cleaning up installer script +2025-11-04T19:30:25.100000Z INFO torrust_tracker_deployer_dependency_installer::handlers::install: Dependency installation completed dependency="OpenTofu" status="installed" # List all dependencies $ dependency-installer list -2025-11-04T17:33:20.960482Z INFO torrust_dependency_installer::handlers::list: Available dependency dependency="cargo-machete" status="installed" -2025-11-04T17:33:20.960494Z INFO torrust_dependency_installer::handlers::list: Available dependency dependency="OpenTofu" status="not installed" -2025-11-04T17:33:20.960962Z INFO torrust_dependency_installer::handlers::list: Available dependency dependency="Ansible" status="not installed" -2025-11-04T17:33:20.961521Z INFO torrust_dependency_installer::handlers::list: Available dependency dependency="LXD" status="installed" +2025-11-04T17:33:20.960482Z INFO torrust_tracker_deployer_dependency_installer::handlers::list: Available dependency dependency="cargo-machete" status="installed" +2025-11-04T17:33:20.960494Z INFO torrust_tracker_deployer_dependency_installer::handlers::list: Available dependency dependency="OpenTofu" status="not installed" +2025-11-04T17:33:20.960962Z INFO torrust_tracker_deployer_dependency_installer::handlers::list: Available dependency dependency="Ansible" status="not installed" +2025-11-04T17:33:20.961521Z INFO torrust_tracker_deployer_dependency_installer::handlers::list: Available dependency dependency="LXD" status="installed" # Enable verbose logging (includes DEBUG level) $ dependency-installer check --verbose -2025-11-04T17:33:20.959872Z DEBUG torrust_dependency_installer::detector::cargo_machete: Checking if cargo-machete is installed dependency="cargo-machete" +2025-11-04T17:33:20.959872Z DEBUG torrust_tracker_deployer_dependency_installer::detector::cargo_machete: Checking if cargo-machete is installed dependency="cargo-machete" ... ``` @@ -187,7 +187,7 @@ The CLI accepts the following dependency names: #### Checking Dependencies ```rust -use torrust_dependency_installer::DependencyManager; +use torrust_tracker_deployer_dependency_installer::DependencyManager; fn main() -> Result<(), Box> { // Initialize tracing for structured logging @@ -214,7 +214,7 @@ fn main() -> Result<(), Box> { #### Installing Dependencies ```rust -use torrust_dependency_installer::{Dependency, DependencyManager}; +use torrust_tracker_deployer_dependency_installer::{Dependency, DependencyManager}; #[tokio::main] async fn main() -> Result<(), Box> { @@ -252,7 +252,7 @@ async fn main() -> Result<(), Box> { #### Using Individual Detectors ```rust -use torrust_dependency_installer::{DependencyDetector, Dependency, DependencyManager}; +use torrust_tracker_deployer_dependency_installer::{DependencyDetector, Dependency, DependencyManager}; fn main() -> Result<(), Box> { tracing_subscriber::fmt::init(); @@ -290,14 +290,14 @@ The Dockerfile serves as **explicit documentation** of what must be installed on ```bash # Run all tests (unit tests run normally, Docker tests use pre-built image) -cargo test -p torrust-dependency-installer +cargo test -p torrust-tracker-deployer-dependency-installer # Run only Docker-based integration tests -cargo test -p torrust-dependency-installer --test docker_install_command -cargo test -p torrust-dependency-installer --test docker_check_command +cargo test -p torrust-tracker-deployer-dependency-installer --test docker_install_command +cargo test -p torrust-tracker-deployer-dependency-installer --test docker_check_command # Run expensive tests (OpenTofu, Ansible, LXD) -cargo test -p torrust-dependency-installer -- --ignored +cargo test -p torrust-tracker-deployer-dependency-installer -- --ignored # Build the test Docker image docker build -f docker/ubuntu-24.04.Dockerfile -t dependency-installer-test:ubuntu-24.04 . @@ -311,15 +311,15 @@ Add to your `Cargo.toml`: ```toml [dependencies] -torrust-dependency-installer = { path = "path/to/torrust-dependency-installer" } +torrust-tracker-deployer-dependency-installer = { path = "path/to/torrust-tracker-deployer-dependency-installer" } ``` Or if using in a workspace: ```toml [workspace] -members = ["packages/torrust-dependency-installer"] +members = ["packages/torrust-tracker-deployer-dependency-installer"] [dependencies] -torrust-dependency-installer = { path = "packages/torrust-dependency-installer" } +torrust-tracker-deployer-dependency-installer = { path = "packages/torrust-tracker-deployer-dependency-installer" } ``` diff --git a/packages/dependency-installer/examples/check_dependencies.rs b/packages/dependency-installer/examples/check_dependencies.rs index 90196f771..0e8af1011 100644 --- a/packages/dependency-installer/examples/check_dependencies.rs +++ b/packages/dependency-installer/examples/check_dependencies.rs @@ -5,7 +5,7 @@ //! //! Run with: `cargo run --example check_dependencies` -use torrust_dependency_installer::{init_tracing, DependencyManager}; +use torrust_tracker_deployer_dependency_installer::{init_tracing, DependencyManager}; fn main() { // Initialize tracing for structured logging with INFO level diff --git a/packages/dependency-installer/src/bin/dependency-installer.rs b/packages/dependency-installer/src/bin/dependency-installer.rs index c8e8f3443..e1d73c5f1 100644 --- a/packages/dependency-installer/src/bin/dependency-installer.rs +++ b/packages/dependency-installer/src/bin/dependency-installer.rs @@ -41,7 +41,7 @@ use std::process; -use torrust_dependency_installer::app; +use torrust_tracker_deployer_dependency_installer::app; #[tokio::main] async fn main() { diff --git a/packages/dependency-installer/src/command.rs b/packages/dependency-installer/src/command.rs index 25be8cfe9..7344f926e 100644 --- a/packages/dependency-installer/src/command.rs +++ b/packages/dependency-installer/src/command.rs @@ -23,7 +23,7 @@ use thiserror::Error; /// # Examples /// /// ```rust -/// use torrust_dependency_installer::command::command_exists; +/// use torrust_tracker_deployer_dependency_installer::command::command_exists; /// /// // Check if 'cargo' is installed /// let exists = command_exists("cargo").unwrap(); @@ -53,7 +53,7 @@ pub fn command_exists(command: &str) -> Result { /// # Examples /// /// ```rust,no_run -/// use torrust_dependency_installer::command::execute_command; +/// use torrust_tracker_deployer_dependency_installer::command::execute_command; /// /// // Get cargo version /// let version = execute_command("cargo", &["--version"]).unwrap(); diff --git a/packages/dependency-installer/src/verification.rs b/packages/dependency-installer/src/verification.rs index b81a99063..00f7d5808 100644 --- a/packages/dependency-installer/src/verification.rs +++ b/packages/dependency-installer/src/verification.rs @@ -28,7 +28,7 @@ use crate::{Dependency, DependencyManager, DetectionError}; /// # Example /// /// ```no_run -/// use torrust_dependency_installer::{Dependency, verify_dependencies}; +/// use torrust_tracker_deployer_dependency_installer::{Dependency, verify_dependencies}; /// /// // Verify all dependencies for a full workflow /// let deps = &[Dependency::OpenTofu, Dependency::Ansible, Dependency::Lxd]; diff --git a/packages/dependency-installer/tests/detector_tests.rs b/packages/dependency-installer/tests/detector_tests.rs index 9b8678137..377b9dff1 100644 --- a/packages/dependency-installer/tests/detector_tests.rs +++ b/packages/dependency-installer/tests/detector_tests.rs @@ -5,10 +5,10 @@ //! - `DependencyManager` functionality //! - Error handling -use torrust_dependency_installer::detector::{ +use torrust_tracker_deployer_dependency_installer::detector::{ AnsibleDetector, CargoMacheteDetector, DependencyDetector, LxdDetector, OpenTofuDetector, }; -use torrust_dependency_installer::{CheckResult, Dependency, DependencyManager}; +use torrust_tracker_deployer_dependency_installer::{CheckResult, Dependency, DependencyManager}; // ============================================================================= // DETECTOR TRAIT TESTS @@ -165,7 +165,7 @@ fn it_should_get_lxd_detector_from_manager() { #[test] fn it_should_create_check_result() { - use torrust_dependency_installer::Dependency; + use torrust_tracker_deployer_dependency_installer::Dependency; let result = CheckResult { dependency: Dependency::CargoMachete, installed: true, @@ -177,7 +177,7 @@ fn it_should_create_check_result() { #[test] fn it_should_clone_check_result() { - use torrust_dependency_installer::Dependency; + use torrust_tracker_deployer_dependency_installer::Dependency; let result = CheckResult { dependency: Dependency::OpenTofu, installed: false, @@ -194,7 +194,7 @@ fn it_should_clone_check_result() { #[test] fn it_should_detect_existing_command() { - use torrust_dependency_installer::command::command_exists; + use torrust_tracker_deployer_dependency_installer::command::command_exists; // Test with 'sh' which should always exist on Unix systems let result = command_exists("sh"); @@ -205,7 +205,7 @@ fn it_should_detect_existing_command() { #[test] fn it_should_detect_nonexistent_command() { - use torrust_dependency_installer::command::command_exists; + use torrust_tracker_deployer_dependency_installer::command::command_exists; // Test with a command that definitely doesn't exist let result = command_exists("this-command-definitely-does-not-exist-12345"); @@ -216,7 +216,7 @@ fn it_should_detect_nonexistent_command() { #[test] fn it_should_execute_command_successfully() { - use torrust_dependency_installer::command::execute_command; + use torrust_tracker_deployer_dependency_installer::command::execute_command; // Test with 'echo' which should always work let result = execute_command("echo", &["hello"]); @@ -226,7 +226,7 @@ fn it_should_execute_command_successfully() { #[test] fn it_should_fail_to_execute_nonexistent_command() { - use torrust_dependency_installer::command::execute_command; + use torrust_tracker_deployer_dependency_installer::command::execute_command; // Test with nonexistent command let result = execute_command("this-command-definitely-does-not-exist-12345", &["test"]); diff --git a/packages/dependency-installer/tests/install_command_docker_integration.rs b/packages/dependency-installer/tests/install_command_docker_integration.rs index 346282f76..375dd9c37 100644 --- a/packages/dependency-installer/tests/install_command_docker_integration.rs +++ b/packages/dependency-installer/tests/install_command_docker_integration.rs @@ -155,7 +155,7 @@ async fn it_should_install_opentofu_successfully() { /// /// **Known Issue**: This test is flaky due to Ansible installation reliability in containers. /// It's marked as `#[ignore]` to prevent CI failures. Run manually with: -/// `cargo test --package torrust-dependency-installer --test install_command_docker_integration it_should_install_ansible_successfully -- --ignored` +/// `cargo test --package torrust-tracker-deployer-dependency-installer --test install_command_docker_integration it_should_install_ansible_successfully -- --ignored` #[tokio::test] #[ignore = "Flaky test: Ansible installation is unreliable in containers"] async fn it_should_install_ansible_successfully() { diff --git a/packages/deployer-types/Cargo.toml b/packages/deployer-types/Cargo.toml index e51b95f36..b67cc2c9c 100644 --- a/packages/deployer-types/Cargo.toml +++ b/packages/deployer-types/Cargo.toml @@ -1,9 +1,11 @@ [package] -name = "torrust-deployer-types" +name = "torrust-tracker-deployer-types" version = "0.1.0" edition = "2021" description = "Shared value objects and traits for the Torrust Tracker Deployer" license = "MIT" +repository = "https://github.com/torrust/torrust-tracker-deployer" +readme = "README.md" [dependencies] chrono = { version = "0.4", features = [ "serde" ] } diff --git a/packages/deployer-types/README.md b/packages/deployer-types/README.md index 1df9f435e..f40b75d4d 100644 --- a/packages/deployer-types/README.md +++ b/packages/deployer-types/README.md @@ -31,17 +31,17 @@ and minimal external dependencies. ```toml [dependencies] -torrust-deployer-types = { path = "packages/deployer-types" } +torrust-tracker-deployer-types = { path = "packages/deployer-types" } ``` ```rust -use torrust_deployer_types::{EnvironmentName, DomainName, Clock}; +use torrust_tracker_deployer_types::{EnvironmentName, DomainName, Clock}; ``` ## Architecture ```text -torrust-deployer-types ← this package (no internal deps) +torrust-tracker-deployer-types ← this package (no internal deps) ↑ ↑ torrust-tracker-deployer torrust-tracker-deployer-sdk ``` diff --git a/packages/deployer-types/src/clock.rs b/packages/deployer-types/src/clock.rs index 7c6793dec..932c1d71c 100644 --- a/packages/deployer-types/src/clock.rs +++ b/packages/deployer-types/src/clock.rs @@ -20,7 +20,7 @@ //! ## In Production Code //! //! ```rust -//! use torrust_deployer_types::Clock; +//! use torrust_tracker_deployer_types::Clock; //! //! fn record_event(clock: &dyn Clock) { //! let timestamp = clock.now(); @@ -72,7 +72,7 @@ pub trait Clock: Send + Sync { /// # Example /// /// ```rust -/// use torrust_deployer_types::{Clock, SystemClock}; +/// use torrust_tracker_deployer_types::{Clock, SystemClock}; /// /// let clock = SystemClock; /// let now = clock.now(); diff --git a/packages/deployer-types/src/domain_name.rs b/packages/deployer-types/src/domain_name.rs index 6f894ea9c..36a3d81ee 100644 --- a/packages/deployer-types/src/domain_name.rs +++ b/packages/deployer-types/src/domain_name.rs @@ -37,7 +37,7 @@ //! # Examples //! //! ``` -//! use torrust_deployer_types::DomainName; +//! use torrust_tracker_deployer_types::DomainName; //! //! // Valid domain names //! let domain = DomainName::new("example.com").unwrap(); @@ -91,7 +91,7 @@ impl DomainName { /// # Examples /// /// ``` - /// use torrust_deployer_types::DomainName; + /// use torrust_tracker_deployer_types::DomainName; /// /// let domain = DomainName::new("tracker.torrust.org").unwrap(); /// assert_eq!(domain.as_str(), "tracker.torrust.org"); @@ -117,7 +117,7 @@ impl DomainName { /// # Examples /// /// ``` - /// use torrust_deployer_types::DomainName; + /// use torrust_tracker_deployer_types::DomainName; /// /// let domain = DomainName::new("api.tracker.torrust.org").unwrap(); /// assert_eq!(domain.tld(), "org"); @@ -135,7 +135,7 @@ impl DomainName { /// # Examples /// /// ``` - /// use torrust_deployer_types::DomainName; + /// use torrust_tracker_deployer_types::DomainName; /// /// let domain = DomainName::new("api.tracker.torrust.org").unwrap(); /// assert_eq!(domain.subdomains(), vec!["api", "tracker", "torrust"]); diff --git a/packages/deployer-types/src/email.rs b/packages/deployer-types/src/email.rs index 66afad6d9..584aff75c 100644 --- a/packages/deployer-types/src/email.rs +++ b/packages/deployer-types/src/email.rs @@ -6,7 +6,7 @@ //! # Usage //! //! ```rust -//! use torrust_deployer_types::Email; +//! use torrust_tracker_deployer_types::Email; //! //! // Valid email //! let email = Email::new("admin@example.com").unwrap(); @@ -47,7 +47,7 @@ use serde::{Deserialize, Serialize}; /// # Examples /// /// ```rust -/// use torrust_deployer_types::Email; +/// use torrust_tracker_deployer_types::Email; /// /// let email = Email::new("user@example.com").unwrap(); /// println!("Email: {}", email); @@ -76,7 +76,7 @@ impl Email { /// # Examples /// /// ```rust - /// use torrust_deployer_types::Email; + /// use torrust_tracker_deployer_types::Email; /// /// let valid = Email::new("admin@example.com"); /// assert!(valid.is_ok()); @@ -104,7 +104,7 @@ impl Email { /// # Examples /// /// ```rust - /// use torrust_deployer_types::Email; + /// use torrust_tracker_deployer_types::Email; /// /// let email = Email::new("user@example.com").unwrap(); /// assert_eq!(email.local_part(), "user"); @@ -119,7 +119,7 @@ impl Email { /// # Examples /// /// ```rust - /// use torrust_deployer_types::Email; + /// use torrust_tracker_deployer_types::Email; /// /// let email = Email::new("user@example.com").unwrap(); /// assert_eq!(email.domain_part(), "example.com"); diff --git a/packages/deployer-types/src/environment_name.rs b/packages/deployer-types/src/environment_name.rs index c660414e5..5d800133d 100644 --- a/packages/deployer-types/src/environment_name.rs +++ b/packages/deployer-types/src/environment_name.rs @@ -43,7 +43,7 @@ use thiserror::Error; /// # Examples /// /// ```rust -/// use torrust_deployer_types::EnvironmentName; +/// use torrust_tracker_deployer_types::EnvironmentName; /// /// // Valid environment names /// let dev = EnvironmentName::new("dev".to_string())?; @@ -75,7 +75,7 @@ impl EnvironmentName { /// # Examples /// /// ```rust - /// # use torrust_deployer_types::EnvironmentName; + /// # use torrust_tracker_deployer_types::EnvironmentName; /// // Valid names - accepts various string types /// assert!(EnvironmentName::new("dev").is_ok()); /// assert!(EnvironmentName::new("e2e-config".to_string()).is_ok()); @@ -103,7 +103,7 @@ impl EnvironmentName { /// # Examples /// /// ```rust - /// use torrust_deployer_types::EnvironmentName; + /// use torrust_tracker_deployer_types::EnvironmentName; /// /// let env_name = EnvironmentName::new("production".to_string())?; /// assert_eq!(env_name.as_str(), "production"); diff --git a/packages/deployer-types/src/error/kind.rs b/packages/deployer-types/src/error/kind.rs index 56e1632b9..b7489d0ad 100644 --- a/packages/deployer-types/src/error/kind.rs +++ b/packages/deployer-types/src/error/kind.rs @@ -23,7 +23,7 @@ use serde::{Deserialize, Serialize}; /// # Examples /// /// ``` -/// use torrust_deployer_types::ErrorKind; +/// use torrust_tracker_deployer_types::ErrorKind; /// /// let kind = ErrorKind::TemplateRendering; /// assert_eq!(format!("{kind:?}"), "TemplateRendering"); diff --git a/packages/deployer-types/src/error/traceable.rs b/packages/deployer-types/src/error/traceable.rs index 65a04a955..4ec4f840c 100644 --- a/packages/deployer-types/src/error/traceable.rs +++ b/packages/deployer-types/src/error/traceable.rs @@ -16,8 +16,8 @@ use super::ErrorKind; /// # Example /// /// ```rust -/// use torrust_deployer_types::error::Traceable; -/// use torrust_deployer_types::ErrorKind; +/// use torrust_tracker_deployer_types::error::Traceable; +/// use torrust_tracker_deployer_types::ErrorKind; /// /// #[derive(Debug, thiserror::Error)] /// enum MyError { @@ -97,7 +97,7 @@ pub trait Traceable: std::error::Error { /// # Example /// /// ```rust - /// use torrust_deployer_types::{Traceable, ErrorKind}; + /// use torrust_tracker_deployer_types::{Traceable, ErrorKind}; /// /// fn handle_error(error: &E) { /// let kind = error.error_kind(); diff --git a/packages/deployer-types/src/secrets/api_token.rs b/packages/deployer-types/src/secrets/api_token.rs index f5e56910e..bd8fac1d7 100644 --- a/packages/deployer-types/src/secrets/api_token.rs +++ b/packages/deployer-types/src/secrets/api_token.rs @@ -31,7 +31,7 @@ impl ApiToken { /// /// # Examples /// ``` - /// use torrust_deployer_types::secrets::ApiToken; + /// use torrust_tracker_deployer_types::secrets::ApiToken; /// /// let from_string = ApiToken::new(String::from("token")); /// let from_str = ApiToken::new("token"); diff --git a/packages/deployer-types/src/secrets/password.rs b/packages/deployer-types/src/secrets/password.rs index 5f99107ed..2549ce015 100644 --- a/packages/deployer-types/src/secrets/password.rs +++ b/packages/deployer-types/src/secrets/password.rs @@ -31,7 +31,7 @@ impl Password { /// /// # Examples /// ``` - /// use torrust_deployer_types::secrets::Password; + /// use torrust_tracker_deployer_types::secrets::Password; /// /// let from_string = Password::new(String::from("password")); /// let from_str = Password::new("password"); diff --git a/packages/deployer-types/src/service_endpoint.rs b/packages/deployer-types/src/service_endpoint.rs index 99e0f13c5..04e44c29b 100644 --- a/packages/deployer-types/src/service_endpoint.rs +++ b/packages/deployer-types/src/service_endpoint.rs @@ -41,7 +41,7 @@ impl std::error::Error for InvalidServiceEndpointUrl {} /// /// ``` /// use std::net::SocketAddr; -/// use torrust_deployer_types::ServiceEndpoint; +/// use torrust_tracker_deployer_types::ServiceEndpoint; /// /// // HTTP endpoint /// let socket_addr: SocketAddr = "10.0.0.1:1212".parse().unwrap(); diff --git a/packages/deployer-types/src/username.rs b/packages/deployer-types/src/username.rs index 3a2c30985..b50d22999 100644 --- a/packages/deployer-types/src/username.rs +++ b/packages/deployer-types/src/username.rs @@ -76,7 +76,7 @@ impl Username { /// # Examples /// /// ```rust - /// use torrust_deployer_types::Username; + /// use torrust_tracker_deployer_types::Username; /// /// // Valid usernames - accepts both &str and String /// let user1 = Username::new("torrust")?; diff --git a/packages/sdk/Cargo.toml b/packages/sdk/Cargo.toml index 261ba934c..0b21ff64d 100644 --- a/packages/sdk/Cargo.toml +++ b/packages/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "torrust-tracker-deployer-sdk" -version = "0.1.0-beta.1" +version = "0.1.0" edition = "2021" description = "Programmatic SDK for the Torrust Tracker Deployer" license = "MIT" @@ -28,8 +28,8 @@ name = "sdk_validate_config" path = "examples/validate_config.rs" [dependencies] -torrust-tracker-deployer = { path = "../.." } -torrust-deployer-types = { path = "../deployer-types" } +torrust-tracker-deployer = { path = "../..", version = "0.1.0" } +torrust-tracker-deployer-types = { path = "../deployer-types", version = "0.1.0" } thiserror = "2.0" [dev-dependencies] diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 2bc9af3ec..0186b1bd9 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -13,7 +13,7 @@ Add to your `Cargo.toml`: ```toml [dependencies] -torrust-tracker-deployer-sdk = { git = "https://github.com/torrust/torrust-tracker-deployer" } +torrust-tracker-deployer-sdk = "0.1.0-beta.1" ``` Basic usage: @@ -46,27 +46,23 @@ cargo run --example sdk_validate_config -p torrust-tracker-deployer-sdk ```text torrust-tracker-deployer-sdk ← this package β”‚ - β–Ό -torrust-tracker-deployer (root crate) + β”œβ”€β”€β–Ά torrust-tracker-deployer (root crate) + β”‚ β”‚ + β”‚ β–Ό + β”‚ Application Layer (command_handlers/) + β”‚ β”‚ + β”‚ β–Ό + β”‚ Domain Layer (environment/, template/, topology/, ...) β”‚ - β–Ό -Application Layer (command_handlers/) - β”‚ - β–Ό -Domain Layer (environment/, template/, topology/, ...) + └──▢ torrust-tracker-deployer-types (packages/deployer-types/) + (shared value objects and traits) ``` -> **Note**: This package currently depends on the root `torrust-tracker-deployer` -> crate for application-layer types. Plans 3 and 4 will progressively decouple -> this dependency by extracting shared types into a `packages/deployer-types/` -> package. - ## Status This package was extracted from `src/presentation/sdk/` in the root crate as part -of the SDK workspace package refactoring (Plan 2 of 4). See the -[refactoring plan](../../docs/refactors/plans/extract-sdk-workspace-package.md) -for details. +of the workspace package refactoring. The extraction is complete and the package is +published on [crates.io](https://crates.io/crates/torrust-tracker-deployer-sdk). ## License diff --git a/packages/sdk/src/lib.rs b/packages/sdk/src/lib.rs index c45dd73e4..752226425 100644 --- a/packages/sdk/src/lib.rs +++ b/packages/sdk/src/lib.rs @@ -40,7 +40,7 @@ pub use builder::{DeployerBuildError, DeployerBuilder}; pub use deployer::Deployer; // === Domain types (inputs only) === -pub use torrust_deployer_types::{EnvironmentName, EnvironmentNameError}; +pub use torrust_tracker_deployer_types::{EnvironmentName, EnvironmentNameError}; // === Configuration types (for create_environment) === pub use torrust_tracker_deployer_lib::application::command_handlers::create::config::{ diff --git a/project-words.txt b/project-words.txt index 0e5ba1d70..30fd91f6f 100644 --- a/project-words.txt +++ b/project-words.txt @@ -51,6 +51,7 @@ Firestore Freshping Frontegg Geeksfor +GHSA Gossman Grafana Grafonnet @@ -97,6 +98,7 @@ Pythonic QUIC RAII RUSTDOCFLAGS +RUSTSEC Regenerable Repomix RepositΓ³ri @@ -162,12 +164,14 @@ bootcmd browsable btih btrfs +buger buildx cdmon celano certbot certonly chatbots +chacha chdir checkmark checkmarks @@ -196,6 +200,7 @@ crontabs cursorignore custompass customuser +cves cyberneering dcron dearmor @@ -238,6 +243,7 @@ ethernets executability exfiltration exitcode +exploitability filesd flatlined frontends @@ -276,6 +282,7 @@ josecelano journalctl jsonlint jsonls +jsonparser keepalive keygen keypair @@ -287,6 +294,7 @@ leecher leechers letsencrypt libc +libcrypto libldap libmariadb libpam @@ -432,6 +440,16 @@ sandboxed sarif sarifs scannability +SCEP +DTLS +mysqlsh +syscall +infocmp +libncurses +libtinfo +libsystemd +libudev +behaviour schemafile schemars scriptable @@ -511,6 +529,7 @@ unconfigured undertested unergonomic unittests +untgz unrepresentable DNAT UNCONN @@ -546,6 +565,10 @@ zeroize zoneinfo worktree zstd +ciphertext +makeslice +rstrip +urlsafe CSPRNG USERINFO plainpassword @@ -555,3 +578,7 @@ userinfo ΠΊΠ»ΡŽΡ‡ ΠΊΠΎΠ½Ρ„ΠΈΠ³ Ρ„Π°ΠΉΠ» + +cpython +kenv +libexpat diff --git a/scripts/setup/README.md b/scripts/setup/README.md index e142aa1da..37a50d835 100644 --- a/scripts/setup/README.md +++ b/scripts/setup/README.md @@ -12,19 +12,19 @@ For dependency installation, use the `dependency-installer` binary: ```bash # Install all dependencies -cargo run -p torrust-dependency-installer --bin dependency-installer -- install +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install # Check which dependencies are installed -cargo run -p torrust-dependency-installer --bin dependency-installer -- check +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- check # List all available dependencies -cargo run -p torrust-dependency-installer --bin dependency-installer -- list +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- list # Install specific dependency -cargo run -p torrust-dependency-installer --bin dependency-installer -- install --dependency opentofu +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install --dependency opentofu # See all options -cargo run -p torrust-dependency-installer --bin dependency-installer -- --help +cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- --help ``` ### Benefits of the New Approach @@ -66,8 +66,8 @@ Example workflow step: ```yaml - name: Install dependencies run: | - cargo build -p torrust-dependency-installer --bin dependency-installer - cargo run -p torrust-dependency-installer --bin dependency-installer -- install + cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer + cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install ``` ### Local Development @@ -84,9 +84,9 @@ For local development, the dependency installer automatically handles: If you encounter issues with the dependency installer: -1. **Check installation status**: `cargo run -p torrust-dependency-installer --bin dependency-installer -- check` +1. **Check installation status**: `cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- check` 2. **Enable debug logging**: Add `--verbose` flag or `--log-level debug` -3. **View available dependencies**: `cargo run -p torrust-dependency-installer --bin dependency-installer -- list` +3. **View available dependencies**: `cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- list` 4. **Check exit codes**: Exit code 0 = success, non-zero = failure For detailed troubleshooting, see the [dependency installer README](../../packages/dependency-installer/README.md). diff --git a/src/application/command_handlers/show/info/docker_images.rs b/src/application/command_handlers/show/info/docker_images.rs index e7de2cb46..0853618f5 100644 --- a/src/application/command_handlers/show/info/docker_images.rs +++ b/src/application/command_handlers/show/info/docker_images.rs @@ -12,7 +12,7 @@ pub struct DockerImagesInfo { /// `MySQL` Docker image reference (e.g. `mysql:8.4`), present when `MySQL` is configured pub mysql: Option, - /// Prometheus Docker image reference (e.g. `prom/prometheus:v3.5.1`), present when configured + /// Prometheus Docker image reference (e.g. `prom/prometheus:v3.11.2`), present when configured pub prometheus: Option, /// Grafana Docker image reference (e.g. `grafana/grafana:12.4.2`), present when configured diff --git a/src/bin/e2e_complete_workflow_tests.rs b/src/bin/e2e_complete_workflow_tests.rs index e75517eb1..9c27f2845 100644 --- a/src/bin/e2e_complete_workflow_tests.rs +++ b/src/bin/e2e_complete_workflow_tests.rs @@ -48,7 +48,7 @@ use anyhow::Result; use clap::Parser; use std::time::Instant; -use torrust_dependency_installer::Dependency; +use torrust_tracker_deployer_dependency_installer::Dependency; use tracing::{error, info}; use torrust_tracker_deployer_lib::bootstrap::logging::{LogFormat, LogOutput, LoggingBuilder}; diff --git a/src/bin/e2e_deployment_workflow_tests.rs b/src/bin/e2e_deployment_workflow_tests.rs index 21d7ce072..85f26b3b5 100644 --- a/src/bin/e2e_deployment_workflow_tests.rs +++ b/src/bin/e2e_deployment_workflow_tests.rs @@ -57,7 +57,7 @@ use std::time::Instant; use anyhow::{Context, Result}; use clap::Parser; -use torrust_dependency_installer::Dependency; +use torrust_tracker_deployer_dependency_installer::Dependency; use tracing::{error, info}; use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials; diff --git a/src/bin/e2e_infrastructure_lifecycle_tests.rs b/src/bin/e2e_infrastructure_lifecycle_tests.rs index d9ba3cc6f..3c3ffa459 100644 --- a/src/bin/e2e_infrastructure_lifecycle_tests.rs +++ b/src/bin/e2e_infrastructure_lifecycle_tests.rs @@ -41,7 +41,7 @@ use anyhow::Result; use clap::Parser; use std::time::Instant; -use torrust_dependency_installer::Dependency; +use torrust_tracker_deployer_dependency_installer::Dependency; use tracing::{error, info}; use torrust_tracker_deployer_lib::bootstrap::logging::{LogFormat, LogOutput, LoggingBuilder}; diff --git a/src/bootstrap/help.rs b/src/bootstrap/help.rs index 8d4d51587..7249a120b 100644 --- a/src/bootstrap/help.rs +++ b/src/bootstrap/help.rs @@ -44,7 +44,7 @@ pub fn display_getting_started() { println!("πŸ“‹ Quick Start:"); println!(" 1. Check dependencies:"); println!( - " cargo run --package torrust-dependency-installer --bin dependency-installer check" + " cargo run --package torrust-tracker-deployer-dependency-installer --bin dependency-installer check" ); println!(); println!(" 2. Create and deploy an environment:"); diff --git a/src/bootstrap/sdk.rs b/src/bootstrap/sdk.rs index f0134b404..b97b1f4a3 100644 --- a/src/bootstrap/sdk.rs +++ b/src/bootstrap/sdk.rs @@ -14,7 +14,7 @@ use std::time::Duration; use crate::application::traits::RepositoryProvider; use crate::infrastructure::persistence::file_repository_factory::FileRepositoryFactory; use crate::shared::SystemClock; -use torrust_deployer_types::Clock; +use torrust_tracker_deployer_types::Clock; /// The default file-lock timeout used by the SDK when no custom value is provided. pub const DEFAULT_SDK_LOCK_TIMEOUT: Duration = Duration::from_secs(30); diff --git a/src/domain/environment/name.rs b/src/domain/environment/name.rs index 98be05007..0907a4f46 100644 --- a/src/domain/environment/name.rs +++ b/src/domain/environment/name.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::environment_name::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::environment_name::*; diff --git a/src/domain/grafana/config.rs b/src/domain/grafana/config.rs index 9248d6a02..760e96f3b 100644 --- a/src/domain/grafana/config.rs +++ b/src/domain/grafana/config.rs @@ -13,7 +13,7 @@ use crate::shared::secrets::Password; pub const GRAFANA_DOCKER_IMAGE_REPOSITORY: &str = "grafana/grafana"; /// Docker image tag for the Grafana container -pub const GRAFANA_DOCKER_IMAGE_TAG: &str = "12.4.2"; +pub const GRAFANA_DOCKER_IMAGE_TAG: &str = "13.0.0"; /// Grafana metrics visualization configuration /// @@ -124,7 +124,7 @@ impl GrafanaConfig { /// use torrust_tracker_deployer_lib::domain::grafana::GrafanaConfig; /// /// let image = GrafanaConfig::docker_image(); - /// assert_eq!(image.full_reference(), "grafana/grafana:12.4.2"); + /// assert_eq!(image.full_reference(), "grafana/grafana:13.0.0"); /// ``` #[must_use] pub fn docker_image() -> DockerImage { diff --git a/src/domain/prometheus/config.rs b/src/domain/prometheus/config.rs index 4d10c293e..6b7d19320 100644 --- a/src/domain/prometheus/config.rs +++ b/src/domain/prometheus/config.rs @@ -21,7 +21,7 @@ const DEFAULT_SCRAPE_INTERVAL_SECS: u32 = 15; pub const PROMETHEUS_DOCKER_IMAGE_REPOSITORY: &str = "prom/prometheus"; /// Docker image tag for the Prometheus container -pub const PROMETHEUS_DOCKER_IMAGE_TAG: &str = "v3.5.1"; +pub const PROMETHEUS_DOCKER_IMAGE_TAG: &str = "v3.11.2"; /// Prometheus metrics collection configuration /// @@ -95,7 +95,7 @@ impl PrometheusConfig { /// use torrust_tracker_deployer_lib::domain::prometheus::PrometheusConfig; /// /// let image = PrometheusConfig::docker_image(); - /// assert_eq!(image.full_reference(), "prom/prometheus:v3.5.1"); + /// assert_eq!(image.full_reference(), "prom/prometheus:v3.11.2"); /// ``` #[must_use] pub fn docker_image() -> DockerImage { diff --git a/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs b/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs index 367411620..f24c79d0e 100644 --- a/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs +++ b/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs @@ -407,8 +407,8 @@ mod tests { "Rendered output should contain prometheus service" ); assert!( - rendered_content.contains("image: prom/prometheus:v3.5.1"), - "Should use Prometheus v3.5.0 image" + rendered_content.contains("image: prom/prometheus:v3.11.2"), + "Should use Prometheus v3.11.2 image" ); assert!( rendered_content.contains("container_name: prometheus"), @@ -466,7 +466,7 @@ mod tests { // Verify Prometheus service is NOT present assert!( - !rendered_content.contains("image: prom/prometheus:v3.5.1"), + !rendered_content.contains("image: prom/prometheus:v3.11.2"), "Should not contain Prometheus service when config absent" ); assert!( diff --git a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/grafana.rs b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/grafana.rs index c2cac4572..819f1c654 100644 --- a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/grafana.rs +++ b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/grafana.rs @@ -18,7 +18,7 @@ use super::service_topology::ServiceTopology; /// Uses `ServiceTopology` to share the common topology structure with other services. #[derive(Serialize, Debug, Clone)] pub struct GrafanaServiceContext { - /// Docker image reference (e.g. `grafana/grafana:12.4.2`) + /// Docker image reference (e.g. `grafana/grafana:13.0.0`) pub image: String, /// Service topology (ports and networks) diff --git a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/prometheus.rs b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/prometheus.rs index bc3db8bf4..01a88477d 100644 --- a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/prometheus.rs +++ b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/prometheus.rs @@ -18,7 +18,7 @@ use super::service_topology::ServiceTopology; /// Uses `ServiceTopology` to share the common topology structure with other services. #[derive(Serialize, Debug, Clone)] pub struct PrometheusServiceContext { - /// Docker image reference (e.g. `prom/prometheus:v3.5.1`) + /// Docker image reference (e.g. `prom/prometheus:v3.11.2`) pub image: String, /// Service topology (ports and networks) diff --git a/src/shared/clock.rs b/src/shared/clock.rs index e97a06724..2057af090 100644 --- a/src/shared/clock.rs +++ b/src/shared/clock.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::clock::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::clock::*; diff --git a/src/shared/domain_name.rs b/src/shared/domain_name.rs index 5a975b979..38de2751d 100644 --- a/src/shared/domain_name.rs +++ b/src/shared/domain_name.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::domain_name::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::domain_name::*; diff --git a/src/shared/email.rs b/src/shared/email.rs index 7c2cef2e2..4d6c049a6 100644 --- a/src/shared/email.rs +++ b/src/shared/email.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::email::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::email::*; diff --git a/src/shared/error/kind.rs b/src/shared/error/kind.rs index 7b6a2018d..78aef4b36 100644 --- a/src/shared/error/kind.rs +++ b/src/shared/error/kind.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::error::kind::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::error::kind::*; diff --git a/src/shared/error/traceable.rs b/src/shared/error/traceable.rs index a3c9a3d90..d773622ca 100644 --- a/src/shared/error/traceable.rs +++ b/src/shared/error/traceable.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::error::traceable::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::error::traceable::*; diff --git a/src/shared/secrets/api_token.rs b/src/shared/secrets/api_token.rs index 0575d6720..f6495328e 100644 --- a/src/shared/secrets/api_token.rs +++ b/src/shared/secrets/api_token.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::secrets::{ApiToken, PlainApiToken}; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::secrets::{ApiToken, PlainApiToken}; diff --git a/src/shared/secrets/password.rs b/src/shared/secrets/password.rs index 2cbded774..2f42fb2ca 100644 --- a/src/shared/secrets/password.rs +++ b/src/shared/secrets/password.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::secrets::{Password, PlainPassword}; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::secrets::{Password, PlainPassword}; diff --git a/src/shared/service_endpoint.rs b/src/shared/service_endpoint.rs index 11626ec49..b0d4bad71 100644 --- a/src/shared/service_endpoint.rs +++ b/src/shared/service_endpoint.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::service_endpoint::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::service_endpoint::*; diff --git a/src/shared/username.rs b/src/shared/username.rs index 4585b012c..5e0cca7a2 100644 --- a/src/shared/username.rs +++ b/src/shared/username.rs @@ -1,2 +1,2 @@ -// Backward compatibility re-export β€” types moved to torrust-deployer-types. -pub use torrust_deployer_types::username::*; +// Backward compatibility re-export β€” types moved to torrust-tracker-deployer-types. +pub use torrust_tracker_deployer_types::username::*; diff --git a/src/testing/e2e/mod.rs b/src/testing/e2e/mod.rs index 8fbc82974..9654331df 100644 --- a/src/testing/e2e/mod.rs +++ b/src/testing/e2e/mod.rs @@ -20,7 +20,7 @@ //! //! ## Dependency Verification //! -//! E2E test binaries use the `torrust-dependency-installer` package to verify +//! E2E test binaries use the `torrust-tracker-deployer-dependency-installer` package to verify //! required system dependencies are installed before running tests. pub mod container; diff --git a/src/testing/e2e/tasks/black_box/mod.rs b/src/testing/e2e/tasks/black_box/mod.rs index 41c1ab1da..56af6200d 100644 --- a/src/testing/e2e/tasks/black_box/mod.rs +++ b/src/testing/e2e/tasks/black_box/mod.rs @@ -23,7 +23,7 @@ //! E2eTestRunner, generate_environment_config, run_preflight_cleanup, //! verify_required_dependencies, //! }; -//! use torrust_dependency_installer::Dependency; +//! use torrust_tracker_deployer_dependency_installer::Dependency; //! //! // Setup tasks (before creating the test runner) //! verify_required_dependencies(&[Dependency::OpenTofu, Dependency::Ansible])?; diff --git a/src/testing/e2e/tasks/black_box/verify_dependencies.rs b/src/testing/e2e/tasks/black_box/verify_dependencies.rs index b3bc31890..1dbdeb9ea 100644 --- a/src/testing/e2e/tasks/black_box/verify_dependencies.rs +++ b/src/testing/e2e/tasks/black_box/verify_dependencies.rs @@ -7,7 +7,7 @@ //! //! ```rust,ignore //! use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::verify_required_dependencies; -//! use torrust_dependency_installer::Dependency; +//! use torrust_tracker_deployer_dependency_installer::Dependency; //! //! // Verify dependencies for provision tests (only Ansible needed) //! verify_required_dependencies(&[Dependency::Ansible])?; @@ -21,7 +21,7 @@ //! ``` use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use tracing::error; /// Verify that all required dependencies are installed for E2E tests. @@ -42,7 +42,7 @@ use tracing::error; /// /// ```rust,ignore /// use torrust_tracker_deployer_lib::testing::e2e::black_box::tasks::verify_required_dependencies; -/// use torrust_dependency_installer::Dependency; +/// use torrust_tracker_deployer_dependency_installer::Dependency; /// /// // For provision-only tests /// verify_required_dependencies(&[Dependency::Ansible])?; diff --git a/templates/docker-compose/docker-compose.yml.tera b/templates/docker-compose/docker-compose.yml.tera index a43e60e59..fa9a45309 100644 --- a/templates/docker-compose/docker-compose.yml.tera +++ b/templates/docker-compose/docker-compose.yml.tera @@ -52,7 +52,7 @@ services: # Placed first as it's the entry point for HTTPS traffic caddy: <<: *defaults - image: caddy:2.10.2 + image: caddy:2.11.2 container_name: caddy # NOTE: No UFW firewall rule needed for these ports! # Docker-published ports bypass iptables/UFW rules entirely. diff --git a/templates/tofu/hetzner/main.tf b/templates/tofu/hetzner/main.tf index b78486960..2f88f9cbb 100644 --- a/templates/tofu/hetzner/main.tf +++ b/templates/tofu/hetzner/main.tf @@ -107,7 +107,7 @@ variable "server_labels" { # Root SSH provides a recovery/debugging path. # # SECURITY NOTE: For production deployments, consider disabling root SSH access -# after verifying deployment succeeded. See docs/security/ssh-root-access-hetzner.md +# after verifying deployment succeeded. See docs/security/user-security/ssh-root-access-hetzner.md # # This key will appear in Hetzner Console β†’ Security β†’ SSH Keys. resource "hcloud_ssh_key" "torrust" { diff --git a/tests/e2e/create_command.rs b/tests/e2e/create_command.rs index aba536511..3d54ef091 100644 --- a/tests/e2e/create_command.rs +++ b/tests/e2e/create_command.rs @@ -22,7 +22,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for create command E2E tests. diff --git a/tests/e2e/destroy_command.rs b/tests/e2e/destroy_command.rs index 1c434344d..1846898b8 100644 --- a/tests/e2e/destroy_command.rs +++ b/tests/e2e/destroy_command.rs @@ -20,7 +20,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for destroy command E2E tests. diff --git a/tests/e2e/exists_command.rs b/tests/e2e/exists_command.rs index 8345b3931..9acbf823e 100644 --- a/tests/e2e/exists_command.rs +++ b/tests/e2e/exists_command.rs @@ -20,7 +20,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for exists command E2E tests. diff --git a/tests/e2e/list_command.rs b/tests/e2e/list_command.rs index a7ed5d303..980129b9f 100644 --- a/tests/e2e/list_command.rs +++ b/tests/e2e/list_command.rs @@ -20,7 +20,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for list command E2E tests. diff --git a/tests/e2e/purge_command.rs b/tests/e2e/purge_command.rs index 7db565998..853b40a1f 100644 --- a/tests/e2e/purge_command.rs +++ b/tests/e2e/purge_command.rs @@ -28,7 +28,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for purge command E2E tests. diff --git a/tests/e2e/render_command.rs b/tests/e2e/render_command.rs index 48c5505a7..825329fb2 100644 --- a/tests/e2e/render_command.rs +++ b/tests/e2e/render_command.rs @@ -32,7 +32,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for render command E2E tests. diff --git a/tests/e2e/show_command.rs b/tests/e2e/show_command.rs index 46e07f64b..0646c69f7 100644 --- a/tests/e2e/show_command.rs +++ b/tests/e2e/show_command.rs @@ -19,7 +19,7 @@ use super::super::support::{process_runner, EnvironmentStateAssertions, TempWorkspace}; use anyhow::Result; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for show command E2E tests. diff --git a/tests/e2e/validate_command.rs b/tests/e2e/validate_command.rs index 00c1bb307..4398c7b7c 100644 --- a/tests/e2e/validate_command.rs +++ b/tests/e2e/validate_command.rs @@ -23,7 +23,7 @@ use super::super::support::{process_runner, TempWorkspace}; use anyhow::Result; use std::fs; -use torrust_dependency_installer::{verify_dependencies, Dependency}; +use torrust_tracker_deployer_dependency_installer::{verify_dependencies, Dependency}; use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config; /// Verify that all required dependencies are installed for validate command E2E tests.