Compare commits
11 Commits
release-v1
...
devon/acl-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ab0e390cd | ||
|
|
eac6538b6d | ||
|
|
2d9d14ee30 | ||
|
|
27331588ef | ||
|
|
6f550c256f | ||
|
|
20f395eaec | ||
|
|
ad9efbea51 | ||
|
|
cfc03b180f | ||
|
|
681987a150 | ||
|
|
e2684682cc | ||
|
|
7be240d44b |
84
.github/workflows/docker.yml
vendored
84
.github/workflows/docker.yml
vendored
@@ -28,10 +28,10 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Extract version from pyproject.toml
|
||||
# Note: explicitly requesting bash will mean bash is invoked with `-eo pipefail`, see
|
||||
@@ -41,50 +41,18 @@ jobs:
|
||||
echo "SYNAPSE_VERSION=$(grep "^version" pyproject.toml | sed -E 's/version\s*=\s*["]([^"]*)["]/\1/')" >> $GITHUB_ENV
|
||||
|
||||
- name: Log in to DockerHub
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Tailscale
|
||||
uses: tailscale/github-action@53acf823325fe9ca47f4cdaa951f90b4b0de5bb9 # v4.1.1
|
||||
with:
|
||||
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
||||
audience: ${{ secrets.TS_AUDIENCE }}
|
||||
tags: tag:github-actions
|
||||
|
||||
- name: Compute vault jwt role name
|
||||
id: vault-jwt-role
|
||||
run: |
|
||||
echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get team registry token
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
|
||||
with:
|
||||
url: https://vault.infra.ci.i.element.dev
|
||||
role: ${{ steps.vault-jwt-role.outputs.role_name }}
|
||||
path: service-management/github-actions
|
||||
jwtGithubAudience: https://vault.infra.ci.i.element.dev
|
||||
method: jwt
|
||||
secrets: |
|
||||
services/backend-repositories/secret/data/oci.element.io username | OCI_USERNAME ;
|
||||
services/backend-repositories/secret/data/oci.element.io password | OCI_PASSWORD ;
|
||||
|
||||
- name: Login to Element OCI Registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: oci-push.vpn.infra.element.io
|
||||
username: ${{ steps.import-secrets.outputs.OCI_USERNAME }}
|
||||
password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }}
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
@@ -96,7 +64,6 @@ jobs:
|
||||
tags: |
|
||||
docker.io/matrixdotorg/synapse
|
||||
ghcr.io/element-hq/synapse
|
||||
oci-push.vpn.infra.element.io/synapse
|
||||
file: "docker/Dockerfile"
|
||||
platforms: ${{ matrix.platform }}
|
||||
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
||||
@@ -108,7 +75,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: digests-${{ matrix.suffix }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -123,67 +90,34 @@ jobs:
|
||||
repository:
|
||||
- docker.io/matrixdotorg/synapse
|
||||
- ghcr.io/element-hq/synapse
|
||||
- oci-push.vpn.infra.element.io/synapse
|
||||
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Log in to DockerHub
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
if: ${{ startsWith(matrix.repository, 'docker.io') }}
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
if: ${{ startsWith(matrix.repository, 'ghcr.io') }}
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Tailscale
|
||||
uses: tailscale/github-action@53acf823325fe9ca47f4cdaa951f90b4b0de5bb9 # v4.1.1
|
||||
with:
|
||||
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
||||
audience: ${{ secrets.TS_AUDIENCE }}
|
||||
tags: tag:github-actions
|
||||
|
||||
- name: Compute vault jwt role name
|
||||
id: vault-jwt-role
|
||||
run: |
|
||||
echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get team registry token
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
|
||||
with:
|
||||
url: https://vault.infra.ci.i.element.dev
|
||||
role: ${{ steps.vault-jwt-role.outputs.role_name }}
|
||||
path: service-management/github-actions
|
||||
jwtGithubAudience: https://vault.infra.ci.i.element.dev
|
||||
method: jwt
|
||||
secrets: |
|
||||
services/backend-repositories/secret/data/oci.element.io username | OCI_USERNAME ;
|
||||
services/backend-repositories/secret/data/oci.element.io password | OCI_PASSWORD ;
|
||||
|
||||
- name: Login to Element OCI Registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: oci-push.vpn.infra.element.io
|
||||
username: ${{ steps.import-secrets.outputs.OCI_USERNAME }}
|
||||
password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
27
.github/workflows/docs-pr.yaml
vendored
27
.github/workflows/docs-pr.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
name: GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
# Fetch all history so that the schema_versions script works.
|
||||
fetch-depth: 0
|
||||
@@ -21,10 +21,10 @@ jobs:
|
||||
- name: Setup mdbook
|
||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
||||
with:
|
||||
mdbook-version: '0.5.2'
|
||||
mdbook-version: '0.4.17'
|
||||
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
cp book/welcome_and_overview.html book/index.html
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: book
|
||||
path: book
|
||||
@@ -50,12 +50,12 @@ jobs:
|
||||
name: Check links in documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Setup mdbook
|
||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
||||
with:
|
||||
mdbook-version: '0.5.2'
|
||||
mdbook-version: '0.4.17'
|
||||
|
||||
- name: Setup htmltest
|
||||
run: |
|
||||
@@ -64,17 +64,8 @@ jobs:
|
||||
tar zxf htmltest_0.17.0_linux_amd64.tar.gz
|
||||
|
||||
- name: Test links with htmltest
|
||||
# Build the book with `./` as the site URL (to make checks on 404.html possible)
|
||||
# Then run htmltest (without checking external links since that involves the network and is slow).
|
||||
run: |
|
||||
# Build the book with `./` as the site URL (to make checks on 404.html possible)
|
||||
MDBOOK_OUTPUT__HTML__SITE_URL="./" mdbook build
|
||||
|
||||
# Delete the contents of the print.html file, as it can raise false
|
||||
# positives during link checking.
|
||||
#
|
||||
# We empty out the file, instead of deleting it, as doing so would
|
||||
# just cause htmltest to complain that links to it were invalid.
|
||||
# Ideally `htmltest` would have an option to ignore specific files
|
||||
# instead.
|
||||
echo '<!DOCTYPE HTML>' > book/print.html
|
||||
|
||||
./htmltest book --conf docs/.htmltest.yml
|
||||
./htmltest book --skip-external
|
||||
|
||||
6
.github/workflows/docs.yaml
vendored
6
.github/workflows/docs.yaml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
needs:
|
||||
- pre
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
# Fetch all history so that the schema_versions script works.
|
||||
fetch-depth: 0
|
||||
@@ -58,13 +58,13 @@ jobs:
|
||||
- name: Setup mdbook
|
||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
||||
with:
|
||||
mdbook-version: '0.5.2'
|
||||
mdbook-version: '0.4.17'
|
||||
|
||||
- name: Set version of docs
|
||||
run: echo 'window.SYNAPSE_VERSION = "${{ needs.pre.outputs.branch-version }}";' > ./docs/website_files/version.js
|
||||
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
|
||||
4
.github/workflows/fix_lint.yaml
vendored
4
.github/workflows/fix_lint.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
- run: cargo fmt
|
||||
continue-on-error: true
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
|
||||
- uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0
|
||||
with:
|
||||
commit_message: "Attempt to fix linting"
|
||||
|
||||
66
.github/workflows/latest_deps.yml
vendored
66
.github/workflows/latest_deps.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
if: needs.check_repo.outputs.should_run_workflow == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
with:
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
postgres-version: "14"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
|
||||
postgres:${{ matrix.postgres-version }}
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: pip install .[all,test]
|
||||
@@ -126,6 +126,7 @@ jobs:
|
||||
-exec echo "::endgroup::" \;
|
||||
|| true
|
||||
|
||||
|
||||
sytest:
|
||||
needs: check_repo
|
||||
if: needs.check_repo.outputs.should_run_workflow == 'true'
|
||||
@@ -151,7 +152,7 @@ jobs:
|
||||
BLACKLIST: ${{ matrix.workers && 'synapse-blacklist-with-workers' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -172,7 +173,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
|
||||
- name: Upload SyTest logs
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.*, ', ') }})
|
||||
@@ -180,6 +181,7 @@ jobs:
|
||||
/logs/results.tap
|
||||
/logs/**/*.log*
|
||||
|
||||
|
||||
complement:
|
||||
needs: check_repo
|
||||
if: "!failure() && !cancelled() && needs.check_repo.outputs.should_run_workflow == 'true'"
|
||||
@@ -200,65 +202,23 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out synapse codebase
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
path: synapse
|
||||
|
||||
- name: Prepare Complement's Prerequisites
|
||||
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
||||
|
||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||
with:
|
||||
cache-dependency-path: complement/go.sum
|
||||
go-version-file: complement/go.mod
|
||||
|
||||
- name: Run Complement Tests
|
||||
id: run_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
- run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log
|
||||
TEST_ONLY_IGNORE_POETRY_LOCKFILE=1 POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
TEST_ONLY_IGNORE_POETRY_LOCKFILE: 1
|
||||
|
||||
- name: Formatted Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
|
||||
- name: Run in-repo Complement Tests
|
||||
id: run_in_repo_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
TEST_ONLY_IGNORE_POETRY_LOCKFILE: 1
|
||||
|
||||
- name: Formatted in-repo Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
name: Run Complement Tests
|
||||
|
||||
# Open an issue if the build fails, so we know about it.
|
||||
# Only do this if we're not experimenting with this action in a PR.
|
||||
@@ -274,7 +234,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
4
.github/workflows/poetry_lockfile.yaml
vendored
4
.github/workflows/poetry_lockfile.yaml
vendored
@@ -16,8 +16,8 @@ jobs:
|
||||
name: "Check locked dependencies have sdists"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- run: pip install tomli
|
||||
|
||||
8
.github/workflows/push_complement_image.yml
vendored
8
.github/workflows/push_complement_image.yml
vendored
@@ -33,22 +33,22 @@ jobs:
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout specific branch (debug build)
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: Checkout clean copy of develop (scheduled build)
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
if: github.event_name == 'schedule'
|
||||
with:
|
||||
ref: develop
|
||||
- name: Checkout clean copy of master (on-push)
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
if: github.event_name == 'push'
|
||||
with:
|
||||
ref: master
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
30
.github/workflows/release-artifacts.yml
vendored
30
.github/workflows/release-artifacts.yml
vendored
@@ -27,8 +27,8 @@ jobs:
|
||||
name: "Calculate list of debian distros"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- id: set-distros
|
||||
@@ -55,16 +55,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
path: src
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Set up docker layer caching
|
||||
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
@@ -72,7 +74,7 @@ jobs:
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
@@ -99,7 +101,7 @@ jobs:
|
||||
echo "ARTIFACT_NAME=${DISTRO#*:}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload debs as artifacts
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: debs-${{ steps.artifact-name.outputs.ARTIFACT_NAME }}
|
||||
path: debs/*
|
||||
@@ -123,9 +125,9 @@ jobs:
|
||||
os: "ubuntu-24.04-arm"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
# setup-python@v4 doesn't impose a default python version. Need to use 3.x
|
||||
# here, because `python` on osx points to Python 2.7.
|
||||
@@ -150,7 +152,7 @@ jobs:
|
||||
# musl: (TODO: investigate).
|
||||
CIBW_TEST_SKIP: pp3*-* *musl*
|
||||
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: Wheel-${{ matrix.os }}
|
||||
path: ./wheelhouse/*.whl
|
||||
@@ -161,8 +163,8 @@ jobs:
|
||||
if: ${{ !startsWith(github.ref, 'refs/pull/') }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
@@ -171,7 +173,7 @@ jobs:
|
||||
- name: Build sdist
|
||||
run: python -m build --sdist
|
||||
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: Sdist
|
||||
path: dist/*.tar.gz
|
||||
@@ -187,7 +189,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download all workflow run artifacts
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
- name: Build a tarball for the debs
|
||||
# We need to merge all the debs uploads into one folder, then compress
|
||||
# that.
|
||||
|
||||
8
.github/workflows/schema.yaml
vendored
8
.github/workflows/schema.yaml
vendored
@@ -14,8 +14,8 @@ jobs:
|
||||
name: Ensure Synapse config schema is valid
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install check-jsonschema
|
||||
@@ -40,8 +40,8 @@ jobs:
|
||||
name: Ensure generated documentation is up-to-date
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install PyYAML
|
||||
|
||||
224
.github/workflows/tests.yml
vendored
224
.github/workflows/tests.yml
vendored
@@ -26,59 +26,59 @@ jobs:
|
||||
linting: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.linting }}
|
||||
linting_readme: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.linting_readme }}
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: filter
|
||||
# We only check on PRs
|
||||
if: startsWith(github.ref, 'refs/pull/')
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'rust/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- '.rustfmt.toml'
|
||||
- '.github/workflows/tests.yml'
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: filter
|
||||
# We only check on PRs
|
||||
if: startsWith(github.ref, 'refs/pull/')
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'rust/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- '.rustfmt.toml'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
trial:
|
||||
- 'synapse/**'
|
||||
- 'tests/**'
|
||||
- 'rust/**'
|
||||
- '.ci/scripts/calculate_jobs.py'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
trial:
|
||||
- 'synapse/**'
|
||||
- 'tests/**'
|
||||
- 'rust/**'
|
||||
- '.ci/scripts/calculate_jobs.py'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
integration:
|
||||
- 'synapse/**'
|
||||
- 'rust/**'
|
||||
- 'docker/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- 'docker/**'
|
||||
- '.ci/**'
|
||||
- 'scripts-dev/complement.sh'
|
||||
- '.github/workflows/tests.yml'
|
||||
integration:
|
||||
- 'synapse/**'
|
||||
- 'rust/**'
|
||||
- 'docker/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- 'docker/**'
|
||||
- '.ci/**'
|
||||
- 'scripts-dev/complement.sh'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
linting:
|
||||
- 'synapse/**'
|
||||
- 'docker/**'
|
||||
- 'tests/**'
|
||||
- 'scripts-dev/**'
|
||||
- 'contrib/**'
|
||||
- 'synmark/**'
|
||||
- 'stubs/**'
|
||||
- '.ci/**'
|
||||
- 'mypy.ini'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
linting:
|
||||
- 'synapse/**'
|
||||
- 'docker/**'
|
||||
- 'tests/**'
|
||||
- 'scripts-dev/**'
|
||||
- 'contrib/**'
|
||||
- 'synmark/**'
|
||||
- 'stubs/**'
|
||||
- '.ci/**'
|
||||
- 'mypy.ini'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
linting_readme:
|
||||
- 'README.rst'
|
||||
linting_readme:
|
||||
- 'README.rst'
|
||||
|
||||
check-sampleconfig:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.linting == 'true' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
with:
|
||||
@@ -106,8 +106,8 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.linting == 'true' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: "pip install 'click==8.1.1' 'GitPython>=3.1.20' 'sqlglot>=28.0.0'"
|
||||
@@ -116,8 +116,8 @@ jobs:
|
||||
check-lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: .ci/scripts/check_lockfile.py
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Setup Poetry
|
||||
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -174,7 +174,7 @@ jobs:
|
||||
# Cribbed from
|
||||
# https://github.com/AustinScola/mypy-cache-github-action/blob/85ea4f2972abed39b33bd02c36e341b28ca59213/src/restore.ts#L10-L17
|
||||
- name: Restore/persist mypy's cache
|
||||
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: |
|
||||
.mypy_cache
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
lint-crlf:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Check line endings
|
||||
run: scripts-dev/check_line_terminators.sh
|
||||
|
||||
@@ -196,11 +196,11 @@ jobs:
|
||||
if: ${{ github.event_name == 'pull_request' && (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.event.pull_request.user.login != 'dependabot[bot]' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: "pip install 'towncrier>=18.6.0rc1'"
|
||||
@@ -214,13 +214,13 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
with:
|
||||
components: clippy
|
||||
toolchain: ${{ env.RUST_VERSION }}
|
||||
components: clippy
|
||||
toolchain: ${{ env.RUST_VERSION }}
|
||||
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||
|
||||
- run: cargo clippy -- -D warnings
|
||||
@@ -233,13 +233,13 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
with:
|
||||
toolchain: nightly-2026-02-01
|
||||
components: clippy
|
||||
toolchain: nightly-2025-04-23
|
||||
components: clippy
|
||||
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||
|
||||
- run: cargo clippy --all-features -- -D warnings
|
||||
@@ -251,7 +251,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -287,7 +287,7 @@ jobs:
|
||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -307,8 +307,8 @@ jobs:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.linting_readme == 'true' }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: "pip install rstcheck"
|
||||
@@ -349,13 +349,14 @@ jobs:
|
||||
lint-rustfmt
|
||||
lint-readme
|
||||
|
||||
|
||||
calculate-test-jobs:
|
||||
if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
|
||||
needs: linting-done
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- id: get-matrix
|
||||
@@ -372,10 +373,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
|
||||
job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- run: sudo apt-get -qq install xmlsec1
|
||||
- name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
|
||||
if: ${{ matrix.job.postgres-version }}
|
||||
@@ -431,7 +432,7 @@ jobs:
|
||||
- changes
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -446,14 +447,14 @@ jobs:
|
||||
sudo apt-get -qq install build-essential libffi-dev python3-dev \
|
||||
libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Prepare old deps
|
||||
# Note: we install using `uv` here, not poetry or pip to allow us to test with the
|
||||
# minimum version of all dependencies, both those explicitly specified and those
|
||||
# implicitly brought in by the explicit dependencies.
|
||||
# implicitly brought in by the explicit dependencies.
|
||||
run: |
|
||||
pip install uv
|
||||
uv pip install --system --resolution=lowest .[all,test]
|
||||
@@ -494,7 +495,7 @@ jobs:
|
||||
extras: ["all"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
# Install libs necessary for PyPy to build binary wheels for dependencies
|
||||
- run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
|
||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||
@@ -544,7 +545,7 @@ jobs:
|
||||
job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Prepare test blacklist
|
||||
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
|
||||
|
||||
@@ -561,7 +562,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
|
||||
- name: Upload SyTest logs
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }})
|
||||
@@ -591,7 +592,7 @@ jobs:
|
||||
--health-retries 5
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- run: sudo apt-get -qq install xmlsec1 postgresql-client
|
||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||
with:
|
||||
@@ -604,6 +605,7 @@ jobs:
|
||||
PGPASSWORD: postgres
|
||||
PGDATABASE: postgres
|
||||
|
||||
|
||||
portdb:
|
||||
if: ${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true'}} # Allow previous steps to be skipped, but not fail
|
||||
needs:
|
||||
@@ -634,7 +636,7 @@ jobs:
|
||||
--health-retries 5
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Add PostgreSQL apt repository
|
||||
# We need a version of pg_dump that can handle the version of
|
||||
# PostgreSQL being tested against. The Ubuntu package repository lags
|
||||
@@ -658,7 +660,7 @@ jobs:
|
||||
PGPASSWORD: postgres
|
||||
PGDATABASE: postgres
|
||||
- name: "Upload schema differences"
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
if: ${{ failure() && !cancelled() && steps.run_tester_script.outcome == 'failure' }}
|
||||
with:
|
||||
name: Schema dumps
|
||||
@@ -689,7 +691,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout synapse codebase
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
path: synapse
|
||||
|
||||
@@ -702,56 +704,20 @@ jobs:
|
||||
- name: Prepare Complement's Prerequisites
|
||||
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
||||
|
||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||
with:
|
||||
cache-dependency-path: complement/go.sum
|
||||
go-version-file: complement/go.mod
|
||||
|
||||
- name: Run Complement Tests
|
||||
id: run_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
# use p=1 concurrency as GHA boxes are underpowered and don't like running tons of synapses at once.
|
||||
- run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | synapse/.ci/scripts/gotestfmt
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
|
||||
- name: Formatted Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
|
||||
- name: Run in-repo Complement Tests
|
||||
id: run_in_repo_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
|
||||
- name: Formatted in-repo Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
name: Run Complement Tests
|
||||
|
||||
cargo-test:
|
||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||
@@ -761,7 +727,7 @@ jobs:
|
||||
- changes
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -781,12 +747,12 @@ jobs:
|
||||
- changes
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
with:
|
||||
toolchain: nightly-2022-12-01
|
||||
toolchain: nightly-2022-12-01
|
||||
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||
|
||||
- run: cargo bench --no-run
|
||||
|
||||
2
.github/workflows/triage_labelled.yml
vendored
2
.github/workflows/triage_labelled.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
# This field is case-sensitive.
|
||||
TARGET_STATUS: Needs info
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
# Only clone the script file we care about, instead of the whole repo.
|
||||
sparse-checkout: .ci/scripts/triage_labelled_issue.sh
|
||||
|
||||
66
.github/workflows/twisted_trunk.yml
vendored
66
.github/workflows/twisted_trunk.yml
vendored
@@ -12,9 +12,10 @@ on:
|
||||
twisted_ref:
|
||||
description: Commit, branch or tag to checkout from upstream Twisted.
|
||||
required: false
|
||||
default: "trunk"
|
||||
default: 'trunk'
|
||||
type: string
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
@@ -42,7 +43,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -69,7 +70,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- run: sudo apt-get -qq install xmlsec1
|
||||
|
||||
- name: Install Rust
|
||||
@@ -88,6 +89,7 @@ jobs:
|
||||
poetry add --extras tls git+https://github.com/twisted/twisted.git#trunk
|
||||
poetry install --no-interaction --extras "all test"
|
||||
- run: poetry run trial --jobs 2 tests
|
||||
|
||||
- name: Dump logs
|
||||
# Logs are most useful when the command fails, always include them.
|
||||
if: ${{ always() }}
|
||||
@@ -115,7 +117,7 @@ jobs:
|
||||
- ${{ github.workspace }}:/src
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master
|
||||
@@ -145,7 +147,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
|
||||
- name: Upload SyTest logs
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.*, ', ') }})
|
||||
@@ -173,14 +175,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Run actions/checkout@v4 for synapse
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
path: synapse
|
||||
|
||||
- name: Prepare Complement's Prerequisites
|
||||
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
||||
|
||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||
with:
|
||||
cache-dependency-path: complement/go.sum
|
||||
go-version-file: complement/go.mod
|
||||
@@ -197,53 +199,11 @@ jobs:
|
||||
poetry lock
|
||||
working-directory: synapse
|
||||
|
||||
- name: Run Complement Tests
|
||||
id: run_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
- run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log
|
||||
TEST_ONLY_SKIP_DEP_HASH_VERIFICATION=1 POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
TEST_ONLY_SKIP_DEP_HASH_VERIFICATION: 1
|
||||
|
||||
- name: Formatted Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
|
||||
- name: Run in-repo Complement Tests
|
||||
id: run_in_repo_complement_tests
|
||||
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
|
||||
# are underpowered and don't like running tons of Synapse instances at once.
|
||||
# -json: Output JSON format so that gotestfmt can parse it.
|
||||
#
|
||||
# tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it
|
||||
# later on for better formatting with gotestfmt. But we still want the command
|
||||
# to output to the terminal as it runs so we can see what's happening in
|
||||
# real-time.
|
||||
run: |
|
||||
set -o pipefail
|
||||
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log
|
||||
shell: bash
|
||||
env:
|
||||
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
||||
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
||||
TEST_ONLY_SKIP_DEP_HASH_VERIFICATION: 1
|
||||
|
||||
- name: Formatted in-repo Complement test logs
|
||||
# Always run this step if we attempted to run the Complement tests.
|
||||
if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped'
|
||||
run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
|
||||
name: Run Complement Tests
|
||||
|
||||
# open an issue if the build fails, so we know about it.
|
||||
open-issue:
|
||||
@@ -257,7 +217,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
211
CHANGES.md
211
CHANGES.md
@@ -1,214 +1,3 @@
|
||||
# Synapse 1.148.0 (2026-02-24)
|
||||
|
||||
No significant changes since 1.148.0rc1.
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.148.0rc1 (2026-02-17)
|
||||
|
||||
## Features
|
||||
|
||||
- Support sending and receiving [MSC4354 Sticky Event](https://github.com/matrix-org/matrix-spec-proposals/pull/4354) metadata. ([\#19365](https://github.com/element-hq/synapse/issues/19365))
|
||||
|
||||
## Improved Documentation
|
||||
|
||||
- Fix reference to the `experimental_features` section of the configuration manual documentation. ([\#19435](https://github.com/element-hq/synapse/issues/19435))
|
||||
|
||||
## Deprecations and Removals
|
||||
|
||||
- Remove support for [MSC3244: Room version capabilities](https://github.com/matrix-org/matrix-spec-proposals/pull/3244) as the MSC was rejected. ([\#19429](https://github.com/element-hq/synapse/issues/19429))
|
||||
|
||||
## Internal Changes
|
||||
|
||||
- Add in-repo Complement tests so we can test Synapse specific behavior at an end-to-end level. ([\#19406](https://github.com/element-hq/synapse/issues/19406))
|
||||
- Push Synapse docker images to Element OCI Registry. ([\#19420](https://github.com/element-hq/synapse/issues/19420))
|
||||
- Allow configuring the Rust HTTP client to use HTTP/2 only. ([\#19457](https://github.com/element-hq/synapse/issues/19457))
|
||||
- Correctly refuse to start if the Rust workspace config has changed and the Rust library has not been rebuilt. ([\#19470](https://github.com/element-hq/synapse/issues/19470))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.147.1 (2026-02-12)
|
||||
|
||||
## Internal Changes
|
||||
|
||||
- Block federation requests and events authenticated using a known insecure signing key. See [CVE-2026-24044](https://www.cve.org/CVERecord?id=CVE-2026-24044) / [ELEMENTSEC-2025-1670](https://github.com/element-hq/ess-helm/security/advisories/GHSA-qwcj-h6m8-vp6q). ([\#19459](https://github.com/element-hq/synapse/issues/19459))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.147.0 (2026-02-10)
|
||||
|
||||
No significant changes since 1.147.0rc1.
|
||||
|
||||
# Synapse 1.147.0rc1 (2026-02-03)
|
||||
|
||||
## Bugfixes
|
||||
|
||||
- Fix memory leak caused by not cleaning up stopped looping calls. Introduced in v1.140.0. ([\#19416](https://github.com/element-hq/synapse/issues/19416))
|
||||
- Fix a typo that incorrectly made `setuptools_rust` a runtime dependency. ([\#19417](https://github.com/element-hq/synapse/issues/19417))
|
||||
|
||||
## Internal Changes
|
||||
|
||||
- Prune stale entries from `sliding_sync_connection_required_state` table. ([\#19306](https://github.com/element-hq/synapse/issues/19306))
|
||||
- Update "Event Send Time Quantiles" graph to only use dots for the event persistence rate (Grafana dashboard). ([\#19399](https://github.com/element-hq/synapse/issues/19399))
|
||||
- Update and align Grafana dashboard to use regex matching for `job` selectors (`job=~"$job"`) so the "all" value works correctly across all panels. ([\#19400](https://github.com/element-hq/synapse/issues/19400))
|
||||
- Don't retry joining partial state rooms all at once on startup. ([\#19402](https://github.com/element-hq/synapse/issues/19402))
|
||||
- Disallow requests to the health endpoint from containing trailing path characters. ([\#19405](https://github.com/element-hq/synapse/issues/19405))
|
||||
- Add notes that new experimental features should have associated tracking issues. ([\#19410](https://github.com/element-hq/synapse/issues/19410))
|
||||
- Bump `pyo3` from 0.26.0 to 0.27.2 and `pythonize` from 0.26.0 to 0.27.0. Contributed by @razvp @ ERCOM. ([\#19412](https://github.com/element-hq/synapse/issues/19412))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.146.0 (2026-01-27)
|
||||
|
||||
No significant changes since 1.146.0rc1.
|
||||
|
||||
## Deprecations and Removals
|
||||
|
||||
- [MSC2697](https://github.com/matrix-org/matrix-spec-proposals/pull/2697) (Dehydrated devices) has been removed, as the MSC is closed. Developers should migrate to [MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814). ([\#19346](https://github.com/element-hq/synapse/issues/19346))
|
||||
- Support for Ubuntu 25.04 (Plucky Puffin) has been dropped. Synapse no longer builds debian packages for Ubuntu 25.04.
|
||||
|
||||
|
||||
|
||||
# Synapse 1.146.0rc1 (2026-01-20)
|
||||
|
||||
## Features
|
||||
|
||||
- Add a new config option [`enable_local_media_storage`](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_local_media_storage) which controls whether media is additionally stored locally when using configured `media_storage_providers`. Setting this to `false` allows off-site media storage without a local cache. Contributed by Patrice Brend'amour @dr.allgood. ([\#19204](https://github.com/element-hq/synapse/issues/19204))
|
||||
- Stabilise support for [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312)'s `m.oauth` User-Interactive Auth stage for resetting cross-signing identity with the OAuth 2.0 API. The old, unstable name (`org.matrix.cross_signing_reset`) is now deprecated and will be removed in a future release. ([\#19273](https://github.com/element-hq/synapse/issues/19273))
|
||||
- Refactor Grafana dashboard to use `server_name` label (instead of `instance`). ([\#19337](https://github.com/element-hq/synapse/issues/19337))
|
||||
|
||||
## Bugfixes
|
||||
|
||||
- Fix joining a restricted v12 room locally when no local room creator is present but local users with sufficient power levels are. Contributed by @nexy7574. ([\#19321](https://github.com/element-hq/synapse/issues/19321))
|
||||
- Fixed parallel calls to `/_matrix/media/v1/create` being ratelimited for appservices even if `rate_limited: false` was set in the registration. Contributed by @tulir @ Beeper. ([\#19335](https://github.com/element-hq/synapse/issues/19335))
|
||||
- Fix a bug introduced in 1.61.0 where a user's membership in a room was accidentally ignored when considering access to historical state events in rooms with the "shared" history visibility. Contributed by Lukas Tautz. ([\#19353](https://github.com/element-hq/synapse/issues/19353))
|
||||
- [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140): Store the JSON content of scheduled delayed events as text instead of a byte array. This fixes the inability to schedule a delayed event with non-ASCII characters in its content. ([\#19360](https://github.com/element-hq/synapse/issues/19360))
|
||||
- Always rollback database transactions when retrying (avoid orphaned connections). ([\#19372](https://github.com/element-hq/synapse/issues/19372))
|
||||
- Fix `InFlightGauge` typing to allow upgrading to `prometheus_client` 0.24. ([\#19379](https://github.com/element-hq/synapse/issues/19379))
|
||||
|
||||
## Updates to the Docker image
|
||||
|
||||
- Add [Prometheus HTTP service discovery](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config) endpoint for easy discovery of all workers when using the `docker/Dockerfile-workers` image (see the [*Metrics* section of our Docker testing docs](docker/README-testing.md#metrics)). ([\#19336](https://github.com/element-hq/synapse/issues/19336))
|
||||
|
||||
## Improved Documentation
|
||||
|
||||
- Remove docs on legacy metric names (no longer in the codebase since 2022-12-06). ([\#19341](https://github.com/element-hq/synapse/issues/19341))
|
||||
- Clarify how the estimated value of room complexity is calculated internally. ([\#19384](https://github.com/element-hq/synapse/issues/19384))
|
||||
|
||||
## Internal Changes
|
||||
|
||||
- Add an internal `cancel_task` API to the task scheduler. ([\#19310](https://github.com/element-hq/synapse/issues/19310))
|
||||
- Tweak docstrings and signatures of `auth_types_for_event` and `get_catchup_room_event_ids`. ([\#19320](https://github.com/element-hq/synapse/issues/19320))
|
||||
- Replace usage of deprecated `assertEquals` with `assertEqual` in unit test code. ([\#19345](https://github.com/element-hq/synapse/issues/19345))
|
||||
- Drop support for Ubuntu 25.04 'Plucky Puffin', add support for Ubuntu 25.10 'Questing Quokka'. ([\#19348](https://github.com/element-hq/synapse/issues/19348))
|
||||
- Revert "Add an Admin API endpoint for listing quarantined media (#19268)". ([\#19351](https://github.com/element-hq/synapse/issues/19351))
|
||||
- Bump `mdbook` from 0.4.17 to 0.5.2 and remove our custom table-of-contents plugin in favour of the new default functionality. ([\#19356](https://github.com/element-hq/synapse/issues/19356))
|
||||
- Replace deprecated usage of PyGitHub's `GitRelease.title` with `.name` in release script. ([\#19358](https://github.com/element-hq/synapse/issues/19358))
|
||||
- Update the Element logo in Synapse's README to be an absolute URL, allowing it to render on other sites (such as PyPI). ([\#19368](https://github.com/element-hq/synapse/issues/19368))
|
||||
- Apply minor tweaks to v1.145.0 changelog. ([\#19376](https://github.com/element-hq/synapse/issues/19376))
|
||||
- Update Grafana dashboard syntax to use the latest from importing/exporting with Grafana 12.3.1. ([\#19381](https://github.com/element-hq/synapse/issues/19381))
|
||||
- Warn about skipping reactor metrics when using unknown reactor type. ([\#19383](https://github.com/element-hq/synapse/issues/19383))
|
||||
- Add support for reactor metrics with the `ProxiedReactor` used in worker Complement tests. ([\#19385](https://github.com/element-hq/synapse/issues/19385))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.145.0 (2026-01-13)
|
||||
|
||||
No significant changes since 1.145.0rc4.
|
||||
|
||||
## End of Life of Ubuntu 25.04 Plucky Puffin
|
||||
|
||||
Ubuntu 25.04 (Plucky Puffin) will be end of life on Jan 17, 2026. Synapse will stop building packages for Ubuntu 25.04 shortly thereafter.
|
||||
|
||||
## Updates to Locked Dependencies No Longer Included in Changelog
|
||||
|
||||
The "Updates to locked dependencies" section has been removed from the changelog due to lack of use and the maintenance burden. ([\#19254](https://github.com/element-hq/synapse/issues/19254))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.145.0rc4 (2026-01-08)
|
||||
|
||||
No significant changes since 1.145.0rc3.
|
||||
|
||||
This RC contains a fix specifically for openSUSE packaging and no other changes.
|
||||
|
||||
|
||||
|
||||
# Synapse 1.145.0rc3 (2026-01-07)
|
||||
|
||||
No significant changes since 1.145.0rc2.
|
||||
|
||||
This RC strips out unnecessary files from the wheels that were added when fixing the source distribution packaging in the previous RC.
|
||||
|
||||
|
||||
|
||||
# Synapse 1.145.0rc2 (2026-01-07)
|
||||
|
||||
No significant changes since 1.145.0rc1.
|
||||
|
||||
This RC fixes the source distribution packaging for uploading to PyPI.
|
||||
|
||||
|
||||
|
||||
# Synapse 1.145.0rc1 (2026-01-06)
|
||||
|
||||
## Features
|
||||
|
||||
- Add `memberships` endpoint to the admin API. This is useful for forensics and T&S purposes. ([\#19260](https://github.com/element-hq/synapse/issues/19260))
|
||||
- Server admins can bypass the quarantine media check when downloading media by setting the `admin_unsafely_bypass_quarantine` query parameter to `true` on Client-Server API media download requests. ([\#19275](https://github.com/element-hq/synapse/issues/19275))
|
||||
- Implemented pagination for the [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) mutual rooms endpoint. Contributed by @tulir @ Beeper. ([\#19279](https://github.com/element-hq/synapse/issues/19279))
|
||||
- Admin API: add worker support to `GET /_synapse/admin/v2/users/<user_id>`. ([\#19281](https://github.com/element-hq/synapse/issues/19281))
|
||||
- Improve proxy support for the `federation_client.py` dev script. Contributed by Denis Kasak (@dkasak). ([\#19300](https://github.com/element-hq/synapse/issues/19300))
|
||||
|
||||
## Bugfixes
|
||||
|
||||
- Fix sliding sync performance slow down for long lived connections. ([\#19206](https://github.com/element-hq/synapse/issues/19206))
|
||||
- Fix a bug where Mastodon posts (and possibly other embeds) have the wrong description for URL previews. ([\#19231](https://github.com/element-hq/synapse/issues/19231))
|
||||
- Fix bug where `Duration` was logged incorrectly. ([\#19267](https://github.com/element-hq/synapse/issues/19267))
|
||||
- Fix bug introduced in 1.143.0 that broke support for versions of `zope-interface` older than 6.2. ([\#19274](https://github.com/element-hq/synapse/issues/19274))
|
||||
- Transform events with client metadata before serialising in /event response. ([\#19340](https://github.com/element-hq/synapse/issues/19340))
|
||||
|
||||
## Updates to the Docker image
|
||||
|
||||
- Add a way to expose metrics from the Docker image (`SYNAPSE_ENABLE_METRICS`). ([\#19324](https://github.com/element-hq/synapse/issues/19324))
|
||||
|
||||
## Improved Documentation
|
||||
|
||||
- Document the importance of `public_baseurl` when configuring OpenID Connect authentication. ([\#19270](https://github.com/element-hq/synapse/issues/19270))
|
||||
|
||||
## Deprecations and Removals
|
||||
|
||||
- Ubuntu 25.04 (Plucky Puffin) will be end of life on Jan 17, 2026. Synapse will stop building packages for Ubuntu 25.04 shortly thereafter.
|
||||
- Remove the "Updates to locked dependencies" section from the changelog due to lack of use and the maintenance burden. ([\#19254](https://github.com/element-hq/synapse/issues/19254))
|
||||
|
||||
## Internal Changes
|
||||
|
||||
- Group together dependabot update PRs to reduce the review load. ([\#18402](https://github.com/element-hq/synapse/issues/18402))
|
||||
- Fix `HomeServer.shutdown()` failing if the homeserver hasn't been setup yet. ([\#19187](https://github.com/element-hq/synapse/issues/19187))
|
||||
- Respond with useful error codes with `Content-Length` header/s are invalid. ([\#19212](https://github.com/element-hq/synapse/issues/19212))
|
||||
- Fix `HomeServer.shutdown()` failing if the homeserver failed to `start`. ([\#19232](https://github.com/element-hq/synapse/issues/19232))
|
||||
- Switch the build backend from `poetry-core` to `maturin`. ([\#19234](https://github.com/element-hq/synapse/issues/19234))
|
||||
- Raise the limit for concurrently-open non-security @dependabot PRs from 5 to 10. ([\#19253](https://github.com/element-hq/synapse/issues/19253))
|
||||
- Require 14 days to pass before pulling in general dependency updates to help mitigate upstream supply chain attacks. ([\#19258](https://github.com/element-hq/synapse/issues/19258))
|
||||
- Drop the broken netlify documentation workflow until a new one is implemented. ([\#19262](https://github.com/element-hq/synapse/issues/19262))
|
||||
- Don't include debug logs in `Clock` unless explicitly enabled. ([\#19278](https://github.com/element-hq/synapse/issues/19278))
|
||||
- Use `uv` to test olddeps to ensure all transitive dependencies use minimum versions. ([\#19289](https://github.com/element-hq/synapse/issues/19289))
|
||||
- Add a config to be able to rate limit search in the user directory. ([\#19291](https://github.com/element-hq/synapse/issues/19291))
|
||||
- Log the original bind exception when encountering `Failed to listen on 0.0.0.0, continuing because listening on [::]`. ([\#19297](https://github.com/element-hq/synapse/issues/19297))
|
||||
- Unpin the version of Rust we use to build Synapse wheels (was 1.82.0) now that MacOS support has been dropped. ([\#19302](https://github.com/element-hq/synapse/issues/19302))
|
||||
- Make it more clear how `shared_extra_conf` is combined in our Docker configuration scripts. ([\#19323](https://github.com/element-hq/synapse/issues/19323))
|
||||
- Update CI to stream Complement progress and format logs in a separate step after all tests are done. ([\#19326](https://github.com/element-hq/synapse/issues/19326))
|
||||
- Format `.github/workflows/tests.yml`. ([\#19327](https://github.com/element-hq/synapse/issues/19327))
|
||||
|
||||
|
||||
|
||||
|
||||
# Synapse 1.144.0 (2025-12-09)
|
||||
|
||||
## Deprecation of MacOS Python wheels
|
||||
|
||||
56
Cargo.lock
generated
56
Cargo.lock
generated
@@ -73,9 +73,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
@@ -705,9 +705,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
@@ -813,9 +813,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.27.2"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d"
|
||||
checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indoc",
|
||||
@@ -831,18 +831,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.27.2"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6"
|
||||
checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f"
|
||||
dependencies = [
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.27.2"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089"
|
||||
checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
@@ -861,9 +861,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.27.2"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02"
|
||||
checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
@@ -873,9 +873,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.27.2"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9"
|
||||
checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
@@ -886,9 +886,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pythonize"
|
||||
version = "0.27.0"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3a8f29db331e28c332c63496cfcbb822aca3d7320bc08b655d7fd0c29c50ede"
|
||||
checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2"
|
||||
dependencies = [
|
||||
"pyo3",
|
||||
"serde",
|
||||
@@ -1024,9 +1024,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.28"
|
||||
version = "0.12.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||
checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -1207,15 +1207,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1416,9 +1416,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.49.0"
|
||||
version = "1.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
||||
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
@@ -1468,9 +1468,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.6.8"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
|
||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
@@ -1921,9 +1921,3 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. image:: https://github.com/element-hq/synapse/raw/develop/docs/element_logo_white_bg.svg
|
||||
.. image:: ./docs/element_logo_white_bg.svg
|
||||
:height: 60px
|
||||
|
||||
**Element Synapse - Matrix homeserver implementation**
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
title = "Synapse"
|
||||
authors = ["The Matrix.org Foundation C.I.C."]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
|
||||
# The directory that documentation files are stored in
|
||||
src = "docs"
|
||||
@@ -30,10 +31,13 @@ site-url = "/synapse/"
|
||||
# Additional HTML, JS, CSS that's injected into each page of the book.
|
||||
# More information available in docs/website_files/README.md
|
||||
additional-css = [
|
||||
"docs/website_files/table-of-contents.css",
|
||||
"docs/website_files/remove-nav-buttons.css",
|
||||
"docs/website_files/indent-section-headers.css",
|
||||
"docs/website_files/version-picker.css",
|
||||
]
|
||||
additional-js = [
|
||||
"docs/website_files/table-of-contents.js",
|
||||
"docs/website_files/version-picker.js",
|
||||
"docs/website_files/version.js",
|
||||
]
|
||||
|
||||
1
changelog.d/18402.misc
Normal file
1
changelog.d/18402.misc
Normal file
@@ -0,0 +1 @@
|
||||
Group together dependabot update PRs to reduce the review load.
|
||||
1
changelog.d/18475.feature
Normal file
1
changelog.d/18475.feature
Normal file
@@ -0,0 +1 @@
|
||||
Make ACLs apply to EDUs per [MSC4163](https://github.com/matrix-org/matrix-spec-proposals/pull/4163).
|
||||
1
changelog.d/19187.misc
Normal file
1
changelog.d/19187.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix `HomeServer.shutdown()` failing if the homeserver hasn't been setup yet.
|
||||
1
changelog.d/19206.bugfix
Normal file
1
changelog.d/19206.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix sliding sync performance slow down for long lived connections.
|
||||
1
changelog.d/19212.misc
Normal file
1
changelog.d/19212.misc
Normal file
@@ -0,0 +1 @@
|
||||
Respond with useful error codes with `Content-Length` header/s are invalid.
|
||||
1
changelog.d/19231.bugfix
Normal file
1
changelog.d/19231.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug where Mastodon posts (and possibly other embeds) have the wrong description for URL previews.
|
||||
1
changelog.d/19232.misc
Normal file
1
changelog.d/19232.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix `HomeServer.shutdown()` failing if the homeserver failed to `start`.
|
||||
1
changelog.d/19234.misc
Normal file
1
changelog.d/19234.misc
Normal file
@@ -0,0 +1 @@
|
||||
Switch the build backend from `poetry-core` to `maturin`.
|
||||
1
changelog.d/19253.misc
Normal file
1
changelog.d/19253.misc
Normal file
@@ -0,0 +1 @@
|
||||
Raise the limit for concurrently-open non-security @dependabot PRs from 5 to 10.
|
||||
1
changelog.d/19254.removal
Normal file
1
changelog.d/19254.removal
Normal file
@@ -0,0 +1 @@
|
||||
Remove the "Updates to locked dependencies" section from the changelog due to lack of use and the maintenance burden.
|
||||
1
changelog.d/19258.misc
Normal file
1
changelog.d/19258.misc
Normal file
@@ -0,0 +1 @@
|
||||
Require 14 days to pass before pulling in general dependency updates to help mitigate upstream supply chain attacks.
|
||||
1
changelog.d/19260.feature
Normal file
1
changelog.d/19260.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add `memberships` endpoint to the admin API. This is useful for forensics and T&S purpose.
|
||||
1
changelog.d/19262.misc
Normal file
1
changelog.d/19262.misc
Normal file
@@ -0,0 +1 @@
|
||||
Drop the broken netlify documentation workflow until a new one is implemented.
|
||||
1
changelog.d/19267.bugfix
Normal file
1
changelog.d/19267.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix bug where `Duration` was logged incorrectly.
|
||||
1
changelog.d/19268.feature
Normal file
1
changelog.d/19268.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add an admin API for retrieving a paginated list of quarantined media.
|
||||
1
changelog.d/19270.doc
Normal file
1
changelog.d/19270.doc
Normal file
@@ -0,0 +1 @@
|
||||
Document the importance of `public_baseurl` when configuring OpenID Connect authentication.
|
||||
1
changelog.d/19274.bugfix
Normal file
1
changelog.d/19274.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix bug introduced in 1.143.0 that broke support for versions of `zope-interface` older than 6.2.
|
||||
1
changelog.d/19275.feature
Normal file
1
changelog.d/19275.feature
Normal file
@@ -0,0 +1 @@
|
||||
Server admins can bypass the quarantine media check when downloading media by setting the `admin_unsafely_bypass_quarantine` query parameter to `true` on Client-Server API media download requests.
|
||||
1
changelog.d/19278.misc
Normal file
1
changelog.d/19278.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't include debug logs in `Clock` unless explicitly enabled.
|
||||
1
changelog.d/19279.feature
Normal file
1
changelog.d/19279.feature
Normal file
@@ -0,0 +1 @@
|
||||
Implemented pagination for the [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) mutual rooms endpoint. Contributed by @tulir @ Beeper.
|
||||
1
changelog.d/19281.feature
Normal file
1
changelog.d/19281.feature
Normal file
@@ -0,0 +1 @@
|
||||
Admin API: add worker support to `GET /_synapse/admin/v2/users/<user_id>`.
|
||||
1
changelog.d/19289.misc
Normal file
1
changelog.d/19289.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use `uv` to test olddeps to ensure all transitive dependencies use minimum versions.
|
||||
1
changelog.d/19300.feature
Normal file
1
changelog.d/19300.feature
Normal file
@@ -0,0 +1 @@
|
||||
Improve proxy support for the `federation_client.py` dev script. Contributed by Denis Kasak (@dkasak).
|
||||
1
changelog.d/19302.misc
Normal file
1
changelog.d/19302.misc
Normal file
@@ -0,0 +1 @@
|
||||
Unpin the version of Rust we use to build Synapse wheels (was 1.82.0) now that MacOS support has been dropped.
|
||||
@@ -1,38 +0,0 @@
|
||||
# Docs: https://golangci-lint.run/docs/configuration/file/
|
||||
#
|
||||
# Go formatting/linting rules
|
||||
#
|
||||
# This is run as part of the normal linting utility script,
|
||||
# `poetry run ./scripts-dev/lint.sh`
|
||||
|
||||
version: "2"
|
||||
|
||||
linters:
|
||||
# Default set of linters.
|
||||
# The value can be:
|
||||
# - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default
|
||||
# - `all`: enables all linters by default.
|
||||
# - `none`: disables all linters by default.
|
||||
# - `fast`: enables only linters considered as "fast" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`).
|
||||
# Default: standard
|
||||
default: standard
|
||||
|
||||
# Enable specific linter.
|
||||
# enable:
|
||||
# - example
|
||||
|
||||
# Disable specific linters.
|
||||
disable:
|
||||
# FIXME: Ideally, we'd enable the `bodyclose` lint but there are many
|
||||
# false-positives (like https://github.com/timakin/bodyclose/issues/39) and just is
|
||||
# not well-suited for our use case (https://github.com/timakin/bodyclose/issues/11 and
|
||||
# https://github.com/timakin/bodyclose/issues/76).
|
||||
- bodyclose
|
||||
|
||||
formatters:
|
||||
# Enable specific formatter.
|
||||
# Default: [] (uses standard Go formatting)
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- golines
|
||||
@@ -1,54 +0,0 @@
|
||||
# Complement testing
|
||||
|
||||
Complement is a black box integration testing framework for Matrix homeservers. It
|
||||
allows us to write end-to-end tests that interact with real Synapse homeservers to
|
||||
ensure everything works at a holistic level.
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
Nothing beyond a [normal Complement
|
||||
setup](https://github.com/matrix-org/complement?tab=readme-ov-file#running) (just Go and
|
||||
Docker).
|
||||
|
||||
|
||||
## Running tests
|
||||
|
||||
Run tests from the [Complement](https://github.com/matrix-org/complement) repo:
|
||||
|
||||
```shell
|
||||
# Run the tests
|
||||
./scripts-dev/complement.sh
|
||||
|
||||
# To run a whole group of tests, you can specify part of the test path:
|
||||
scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate
|
||||
# To run a specific test, you can specify the whole name structure:
|
||||
scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate/Parallel/POST_/createRoom_makes_a_public_room
|
||||
# Generally though, the `-run` parameter accepts regex patterns, so you can match however you like:
|
||||
scripts-dev/complement.sh ./tests/... -run 'TestRoomCreate/Parallel/POST_/createRoom_makes_a_(.*)'
|
||||
```
|
||||
|
||||
Typically, if you're developing the Synapse and Complement tests side-by-side, you will
|
||||
run something like this:
|
||||
|
||||
```shell
|
||||
# To run a specific test
|
||||
COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate
|
||||
```
|
||||
|
||||
|
||||
### Running in-repo tests
|
||||
|
||||
In-repo Complement tests are tests that are vendored into this project. We use the
|
||||
in-repo test suite to test Synapse specific behaviors like the admin API.
|
||||
|
||||
To run the in-repo Complement tests, use the `--in-repo` command line argument.
|
||||
|
||||
```shell
|
||||
# Run only a specific test package.
|
||||
# Note: test packages are relative to the `./complement` directory in this project
|
||||
./scripts-dev/complement.sh --in-repo ./tests/...
|
||||
|
||||
# Similarly, you can also use `-run` to specify all or part of a specific test path to run
|
||||
scripts-dev/complement.sh --in-repo ./tests/... -run TestIntraShardFederation
|
||||
```
|
||||
@@ -1,57 +0,0 @@
|
||||
module github.com/element-hq/synapse
|
||||
|
||||
go 1.24.1
|
||||
|
||||
toolchain go1.24.4
|
||||
|
||||
require (
|
||||
github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/docker/docker v28.3.3+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/hashicorp/go-set/v3 v3.0.0 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/oleiade/lane/v2 v2.0.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
gotest.tools/v3 v3.4.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
@@ -1,169 +0,0 @@
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/hashicorp/go-set/v3 v3.0.0 h1:CaJBQvQCOWoftrBcDt7Nwgo0kdpmrKxar/x2o6pV9JA=
|
||||
github.com/hashicorp/go-set/v3 v3.0.0/go.mod h1:IEghM2MpE5IaNvL+D7X480dfNtxjRXZ6VMpK3C8s2ok=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d h1:s2Xc9GB2E/pXdElP18h8+04Y3SmhaII7xh2YmCM7oZc=
|
||||
github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d/go.mod h1:HioTV089DHLBfljH9QLGifJRE4Avnyk08BXXhCwd4gs=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744 h1:5GvC2FD9O/PhuyY95iJQdNYHbDioEhMWdeMP9maDUL8=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744/go.mod h1:b6KVfDjXjA5Q7vhpOaMqIhFYvu5BuFVZixlNeTV/CLc=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
|
||||
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
|
||||
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/oleiade/lane/v2 v2.0.0 h1:XW/ex/Inr+bPkLd3O240xrFOhUkTd4Wy176+Gv0E3Qw=
|
||||
github.com/oleiade/lane/v2 v2.0.0/go.mod h1:i5FBPFAYSWCgLh58UkUGCChjcCzef/MI7PlQm2TKCeg=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/shoenig/test v1.11.0 h1:NoPa5GIoBwuqzIviCrnUJa+t5Xb4xi5Z+zODJnIDsEQ=
|
||||
github.com/shoenig/test v1.11.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
|
||||
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
|
||||
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
|
||||
@@ -1,65 +0,0 @@
|
||||
// This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||
//
|
||||
// Copyright (C) 2026 Element Creations Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// See the GNU Affero General Public License for more details:
|
||||
// <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||
|
||||
package synapse_tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/complement"
|
||||
"github.com/matrix-org/complement/client"
|
||||
"github.com/matrix-org/complement/helpers"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
||||
// Stub test to ensure that homeservers can communicate with each other (federation works correctly).
|
||||
//
|
||||
// TODO: This test will disappear once we have other real Synapse specific tests in
|
||||
// place. This is simply here as an example without bloating the PR with some specific
|
||||
// new tests.
|
||||
func TestFederation(t *testing.T) {
|
||||
// Create two homeservers
|
||||
deployment := complement.Deploy(t, 2)
|
||||
defer deployment.Destroy(t)
|
||||
|
||||
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
|
||||
bob := deployment.Register(t, "hs2", helpers.RegistrationOpts{})
|
||||
|
||||
aliceRoomID := alice.MustCreateRoom(t, map[string]any{
|
||||
"preset": "public_chat",
|
||||
})
|
||||
bobRoomID := bob.MustCreateRoom(t, map[string]any{
|
||||
"preset": "public_chat",
|
||||
})
|
||||
|
||||
t.Run("parallel", func(t *testing.T) {
|
||||
t.Run("HS1 -> HS2", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
alice.MustJoinRoom(t, bobRoomID, []spec.ServerName{
|
||||
deployment.GetFullyQualifiedHomeserverName(t, "hs2"),
|
||||
})
|
||||
|
||||
bob.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(alice.UserID, bobRoomID))
|
||||
})
|
||||
|
||||
t.Run("HS2 -> HS1", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
bob.MustJoinRoom(t, aliceRoomID, []spec.ServerName{
|
||||
deployment.GetFullyQualifiedHomeserverName(t, "hs1"),
|
||||
})
|
||||
|
||||
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob.UserID, aliceRoomID))
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||
//
|
||||
// Copyright (C) 2026 Element Creations Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// See the GNU Affero General Public License for more details:
|
||||
// <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||
|
||||
package synapse_tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/complement"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
complement.TestMain(m, "synapse")
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
72
debian/changelog
vendored
72
debian/changelog
vendored
@@ -1,75 +1,3 @@
|
||||
matrix-synapse-py3 (1.148.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.148.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 24 Feb 2026 11:17:49 +0000
|
||||
|
||||
matrix-synapse-py3 (1.148.0~rc1) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.148.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 17 Feb 2026 16:44:08 +0000
|
||||
|
||||
matrix-synapse-py3 (1.147.1) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.147.1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Thu, 12 Feb 2026 15:45:15 +0000
|
||||
|
||||
matrix-synapse-py3 (1.147.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.147.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 10 Feb 2026 12:39:58 +0000
|
||||
|
||||
matrix-synapse-py3 (1.147.0~rc1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.147.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 03 Feb 2026 08:53:17 -0700
|
||||
|
||||
matrix-synapse-py3 (1.146.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.146.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 27 Jan 2026 08:43:59 -0700
|
||||
|
||||
matrix-synapse-py3 (1.146.0~rc1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.146.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 20 Jan 2026 08:42:10 -0700
|
||||
|
||||
matrix-synapse-py3 (1.145.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.145.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 13 Jan 2026 08:37:42 -0700
|
||||
|
||||
matrix-synapse-py3 (1.145.0~rc4) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.145.0rc4.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Thu, 08 Jan 2026 12:06:35 -0700
|
||||
|
||||
matrix-synapse-py3 (1.145.0~rc3) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.145.0rc3.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 07 Jan 2026 15:32:07 -0700
|
||||
|
||||
matrix-synapse-py3 (1.145.0~rc2) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.145.0rc2.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 07 Jan 2026 10:10:07 -0700
|
||||
|
||||
matrix-synapse-py3 (1.145.0~rc1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.145.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 06 Jan 2026 09:29:39 -0700
|
||||
|
||||
matrix-synapse-py3 (1.144.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.144.0.
|
||||
|
||||
@@ -145,12 +145,6 @@ for port in 8080 8081 8082; do
|
||||
rc_delayed_event_mgmt:
|
||||
per_second: 1000
|
||||
burst_count: 1000
|
||||
rc_room_creation:
|
||||
per_second: 1000
|
||||
burst_count: 1000
|
||||
rc_user_directory:
|
||||
per_second: 1000
|
||||
burst_count: 1000
|
||||
RC
|
||||
)
|
||||
echo "${ratelimiting}" >> "$port.config"
|
||||
|
||||
@@ -188,12 +188,7 @@ COPY --from=builder --exclude=.lock /install /usr/local
|
||||
COPY ./docker/start.py /start.py
|
||||
COPY ./docker/conf /conf
|
||||
|
||||
# 8008: CS Matrix API port from Synapse
|
||||
# 8448: SS Matrix API port from Synapse
|
||||
EXPOSE 8008/tcp 8448/tcp
|
||||
# 19090: Metrics listener port for the main process (metrics must be enabled with
|
||||
# SYNAPSE_ENABLE_METRICS=1).
|
||||
EXPOSE 19090/tcp
|
||||
EXPOSE 8008/tcp 8009/tcp 8448/tcp
|
||||
|
||||
ENTRYPOINT ["/start.py"]
|
||||
|
||||
|
||||
@@ -71,15 +71,6 @@ FROM $FROM
|
||||
|
||||
# Expose nginx listener port
|
||||
EXPOSE 8080/tcp
|
||||
# Metrics for workers are on ports starting from 19091 but since these are dynamic
|
||||
# we don't expose them by default (metrics must be enabled with
|
||||
# SYNAPSE_ENABLE_METRICS=1)
|
||||
#
|
||||
# Instead, we expose a single port used for Prometheus HTTP service discovery
|
||||
# (`http://<synapse_container>:9469/metrics/service_discovery`) and proxy all of the
|
||||
# workers' metrics endpoints through that
|
||||
# (`http://<synapse_container>:9469/metrics/worker/<worker_name>`).
|
||||
EXPOSE 9469/tcp
|
||||
|
||||
# A script to read environment variables and create the necessary
|
||||
# files to run the desired worker configuration. Will start supervisord.
|
||||
|
||||
@@ -135,49 +135,3 @@ but it does not serve TLS by default.
|
||||
You can configure `SYNAPSE_TLS_CERT` and `SYNAPSE_TLS_KEY` to point to a
|
||||
TLS certificate and key (respectively), both in PEM (textual) format.
|
||||
In this case, Nginx will additionally serve using HTTPS on port 8448.
|
||||
|
||||
|
||||
### Metrics
|
||||
|
||||
Set `SYNAPSE_ENABLE_METRICS=1` to configure `enable_metrics: true` and setup the
|
||||
`metrics` listener on the main and worker processes. Defaults to `0` (disabled). The
|
||||
main process will listen on port `19090` and workers on port `19091 + <worker index>`.
|
||||
|
||||
When using `docker/Dockerfile-workers`, to ease the complexity with the metrics setup,
|
||||
we also have a [Prometheus HTTP service
|
||||
discovery](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config)
|
||||
endpoint available at `http://<synapse_container>:9469/metrics/service_discovery`.
|
||||
|
||||
The metrics from each worker can also be accessed via
|
||||
`http://<synapse_container>:9469/metrics/worker/<worker_name>` which is what the service
|
||||
discovery response points to behind the scenes. This way, you only need to expose a
|
||||
single port (9469) to access all metrics.
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: synapse
|
||||
scrape_interval: 15s
|
||||
metrics_path: /_synapse/metrics
|
||||
scheme: http
|
||||
# We set `honor_labels` so that each service can set their own `job`/`instance` label
|
||||
#
|
||||
# > honor_labels controls how Prometheus handles conflicts between labels that are
|
||||
# > already present in scraped data and labels that Prometheus would attach
|
||||
# > server-side ("job" and "instance" labels, manually configured target
|
||||
# > labels, and labels generated by service discovery implementations).
|
||||
# >
|
||||
# > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config*
|
||||
honor_labels: true
|
||||
# Use HTTP service discovery
|
||||
#
|
||||
# Reference:
|
||||
# - https://prometheus.io/docs/prometheus/latest/http_sd/
|
||||
# - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config
|
||||
http_sd_configs:
|
||||
- url: 'http://localhost:9469/metrics/service_discovery'
|
||||
```
|
||||
|
||||
@@ -75,9 +75,6 @@ The following environment variables are supported in `generate` mode:
|
||||
particularly tricky.
|
||||
* `SYNAPSE_LOG_TESTING`: if set, Synapse will log additional information useful
|
||||
for testing.
|
||||
* `SYNAPSE_ENABLE_METRICS`: if set to `1`, the metrics listener will be enabled on the
|
||||
main and worker processes. Defaults to `0` (disabled). The main process will listen on
|
||||
port `19090` and workers on port `19091 + <worker index>`.
|
||||
|
||||
## Postgres
|
||||
|
||||
|
||||
@@ -102,10 +102,6 @@ rc_room_creation:
|
||||
per_second: 9999
|
||||
burst_count: 9999
|
||||
|
||||
rc_user_directory:
|
||||
per_second: 9999
|
||||
burst_count: 9999
|
||||
|
||||
federation_rr_transactions_per_room_per_second: 9999
|
||||
|
||||
allow_device_name_lookup_over_federation: true
|
||||
@@ -139,8 +135,6 @@ experimental_features:
|
||||
msc4155_enabled: true
|
||||
# Thread Subscriptions
|
||||
msc4306_enabled: true
|
||||
# Sticky Events
|
||||
msc4354_enabled: true
|
||||
|
||||
server_notices:
|
||||
system_mxid_localpart: _server
|
||||
|
||||
@@ -48,5 +48,3 @@ server {
|
||||
proxy_set_header Host $host:$server_port;
|
||||
}
|
||||
}
|
||||
|
||||
{{ nginx_prometheus_metrics_service_discovery }}
|
||||
|
||||
@@ -20,9 +20,4 @@ app_service_config_files:
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{# Controlled by SYNAPSE_ENABLE_METRICS #}
|
||||
{% if enable_metrics %}
|
||||
enable_metrics: true
|
||||
{% endif %}
|
||||
|
||||
{{ shared_worker_config }}
|
||||
|
||||
@@ -21,14 +21,6 @@ worker_listeners:
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
|
||||
{# Controlled by SYNAPSE_ENABLE_METRICS #}
|
||||
{% if metrics_port %}
|
||||
- type: metrics
|
||||
# Prometheus does not support Unix sockets so we don't bother with
|
||||
# `SYNAPSE_USE_UNIX_SOCKET`, https://github.com/prometheus/prometheus/issues/12024
|
||||
port: {{ metrics_port }}
|
||||
{% endif %}
|
||||
|
||||
worker_log_config: {{ worker_log_config_filepath }}
|
||||
|
||||
{{ worker_extra_conf }}
|
||||
|
||||
@@ -53,15 +53,6 @@ listeners:
|
||||
- names: [federation]
|
||||
compress: false
|
||||
|
||||
{% if SYNAPSE_ENABLE_METRICS %}
|
||||
- type: metrics
|
||||
# The main process always uses the same port 19090
|
||||
#
|
||||
# Prometheus does not support Unix sockets so we don't bother with
|
||||
# `SYNAPSE_USE_UNIX_SOCKET`, https://github.com/prometheus/prometheus/issues/12024
|
||||
port: 19090
|
||||
{% endif %}
|
||||
|
||||
## Database ##
|
||||
|
||||
{% if POSTGRES_PASSWORD %}
|
||||
|
||||
@@ -49,16 +49,11 @@
|
||||
# regardless of the SYNAPSE_LOG_LEVEL setting.
|
||||
# * SYNAPSE_LOG_TESTING: if set, Synapse will log additional information useful
|
||||
# for testing.
|
||||
# * SYNAPSE_USE_UNIX_SOCKET: TODO
|
||||
# * `SYNAPSE_ENABLE_METRICS`: if set to `1`, the metrics listener will be enabled on the
|
||||
# main and worker processes. Defaults to `0` (disabled). The main process will listen on
|
||||
# port `19090` and workers on port `19091 + <worker index>`.
|
||||
#
|
||||
# NOTE: According to Complement's ENTRYPOINT expectations for a homeserver image (as defined
|
||||
# in the project's README), this script may be run multiple times, and functionality should
|
||||
# continue to work if so.
|
||||
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
@@ -76,7 +71,6 @@ from typing import (
|
||||
SupportsIndex,
|
||||
)
|
||||
|
||||
import attr
|
||||
import yaml
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
@@ -343,7 +337,7 @@ WORKERS_CONFIG: dict[str, dict[str, Any]] = {
|
||||
}
|
||||
|
||||
# Templates for sections that may be inserted multiple times in config files
|
||||
NGINX_LOCATION_REGEX_CONFIG_BLOCK = """
|
||||
NGINX_LOCATION_CONFIG_BLOCK = """
|
||||
location ~* {endpoint} {{
|
||||
proxy_pass {upstream};
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
@@ -352,25 +346,6 @@ NGINX_LOCATION_REGEX_CONFIG_BLOCK = """
|
||||
}}
|
||||
"""
|
||||
|
||||
# Having both **regex** (`NGINX_LOCATION_REGEX_CONFIG_BLOCK`) match vs **exact**
|
||||
# (`NGINX_LOCATION_EXACT_CONFIG_BLOCK`) match is necessary because we can't use a URI
|
||||
# path in `proxy_pass http://localhost:19090/_synapse/metrics` with the regex version.
|
||||
#
|
||||
# Example of what happens if you try to use `proxy_pass http://localhost:19090/_synapse/metrics`
|
||||
# with `NGINX_LOCATION_REGEX_CONFIG_BLOCK`:
|
||||
# ```
|
||||
# nginx | 2025/12/31 22:58:34 [emerg] 21#21: "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/conf.d/matrix-synapse.conf:732
|
||||
# ```
|
||||
NGINX_LOCATION_EXACT_CONFIG_BLOCK = """
|
||||
location = {endpoint} {{
|
||||
proxy_pass {upstream};
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $host;
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
NGINX_UPSTREAM_CONFIG_BLOCK = """
|
||||
upstream {upstream_worker_base_name} {{
|
||||
{body}
|
||||
@@ -378,63 +353,6 @@ upstream {upstream_worker_base_name} {{
|
||||
"""
|
||||
|
||||
|
||||
PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH = (
|
||||
"/data/prometheus_service_discovery.json"
|
||||
)
|
||||
"""
|
||||
We serve this file with nginx so people can use it with `http_sd_config` in their
|
||||
Prometheus config.
|
||||
"""
|
||||
|
||||
NGINX_HOST_PLACEHOLDER = "<HOST_PLACEHOLDER>"
|
||||
"""Will be replaced with the whatever hostname:port used to access the nginx metrics endpoint."""
|
||||
|
||||
NGINX_PROMETHEUS_METRICS_SERVICE_DISCOVERY = """
|
||||
server {{
|
||||
listen 9469;
|
||||
location = /metrics/service_discovery {{
|
||||
alias {service_discovery_file_path};
|
||||
default_type application/json;
|
||||
|
||||
# Find/replace the host placeholder in the response body with the actual
|
||||
# host used to access this endpoint.
|
||||
#
|
||||
# We want to reflect back whatever host the client used to access this file.
|
||||
# For example, if they accessed it via `localhost:9469`, then they
|
||||
# can also reach all of the proxied metrics endpoints at the same address.
|
||||
# Or if it's Prometheus in another container, it will access this via
|
||||
# `host.docker.internal:9469`, etc. Or perhaps it's even some randomly assigned
|
||||
# port mapping.
|
||||
sub_filter '{host_placeholder}' '$http_host';
|
||||
# By default, `ngx_http_sub_module` only works on `text/html` responses. We want
|
||||
# to find/replace in `application/JSON`.
|
||||
sub_filter_types application/json;
|
||||
# Replace all occurences
|
||||
sub_filter_once off;
|
||||
}}
|
||||
|
||||
# Make the service discovery endpoint easy to find; redirect to the correct spot.
|
||||
location = / {{
|
||||
return 302 /metrics/service_discovery;
|
||||
}}
|
||||
|
||||
{metrics_proxy_locations}
|
||||
}}
|
||||
"""
|
||||
"""
|
||||
Setup the nginx config necessary to serve the JSON file for Prometheus HTTP service discovery
|
||||
(`http_sd_config`). Served at `/metrics/service_discovery`.
|
||||
|
||||
Reference:
|
||||
- https://prometheus.io/docs/prometheus/latest/http_sd/
|
||||
- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config
|
||||
|
||||
We also proxy all of the Synapse metrics endpoints through a central place so that
|
||||
people only need to expose the single 9469 port and service discovery can take care of
|
||||
the rest: `/metrics/worker/<worker_name>` -> http://localhost:19090/_synapse/metrics
|
||||
"""
|
||||
|
||||
|
||||
# Utility functions
|
||||
def log(txt: str) -> None:
|
||||
print(txt)
|
||||
@@ -694,42 +612,9 @@ def generate_base_homeserver_config() -> None:
|
||||
subprocess.run([sys.executable, "/start.py", "migrate_config"], check=True)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class Worker:
|
||||
worker_name: str
|
||||
"""
|
||||
ex.
|
||||
`event_persister:2` -> `event_persister1` and `event_persister2`
|
||||
`stream_writers=account_data+presence+receipts+to_device+typing"` -> `stream_writers`
|
||||
"""
|
||||
|
||||
worker_base_name: str
|
||||
"""
|
||||
ex.
|
||||
`event_persister:2` -> `event_persister`
|
||||
`stream_writers=account_data+presence+receipts+to_device+typing"` -> `stream_writers`
|
||||
"""
|
||||
|
||||
worker_index: int
|
||||
"""
|
||||
The index of the worker starting from 1 for each worker type requested.
|
||||
|
||||
ex.
|
||||
`event_persister:2` -> `1` and `2`
|
||||
`stream_writers=account_data+presence+receipts+to_device+typing"` -> `1`
|
||||
"""
|
||||
|
||||
worker_types: set[str]
|
||||
"""
|
||||
ex.
|
||||
`event_persister:2` -> `{"event_persister"}`
|
||||
`stream_writers=account_data+presence+receipts+to_device+typing"` -> `{"account_data", "presence", "receipts","to_device", "typing"}
|
||||
"""
|
||||
|
||||
|
||||
def parse_worker_types(
|
||||
requested_worker_types: list[str],
|
||||
) -> list[Worker]:
|
||||
) -> dict[str, set[str]]:
|
||||
"""Read the desired list of requested workers and prepare the data for use in
|
||||
generating worker config files while also checking for potential gotchas.
|
||||
|
||||
@@ -737,7 +622,10 @@ def parse_worker_types(
|
||||
requested_worker_types: The list formed from the split environment variable
|
||||
containing the unprocessed requests for workers.
|
||||
|
||||
Returns: A list of requested workers
|
||||
Returns: A dict of worker names to set of worker types. Format:
|
||||
{'worker_name':
|
||||
{'worker_type', 'worker_type2'}
|
||||
}
|
||||
"""
|
||||
# A counter of worker_base_name -> int. Used for determining the name for a given
|
||||
# worker when generating its config file, as each worker's name is just
|
||||
@@ -748,8 +636,8 @@ def parse_worker_types(
|
||||
# more than a single worker for cases where multiples would be bad(e.g. presence).
|
||||
worker_type_shard_counter: dict[str, int] = defaultdict(int)
|
||||
|
||||
# Map from worker name to `Worker`
|
||||
worker_dict: dict[str, Worker] = {}
|
||||
# The final result of all this processing
|
||||
dict_to_return: dict[str, set[str]] = {}
|
||||
|
||||
# Handle any multipliers requested for given workers.
|
||||
multiple_processed_worker_types = apply_requested_multiplier_for_worker(
|
||||
@@ -835,29 +723,24 @@ def parse_worker_types(
|
||||
if worker_number > 1:
|
||||
# If this isn't the first worker, check that we don't have a confusing
|
||||
# mixture of worker types with the same base name.
|
||||
first_worker_with_base_name = worker_dict[f"{worker_base_name}1"]
|
||||
if first_worker_with_base_name.worker_types != worker_types_set:
|
||||
first_worker_with_base_name = dict_to_return[f"{worker_base_name}1"]
|
||||
if first_worker_with_base_name != worker_types_set:
|
||||
error(
|
||||
f"Can not use worker_name: '{worker_name}' for worker_type(s): "
|
||||
f"{worker_types_set!r}. It is already in use by "
|
||||
f"worker_type(s): {first_worker_with_base_name.worker_types!r}"
|
||||
f"worker_type(s): {first_worker_with_base_name!r}"
|
||||
)
|
||||
|
||||
worker_dict[worker_name] = Worker(
|
||||
worker_name=worker_name,
|
||||
worker_base_name=worker_base_name,
|
||||
worker_index=worker_number,
|
||||
worker_types=worker_types_set,
|
||||
)
|
||||
dict_to_return[worker_name] = worker_types_set
|
||||
|
||||
return list(worker_dict.values())
|
||||
return dict_to_return
|
||||
|
||||
|
||||
def generate_worker_files(
|
||||
environ: Mapping[str, str],
|
||||
config_path: str,
|
||||
data_dir: str,
|
||||
requested_workers: list[Worker],
|
||||
requested_worker_types: dict[str, set[str]],
|
||||
) -> None:
|
||||
"""Read the desired workers(if any) that is passed in and generate shared
|
||||
homeserver, nginx and supervisord configs.
|
||||
@@ -867,16 +750,14 @@ def generate_worker_files(
|
||||
config_path: The location of the generated Synapse main worker config file.
|
||||
data_dir: The location of the synapse data directory. Where log and
|
||||
user-facing config files live.
|
||||
requested_workers: A list of requested workers
|
||||
requested_worker_types: A Dict containing requested workers in the format of
|
||||
{'worker_name1': {'worker_type', ...}}
|
||||
"""
|
||||
# Note that yaml cares about indentation, so care should be taken to insert lines
|
||||
# into files at the correct indentation below.
|
||||
|
||||
# Convenience helper for if using unix sockets instead of host:port
|
||||
using_unix_sockets = environ.get("SYNAPSE_USE_UNIX_SOCKET", False)
|
||||
|
||||
enable_metrics = environ.get("SYNAPSE_ENABLE_METRICS", "0") == "1"
|
||||
|
||||
# First read the original config file and extract the listeners block. Then we'll
|
||||
# add another listener for replication. Later we'll write out the result to the
|
||||
# shared config file.
|
||||
@@ -908,11 +789,7 @@ def generate_worker_files(
|
||||
# base shared worker jinja2 template. This config file will be passed to all
|
||||
# workers, included Synapse's main process. It is intended mainly for disabling
|
||||
# functionality when certain workers are spun up, and adding a replication listener.
|
||||
shared_config: dict[str, Any] = {
|
||||
"listeners": listeners,
|
||||
# Controls `enable_metrics: true`
|
||||
"enable_metrics": enable_metrics,
|
||||
}
|
||||
shared_config: dict[str, Any] = {"listeners": listeners}
|
||||
|
||||
# List of dicts that describe workers.
|
||||
# We pass this to the Supervisor template later to generate the appropriate
|
||||
@@ -939,8 +816,6 @@ def generate_worker_files(
|
||||
|
||||
# Start worker ports from this arbitrary port
|
||||
worker_port = 18009
|
||||
# The main process metrics port is 19090, so start workers from 19091
|
||||
worker_metrics_port = 19091
|
||||
|
||||
# A list of internal endpoints to healthcheck, starting with the main process
|
||||
# which exists even if no workers do.
|
||||
@@ -957,9 +832,7 @@ def generate_worker_files(
|
||||
healthcheck_urls = ["http://localhost:8080/health"]
|
||||
|
||||
# Get the set of all worker types that we have configured
|
||||
all_worker_types_in_use = set(
|
||||
chain(*[worker.worker_types for worker in requested_workers])
|
||||
)
|
||||
all_worker_types_in_use = set(chain(*requested_worker_types.values()))
|
||||
# Map locations to upstreams (corresponding to worker types) in Nginx
|
||||
# but only if we use the appropriate worker type
|
||||
for worker_type in all_worker_types_in_use:
|
||||
@@ -968,13 +841,12 @@ def generate_worker_files(
|
||||
|
||||
# For each worker type specified by the user, create config values and write it's
|
||||
# yaml config file
|
||||
worker_name_to_metrics_port_map: dict[str, int] = {}
|
||||
for worker in requested_workers:
|
||||
for worker_name, worker_types_set in requested_worker_types.items():
|
||||
# The collected and processed data will live here.
|
||||
worker_config: dict[str, Any] = {}
|
||||
|
||||
# Merge all worker config templates for this worker into a single config
|
||||
for worker_type in worker.worker_types:
|
||||
for worker_type in worker_types_set:
|
||||
copy_of_template_config = WORKERS_CONFIG[worker_type].copy()
|
||||
|
||||
# Merge worker type template configuration data. It's a combination of lists
|
||||
@@ -984,27 +856,16 @@ def generate_worker_files(
|
||||
)
|
||||
|
||||
# Replace placeholder names in the config template with the actual worker name.
|
||||
worker_config = insert_worker_name_for_worker_config(
|
||||
worker_config, worker.worker_name
|
||||
)
|
||||
worker_config = insert_worker_name_for_worker_config(worker_config, worker_name)
|
||||
|
||||
worker_config.update(
|
||||
{
|
||||
"name": worker.worker_name,
|
||||
"port": str(worker_port),
|
||||
"config_path": config_path,
|
||||
}
|
||||
{"name": worker_name, "port": str(worker_port), "config_path": config_path}
|
||||
)
|
||||
|
||||
# Keep the `shared_config` up to date with the `shared_extra_conf` from each
|
||||
# worker.
|
||||
shared_config = {
|
||||
**worker_config["shared_extra_conf"],
|
||||
# We combine `shared_config` second to avoid overwriting existing keys just
|
||||
# for sanity sake (always use the first worker).
|
||||
**shared_config,
|
||||
}
|
||||
|
||||
# Update the shared config with any worker_type specific options. The first of a
|
||||
# given worker_type needs to stay assigned and not be replaced.
|
||||
worker_config["shared_extra_conf"].update(shared_config)
|
||||
shared_config = worker_config["shared_extra_conf"]
|
||||
if using_unix_sockets:
|
||||
healthcheck_urls.append(
|
||||
f"--unix-socket /run/worker.{worker_port} http://localhost/health"
|
||||
@@ -1016,51 +877,39 @@ def generate_worker_files(
|
||||
# the `events` stream. For other workers, the worker name is the same
|
||||
# name of the stream they write to, but for some reason it is not the
|
||||
# case for event_persister.
|
||||
if "event_persister" in worker.worker_types:
|
||||
worker.worker_types.add("events")
|
||||
if "event_persister" in worker_types_set:
|
||||
worker_types_set.add("events")
|
||||
|
||||
# Update the shared config with sharding-related options if necessary
|
||||
add_worker_roles_to_shared_config(
|
||||
shared_config, worker.worker_types, worker.worker_name, worker_port
|
||||
shared_config, worker_types_set, worker_name, worker_port
|
||||
)
|
||||
|
||||
# Enable the worker in supervisord
|
||||
worker_descriptors.append(worker_config)
|
||||
|
||||
# Write out the worker's logging config file
|
||||
log_config_filepath = generate_worker_log_config(
|
||||
environ, worker.worker_name, data_dir
|
||||
)
|
||||
|
||||
worker_name_to_metrics_port_map[worker.worker_name] = worker_metrics_port
|
||||
if enable_metrics:
|
||||
# Enable prometheus metrics endpoint on this worker
|
||||
worker_config["metrics_port"] = worker_metrics_port
|
||||
|
||||
if enable_metrics:
|
||||
# Enable prometheus metrics endpoint on this worker
|
||||
worker_config["metrics_port"] = worker_metrics_port
|
||||
log_config_filepath = generate_worker_log_config(environ, worker_name, data_dir)
|
||||
|
||||
# Then a worker config file
|
||||
convert(
|
||||
"/conf/worker.yaml.j2",
|
||||
f"/conf/workers/{worker.worker_name}.yaml",
|
||||
f"/conf/workers/{worker_name}.yaml",
|
||||
**worker_config,
|
||||
worker_log_config_filepath=log_config_filepath,
|
||||
using_unix_sockets=using_unix_sockets,
|
||||
)
|
||||
|
||||
# Save this worker's port number to the correct nginx upstreams
|
||||
for worker_type in worker.worker_types:
|
||||
for worker_type in worker_types_set:
|
||||
nginx_upstreams.setdefault(worker_type, set()).add(worker_port)
|
||||
|
||||
worker_port += 1
|
||||
worker_metrics_port += 1
|
||||
|
||||
# Build the nginx location config blocks
|
||||
nginx_location_config = ""
|
||||
for endpoint, upstream in nginx_locations.items():
|
||||
nginx_location_config += NGINX_LOCATION_REGEX_CONFIG_BLOCK.format(
|
||||
nginx_location_config += NGINX_LOCATION_CONFIG_BLOCK.format(
|
||||
endpoint=endpoint,
|
||||
upstream=upstream,
|
||||
)
|
||||
@@ -1083,111 +932,6 @@ def generate_worker_files(
|
||||
body=body,
|
||||
)
|
||||
|
||||
# Provide a Prometheus metrics service discovery endpoint to easily be able to pick
|
||||
# up all of the workers
|
||||
nginx_prometheus_metrics_service_discovery = ""
|
||||
if enable_metrics:
|
||||
# Write JSON file for Prometheus service discovery pointing to all of the
|
||||
# workers. We serve this file with nginx so people can use it with
|
||||
# `http_sd_config` in their Prometheus config.
|
||||
#
|
||||
# > It fetches targets from an HTTP endpoint containing a list of zero or more
|
||||
# > `<static_config>`s. The target must reply with an HTTP 200 response. The HTTP
|
||||
# > header `Content-Type` must be `application/json`, and the body must be valid
|
||||
# > JSON.
|
||||
# >
|
||||
# > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config*
|
||||
#
|
||||
# Another reference: https://prometheus.io/docs/prometheus/latest/http_sd/
|
||||
prometheus_http_service_discovery_content = [
|
||||
{
|
||||
"targets": [NGINX_HOST_PLACEHOLDER],
|
||||
"labels": {
|
||||
# The downstream user should also configure `honor_labels: true` in
|
||||
# their Prometheus config to prevent Prometheus from overwriting the
|
||||
# `job` labels.
|
||||
#
|
||||
# > honor_labels controls how Prometheus handles conflicts between labels that are
|
||||
# > already present in scraped data and labels that Prometheus would attach
|
||||
# > server-side ("job" and "instance" labels, manually configured target
|
||||
# > labels, and labels generated by service discovery implementations).
|
||||
# >
|
||||
# > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config*
|
||||
#
|
||||
# Reference:
|
||||
# - https://prometheus.io/docs/concepts/jobs_instances/
|
||||
# - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
|
||||
"job": worker.worker_base_name,
|
||||
"index": f"{worker.worker_index}",
|
||||
# This allows us to change the `metrics_path` on a per-target basis.
|
||||
# We want to grab the metrics from our nginx proxied location (setup
|
||||
# below).
|
||||
#
|
||||
# While there doesn't seem to be official docs on these special
|
||||
# labels (`__metrics_path__`, `__scheme__`, `__scrape_interval__`,
|
||||
# `__scrape_timeout__`), this discussion best summarizes how this
|
||||
# works: https://github.com/prometheus/prometheus/discussions/13217
|
||||
"__metrics_path__": f"/metrics/worker/{worker.worker_name}",
|
||||
},
|
||||
}
|
||||
for worker in requested_workers
|
||||
]
|
||||
# Add the main Synapse process as well
|
||||
prometheus_http_service_discovery_content.append(
|
||||
{
|
||||
"targets": [NGINX_HOST_PLACEHOLDER],
|
||||
"labels": {
|
||||
# We use `"synapse"` as the job name for the main process because it
|
||||
# matches what we expect people to use from a monolith setup with
|
||||
# their static scrape config. It's `job` name used in our Grafana
|
||||
# dashboard for the main process.
|
||||
"job": "synapse",
|
||||
"index": "1",
|
||||
"__metrics_path__": "/metrics/worker/main",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
# Check to make sure the file doesn't already exist
|
||||
if os.path.isfile(PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH):
|
||||
error(
|
||||
f"Prometheus service discovery file "
|
||||
f"'{PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH}' already exists (unexpected)! "
|
||||
f"This is a problem because the existing file probably doesn't match the "
|
||||
"Synapse workers we're setting up now."
|
||||
)
|
||||
|
||||
# Write the file
|
||||
with open(PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH, "w") as outfile:
|
||||
outfile.write(
|
||||
json.dumps(prometheus_http_service_discovery_content, indent=4)
|
||||
)
|
||||
|
||||
# Proxy all of the Synapse metrics endpoints through a central place so that
|
||||
# people only need to expose the single 9469 port and service discovery can take
|
||||
# care of the rest: `/metrics/worker/<worker_name>` ->
|
||||
# http://localhost:19090/_synapse/metrics
|
||||
#
|
||||
# Build the nginx location config blocks
|
||||
metrics_proxy_locations = ""
|
||||
for worker in requested_workers:
|
||||
metrics_proxy_locations += NGINX_LOCATION_EXACT_CONFIG_BLOCK.format(
|
||||
endpoint=f"/metrics/worker/{worker.worker_name}",
|
||||
upstream=f"http://localhost:{worker_name_to_metrics_port_map[worker.worker_name]}/_synapse/metrics",
|
||||
)
|
||||
# Add the main Synapse process as well
|
||||
metrics_proxy_locations += NGINX_LOCATION_EXACT_CONFIG_BLOCK.format(
|
||||
endpoint="/metrics/worker/main",
|
||||
upstream="http://localhost:19090/_synapse/metrics",
|
||||
)
|
||||
|
||||
# Add a nginx server/location to serve the JSON file
|
||||
nginx_prometheus_metrics_service_discovery = NGINX_PROMETHEUS_METRICS_SERVICE_DISCOVERY.format(
|
||||
service_discovery_file_path=PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH,
|
||||
host_placeholder=NGINX_HOST_PLACEHOLDER,
|
||||
metrics_proxy_locations=metrics_proxy_locations,
|
||||
)
|
||||
|
||||
# Finally, we'll write out the config files.
|
||||
|
||||
# log config for the master process
|
||||
@@ -1205,7 +949,7 @@ def generate_worker_files(
|
||||
if reg_path.suffix.lower() in (".yaml", ".yml")
|
||||
]
|
||||
|
||||
workers_in_use = len(requested_workers) > 0
|
||||
workers_in_use = len(requested_worker_types) > 0
|
||||
|
||||
# If there are workers, add the main process to the instance_map too.
|
||||
if workers_in_use:
|
||||
@@ -1240,7 +984,6 @@ def generate_worker_files(
|
||||
tls_cert_path=os.environ.get("SYNAPSE_TLS_CERT"),
|
||||
tls_key_path=os.environ.get("SYNAPSE_TLS_KEY"),
|
||||
using_unix_sockets=using_unix_sockets,
|
||||
nginx_prometheus_metrics_service_discovery=nginx_prometheus_metrics_service_discovery,
|
||||
)
|
||||
|
||||
# Supervisord config
|
||||
@@ -1341,20 +1084,15 @@ def main(args: list[str], environ: MutableMapping[str, str]) -> None:
|
||||
if not worker_types_env:
|
||||
# No workers, just the main process
|
||||
worker_types = []
|
||||
requested_workers: list[Worker] = []
|
||||
requested_worker_types: dict[str, Any] = {}
|
||||
else:
|
||||
# Split type names by comma, ignoring whitespace.
|
||||
worker_types = split_and_strip_string(worker_types_env, ",")
|
||||
requested_workers = parse_worker_types(worker_types)
|
||||
requested_worker_types = parse_worker_types(worker_types)
|
||||
|
||||
# Always regenerate all other config files
|
||||
log("Generating worker config files")
|
||||
generate_worker_files(
|
||||
environ=environ,
|
||||
config_path=config_path,
|
||||
data_dir=data_dir,
|
||||
requested_workers=requested_workers,
|
||||
)
|
||||
generate_worker_files(environ, config_path, data_dir, requested_worker_types)
|
||||
|
||||
# Mark workers as being configured
|
||||
with open(mark_filepath, "w") as f:
|
||||
|
||||
@@ -31,25 +31,6 @@ def flush_buffers() -> None:
|
||||
sys.stderr.flush()
|
||||
|
||||
|
||||
def strtobool(val: str) -> bool:
|
||||
"""Convert a string representation of truth to True or False
|
||||
|
||||
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
|
||||
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
|
||||
'val' is anything else.
|
||||
|
||||
This is lifted from distutils.util.strtobool, with the exception that it actually
|
||||
returns a bool, rather than an int.
|
||||
"""
|
||||
val = val.lower()
|
||||
if val in ("y", "yes", "t", "true", "on", "1"):
|
||||
return True
|
||||
elif val in ("n", "no", "f", "false", "off", "0"):
|
||||
return False
|
||||
else:
|
||||
raise ValueError("invalid truth value %r" % (val,))
|
||||
|
||||
|
||||
def convert(src: str, dst: str, environ: Mapping[str, object]) -> None:
|
||||
"""Generate a file from a template
|
||||
|
||||
@@ -117,16 +98,19 @@ def generate_config_from_template(
|
||||
os.mkdir(config_dir)
|
||||
|
||||
# Convert SYNAPSE_NO_TLS to boolean if exists
|
||||
tlsanswerstring = environ.get("SYNAPSE_NO_TLS")
|
||||
if tlsanswerstring is not None:
|
||||
try:
|
||||
environ["SYNAPSE_NO_TLS"] = strtobool(tlsanswerstring)
|
||||
except ValueError:
|
||||
error(
|
||||
'Environment variable "SYNAPSE_NO_TLS" found but value "'
|
||||
+ tlsanswerstring
|
||||
+ '" unrecognized; exiting.'
|
||||
)
|
||||
if "SYNAPSE_NO_TLS" in environ:
|
||||
tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"])
|
||||
if tlsanswerstring in ("true", "on", "1", "yes"):
|
||||
environ["SYNAPSE_NO_TLS"] = True
|
||||
else:
|
||||
if tlsanswerstring in ("false", "off", "0", "no"):
|
||||
environ["SYNAPSE_NO_TLS"] = False
|
||||
else:
|
||||
error(
|
||||
'Environment variable "SYNAPSE_NO_TLS" found but value "'
|
||||
+ tlsanswerstring
|
||||
+ '" unrecognized; exiting.'
|
||||
)
|
||||
|
||||
if "SYNAPSE_LOG_CONFIG" not in environ:
|
||||
environ["SYNAPSE_LOG_CONFIG"] = config_dir + "/log.config"
|
||||
@@ -180,18 +164,6 @@ def run_generate_config(environ: Mapping[str, str], ownership: str | None) -> No
|
||||
config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
|
||||
config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml")
|
||||
data_dir = environ.get("SYNAPSE_DATA_DIR", "/data")
|
||||
enable_metrics_raw = environ.get("SYNAPSE_ENABLE_METRICS", "0")
|
||||
|
||||
enable_metrics = False
|
||||
if enable_metrics_raw is not None:
|
||||
try:
|
||||
enable_metrics = strtobool(enable_metrics_raw)
|
||||
except ValueError:
|
||||
error(
|
||||
'Environment variable "SYNAPSE_ENABLE_METRICS" found but value "'
|
||||
+ enable_metrics_raw
|
||||
+ '" unrecognized; exiting.'
|
||||
)
|
||||
|
||||
# create a suitable log config from our template
|
||||
log_config_file = "%s/%s.log.config" % (config_dir, server_name)
|
||||
@@ -218,9 +190,6 @@ def run_generate_config(environ: Mapping[str, str], ownership: str | None) -> No
|
||||
"--open-private-ports",
|
||||
]
|
||||
|
||||
if enable_metrics:
|
||||
args.append("--enable-metrics")
|
||||
|
||||
if ownership is not None:
|
||||
# make sure that synapse has perms to write to the data dir.
|
||||
log(f"Setting ownership on {data_dir} to {ownership}")
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Configuration for htmltest, which we run in CI to check that links aren't broken in the built documentation.
|
||||
# See all config options: https://github.com/wjdp/htmltest#wrench-configuration
|
||||
|
||||
# Don't check external links, as that requires network access and is slow.
|
||||
CheckExternal: false
|
||||
@@ -73,6 +73,33 @@ Response:
|
||||
}
|
||||
```
|
||||
|
||||
## Listing all quarantined media
|
||||
|
||||
This API returns a list of all quarantined media on the server. It is paginated, and can be scoped to either local or
|
||||
remote media. Note that the pagination values are also scoped to the request parameters - changing them but keeping the
|
||||
same pagination values will result in unexpected results.
|
||||
|
||||
Request:
|
||||
```http
|
||||
GET /_synapse/admin/v1/media/quarantined?from=0&limit=100&kind=local
|
||||
```
|
||||
|
||||
`from` and `limit` are optional parameters, and default to `0` and `100` respectively. They are the row index and number
|
||||
of rows to return - they are not timestamps.
|
||||
|
||||
`kind` *MUST* either be `local` or `remote`.
|
||||
|
||||
The API returns a JSON body containing MXC URIs for the quarantined media, like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"media": [
|
||||
"mxc://localhost/xwvutsrqponmlkjihgfedcba",
|
||||
"mxc://localhost/abcdefghijklmnopqrstuvwx"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
# Quarantine media
|
||||
|
||||
Quarantining media means that it is marked as inaccessible by users. It applies
|
||||
|
||||
@@ -36,10 +36,9 @@ It returns a JSON body like the following:
|
||||
- "scheduled" - Task is scheduled but not active
|
||||
- "active" - Task is active and probably running, and if not will be run on next scheduler loop run
|
||||
- "complete" - Task has completed successfully
|
||||
- "cancelled" - Task has been cancelled
|
||||
- "failed" - Task is over and either returned a failed status, or had an exception
|
||||
|
||||
* `max_timestamp`: int - Is optional. Returns only the scheduled tasks with a timestamp (in milliseconds since the unix epoch) inferior to the specified one.
|
||||
* `max_timestamp`: int - Is optional. Returns only the scheduled tasks with a timestamp inferior to the specified one.
|
||||
|
||||
**Response**
|
||||
|
||||
|
||||
@@ -32,33 +32,6 @@ expected and not an issue.
|
||||
It is not a requirement for experimental features to be behind a configuration flag,
|
||||
but one should be used if unsure.
|
||||
|
||||
New experimental configuration flags should be added under the `experimental_features`
|
||||
New experimental configuration flags should be added under the `experimental`
|
||||
configuration key (see the `synapse.config.experimental` file) and either explain
|
||||
(briefly) what is being enabled, or include the MSC number.
|
||||
The configuration flag should link to the tracking issue for the experimental feature (see below).
|
||||
|
||||
|
||||
## Tracking issues for experimental features
|
||||
|
||||
In the interest of having some documentation around experimental features, without
|
||||
polluting the stable documentation, all new experimental features should have a tracking issue with
|
||||
[the `T-ExperimentalFeature` label](https://github.com/element-hq/synapse/issues?q=sort%3Aupdated-desc+state%3Aopen+label%3A%22T-ExperimentalFeature%22),
|
||||
kept open as long as the experimental feature is present in Synapse.
|
||||
|
||||
The configuration option for the feature should have a comment linking to the tracking issue,
|
||||
for ease of discoverability.
|
||||
|
||||
As a guideline, the issue should contain:
|
||||
|
||||
- Context for why this experimental feature is in Synapse
|
||||
- This could well be a link to somewhere else, where this context is already available.
|
||||
- If applicable, why the feature is enabled by default. (Why do we need to enable it by default and why is it safe?)
|
||||
- If applicable, setup instructions for any non-standard components or configuration needed by the feature.
|
||||
(Ideally this will be moved to the configuration manual after stabilisation.)
|
||||
- Design decisions behind the Synapse implementation.
|
||||
(Ideally this will be moved to the developers' documentation after stabilisation.)
|
||||
- Any caveats around the current implementation of the feature, such as:
|
||||
- missing aspects
|
||||
- breakage or incompatibility that is expected if/when the feature is stabilised,
|
||||
or when the feature is turned on/off
|
||||
- Criteria for how we know whether we can remove the feature in the future.
|
||||
|
||||
@@ -123,21 +123,193 @@ Example Prometheus target for Synapse with workers:
|
||||
static_configs:
|
||||
- targets: ["my.server.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "master"
|
||||
index: 1
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "generic_worker"
|
||||
index: 1
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "generic_worker"
|
||||
index: 2
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "media_repository"
|
||||
index: 1
|
||||
```
|
||||
|
||||
Labels (`job`, `index`) can be defined as anything.
|
||||
Labels (`instance`, `job`, `index`) can be defined as anything.
|
||||
The labels are used to group graphs in grafana.
|
||||
|
||||
## Renaming of metrics & deprecation of old names in 1.2
|
||||
|
||||
Synapse 1.2 updates the Prometheus metrics to match the naming
|
||||
convention of the upstream `prometheus_client`. The old names are
|
||||
considered deprecated and will be removed in a future version of
|
||||
Synapse.
|
||||
**The old names will be disabled by default in Synapse v1.71.0 and removed
|
||||
altogether in Synapse v1.73.0.**
|
||||
|
||||
| New Name | Old Name |
|
||||
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| python_gc_objects_collected_total | python_gc_objects_collected |
|
||||
| python_gc_objects_uncollectable_total | python_gc_objects_uncollectable |
|
||||
| python_gc_collections_total | python_gc_collections |
|
||||
| process_cpu_seconds_total | process_cpu_seconds |
|
||||
| synapse_federation_client_sent_transactions_total | synapse_federation_client_sent_transactions |
|
||||
| synapse_federation_client_events_processed_total | synapse_federation_client_events_processed |
|
||||
| synapse_event_processing_loop_count_total | synapse_event_processing_loop_count |
|
||||
| synapse_event_processing_loop_room_count_total | synapse_event_processing_loop_room_count |
|
||||
| synapse_util_caches_cache_hits | synapse_util_caches_cache:hits |
|
||||
| synapse_util_caches_cache_size | synapse_util_caches_cache:size |
|
||||
| synapse_util_caches_cache_evicted_size | synapse_util_caches_cache:evicted_size |
|
||||
| synapse_util_caches_cache | synapse_util_caches_cache:total |
|
||||
| synapse_util_caches_response_cache_size | synapse_util_caches_response_cache:size |
|
||||
| synapse_util_caches_response_cache_hits | synapse_util_caches_response_cache:hits |
|
||||
| synapse_util_caches_response_cache_evicted_size | synapse_util_caches_response_cache:evicted_size |
|
||||
| synapse_util_metrics_block_count_total | synapse_util_metrics_block_count |
|
||||
| synapse_util_metrics_block_time_seconds_total | synapse_util_metrics_block_time_seconds |
|
||||
| synapse_util_metrics_block_ru_utime_seconds_total | synapse_util_metrics_block_ru_utime_seconds |
|
||||
| synapse_util_metrics_block_ru_stime_seconds_total | synapse_util_metrics_block_ru_stime_seconds |
|
||||
| synapse_util_metrics_block_db_txn_count_total | synapse_util_metrics_block_db_txn_count |
|
||||
| synapse_util_metrics_block_db_txn_duration_seconds_total | synapse_util_metrics_block_db_txn_duration_seconds |
|
||||
| synapse_util_metrics_block_db_sched_duration_seconds_total | synapse_util_metrics_block_db_sched_duration_seconds |
|
||||
| synapse_background_process_start_count_total | synapse_background_process_start_count |
|
||||
| synapse_background_process_ru_utime_seconds_total | synapse_background_process_ru_utime_seconds |
|
||||
| synapse_background_process_ru_stime_seconds_total | synapse_background_process_ru_stime_seconds |
|
||||
| synapse_background_process_db_txn_count_total | synapse_background_process_db_txn_count |
|
||||
| synapse_background_process_db_txn_duration_seconds_total | synapse_background_process_db_txn_duration_seconds |
|
||||
| synapse_background_process_db_sched_duration_seconds_total | synapse_background_process_db_sched_duration_seconds |
|
||||
| synapse_storage_events_persisted_events_total | synapse_storage_events_persisted_events |
|
||||
| synapse_storage_events_persisted_events_sep_total | synapse_storage_events_persisted_events_sep |
|
||||
| synapse_storage_events_state_delta_total | synapse_storage_events_state_delta |
|
||||
| synapse_storage_events_state_delta_single_event_total | synapse_storage_events_state_delta_single_event |
|
||||
| synapse_storage_events_state_delta_reuse_delta_total | synapse_storage_events_state_delta_reuse_delta |
|
||||
| synapse_federation_server_received_pdus_total | synapse_federation_server_received_pdus |
|
||||
| synapse_federation_server_received_edus_total | synapse_federation_server_received_edus |
|
||||
| synapse_handler_presence_notified_presence_total | synapse_handler_presence_notified_presence |
|
||||
| synapse_handler_presence_federation_presence_out_total | synapse_handler_presence_federation_presence_out |
|
||||
| synapse_handler_presence_presence_updates_total | synapse_handler_presence_presence_updates |
|
||||
| synapse_handler_presence_timers_fired_total | synapse_handler_presence_timers_fired |
|
||||
| synapse_handler_presence_federation_presence_total | synapse_handler_presence_federation_presence |
|
||||
| synapse_handler_presence_bump_active_time_total | synapse_handler_presence_bump_active_time |
|
||||
| synapse_federation_client_sent_edus_total | synapse_federation_client_sent_edus |
|
||||
| synapse_federation_client_sent_pdu_destinations_count_total | synapse_federation_client_sent_pdu_destinations:count |
|
||||
| synapse_federation_client_sent_pdu_destinations_total | synapse_federation_client_sent_pdu_destinations:total |
|
||||
| synapse_handlers_appservice_events_processed_total | synapse_handlers_appservice_events_processed |
|
||||
| synapse_notifier_notified_events_total | synapse_notifier_notified_events |
|
||||
| synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter_total | synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter |
|
||||
| synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter_total | synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter |
|
||||
| synapse_http_httppusher_http_pushes_processed_total | synapse_http_httppusher_http_pushes_processed |
|
||||
| synapse_http_httppusher_http_pushes_failed_total | synapse_http_httppusher_http_pushes_failed |
|
||||
| synapse_http_httppusher_badge_updates_processed_total | synapse_http_httppusher_badge_updates_processed |
|
||||
| synapse_http_httppusher_badge_updates_failed_total | synapse_http_httppusher_badge_updates_failed |
|
||||
| synapse_admin_mau_current | synapse_admin_mau:current |
|
||||
| synapse_admin_mau_max | synapse_admin_mau:max |
|
||||
| synapse_admin_mau_registered_reserved_users | synapse_admin_mau:registered_reserved_users |
|
||||
|
||||
Removal of deprecated metrics & time based counters becoming histograms in 0.31.0
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
The duplicated metrics deprecated in Synapse 0.27.0 have been removed.
|
||||
|
||||
All time duration-based metrics have been changed to be seconds. This
|
||||
affects:
|
||||
|
||||
| msec -> sec metrics |
|
||||
| -------------------------------------- |
|
||||
| python_gc_time |
|
||||
| python_twisted_reactor_tick_time |
|
||||
| synapse_storage_query_time |
|
||||
| synapse_storage_schedule_time |
|
||||
| synapse_storage_transaction_time |
|
||||
|
||||
Several metrics have been changed to be histograms, which sort entries
|
||||
into buckets and allow better analysis. The following metrics are now
|
||||
histograms:
|
||||
|
||||
| Altered metrics |
|
||||
| ------------------------------------------------ |
|
||||
| python_gc_time |
|
||||
| python_twisted_reactor_pending_calls |
|
||||
| python_twisted_reactor_tick_time |
|
||||
| synapse_http_server_response_time_seconds |
|
||||
| synapse_storage_query_time |
|
||||
| synapse_storage_schedule_time |
|
||||
| synapse_storage_transaction_time |
|
||||
|
||||
Block and response metrics renamed for 0.27.0
|
||||
---------------------------------------------
|
||||
|
||||
Synapse 0.27.0 begins the process of rationalising the duplicate
|
||||
`*:count` metrics reported for the resource tracking for code blocks and
|
||||
HTTP requests.
|
||||
|
||||
At the same time, the corresponding `*:total` metrics are being renamed,
|
||||
as the `:total` suffix no longer makes sense in the absence of a
|
||||
corresponding `:count` metric.
|
||||
|
||||
To enable a graceful migration path, this release just adds new names
|
||||
for the metrics being renamed. A future release will remove the old
|
||||
ones.
|
||||
|
||||
The following table shows the new metrics, and the old metrics which
|
||||
they are replacing.
|
||||
|
||||
| New name | Old name |
|
||||
| ------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| synapse_util_metrics_block_count | synapse_util_metrics_block_timer:count |
|
||||
| synapse_util_metrics_block_count | synapse_util_metrics_block_ru_utime:count |
|
||||
| synapse_util_metrics_block_count | synapse_util_metrics_block_ru_stime:count |
|
||||
| synapse_util_metrics_block_count | synapse_util_metrics_block_db_txn_count:count |
|
||||
| synapse_util_metrics_block_count | synapse_util_metrics_block_db_txn_duration:count |
|
||||
| synapse_util_metrics_block_time_seconds | synapse_util_metrics_block_timer:total |
|
||||
| synapse_util_metrics_block_ru_utime_seconds | synapse_util_metrics_block_ru_utime:total |
|
||||
| synapse_util_metrics_block_ru_stime_seconds | synapse_util_metrics_block_ru_stime:total |
|
||||
| synapse_util_metrics_block_db_txn_count | synapse_util_metrics_block_db_txn_count:total |
|
||||
| synapse_util_metrics_block_db_txn_duration_seconds | synapse_util_metrics_block_db_txn_duration:total |
|
||||
| synapse_http_server_response_count | synapse_http_server_requests |
|
||||
| synapse_http_server_response_count | synapse_http_server_response_time:count |
|
||||
| synapse_http_server_response_count | synapse_http_server_response_ru_utime:count |
|
||||
| synapse_http_server_response_count | synapse_http_server_response_ru_stime:count |
|
||||
| synapse_http_server_response_count | synapse_http_server_response_db_txn_count:count |
|
||||
| synapse_http_server_response_count | synapse_http_server_response_db_txn_duration:count |
|
||||
| synapse_http_server_response_time_seconds | synapse_http_server_response_time:total |
|
||||
| synapse_http_server_response_ru_utime_seconds | synapse_http_server_response_ru_utime:total |
|
||||
| synapse_http_server_response_ru_stime_seconds | synapse_http_server_response_ru_stime:total |
|
||||
| synapse_http_server_response_db_txn_count | synapse_http_server_response_db_txn_count:total |
|
||||
| synapse_http_server_response_db_txn_duration_seconds | synapse_http_server_response_db_txn_duration:total |
|
||||
|
||||
Standard Metric Names
|
||||
---------------------
|
||||
|
||||
As of synapse version 0.18.2, the format of the process-wide metrics has
|
||||
been changed to fit prometheus standard naming conventions. Additionally
|
||||
the units have been changed to seconds, from milliseconds.
|
||||
|
||||
| New name | Old name |
|
||||
| ---------------------------------------- | --------------------------------- |
|
||||
| process_cpu_user_seconds_total | process_resource_utime / 1000 |
|
||||
| process_cpu_system_seconds_total | process_resource_stime / 1000 |
|
||||
| process_open_fds (no \'type\' label) | process_fds |
|
||||
|
||||
The python-specific counts of garbage collector performance have been
|
||||
renamed.
|
||||
|
||||
| New name | Old name |
|
||||
| -------------------------------- | -------------------------- |
|
||||
| python_gc_time | reactor_gc_time |
|
||||
| python_gc_unreachable_total | reactor_gc_unreachable |
|
||||
| python_gc_counts | reactor_gc_counts |
|
||||
|
||||
The twisted-specific reactor metrics have been renamed.
|
||||
|
||||
| New name | Old name |
|
||||
| -------------------------------------- | ----------------------- |
|
||||
| python_twisted_reactor_pending_calls | reactor_pending_calls |
|
||||
| python_twisted_reactor_tick_time | reactor_tick_time |
|
||||
|
||||
@@ -24,18 +24,14 @@
|
||||
server_name: "SERVERNAME"
|
||||
pid_file: DATADIR/homeserver.pid
|
||||
listeners:
|
||||
- bind_addresses:
|
||||
- ::1
|
||||
- 127.0.0.1
|
||||
port: 8008
|
||||
resources:
|
||||
- compress: false
|
||||
names:
|
||||
- client
|
||||
- federation
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
bind_addresses: ['::1', '127.0.0.1']
|
||||
resources:
|
||||
- names: [client, federation]
|
||||
compress: false
|
||||
database:
|
||||
name: sqlite3
|
||||
args:
|
||||
|
||||
@@ -117,22 +117,6 @@ each upgrade are complete before moving on to the next upgrade, to avoid
|
||||
stacking them up. You can monitor the currently running background updates with
|
||||
[the Admin API](usage/administration/admin_api/background_updates.html#status).
|
||||
|
||||
# Upgrading to v1.146.0
|
||||
|
||||
## Drop support for Ubuntu 25.04 Plucky Puffin, and add support for 25.10 Questing Quokka
|
||||
|
||||
Ubuntu 25.04 Plucky Puffin [is end-of-life as of 17 Jan
|
||||
2026](https://endoflife.date/ubuntu). This release drops support for Ubuntu
|
||||
25.04, and in its place adds support for Ubuntu 25.10 Questing Quokka.
|
||||
|
||||
## Removal of MSC2697 (Legacy) Dehydrated devices
|
||||
|
||||
The endpoints for
|
||||
[MSC2697](https://github.com/matrix-org/matrix-spec-proposals/pull/2697) have now
|
||||
been removed, since the MSC is closed. Developers who rely on this feature should
|
||||
migrate to [MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814)
|
||||
which introduces support for a newer version of dehydrated devices.
|
||||
|
||||
# Upgrading to v1.144.0
|
||||
|
||||
## Worker support for unstable MSC4140 `/restart` endpoint
|
||||
@@ -844,7 +828,7 @@ the names of Prometheus metrics.
|
||||
If you want to test your changes before legacy names are disabled by default,
|
||||
you may specify `enable_legacy_metrics: false` in your homeserver configuration.
|
||||
|
||||
A list of affected metrics is available on the [Metrics How-to page](https://element-hq.github.io/synapse/v1.69/metrics-howto.html#renaming-of-metrics--deprecation-of-old-names-in-12).
|
||||
A list of affected metrics is available on the [Metrics How-to page](https://element-hq.github.io/synapse/v1.69/metrics-howto.html?highlight=metrics%20deprecated#renaming-of-metrics--deprecation-of-old-names-in-12).
|
||||
|
||||
|
||||
## Deprecation of the `generate_short_term_login_token` module API method
|
||||
@@ -2439,7 +2423,7 @@ back to v1.3.1, subject to the following:
|
||||
|
||||
Some counter metrics have been renamed, with the old names deprecated.
|
||||
See [the metrics
|
||||
documentation](https://element-hq.github.io/synapse/v1.69/metrics-howto.html#renaming-of-metrics--deprecation-of-old-names-in-12)
|
||||
documentation](metrics-howto.md#renaming-of-metrics--deprecation-of-old-names-in-12)
|
||||
for details.
|
||||
|
||||
# Upgrading to v1.1.0
|
||||
|
||||
@@ -956,7 +956,7 @@ server_context: context
|
||||
---
|
||||
### `limit_remote_rooms`
|
||||
|
||||
*(object)* When this option is enabled, the room "complexity" will be checked before a user joins a new remote room. If it is above the complexity limit, the server will disallow joining, or will instantly leave. This is useful for homeservers that are resource-constrained. In Synapse, the complexity of a room is measured by the number of current state events in a room, divided by 500. "Current" here means the latest state, i.e. if a user joins, then leaves, then joins, that will count as 1 current `m.room.member` state event.
|
||||
*(object)* When this option is enabled, the room "complexity" will be checked before a user joins a new remote room. If it is above the complexity limit, the server will disallow joining, or will instantly leave. This is useful for homeservers that are resource-constrained. Room complexity is an arbitrary measure based on factors such as the number of users in the room.
|
||||
|
||||
This setting has the following sub-options:
|
||||
|
||||
@@ -2041,25 +2041,6 @@ rc_room_creation:
|
||||
burst_count: 5.0
|
||||
```
|
||||
---
|
||||
### `rc_user_directory`
|
||||
|
||||
*(object)* This option allows admins to ratelimit searches in the user directory.
|
||||
|
||||
_Added in Synapse 1.145.0._
|
||||
|
||||
This setting has the following sub-options:
|
||||
|
||||
* `per_second` (number): Maximum number of requests a client can send per second.
|
||||
|
||||
* `burst_count` (number): Maximum number of requests a client can send before being throttled.
|
||||
|
||||
Default configuration:
|
||||
```yaml
|
||||
rc_user_directory:
|
||||
per_second: 0.016
|
||||
burst_count: 200.0
|
||||
```
|
||||
---
|
||||
### `federation_rr_transactions_per_room_per_second`
|
||||
|
||||
*(integer)* Sets outgoing federation transaction frequency for sending read-receipts, per-room.
|
||||
@@ -2111,16 +2092,6 @@ Example configuration:
|
||||
enable_media_repo: false
|
||||
```
|
||||
---
|
||||
### `enable_local_media_storage`
|
||||
|
||||
*(boolean)* Enable the local on-disk media storage provider. When disabled, media is stored only in configured `media_storage_providers` and temporary files are used for processing.
|
||||
**Warning:** If this option is set to `false` and no `media_storage_providers` are configured, all media requests will return 404 errors as there will be no storage backend available. Defaults to `true`.
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
enable_local_media_storage: false
|
||||
```
|
||||
---
|
||||
### `media_store_path`
|
||||
|
||||
*(string)* Directory where uploaded images and attachments are stored. Defaults to `"media_store"`.
|
||||
|
||||
@@ -9,18 +9,27 @@ point to additional JS/CSS in this directory that are added on each page load. I
|
||||
addition, the `theme` directory contains files that overwrite their counterparts in
|
||||
each of the default themes included with mdbook.
|
||||
|
||||
Currently we use these files to make a few modifications:
|
||||
Currently we use these files to generate a floating Table of Contents panel. The code for
|
||||
which was partially taken from
|
||||
[JorelAli/mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc/)
|
||||
before being modified such that it scrolls with the content of the page. This is handled
|
||||
by the `table-of-contents.js/css` files. The table of contents panel only appears on pages
|
||||
that have more than one header, as well as only appearing on desktop-sized monitors.
|
||||
|
||||
* We stylise the chapter titles in the left sidebar by indenting them
|
||||
slightly so that they are more visually distinguishable from the section headers
|
||||
(the bold titles). This is done through the `indent-section-headers.css` file.
|
||||
We remove the navigation arrows which typically appear on the left and right side of the
|
||||
screen on desktop as they interfere with the table of contents. This is handled by
|
||||
the `remove-nav-buttons.css` file.
|
||||
|
||||
* We add a version picker pertaining to the different documentation versions
|
||||
shipped with each version of Synapse. This functionality was implemented through
|
||||
the `version-picker.js` and `version-picker.css` files, and is currently the only
|
||||
requirement for the custom `theme/`.
|
||||
Finally, we also stylise the chapter titles in the left sidebar by indenting them
|
||||
slightly so that they are more visually distinguishable from the section headers
|
||||
(the bold titles). This is done through the `indent-section-headers.css` file.
|
||||
|
||||
In addition to these modifications, we have added a version picker to the documentation.
|
||||
Users can switch between documentations for different versions of Synapse.
|
||||
This functionality was implemented through the `version-picker.js` and
|
||||
`version-picker.css` files.
|
||||
|
||||
More information can be found in mdbook's official documentation for
|
||||
[injecting page JS/CSS](https://rust-lang.github.io/mdBook/format/config.html)
|
||||
and
|
||||
[customising the default themes](https://rust-lang.github.io/mdBook/format/theme/index.html).
|
||||
[customising the default themes](https://rust-lang.github.io/mdBook/format/theme/index.html).
|
||||
8
docs/website_files/remove-nav-buttons.css
Normal file
8
docs/website_files/remove-nav-buttons.css
Normal file
@@ -0,0 +1,8 @@
|
||||
/* Remove the prev, next chapter buttons as they interfere with the
|
||||
* table of contents.
|
||||
* Note that the table of contents only appears on desktop, thus we
|
||||
* only remove the desktop (wide) chapter buttons.
|
||||
*/
|
||||
.nav-wide-wrapper {
|
||||
display: none
|
||||
}
|
||||
47
docs/website_files/table-of-contents.css
Normal file
47
docs/website_files/table-of-contents.css
Normal file
@@ -0,0 +1,47 @@
|
||||
:root {
|
||||
--pagetoc-width: 250px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width:1439px) {
|
||||
.sidetoc {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width:1440px) {
|
||||
main {
|
||||
position: relative;
|
||||
margin-left: 100px !important;
|
||||
margin-right: var(--pagetoc-width) !important;
|
||||
}
|
||||
.sidetoc {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
left: calc(100% + (var(--content-max-width))/4 - 140px);
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
}
|
||||
.pagetoc {
|
||||
position: fixed;
|
||||
width: var(--pagetoc-width);
|
||||
overflow: auto;
|
||||
right: 20px;
|
||||
height: calc(100% - var(--menu-bar-height));
|
||||
}
|
||||
.pagetoc a {
|
||||
color: var(--fg) !important;
|
||||
display: block;
|
||||
padding: 5px 15px 5px 10px;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
}
|
||||
.pagetoc a:hover,
|
||||
.pagetoc a.active {
|
||||
background: var(--sidebar-bg) !important;
|
||||
color: var(--sidebar-fg) !important;
|
||||
}
|
||||
.pagetoc .active {
|
||||
background: var(--sidebar-bg);
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
}
|
||||
148
docs/website_files/table-of-contents.js
Normal file
148
docs/website_files/table-of-contents.js
Normal file
@@ -0,0 +1,148 @@
|
||||
const getPageToc = () => document.getElementsByClassName('pagetoc')[0];
|
||||
|
||||
const pageToc = getPageToc();
|
||||
const pageTocChildren = [...pageToc.children];
|
||||
const headers = [...document.getElementsByClassName('header')];
|
||||
|
||||
|
||||
// Select highlighted item in ToC when clicking an item
|
||||
pageTocChildren.forEach(child => {
|
||||
child.addEventHandler('click', () => {
|
||||
pageTocChildren.forEach(child => {
|
||||
child.classList.remove('active');
|
||||
});
|
||||
child.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test whether a node is in the viewport
|
||||
*/
|
||||
function isInViewport(node) {
|
||||
const rect = node.getBoundingClientRect();
|
||||
return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a new ToC entry.
|
||||
* Clear any previously highlighted ToC items, set the new one,
|
||||
* and adjust the ToC scroll position.
|
||||
*/
|
||||
function setTocEntry() {
|
||||
let activeEntry;
|
||||
const pageTocChildren = [...getPageToc().children];
|
||||
|
||||
// Calculate which header is the current one at the top of screen
|
||||
headers.forEach(header => {
|
||||
if (window.pageYOffset >= header.offsetTop) {
|
||||
activeEntry = header;
|
||||
}
|
||||
});
|
||||
|
||||
// Update selected item in ToC when scrolling
|
||||
pageTocChildren.forEach(child => {
|
||||
if (activeEntry.href.localeCompare(child.href) === 0) {
|
||||
child.classList.add('active');
|
||||
} else {
|
||||
child.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
let tocEntryForLocation = document.querySelector(`nav a[href="${activeEntry.href}"]`);
|
||||
if (tocEntryForLocation) {
|
||||
const headingForLocation = document.querySelector(activeEntry.hash);
|
||||
if (headingForLocation && isInViewport(headingForLocation)) {
|
||||
// Update ToC scroll
|
||||
const nav = getPageToc();
|
||||
const content = document.querySelector('html');
|
||||
if (content.scrollTop !== 0) {
|
||||
nav.scrollTo({
|
||||
top: tocEntryForLocation.offsetTop - 100,
|
||||
left: 0,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
} else {
|
||||
nav.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populate sidebar on load
|
||||
*/
|
||||
window.addEventListener('load', () => {
|
||||
// Prevent rendering the table of contents of the "print book" page, as it
|
||||
// will end up being rendered into the output (in a broken-looking way)
|
||||
|
||||
// Get the name of the current page (i.e. 'print.html')
|
||||
const pageNameExtension = window.location.pathname.split('/').pop();
|
||||
|
||||
// Split off the extension (as '.../print' is also a valid page name), which
|
||||
// should result in 'print'
|
||||
const pageName = pageNameExtension.split('.')[0];
|
||||
if (pageName === "print") {
|
||||
// Don't render the table of contents on this page
|
||||
return;
|
||||
}
|
||||
|
||||
// Only create table of contents if there is more than one header on the page
|
||||
if (headers.length <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an entry in the page table of contents for each header in the document
|
||||
headers.forEach((header, index) => {
|
||||
const link = document.createElement('a');
|
||||
|
||||
// Indent shows hierarchy
|
||||
let indent = '0px';
|
||||
switch (header.parentElement.tagName) {
|
||||
case 'H1':
|
||||
indent = '5px';
|
||||
break;
|
||||
case 'H2':
|
||||
indent = '20px';
|
||||
break;
|
||||
case 'H3':
|
||||
indent = '30px';
|
||||
break;
|
||||
case 'H4':
|
||||
indent = '40px';
|
||||
break;
|
||||
case 'H5':
|
||||
indent = '50px';
|
||||
break;
|
||||
case 'H6':
|
||||
indent = '60px';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
let tocEntry;
|
||||
if (index == 0) {
|
||||
// Create a bolded title for the first element
|
||||
tocEntry = document.createElement("strong");
|
||||
tocEntry.innerHTML = header.text;
|
||||
} else {
|
||||
// All other elements are non-bold
|
||||
tocEntry = document.createTextNode(header.text);
|
||||
}
|
||||
link.appendChild(tocEntry);
|
||||
|
||||
link.style.paddingLeft = indent;
|
||||
link.href = header.href;
|
||||
pageToc.appendChild(link);
|
||||
});
|
||||
setTocEntry.call();
|
||||
});
|
||||
|
||||
|
||||
// Handle active headers on scroll, if there is more than one header on the page
|
||||
if (headers.length > 1) {
|
||||
window.addEventListener('scroll', setTocEntry);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="{{ language }}" class="{{ default_theme }} sidebar-visible" dir="{{ text_direction }}">
|
||||
<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
{{#if is_print }}
|
||||
<meta name="robots" content="noindex">
|
||||
<meta name="robots" content="noindex" />
|
||||
{{/if}}
|
||||
{{#if base_url}}
|
||||
<base href="{{ base_url }}">
|
||||
@@ -15,78 +15,60 @@
|
||||
<!-- Custom HTML head -->
|
||||
{{> head}}
|
||||
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
{{#if favicon_svg}}
|
||||
<link rel="icon" href="{{ resource "favicon.svg" }}">
|
||||
<link rel="icon" href="{{ path_to_root }}favicon.svg">
|
||||
{{/if}}
|
||||
{{#if favicon_png}}
|
||||
<link rel="shortcut icon" href="{{ resource "favicon.png" }}">
|
||||
<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
|
||||
{{/if}}
|
||||
<link rel="stylesheet" href="{{ resource "css/variables.css" }}">
|
||||
<link rel="stylesheet" href="{{ resource "css/general.css" }}">
|
||||
<link rel="stylesheet" href="{{ resource "css/chrome.css" }}">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
|
||||
{{#if print_enable}}
|
||||
<link rel="stylesheet" href="{{ resource "css/print.css" }}" media="print">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
|
||||
{{/if}}
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ resource "fonts/fonts.css" }}">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
|
||||
{{#if copy_fonts}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
|
||||
{{/if}}
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" id="mdbook-highlight-css" href="{{ resource "highlight.css" }}">
|
||||
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="{{ resource "tomorrow-night.css" }}">
|
||||
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="{{ resource "ayu-highlight.css" }}">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
{{#each additional_css}}
|
||||
<link rel="stylesheet" href="{{ resource this }}">
|
||||
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
|
||||
{{/each}}
|
||||
|
||||
{{#if mathjax_support}}
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
<script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
{{/if}}
|
||||
|
||||
<!-- Provide site root and default themes to javascript -->
|
||||
<script>
|
||||
const path_to_root = "{{ path_to_root }}";
|
||||
const default_light_theme = "{{ default_theme }}";
|
||||
const default_dark_theme = "{{ preferred_dark_theme }}";
|
||||
{{#if search_js}}
|
||||
window.path_to_searchindex_js = "{{ resource "searchindex.js" }}";
|
||||
{{/if}}
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="{{ resource "toc.js" }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mdbook-help-container">
|
||||
<div id="mdbook-help-popup">
|
||||
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
|
||||
<div>
|
||||
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
|
||||
{{#if search_enabled}}
|
||||
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
|
||||
{{/if}}
|
||||
<p>Press <kbd>?</kbd> to show this help</p>
|
||||
<p>Press <kbd>Esc</kbd> to hide this help</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mdbook-body-container">
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
let theme = localStorage.getItem('mdbook-theme');
|
||||
let sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "{{ path_to_root }}";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
@@ -94,107 +76,91 @@
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
||||
let theme;
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
const html = document.documentElement;
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('{{ default_theme }}')
|
||||
html.classList.add(theme);
|
||||
html.classList.add("js");
|
||||
html.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="mdbook-sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
let sidebar = null;
|
||||
const sidebar_toggle = document.getElementById("mdbook-sidebar-toggle-anchor");
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
sidebar_toggle.checked = false;
|
||||
}
|
||||
if (sidebar === 'visible') {
|
||||
sidebar_toggle.checked = true;
|
||||
} else {
|
||||
html.classList.remove('sidebar-visible');
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="mdbook-sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<!-- populated by js -->
|
||||
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||||
<noscript>
|
||||
<iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe>
|
||||
</noscript>
|
||||
<div id="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
{{#toc}}{{/toc}}
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<div id="mdbook-page-wrapper" class="page-wrapper">
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
{{> header}}
|
||||
<div id="mdbook-menu-bar-hover-placeholder"></div>
|
||||
<div id="mdbook-menu-bar" class="menu-bar sticky">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
|
||||
{{fa "solid" "bars"}}
|
||||
</label>
|
||||
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
|
||||
{{fa "solid" "paintbrush"}}
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
|
||||
</ul>
|
||||
{{#if search_enabled}}
|
||||
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
|
||||
{{fa "solid" "magnifying-glass"}}
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<!-- BEGIN CUSTOM SYNAPSE MODIFICATIONS -->
|
||||
<div class="version-picker">
|
||||
<div class="dropdown">
|
||||
<div class="select">
|
||||
<span></span>
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
<div class="version-picker">
|
||||
<div class="dropdown">
|
||||
<div class="select">
|
||||
<span></span>
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
</div>
|
||||
<input type="hidden" name="version">
|
||||
<ul class="dropdown-menu">
|
||||
<!-- Versions will be added dynamically in version-picker.js -->
|
||||
</ul>
|
||||
</div>
|
||||
<input type="hidden" name="version">
|
||||
<ul class="dropdown-menu">
|
||||
<!-- Versions will be added dynamically in version-picker.js -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END CUSTOM SYNAPSE MODIFICATIONS -->
|
||||
|
||||
<h1 class="menu-title">{{ book_title }}</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
{{#if print_enable}}
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
{{fa "solid" "print" "print-button"}}
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_url}}
|
||||
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
|
||||
{{fa git_repository_icon_class git_repository_icon}}
|
||||
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_edit_url}}
|
||||
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
|
||||
{{fa "solid" "pencil" "git-edit-button"}}
|
||||
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
|
||||
<i id="git-edit-button" class="fa fa-edit"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
@@ -202,58 +168,50 @@
|
||||
</div>
|
||||
|
||||
{{#if search_enabled}}
|
||||
<div id="mdbook-search-wrapper" class="hidden">
|
||||
<form id="mdbook-searchbar-outer" class="searchbar-outer">
|
||||
<div class="search-wrapper">
|
||||
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
|
||||
<div class="spinner-wrapper">
|
||||
{{fa "solid" "spinner" "fa-spin"}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="mdbook-searchresults">
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="mdbook-content" class="content">
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<!-- Page table of contents -->
|
||||
<div class="sidetoc">
|
||||
<nav class="pagetoc"></nav>
|
||||
</div>
|
||||
|
||||
{{{ content }}}
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
{{#if previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{else}}
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{/if}}
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/previous}}
|
||||
|
||||
{{#if next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{else}}
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{/if}}
|
||||
{{#next}}
|
||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/next}}
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
@@ -261,92 +219,92 @@
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
{{#if previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{else}}
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{/if}}
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/previous}}
|
||||
|
||||
{{#if next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
{{#if (eq text_direction "rtl")}}
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{else}}
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{/if}}
|
||||
{{#next}}
|
||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/next}}
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
<template id=fa-eye>{{fa "solid" "eye"}}</template>
|
||||
<template id=fa-eye-slash>{{fa "solid" "eye-slash"}}</template>
|
||||
<template id=fa-copy>{{fa "regular" "copy"}}</template>
|
||||
<template id=fa-play>{{fa "solid" "play"}}</template>
|
||||
<template id=fa-clock-rotate-left>{{fa "solid" "clock-rotate-left"}}</template>
|
||||
|
||||
{{#if live_reload_endpoint}}
|
||||
{{#if livereload}}
|
||||
<!-- Livereload script (if served using the cli tool) -->
|
||||
<script>
|
||||
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
|
||||
const socket = new WebSocket(wsAddress);
|
||||
<script type="text/javascript">
|
||||
var socket = new WebSocket("{{{livereload}}}");
|
||||
socket.onmessage = function (event) {
|
||||
if (event.data === "reload") {
|
||||
socket.close();
|
||||
location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
window.onbeforeunload = function() {
|
||||
socket.close();
|
||||
}
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if google_analytics}}
|
||||
<!-- Google Analytics Tag -->
|
||||
<script type="text/javascript">
|
||||
var localAddrs = ["localhost", "127.0.0.1", ""];
|
||||
// make sure we don't activate google analytics if the developer is
|
||||
// inspecting the book locally...
|
||||
if (localAddrs.indexOf(document.location.hostname) === -1) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', '{{google_analytics}}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_line_numbers}}
|
||||
<script>
|
||||
<script type="text/javascript">
|
||||
window.playground_line_numbers = true;
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_copyable}}
|
||||
<script>
|
||||
<script type="text/javascript">
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_js}}
|
||||
<script src="{{ resource "ace.js" }}"></script>
|
||||
<script src="{{ resource "mode-rust.js" }}"></script>
|
||||
<script src="{{ resource "editor.js" }}"></script>
|
||||
<script src="{{ resource "theme-dawn.js" }}"></script>
|
||||
<script src="{{ resource "theme-tomorrow_night.js" }}"></script>
|
||||
<script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
|
||||
{{/if}}
|
||||
|
||||
{{#if search_js}}
|
||||
<script src="{{ resource "elasticlunr.min.js" }}"></script>
|
||||
<script src="{{ resource "mark.min.js" }}"></script>
|
||||
<script src="{{ resource "searcher.js" }}"></script>
|
||||
<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
{{/if}}
|
||||
|
||||
<script src="{{ resource "clipboard.min.js" }}"></script>
|
||||
<script src="{{ resource "highlight.js" }}"></script>
|
||||
<script src="{{ resource "book.js" }}"></script>
|
||||
<script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
{{#each additional_js}}
|
||||
<script src="{{ resource this}}"></script>
|
||||
<script type="text/javascript" src="{{ ../path_to_root }}{{this}}"></script>
|
||||
{{/each}}
|
||||
|
||||
{{#if is_print}}
|
||||
{{#if mathjax_support}}
|
||||
<script>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('load', function() {
|
||||
MathJax.Hub.Register.StartupHook('End', function() {
|
||||
window.setTimeout(window.print, 100);
|
||||
@@ -354,7 +312,7 @@
|
||||
});
|
||||
</script>
|
||||
{{else}}
|
||||
<script>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('load', function() {
|
||||
window.setTimeout(window.print, 100);
|
||||
});
|
||||
@@ -362,21 +320,5 @@
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if fragment_map}}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const fragmentMap =
|
||||
{{{fragment_map}}}
|
||||
;
|
||||
const target = fragmentMap[window.location.hash];
|
||||
if (target) {
|
||||
let url = new URL(target, window.location.href);
|
||||
window.location.replace(url.href);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
222
poetry.lock
generated
222
poetry.lock
generated
@@ -26,15 +26,15 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "authlib"
|
||||
version = "1.6.6"
|
||||
version = "1.6.5"
|
||||
description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients."
|
||||
optional = true
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"jwt\" or extra == \"oidc\""
|
||||
markers = "extra == \"oidc\" or extra == \"jwt\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "authlib-1.6.6-py2.py3-none-any.whl", hash = "sha256:7d9e9bc535c13974313a87f53e8430eb6ea3d1cf6ae4f6efcd793f2e949143fd"},
|
||||
{file = "authlib-1.6.6.tar.gz", hash = "sha256:45770e8e056d0f283451d9996fbb59b70d45722b45d854d58f32878d0a40c38e"},
|
||||
{file = "authlib-1.6.5-py2.py3-none-any.whl", hash = "sha256:3e0e0507807f842b02175507bdee8957a1d5707fd4afb17c32fb43fee90b6e3a"},
|
||||
{file = "authlib-1.6.5.tar.gz", hash = "sha256:6aaf9c79b7cc96c900f0b284061691c5d4e61221640a948fe690b556a6d6d10b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -398,61 +398,66 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "46.0.5"
|
||||
version = "46.0.3"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = false
|
||||
python-versions = "!=3.9.0,!=3.9.1,>=3.8"
|
||||
groups = ["main", "dev"]
|
||||
files = [
|
||||
{file = "cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48"},
|
||||
{file = "cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a"},
|
||||
{file = "cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72"},
|
||||
{file = "cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257"},
|
||||
{file = "cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7"},
|
||||
{file = "cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"},
|
||||
{file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"},
|
||||
{file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"},
|
||||
{file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -466,7 +471,7 @@ nox = ["nox[uv] (>=2024.4.15)"]
|
||||
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"]
|
||||
sdist = ["build (>=1.0.0)"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi (>=2024)", "cryptography-vectors (==46.0.5)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
|
||||
test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
@@ -476,7 +481,7 @@ description = "XML bomb protection for Python stdlib modules"
|
||||
optional = true
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
||||
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
|
||||
@@ -501,7 +506,7 @@ description = "XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and l
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "elementpath-4.1.5-py3-none-any.whl", hash = "sha256:2ac1a2fb31eb22bbbf817f8cf6752f844513216263f0e3892c8e79782fe4bb55"},
|
||||
{file = "elementpath-4.1.5.tar.gz", hash = "sha256:c2d6dc524b29ef751ecfc416b0627668119d8812441c555d7471da41d4bacb8d"},
|
||||
@@ -551,7 +556,7 @@ description = "Python wrapper for hiredis"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"redis\""
|
||||
markers = "extra == \"redis\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "hiredis-3.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:9937d9b69321b393fbace69f55423480f098120bc55a3316e1ca3508c4dbbd6f"},
|
||||
{file = "hiredis-3.3.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:50351b77f89ba6a22aff430b993653847f36b71d444509036baa0f2d79d1ebf4"},
|
||||
@@ -874,7 +879,7 @@ description = "Jaeger Python OpenTracing Tracer implementation"
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"},
|
||||
]
|
||||
@@ -1012,7 +1017,7 @@ description = "A strictly RFC 4510 conforming LDAP V3 pure Python client library
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\""
|
||||
markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"},
|
||||
{file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"},
|
||||
@@ -1114,7 +1119,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"url-preview\""
|
||||
markers = "extra == \"url-preview\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "lxml-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e77dd455b9a16bbd2a5036a63ddbd479c19572af81b624e79ef422f929eef388"},
|
||||
{file = "lxml-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d444858b9f07cefff6455b983aea9a67f7462ba1f6cbe4a21e8bf6791bf2153"},
|
||||
@@ -1400,7 +1405,7 @@ description = "An LDAP3 auth provider for Synapse"
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\""
|
||||
markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "matrix-synapse-ldap3-0.3.0.tar.gz", hash = "sha256:8bb6517173164d4b9cc44f49de411d8cebdb2e705d5dd1ea1f38733c4a009e1d"},
|
||||
{file = "matrix_synapse_ldap3-0.3.0-py3-none-any.whl", hash = "sha256:8b4d701f8702551e98cc1d8c20dbed532de5613584c08d0df22de376ba99159d"},
|
||||
@@ -1643,7 +1648,7 @@ description = "OpenTracing API for Python. See documentation at http://opentraci
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"},
|
||||
]
|
||||
@@ -1833,7 +1838,7 @@ description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
optional = true
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"postgres\""
|
||||
markers = "extra == \"postgres\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "psycopg2-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:103e857f46bb76908768ead4e2d0ba1d1a130e7b8ed77d3ae91e8b33481813e8"},
|
||||
{file = "psycopg2-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:210daed32e18f35e3140a1ebe059ac29209dd96468f2f7559aa59f75ee82a5cb"},
|
||||
@@ -1851,7 +1856,7 @@ description = ".. image:: https://travis-ci.org/chtd/psycopg2cffi.svg?branch=mas
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")"
|
||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")"
|
||||
files = [
|
||||
{file = "psycopg2cffi-2.9.0.tar.gz", hash = "sha256:7e272edcd837de3a1d12b62185eb85c45a19feda9e62fa1b120c54f9e8d35c52"},
|
||||
]
|
||||
@@ -1867,7 +1872,7 @@ description = "A Simple library to enable psycopg2 compatability"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")"
|
||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")"
|
||||
files = [
|
||||
{file = "psycopg2cffi-compat-1.1.tar.gz", hash = "sha256:d25e921748475522b33d13420aad5c2831c743227dc1f1f2585e0fdb5c914e05"},
|
||||
]
|
||||
@@ -1877,14 +1882,14 @@ psycopg2 = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.2"
|
||||
version = "0.6.1"
|
||||
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"},
|
||||
{file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"},
|
||||
{file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"},
|
||||
{file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2149,7 +2154,7 @@ description = "A development tool to measure, monitor and analyze the memory beh
|
||||
optional = true
|
||||
python-versions = ">=3.6"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"cache-memory\""
|
||||
markers = "extra == \"cache-memory\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"},
|
||||
{file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"},
|
||||
@@ -2157,45 +2162,30 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pynacl"
|
||||
version = "1.6.2"
|
||||
version = "1.5.0"
|
||||
description = "Python binding to the Networking and Cryptography (NaCl) library"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.6"
|
||||
groups = ["main", "dev"]
|
||||
files = [
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-macosx_10_10_universal2.whl", hash = "sha256:622d7b07cc5c02c666795792931b50c91f3ce3c2649762efb1ef0d5684c81594"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d071c6a9a4c94d79eb665db4ce5cedc537faf74f2355e4d502591d850d3913c0"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe9847ca47d287af41e82be1dd5e23023d3c31a951da134121ab02e42ac218c9"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04316d1fc625d860b6c162fff704eb8426b1a8bcd3abacea11142cbd99a6b574"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44081faff368d6c5553ccf55322ef2819abb40e25afaec7e740f159f74813634"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:a9f9932d8d2811ce1a8ffa79dcbdf3970e7355b5c8eb0c1a881a57e7f7d96e88"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:bc4a36b28dd72fb4845e5d8f9760610588a96d5a51f01d84d8c6ff9849968c14"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bffb6d0f6becacb6526f8f42adfb5efb26337056ee0831fb9a7044d1a964444"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fef529ef3ee487ad8113d287a593fa26f48ee3620d92ecc6f1d09ea38e0709b"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-win32.whl", hash = "sha256:a84bf1c20339d06dc0c85d9aea9637a24f718f375d861b2668b2f9f96fa51145"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-win_amd64.whl", hash = "sha256:320ef68a41c87547c91a8b58903c9caa641ab01e8512ce291085b5fe2fcb7590"},
|
||||
{file = "pynacl-1.6.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d29bfe37e20e015a7d8b23cfc8bd6aa7909c92a1b8f41ee416bbb3e79ef182b2"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-win32.whl", hash = "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0"},
|
||||
{file = "pynacl-1.6.2-cp38-abi3-win_arm64.whl", hash = "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c"},
|
||||
{file = "pynacl-1.6.2.tar.gz", hash = "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"},
|
||||
{file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cffi = {version = ">=2.0.0", markers = "platform_python_implementation != \"PyPy\" and python_version >= \"3.9\""}
|
||||
cffi = ">=1.4.1"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (<7)", "sphinx_rtd_theme"]
|
||||
tests = ["hypothesis (>=3.27.0)", "pytest (>=7.4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
|
||||
docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"]
|
||||
tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyopenssl"
|
||||
@@ -2281,7 +2271,7 @@ description = "Python implementation of SAML Version 2 Standard"
|
||||
optional = true
|
||||
python-versions = ">=3.9,<4.0"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "pysaml2-7.5.0-py3-none-any.whl", hash = "sha256:bc6627cc344476a83c757f440a73fda1369f13b6fda1b4e16bca63ffbabb5318"},
|
||||
{file = "pysaml2-7.5.0.tar.gz", hash = "sha256:f36871d4e5ee857c6b85532e942550d2cf90ea4ee943d75eb681044bbc4f54f7"},
|
||||
@@ -2306,7 +2296,7 @@ description = "Extensions to the standard Python datetime module"
|
||||
optional = true
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||
@@ -2317,14 +2307,14 @@ six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.22"
|
||||
version = "0.0.20"
|
||||
description = "A streaming multipart parser for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155"},
|
||||
{file = "python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58"},
|
||||
{file = "python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104"},
|
||||
{file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2334,7 +2324,7 @@ description = "World timezone definitions, modern and historical"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"},
|
||||
{file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"},
|
||||
@@ -2738,7 +2728,7 @@ description = "Python client for Sentry (https://sentry.io)"
|
||||
optional = true
|
||||
python-versions = ">=3.6"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"sentry\""
|
||||
markers = "extra == \"sentry\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "sentry_sdk-2.46.0-py2.py3-none-any.whl", hash = "sha256:4eeeb60198074dff8d066ea153fa6f241fef1668c10900ea53a4200abc8da9b1"},
|
||||
{file = "sentry_sdk-2.46.0.tar.gz", hash = "sha256:91821a23460725734b7741523021601593f35731808afc0bb2ba46c27b8acd91"},
|
||||
@@ -2948,7 +2938,7 @@ description = "Tornado IOLoop Backed Concurrent Futures"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"},
|
||||
{file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"},
|
||||
@@ -2964,7 +2954,7 @@ description = "Python bindings for the Apache Thrift RPC system"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "thrift-0.16.0.tar.gz", hash = "sha256:2b5b6488fcded21f9d312aa23c9ff6a0195d0f6ae26ddbd5ad9e3e25dfc14408"},
|
||||
]
|
||||
@@ -3037,7 +3027,7 @@ description = "Tornado is a Python web framework and asynchronous networking lib
|
||||
optional = true
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "tornado-6.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:f81067dad2e4443b015368b24e802d0083fecada4f0a4572fdb72fc06e54a9a6"},
|
||||
{file = "tornado-6.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ac1cbe1db860b3cbb251e795c701c41d343f06a96049d6274e7c77559117e41"},
|
||||
@@ -3171,7 +3161,7 @@ description = "non-blocking redis client for python"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"redis\""
|
||||
markers = "extra == \"redis\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "txredisapi-1.4.11-py3-none-any.whl", hash = "sha256:ac64d7a9342b58edca13ef267d4fa7637c1aa63f8595e066801c1e8b56b22d0b"},
|
||||
{file = "txredisapi-1.4.11.tar.gz", hash = "sha256:3eb1af99aefdefb59eb877b1dd08861efad60915e30ad5bf3d5bf6c5cedcdbc6"},
|
||||
@@ -3382,14 +3372,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.3"
|
||||
version = "2.6.0"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main", "dev"]
|
||||
files = [
|
||||
{file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
|
||||
{file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
|
||||
{file = "urllib3-2.6.0-py3-none-any.whl", hash = "sha256:c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f"},
|
||||
{file = "urllib3-2.6.0.tar.gz", hash = "sha256:cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -3417,7 +3407,7 @@ description = "An XML Schema validator and decoder"
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"all\" or extra == \"saml2\""
|
||||
markers = "extra == \"saml2\" or extra == \"all\""
|
||||
files = [
|
||||
{file = "xmlschema-2.4.0-py3-none-any.whl", hash = "sha256:dc87be0caaa61f42649899189aab2fd8e0d567f2cf548433ba7b79278d231a4a"},
|
||||
{file = "xmlschema-2.4.0.tar.gz", hash = "sha256:d74cd0c10866ac609e1ef94a5a69b018ad16e39077bc6393408b40c6babee793"},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "matrix-synapse"
|
||||
version = "1.148.0"
|
||||
version = "1.144.0"
|
||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||
readme = "README.rst"
|
||||
authors = [
|
||||
@@ -415,32 +415,28 @@ line-ending = "auto"
|
||||
manifest-path = "rust/Cargo.toml"
|
||||
module-name = "synapse.synapse_rust"
|
||||
python-source = "."
|
||||
include = [
|
||||
{ path = "AUTHORS.rst", format = "sdist" },
|
||||
{ path = "book.toml", format = "sdist" },
|
||||
{ path = "changelog.d/**/*", format = "sdist" },
|
||||
{ path = "CHANGES.md", format = "sdist" },
|
||||
{ path = "CONTRIBUTING.md", format = "sdist" },
|
||||
{ path = "demo/**/*", format = "sdist" },
|
||||
{ path = "docs/**/*", format = "sdist" },
|
||||
{ path = "INSTALL.md", format = "sdist" },
|
||||
{ path = "LICENSE-AGPL-3.0", format = "sdist" },
|
||||
{ path = "LICENSE-COMMERCIAL", format = "sdist" },
|
||||
{ path = "mypy.ini", format = "sdist" },
|
||||
{ path = "scripts-dev/**/*", format = "sdist" },
|
||||
{ path = "synmark/**/*", format = "sdist" },
|
||||
{ path = "sytest-blacklist", format = "sdist" },
|
||||
{ path = "tests/**/*", format = "sdist" },
|
||||
{ path = "UPGRADE.rst", format = "sdist" },
|
||||
{ path = "Cargo.toml", format = "sdist" },
|
||||
{ path = "Cargo.lock", format = "sdist" },
|
||||
{ path = "rust/Cargo.toml", format = "sdist" },
|
||||
{ path = "rust/build.rs", format = "sdist" },
|
||||
{ path = "rust/src/**", format = "sdist" },
|
||||
]
|
||||
exclude = [
|
||||
{ path = "synapse/*.so", format = "sdist" },
|
||||
sdist-include = [
|
||||
"AUTHORS.rst",
|
||||
"book.toml",
|
||||
"changelog.d",
|
||||
"CHANGES.md",
|
||||
"CONTRIBUTING.md",
|
||||
"demo",
|
||||
"docs",
|
||||
"INSTALL.md",
|
||||
"mypy.ini",
|
||||
"scripts-dev",
|
||||
"synmark",
|
||||
"sytest-blacklist",
|
||||
"tests",
|
||||
"UPGRADE.rst",
|
||||
"Cargo.toml",
|
||||
"Cargo.lock",
|
||||
"rust/Cargo.toml",
|
||||
"rust/build.rs",
|
||||
"rust/src/**",
|
||||
]
|
||||
sdist-exclude = ["synapse/*.so"]
|
||||
|
||||
[build-system]
|
||||
# The upper bounds here are defensive, intended to prevent situations like
|
||||
|
||||
@@ -30,14 +30,14 @@ http = "1.1.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.17"
|
||||
mime = "0.3.17"
|
||||
pyo3 = { version = "0.27.2", features = [
|
||||
pyo3 = { version = "0.26.0", features = [
|
||||
"macros",
|
||||
"anyhow",
|
||||
"abi3",
|
||||
"abi3-py310",
|
||||
] }
|
||||
pyo3-log = "0.13.1"
|
||||
pythonize = "0.27.0"
|
||||
pythonize = "0.26.0"
|
||||
regex = "1.6.0"
|
||||
sha2 = "0.10.8"
|
||||
serde = { version = "1.0.144", features = ["derive"] }
|
||||
|
||||
@@ -29,13 +29,6 @@ fn main() -> Result<(), std::io::Error> {
|
||||
}
|
||||
}
|
||||
|
||||
// Manually add Cargo.toml's, Cargo.lock and build.rs to the hash, since changes to
|
||||
// these files should also invalidate the built module.
|
||||
paths.push("Cargo.toml".to_string());
|
||||
paths.push("../Cargo.lock".to_string());
|
||||
paths.push("../Cargo.toml".to_string());
|
||||
paths.push("build.rs".to_string());
|
||||
|
||||
paths.sort();
|
||||
|
||||
let mut hasher = Blake2b512::new();
|
||||
@@ -48,12 +41,5 @@ fn main() -> Result<(), std::io::Error> {
|
||||
let hex_digest = hex::encode(hasher.finalize());
|
||||
println!("cargo:rustc-env=SYNAPSE_RUST_DIGEST={hex_digest}");
|
||||
|
||||
// The default rules don't pick up trivial changes to the workspace config
|
||||
// files, but we need to rebuild if those change to pick up the changed
|
||||
// hashes.
|
||||
println!("cargo::rerun-if-changed=.");
|
||||
println!("cargo::rerun-if-changed=../Cargo.lock");
|
||||
println!("cargo::rerun-if-changed=../Cargo.toml");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ fn read_io_body(body: &Bound<'_, PyAny>, chunk_size: usize) -> PyResult<Bytes> {
|
||||
let mut buf = BytesMut::new();
|
||||
loop {
|
||||
let bound = &body.call_method1("read", (chunk_size,))?;
|
||||
let bytes: &Bound<'_, PyBytes> = bound.cast()?;
|
||||
let bytes: &Bound<'_, PyBytes> = bound.downcast()?;
|
||||
if bytes.as_bytes().is_empty() {
|
||||
return Ok(buf.into());
|
||||
}
|
||||
@@ -58,12 +58,12 @@ pub fn http_request_from_twisted(request: &Bound<'_, PyAny>) -> PyResult<Request
|
||||
let mut req = Request::new(body);
|
||||
|
||||
let bound = &request.getattr("uri")?;
|
||||
let uri: &Bound<'_, PyBytes> = bound.cast()?;
|
||||
let uri: &Bound<'_, PyBytes> = bound.downcast()?;
|
||||
*req.uri_mut() =
|
||||
Uri::try_from(uri.as_bytes()).map_err(|_| PyValueError::new_err("invalid uri"))?;
|
||||
|
||||
let bound = &request.getattr("method")?;
|
||||
let method: &Bound<'_, PyBytes> = bound.cast()?;
|
||||
let method: &Bound<'_, PyBytes> = bound.downcast()?;
|
||||
*req.method_mut() = Method::from_bytes(method.as_bytes())
|
||||
.map_err(|_| PyValueError::new_err("invalid method"))?;
|
||||
|
||||
@@ -74,17 +74,17 @@ pub fn http_request_from_twisted(request: &Bound<'_, PyAny>) -> PyResult<Request
|
||||
|
||||
for header in headers_iter {
|
||||
let header = header?;
|
||||
let header: &Bound<'_, PyTuple> = header.cast()?;
|
||||
let header: &Bound<'_, PyTuple> = header.downcast()?;
|
||||
let bound = &header.get_item(0)?;
|
||||
let name: &Bound<'_, PyBytes> = bound.cast()?;
|
||||
let name: &Bound<'_, PyBytes> = bound.downcast()?;
|
||||
let name = HeaderName::from_bytes(name.as_bytes())
|
||||
.map_err(|_| PyValueError::new_err("invalid header name"))?;
|
||||
|
||||
let bound = &header.get_item(1)?;
|
||||
let values: &Bound<'_, PySequence> = bound.cast()?;
|
||||
let values: &Bound<'_, PySequence> = bound.downcast()?;
|
||||
for index in 0..values.len()? {
|
||||
let bound = &values.get_item(index)?;
|
||||
let value: &Bound<'_, PyBytes> = bound.cast()?;
|
||||
let value: &Bound<'_, PyBytes> = bound.downcast()?;
|
||||
let value = HeaderValue::from_bytes(value.as_bytes())
|
||||
.map_err(|_| PyValueError::new_err("invalid header value"))?;
|
||||
req.headers_mut().append(name.clone(), value);
|
||||
|
||||
@@ -171,27 +171,15 @@ struct HttpClient {
|
||||
#[pymethods]
|
||||
impl HttpClient {
|
||||
#[new]
|
||||
#[pyo3(signature = (reactor, user_agent, http2_only = false))]
|
||||
pub fn py_new(
|
||||
reactor: Bound<PyAny>,
|
||||
user_agent: &str,
|
||||
http2_only: bool,
|
||||
) -> PyResult<HttpClient> {
|
||||
pub fn py_new(reactor: Bound<PyAny>, user_agent: &str) -> PyResult<HttpClient> {
|
||||
// Make sure the runtime gets installed
|
||||
let _ = runtime(&reactor)?;
|
||||
|
||||
let mut builder = reqwest::Client::builder().user_agent(user_agent);
|
||||
|
||||
if http2_only {
|
||||
// Create the client with 'HTTP/2 prior knowledge' enabled, which
|
||||
// means it will always use HTTP/2 for unencrypted connections
|
||||
builder = builder.http2_prior_knowledge();
|
||||
}
|
||||
|
||||
let client = builder.build().context("building reqwest client")?;
|
||||
|
||||
Ok(HttpClient {
|
||||
client,
|
||||
client: reqwest::Client::builder()
|
||||
.user_agent(user_agent)
|
||||
.build()
|
||||
.context("building reqwest client")?,
|
||||
reactor: reactor.unbind(),
|
||||
})
|
||||
}
|
||||
@@ -328,8 +316,5 @@ fn make_deferred_yieldable<'py>(
|
||||
func
|
||||
});
|
||||
|
||||
make_deferred_yieldable
|
||||
.call1(py, (deferred,))?
|
||||
.extract(py)
|
||||
.map_err(Into::into)
|
||||
make_deferred_yieldable.call1(py, (deferred,))?.extract(py)
|
||||
}
|
||||
|
||||
@@ -273,16 +273,14 @@ pub enum SimpleJsonValue {
|
||||
Null,
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'_, 'source> for SimpleJsonValue {
|
||||
type Error = PyErr;
|
||||
|
||||
fn extract(ob: Borrowed<'_, 'source, PyAny>) -> Result<Self, Self::Error> {
|
||||
if let Ok(s) = ob.cast::<PyString>() {
|
||||
impl<'source> FromPyObject<'source> for SimpleJsonValue {
|
||||
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
|
||||
if let Ok(s) = ob.downcast::<PyString>() {
|
||||
Ok(SimpleJsonValue::Str(Cow::Owned(s.to_string())))
|
||||
// A bool *is* an int, ensure we try bool first.
|
||||
} else if let Ok(b) = ob.cast::<PyBool>() {
|
||||
} else if let Ok(b) = ob.downcast::<PyBool>() {
|
||||
Ok(SimpleJsonValue::Bool(b.extract()?))
|
||||
} else if let Ok(i) = ob.cast::<PyInt>() {
|
||||
} else if let Ok(i) = ob.downcast::<PyInt>() {
|
||||
Ok(SimpleJsonValue::Int(i.extract()?))
|
||||
} else if ob.is_none() {
|
||||
Ok(SimpleJsonValue::Null)
|
||||
@@ -303,14 +301,12 @@ pub enum JsonValue {
|
||||
Value(SimpleJsonValue),
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'_, 'source> for JsonValue {
|
||||
type Error = PyErr;
|
||||
|
||||
fn extract(ob: Borrowed<'_, 'source, PyAny>) -> Result<Self, Self::Error> {
|
||||
if let Ok(l) = ob.cast::<PyList>() {
|
||||
impl<'source> FromPyObject<'source> for JsonValue {
|
||||
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
|
||||
if let Ok(l) = ob.downcast::<PyList>() {
|
||||
match l
|
||||
.iter()
|
||||
.map(|it| SimpleJsonValue::extract(it.as_borrowed()))
|
||||
.map(|it| SimpleJsonValue::extract_bound(&it))
|
||||
.collect()
|
||||
{
|
||||
Ok(a) => Ok(JsonValue::Array(a)),
|
||||
@@ -318,7 +314,7 @@ impl<'source> FromPyObject<'_, 'source> for JsonValue {
|
||||
"Can't convert to JsonValue::Array: {e}"
|
||||
))),
|
||||
}
|
||||
} else if let Ok(v) = SimpleJsonValue::extract(ob) {
|
||||
} else if let Ok(v) = SimpleJsonValue::extract_bound(ob) {
|
||||
Ok(JsonValue::Value(v))
|
||||
} else {
|
||||
Err(PyTypeError::new_err(format!(
|
||||
@@ -389,11 +385,9 @@ impl<'source> IntoPyObject<'source> for Condition {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'_, 'source> for Condition {
|
||||
type Error = PyErr;
|
||||
|
||||
fn extract(ob: Borrowed<'_, 'source, PyAny>) -> Result<Self, Self::Error> {
|
||||
Ok(depythonize(&ob)?)
|
||||
impl<'source> FromPyObject<'source> for Condition {
|
||||
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
|
||||
Ok(depythonize(ob)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
$schema: https://element-hq.github.io/synapse/latest/schema/v1/meta.schema.json
|
||||
$id: https://element-hq.github.io/synapse/schema/synapse/v1.148/synapse-config.schema.json
|
||||
$id: https://element-hq.github.io/synapse/schema/synapse/v1.144/synapse-config.schema.json
|
||||
type: object
|
||||
properties:
|
||||
modules:
|
||||
@@ -1113,11 +1113,8 @@ properties:
|
||||
When this option is enabled, the room "complexity" will be checked before
|
||||
a user joins a new remote room. If it is above the complexity limit, the
|
||||
server will disallow joining, or will instantly leave. This is useful for
|
||||
homeservers that are resource-constrained. In Synapse, the complexity of a
|
||||
room is measured by the number of current state events in a room, divided
|
||||
by 500. "Current" here means the latest state, i.e. if a user joins, then
|
||||
leaves, then joins, that will count as 1 current `m.room.member` state
|
||||
event.
|
||||
homeservers that are resource-constrained. Room complexity is an arbitrary
|
||||
measure based on factors such as the number of users in the room.
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
@@ -2277,16 +2274,6 @@ properties:
|
||||
examples:
|
||||
- per_second: 1.0
|
||||
burst_count: 5.0
|
||||
rc_user_directory:
|
||||
$ref: "#/$defs/rc"
|
||||
description: >-
|
||||
This option allows admins to ratelimit searches in the user directory.
|
||||
|
||||
|
||||
_Added in Synapse 1.145.0._
|
||||
default:
|
||||
per_second: 0.016
|
||||
burst_count: 200.0
|
||||
federation_rr_transactions_per_room_per_second:
|
||||
type: integer
|
||||
description: >-
|
||||
@@ -2351,19 +2338,6 @@ properties:
|
||||
default: true
|
||||
examples:
|
||||
- false
|
||||
enable_local_media_storage:
|
||||
type: boolean
|
||||
description: >-
|
||||
Enable the local on-disk media storage provider. When disabled, media is
|
||||
stored only in configured `media_storage_providers` and temporary files are
|
||||
used for processing.
|
||||
|
||||
**Warning:** If this option is set to `false` and no `media_storage_providers`
|
||||
are configured, all media requests will return 404 errors as there will be
|
||||
no storage backend available.
|
||||
default: true
|
||||
examples:
|
||||
- false
|
||||
media_store_path:
|
||||
type: string
|
||||
description: Directory where uploaded images and attachments are stored.
|
||||
|
||||
@@ -31,7 +31,7 @@ DISTS = (
|
||||
"debian:sid", # (rolling distro, no EOL)
|
||||
"ubuntu:jammy", # 22.04 LTS (EOL 2027-04) (our EOL forced by Python 3.10 is 2026-10-04)
|
||||
"ubuntu:noble", # 24.04 LTS (EOL 2029-06)
|
||||
"ubuntu:questing", # 25.10 (EOL 2026-07)
|
||||
"ubuntu:plucky", # 25.04 (EOL 2026-01)
|
||||
"debian:trixie", # (EOL not specified yet)
|
||||
)
|
||||
|
||||
@@ -94,7 +94,6 @@ class Builder:
|
||||
build_args = (
|
||||
(
|
||||
"docker",
|
||||
"buildx",
|
||||
"build",
|
||||
"--tag",
|
||||
"dh-venv-builder:" + tag,
|
||||
|
||||
@@ -187,14 +187,6 @@ def check_schema_delta(delta_files: list[str], force_colors: bool) -> bool:
|
||||
sql_lang = "postgres"
|
||||
if delta_file.endswith(".sqlite"):
|
||||
sql_lang = "sqlite"
|
||||
elif delta_file.endswith(".py"):
|
||||
click.secho(
|
||||
f"Skipping Python delta file: '{delta_file}'",
|
||||
fg="yellow",
|
||||
bold=True,
|
||||
color=force_colors,
|
||||
)
|
||||
return True
|
||||
|
||||
statements = sqlglot.parse(delta_contents, read=sql_lang)
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@ usage() {
|
||||
cat >&2 <<EOF
|
||||
Usage: $0 [-f] <go test arguments>...
|
||||
Run the complement test suite on Synapse.
|
||||
--in-repo
|
||||
Whether to run the in-repo suite of Complement tests (see `./complement` in this project)
|
||||
vs the Complement tests from the Complement repo.
|
||||
|
||||
-f, --fast
|
||||
Skip rebuilding the docker images, and just use the most recent
|
||||
@@ -85,7 +82,6 @@ main() {
|
||||
# parse our arguments
|
||||
skip_docker_build=""
|
||||
skip_complement_run=""
|
||||
use_in_repo_tests=""
|
||||
while [ $# -ge 1 ]; do
|
||||
arg=$1
|
||||
case "$arg" in
|
||||
@@ -93,9 +89,6 @@ main() {
|
||||
usage
|
||||
return 1
|
||||
;;
|
||||
"--in-repo")
|
||||
use_in_repo_tests=1
|
||||
;;
|
||||
"-f"|"--fast")
|
||||
skip_docker_build=1
|
||||
;;
|
||||
@@ -223,10 +216,7 @@ main() {
|
||||
echo "Skipping Docker image build as requested."
|
||||
fi
|
||||
|
||||
# Default set of Complement tests to run from the Complement repo
|
||||
#
|
||||
# We pick and choose the specific MSC's that Synapse supports.
|
||||
default_complement_test_packages=(
|
||||
test_packages=(
|
||||
./tests/csapi
|
||||
./tests
|
||||
./tests/msc3874
|
||||
@@ -243,15 +233,7 @@ main() {
|
||||
|
||||
# Export the list of test packages as a space-separated environment variable, so other
|
||||
# scripts can use it.
|
||||
export SYNAPSE_SUPPORTED_COMPLEMENT_TEST_PACKAGES="${default_complement_test_packages[@]}"
|
||||
|
||||
# Default set of Complement tests to run when using the in-repo test suite. Most
|
||||
# likely, this should be all tests.
|
||||
#
|
||||
# Relative to the `./complement` repo in this project
|
||||
default_in_repo_complement_test_packages=(
|
||||
./tests/...
|
||||
)
|
||||
export SYNAPSE_SUPPORTED_COMPLEMENT_TEST_PACKAGES="${test_packages[@]}"
|
||||
|
||||
export COMPLEMENT_BASE_IMAGE=complement-synapse
|
||||
if [ -n "$use_editable_synapse" ]; then
|
||||
@@ -334,26 +316,11 @@ main() {
|
||||
echo "Skipping Complement run as requested."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Print out the executed commands so it's more obvious what's happening at the end here.
|
||||
# Things are slightly ambiguous with the in-repo vs Complement tests.
|
||||
set -x
|
||||
|
||||
if [ -n "$use_in_repo_tests" ]; then
|
||||
# Run the suite of Complement tests in the `./complement` directory in this repo
|
||||
cd "./complement"
|
||||
go test "${test_args[@]}" "$@" "${default_in_repo_complement_test_packages[@]}"
|
||||
else
|
||||
# Run the tests (from the Complement repo)!
|
||||
cd "$COMPLEMENT_DIR"
|
||||
go test "${test_args[@]}" "$@" "${default_complement_test_packages[@]}"
|
||||
fi
|
||||
|
||||
# We don't need to print out executed commands anymore
|
||||
#
|
||||
# This is just `set +x` without printing `+ set +x` to the console (via
|
||||
# https://stackoverflow.com/questions/13195655/bash-set-x-without-it-being-printed/19226038#19226038)
|
||||
{ set +x; } 2>/dev/null
|
||||
# Run the tests!
|
||||
echo "Running Complement with ${test_args[@]} $@ ${test_packages[@]}"
|
||||
cd "$COMPLEMENT_DIR"
|
||||
go test "${test_args[@]}" "$@" "${test_packages[@]}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -139,14 +139,3 @@ mypy
|
||||
|
||||
# Generate configuration documentation from the JSON Schema
|
||||
./scripts-dev/gen_config_documentation.py schema/synapse-config.schema.yaml > docs/usage/configuration/config_documentation.md
|
||||
|
||||
# Lint/format the in-repo Complement test code (Go)
|
||||
pushd ./complement
|
||||
# Run golangci-lint with:
|
||||
# - The `run` command will lint the code
|
||||
# - `--fix`: Will apply any suggested fixes like autofixes from `linters` *and*
|
||||
# `formatters` which always produce suggested fixes that are equivalent to running
|
||||
# `golangci-lint fmt`.
|
||||
# - `--max-issues-per-linter=0`: Show all issues, don't limit the number reported
|
||||
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.1 run ./... --fix --max-issues-per-linter=0
|
||||
popd
|
||||
|
||||
@@ -133,7 +133,6 @@ prometheus_metric_fullname_to_label_arg_map: Mapping[str, ArgLocation | None] =
|
||||
"prometheus_client.metrics.Info": ArgLocation("labelnames", 2),
|
||||
"prometheus_client.metrics.Enum": ArgLocation("labelnames", 2),
|
||||
"synapse.metrics.LaterGauge": ArgLocation("labelnames", 2),
|
||||
"synapse.metrics._InFlightGaugeRuntime": ArgLocation("labels", 2),
|
||||
"synapse.metrics.InFlightGauge": ArgLocation("labels", 2),
|
||||
"synapse.metrics.GaugeBucketCollector": ArgLocation("labelnames", 2),
|
||||
"prometheus_client.registry.Collector": None,
|
||||
|
||||
@@ -455,19 +455,19 @@ def _publish(gh_token: str) -> None:
|
||||
gh = Github(auth=github.Auth.Token(token=gh_token))
|
||||
gh_repo = gh.get_repo("element-hq/synapse")
|
||||
for release in gh_repo.get_releases():
|
||||
if release.name == tag_name:
|
||||
if release.title == tag_name:
|
||||
break
|
||||
else:
|
||||
raise ClickException(f"Failed to find GitHub release for {tag_name}")
|
||||
|
||||
assert release.name == tag_name
|
||||
assert release.title == tag_name
|
||||
|
||||
if not release.draft:
|
||||
click.echo("Release already published.")
|
||||
return
|
||||
|
||||
release = release.update_release(
|
||||
name=release.name,
|
||||
name=release.title,
|
||||
message=release.body,
|
||||
tag_name=release.tag_name,
|
||||
prerelease=release.prerelease,
|
||||
|
||||
@@ -172,7 +172,7 @@ if __name__ == "__main__":
|
||||
# Expect JSON data on stdin.
|
||||
context, book = json.load(sys.stdin)
|
||||
|
||||
for section in book["items"]:
|
||||
for section in book["sections"]:
|
||||
if "Chapter" in section and section["Chapter"]["path"] == "upgrade.md":
|
||||
section["Chapter"]["content"] = section["Chapter"]["content"].replace(
|
||||
"<!-- REPLACE_WITH_SCHEMA_VERSIONS -->", calculate_version_chart()
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
"""Contains constants from the specification."""
|
||||
|
||||
import enum
|
||||
from typing import Final, TypedDict
|
||||
|
||||
from synapse.util.duration import Duration
|
||||
from typing import Final
|
||||
|
||||
# the max size of a (canonical-json-encoded) event
|
||||
MAX_PDU_SIZE = 65536
|
||||
@@ -294,8 +292,6 @@ class EventUnsignedContentFields:
|
||||
# Requesting user's membership, per MSC4115
|
||||
MEMBERSHIP: Final = "membership"
|
||||
|
||||
STICKY_TTL: Final = "msc4354_sticky_duration_ttl_ms"
|
||||
|
||||
|
||||
class MTextFields:
|
||||
"""Fields found inside m.text content blocks."""
|
||||
@@ -381,40 +377,3 @@ class Direction(enum.Enum):
|
||||
class ProfileFields:
|
||||
DISPLAYNAME: Final = "displayname"
|
||||
AVATAR_URL: Final = "avatar_url"
|
||||
|
||||
|
||||
class StickyEventField(TypedDict):
|
||||
"""
|
||||
Dict content of the `sticky` part of an event.
|
||||
"""
|
||||
|
||||
duration_ms: int
|
||||
|
||||
|
||||
class StickyEvent:
|
||||
QUERY_PARAM_NAME: Final = "org.matrix.msc4354.sticky_duration_ms"
|
||||
"""
|
||||
Query parameter used by clients for setting the sticky duration of an event they are sending.
|
||||
|
||||
Applies to:
|
||||
- /rooms/.../send/...
|
||||
- /rooms/.../state/...
|
||||
"""
|
||||
|
||||
EVENT_FIELD_NAME: Final = "msc4354_sticky"
|
||||
"""
|
||||
Name of the field in the top-level event dict that contains the sticky event dict.
|
||||
"""
|
||||
|
||||
MAX_DURATION: Duration = Duration(hours=1)
|
||||
"""
|
||||
Maximum stickiness duration as specified in MSC4354.
|
||||
Ensures that data in the /sync response can go down and not grow unbounded.
|
||||
"""
|
||||
|
||||
MAX_EVENTS_IN_SYNC: Final = 100
|
||||
"""
|
||||
Maximum number of sticky events to include in /sync.
|
||||
|
||||
This is the default specified in the MSC. Chosen arbitrarily.
|
||||
"""
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#
|
||||
#
|
||||
|
||||
from typing import Callable
|
||||
|
||||
import attr
|
||||
|
||||
@@ -495,3 +496,40 @@ KNOWN_ROOM_VERSIONS: dict[str, RoomVersion] = {
|
||||
RoomVersions.HydraV11,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||
class RoomVersionCapability:
|
||||
"""An object which describes the unique attributes of a room version."""
|
||||
|
||||
identifier: str # the identifier for this capability
|
||||
preferred_version: RoomVersion | None
|
||||
support_check_lambda: Callable[[RoomVersion], bool]
|
||||
|
||||
|
||||
MSC3244_CAPABILITIES = {
|
||||
cap.identifier: {
|
||||
"preferred": (
|
||||
cap.preferred_version.identifier
|
||||
if cap.preferred_version is not None
|
||||
else None
|
||||
),
|
||||
"support": [
|
||||
v.identifier
|
||||
for v in KNOWN_ROOM_VERSIONS.values()
|
||||
if cap.support_check_lambda(v)
|
||||
],
|
||||
}
|
||||
for cap in (
|
||||
RoomVersionCapability(
|
||||
"knock",
|
||||
RoomVersions.V7,
|
||||
lambda room_version: room_version.knock_join_rule,
|
||||
),
|
||||
RoomVersionCapability(
|
||||
"restricted",
|
||||
RoomVersions.V9,
|
||||
lambda room_version: room_version.restricted_join_rule,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,9 +54,7 @@ def check_bind_error(
|
||||
"""
|
||||
if address == "0.0.0.0" and "::" in bind_addresses:
|
||||
logger.warning(
|
||||
"Failed to listen on 0.0.0.0, continuing because listening on [::]. Original exception: %s: %s",
|
||||
type(e).__name__,
|
||||
str(e),
|
||||
"Failed to listen on 0.0.0.0, continuing because listening on [::]"
|
||||
)
|
||||
else:
|
||||
raise e
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#
|
||||
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||
#
|
||||
# Copyright (C) 2026 New Vector, Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# See the GNU Affero General Public License for more details:
|
||||
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||
#
|
||||
# [This file includes modifications made by New Vector Limited]
|
||||
#
|
||||
#
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
class ProxiedReactor:
|
||||
"""
|
||||
Twisted tracks the 'installed' reactor as a global variable.
|
||||
(Actually, it does some module trickery, but the effect is similar.)
|
||||
|
||||
The default EpollReactor is buggy if it's created before a process is
|
||||
forked, then used in the child.
|
||||
See https://twistedmatrix.com/trac/ticket/4759#comment:17.
|
||||
|
||||
However, importing certain Twisted modules will automatically create and
|
||||
install a reactor if one hasn't already been installed.
|
||||
It's not normally possible to re-install a reactor.
|
||||
|
||||
Given the goal of launching workers with fork() to only import the code once,
|
||||
this presents a conflict.
|
||||
Our work around is to 'install' this ProxiedReactor which prevents Twisted
|
||||
from creating and installing one, but which lets us replace the actual reactor
|
||||
in use later on.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.___reactor_target: Any = None
|
||||
|
||||
def _install_real_reactor(self, new_reactor: Any) -> None:
|
||||
"""
|
||||
Install a real reactor for this ProxiedReactor to forward lookups onto.
|
||||
|
||||
This method is specific to our ProxiedReactor and should not clash with
|
||||
any names used on an actual Twisted reactor.
|
||||
"""
|
||||
self.___reactor_target = new_reactor
|
||||
|
||||
# Import here to avoid circular imports.
|
||||
from synapse.metrics._reactor_metrics import install_reactor_metrics
|
||||
|
||||
# Install reactor metrics now we've got a real reactor.
|
||||
install_reactor_metrics(new_reactor)
|
||||
|
||||
def __getattr__(self, attr_name: str) -> Any:
|
||||
return getattr(self.___reactor_target, attr_name)
|
||||
@@ -30,13 +30,47 @@ from typing import Any, Callable
|
||||
|
||||
from twisted.internet.main import installReactor
|
||||
|
||||
from synapse.app.complement_fork_proxied_reactor import ProxiedReactor
|
||||
|
||||
# a list of the original signal handlers, before we installed our custom ones.
|
||||
# We restore these in our child processes.
|
||||
_original_signal_handlers: dict[int, Any] = {}
|
||||
|
||||
|
||||
class ProxiedReactor:
|
||||
"""
|
||||
Twisted tracks the 'installed' reactor as a global variable.
|
||||
(Actually, it does some module trickery, but the effect is similar.)
|
||||
|
||||
The default EpollReactor is buggy if it's created before a process is
|
||||
forked, then used in the child.
|
||||
See https://twistedmatrix.com/trac/ticket/4759#comment:17.
|
||||
|
||||
However, importing certain Twisted modules will automatically create and
|
||||
install a reactor if one hasn't already been installed.
|
||||
It's not normally possible to re-install a reactor.
|
||||
|
||||
Given the goal of launching workers with fork() to only import the code once,
|
||||
this presents a conflict.
|
||||
Our work around is to 'install' this ProxiedReactor which prevents Twisted
|
||||
from creating and installing one, but which lets us replace the actual reactor
|
||||
in use later on.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.___reactor_target: Any = None
|
||||
|
||||
def _install_real_reactor(self, new_reactor: Any) -> None:
|
||||
"""
|
||||
Install a real reactor for this ProxiedReactor to forward lookups onto.
|
||||
|
||||
This method is specific to our ProxiedReactor and should not clash with
|
||||
any names used on an actual Twisted reactor.
|
||||
"""
|
||||
self.___reactor_target = new_reactor
|
||||
|
||||
def __getattr__(self, attr_name: str) -> Any:
|
||||
return getattr(self.___reactor_target, attr_name)
|
||||
|
||||
|
||||
def _worker_entrypoint(
|
||||
func: Callable[[], None], proxy_reactor: ProxiedReactor, args: list[str]
|
||||
) -> None:
|
||||
|
||||
@@ -102,7 +102,6 @@ from synapse.storage.databases.main.signatures import SignatureWorkerStore
|
||||
from synapse.storage.databases.main.sliding_sync import SlidingSyncStore
|
||||
from synapse.storage.databases.main.state import StateGroupWorkerStore
|
||||
from synapse.storage.databases.main.stats import StatsStore
|
||||
from synapse.storage.databases.main.sticky_events import StickyEventsWorkerStore
|
||||
from synapse.storage.databases.main.stream import StreamWorkerStore
|
||||
from synapse.storage.databases.main.tags import TagsWorkerStore
|
||||
from synapse.storage.databases.main.task_scheduler import TaskSchedulerWorkerStore
|
||||
@@ -138,7 +137,6 @@ class GenericWorkerStore(
|
||||
RoomWorkerStore,
|
||||
DirectoryWorkerStore,
|
||||
ThreadSubscriptionsWorkerStore,
|
||||
StickyEventsWorkerStore,
|
||||
PushRulesWorkerStore,
|
||||
ApplicationServiceTransactionWorkerStore,
|
||||
ApplicationServiceWorkerStore,
|
||||
|
||||
@@ -44,7 +44,6 @@ import jinja2
|
||||
import yaml
|
||||
|
||||
from synapse.types import StrSequence
|
||||
from synapse.util.stringutils import parse_and_validate_server_name
|
||||
from synapse.util.templates import _create_mxc_to_http_filter, _format_ts_filter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -466,7 +465,6 @@ class RootConfig:
|
||||
generate_secrets: bool = False,
|
||||
report_stats: bool | None = None,
|
||||
open_private_ports: bool = False,
|
||||
enable_metrics: bool = False,
|
||||
listeners: list[dict] | None = None,
|
||||
tls_certificate_path: str | None = None,
|
||||
tls_private_key_path: str | None = None,
|
||||
@@ -497,15 +495,9 @@ class RootConfig:
|
||||
open_private_ports: True to leave private ports (such as the non-TLS
|
||||
HTTP listener) open to the internet.
|
||||
|
||||
enable_metrics: True to set `enable_metrics: true` and when using the
|
||||
default set of listeners, will also add the metrics listener on port 19090.
|
||||
|
||||
listeners: A list of descriptions of the listeners synapse should
|
||||
start with each of which specifies a port (int), a list of resources
|
||||
(list(str)), tls (bool) and type (str). There is a default set of
|
||||
listeners when `None`.
|
||||
|
||||
Example usage:
|
||||
start with each of which specifies a port (int), a list of
|
||||
resources (list(str)), tls (bool) and type (str). For example:
|
||||
[{
|
||||
"port": 8448,
|
||||
"resources": [{"names": ["federation"]}],
|
||||
@@ -526,35 +518,6 @@ class RootConfig:
|
||||
Returns:
|
||||
The yaml config file
|
||||
"""
|
||||
_, bind_port = parse_and_validate_server_name(server_name)
|
||||
if bind_port is not None:
|
||||
unsecure_port = bind_port - 400
|
||||
else:
|
||||
bind_port = 8448
|
||||
unsecure_port = 8008
|
||||
|
||||
# The default listeners
|
||||
if listeners is None:
|
||||
listeners = [
|
||||
{
|
||||
"port": unsecure_port,
|
||||
"tls": False,
|
||||
"type": "http",
|
||||
"x_forwarded": True,
|
||||
"resources": [
|
||||
{"names": ["client", "federation"], "compress": False}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
if enable_metrics:
|
||||
listeners.append(
|
||||
{
|
||||
"port": 19090,
|
||||
"tls": False,
|
||||
"type": "metrics",
|
||||
}
|
||||
)
|
||||
|
||||
conf = CONFIG_FILE_HEADER + "\n".join(
|
||||
dedent(conf)
|
||||
@@ -566,7 +529,6 @@ class RootConfig:
|
||||
generate_secrets=generate_secrets,
|
||||
report_stats=report_stats,
|
||||
open_private_ports=open_private_ports,
|
||||
enable_metrics=enable_metrics,
|
||||
listeners=listeners,
|
||||
tls_certificate_path=tls_certificate_path,
|
||||
tls_private_key_path=tls_private_key_path,
|
||||
@@ -794,14 +756,6 @@ class RootConfig:
|
||||
" internet. Do not use this unless you know what you are doing."
|
||||
),
|
||||
)
|
||||
generate_group.add_argument(
|
||||
"--enable-metrics",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Sets `enable_metrics: true` and when using the default set of listeners, "
|
||||
"will also add the metrics listener on port 19090."
|
||||
),
|
||||
)
|
||||
|
||||
cls.invoke_all_static("add_arguments", parser)
|
||||
config_args = parser.parse_args(argv_options)
|
||||
@@ -858,7 +812,6 @@ class RootConfig:
|
||||
report_stats=(config_args.report_stats == "yes"),
|
||||
generate_secrets=True,
|
||||
open_private_ports=config_args.open_private_ports,
|
||||
enable_metrics=config_args.enable_metrics,
|
||||
)
|
||||
|
||||
os.makedirs(config_dir_path, exist_ok=True)
|
||||
|
||||
@@ -146,7 +146,6 @@ class RootConfig:
|
||||
generate_secrets: bool = ...,
|
||||
report_stats: bool | None = ...,
|
||||
open_private_ports: bool = ...,
|
||||
enable_metrics: bool = ...,
|
||||
listeners: Any | None = ...,
|
||||
tls_certificate_path: str | None = ...,
|
||||
tls_private_key_path: str | None = ...,
|
||||
|
||||
@@ -366,11 +366,7 @@ class MSC3866Config:
|
||||
|
||||
|
||||
class ExperimentalConfig(Config):
|
||||
"""Config section for enabling experimental features
|
||||
|
||||
All new experimental features should have a tracking issue with the
|
||||
`T-ExperimentalFeatures` label, kept open as long as the experimental
|
||||
feature is present in Synapse."""
|
||||
"""Config section for enabling experimental features"""
|
||||
|
||||
section = "experimental"
|
||||
|
||||
@@ -382,9 +378,30 @@ class ExperimentalConfig(Config):
|
||||
# MSC3026 (busy presence state)
|
||||
self.msc3026_enabled: bool = experimental.get("msc3026_enabled", False)
|
||||
|
||||
# MSC2697 (device dehydration)
|
||||
# Enabled by default since this option was added after adding the feature.
|
||||
# It is not recommended that both MSC2697 and MSC3814 both be enabled at
|
||||
# once.
|
||||
self.msc2697_enabled: bool = experimental.get("msc2697_enabled", True)
|
||||
|
||||
# MSC3814 (dehydrated devices with SSSS)
|
||||
# This is an alternative method to achieve the same goals as MSC2697.
|
||||
# It is not recommended that both MSC2697 and MSC3814 both be enabled at
|
||||
# once.
|
||||
self.msc3814_enabled: bool = experimental.get("msc3814_enabled", False)
|
||||
|
||||
if self.msc2697_enabled and self.msc3814_enabled:
|
||||
raise ConfigError(
|
||||
"MSC2697 and MSC3814 should not both be enabled.",
|
||||
(
|
||||
"experimental_features",
|
||||
"msc3814_enabled",
|
||||
),
|
||||
)
|
||||
|
||||
# MSC3244 (room version capabilities)
|
||||
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", True)
|
||||
|
||||
# MSC3266 (room summary api)
|
||||
self.msc3266_enabled: bool = experimental.get("msc3266_enabled", False)
|
||||
|
||||
@@ -580,11 +597,5 @@ class ExperimentalConfig(Config):
|
||||
# (and MSC4308: Thread Subscriptions extension to Sliding Sync)
|
||||
self.msc4306_enabled: bool = experimental.get("msc4306_enabled", False)
|
||||
|
||||
# MSC4354: Sticky Events
|
||||
# Tracked in: https://github.com/element-hq/synapse/issues/19409
|
||||
# Note that sticky events persisted before this feature is enabled will not be
|
||||
# considered sticky by the local homeserver.
|
||||
self.msc4354_enabled: bool = experimental.get("msc4354_enabled", False)
|
||||
|
||||
# MSC4380: Invite blocking
|
||||
self.msc4380_enabled: bool = experimental.get("msc4380_enabled", False)
|
||||
|
||||
@@ -75,19 +75,10 @@ class MetricsConfig(Config):
|
||||
)
|
||||
|
||||
def generate_config_section(
|
||||
self,
|
||||
report_stats: bool | None = None,
|
||||
enable_metrics: bool = False,
|
||||
**kwargs: Any,
|
||||
self, report_stats: bool | None = None, **kwargs: Any
|
||||
) -> str:
|
||||
if report_stats is not None:
|
||||
res = "report_stats: %s\n" % ("true" if report_stats else "false")
|
||||
else:
|
||||
res = "\n"
|
||||
|
||||
# We avoid adding anything if it's `False` since that's the default (less noise
|
||||
# in the default generated config)
|
||||
if enable_metrics:
|
||||
res += "enable_metrics: true\n"
|
||||
|
||||
return res
|
||||
|
||||
@@ -252,9 +252,3 @@ class RatelimitConfig(Config):
|
||||
"rc_reports",
|
||||
defaults={"per_second": 1, "burst_count": 5},
|
||||
)
|
||||
|
||||
self.rc_user_directory = RatelimitSettings.parse(
|
||||
config,
|
||||
"rc_user_directory",
|
||||
defaults={"per_second": 0.016, "burst_count": 200},
|
||||
)
|
||||
|
||||
@@ -174,11 +174,6 @@ class ContentRepositoryConfig(Config):
|
||||
config.get("media_store_path", "media_store")
|
||||
)
|
||||
|
||||
# Whether to enable the local media storage provider. When disabled,
|
||||
# media will only be stored in configured storage providers and temp
|
||||
# files will be used for processing.
|
||||
self.enable_local_media_storage = config.get("enable_local_media_storage", True)
|
||||
|
||||
backup_media_store_path = config.get("backup_media_store_path")
|
||||
|
||||
synchronous_backup_media_store = config.get(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user