Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • maunium/synapse
  • leytilera/synapse
2 results
Show changes
Showing
with 85 additions and 48 deletions
Reduce overhead of restarting synchrotrons.
Update the link to Redis pub/sub documentation in the workers documentation..
\ No newline at end of file
Fix `/messages` returning backfilled and [MSC2716](https://github.com/matrix-org/synapse/pull/12319) historic messages our of order.
Add type hints to tests files.
\ No newline at end of file
Reduce overhead of restarting synchrotrons.
Allow specifying the Postgres database's port when running unit tests with Postgres.
\ No newline at end of file
Remove temporary pin of signedjson<=1.1.1 that was added in Synapse 1.56.0.
Lay groundwork for using `poetry` to manage Synapse's dependencies.
\ No newline at end of file
Make missing `importlib_metadata` dependency explicit.
\ No newline at end of file
Update type annotations for compatiblity with prometheus_client 0.14.
#!/usr/bin/env python #!/usr/bin/env python
#
# This file is licensed under the Affero General Public License (AGPL) version 3.
#
# Copyright 2014-2016 OpenMarket Ltd # Copyright 2014-2016 OpenMarket Ltd
# Copyright (C) 2023 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>.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Originally licensed under the Apache License, Version 2.0:
# you may not use this file except in compliance with the License. # <http://www.apache.org/licenses/LICENSE-2.0>.
# You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # [This file includes modifications made by New Vector Limited]
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """Starts a synapse client console."""
# See the License for the specific language governing permissions and
# limitations under the License.
""" Starts a synapse client console. """
import argparse import argparse
import binascii
import cmd import cmd
import getpass import getpass
import json import json
...@@ -26,9 +35,8 @@ import urllib ...@@ -26,9 +35,8 @@ import urllib
from http import TwistedHttpClient from http import TwistedHttpClient
from typing import Optional from typing import Optional
import nacl.encoding
import nacl.signing
import urlparse import urlparse
from signedjson.key import NACL_ED25519, decode_verify_key_bytes
from signedjson.sign import SignatureVerifyException, verify_signed_json from signedjson.sign import SignatureVerifyException, verify_signed_json
from twisted.internet import defer, reactor, threads from twisted.internet import defer, reactor, threads
...@@ -41,7 +49,6 @@ TRUSTED_ID_SERVERS = ["localhost:8001"] ...@@ -41,7 +49,6 @@ TRUSTED_ID_SERVERS = ["localhost:8001"]
class SynapseCmd(cmd.Cmd): class SynapseCmd(cmd.Cmd):
"""Basic synapse command-line processor. """Basic synapse command-line processor.
This processes commands from the user and calls the relevant HTTP methods. This processes commands from the user and calls the relevant HTTP methods.
...@@ -238,7 +245,7 @@ class SynapseCmd(cmd.Cmd): ...@@ -238,7 +245,7 @@ class SynapseCmd(cmd.Cmd):
if "flows" not in json_res: if "flows" not in json_res:
print("Failed to find any login flows.") print("Failed to find any login flows.")
defer.returnValue(False) return False
flow = json_res["flows"][0] # assume first is the one we want. flow = json_res["flows"][0] # assume first is the one we want.
if "type" not in flow or "m.login.password" != flow["type"] or "stages" in flow: if "type" not in flow or "m.login.password" != flow["type"] or "stages" in flow:
...@@ -247,8 +254,8 @@ class SynapseCmd(cmd.Cmd): ...@@ -247,8 +254,8 @@ class SynapseCmd(cmd.Cmd):
"Unable to login via the command line client. Please visit " "Unable to login via the command line client. Please visit "
"%s to login." % fallback_url "%s to login." % fallback_url
) )
defer.returnValue(False) return False
defer.returnValue(True) return True
def do_emailrequest(self, line): def do_emailrequest(self, line):
"""Requests the association of a third party identifier """Requests the association of a third party identifier
...@@ -420,8 +427,8 @@ class SynapseCmd(cmd.Cmd): ...@@ -420,8 +427,8 @@ class SynapseCmd(cmd.Cmd):
pubKey = None pubKey = None
pubKeyObj = yield self.http_client.do_request("GET", url) pubKeyObj = yield self.http_client.do_request("GET", url)
if "public_key" in pubKeyObj: if "public_key" in pubKeyObj:
pubKey = nacl.signing.VerifyKey( pubKey = decode_verify_key_bytes(
pubKeyObj["public_key"], encoder=nacl.encoding.HexEncoder NACL_ED25519, binascii.unhexlify(pubKeyObj["public_key"])
) )
else: else:
print("No public key found in pubkey response!") print("No public key found in pubkey response!")
...@@ -770,7 +777,7 @@ def main(server_url, identity_server_url, username, token, config_path): ...@@ -770,7 +777,7 @@ def main(server_url, identity_server_url, username, token, config_path):
global CONFIG_JSON global CONFIG_JSON
CONFIG_JSON = config_path # bit cheeky, but just overwrite the global CONFIG_JSON = config_path # bit cheeky, but just overwrite the global
try: try:
with open(config_path, "r") as config: with open(config_path) as config:
syn_cmd.config = json.load(config) syn_cmd.config = json.load(config)
try: try:
http_client.verbose = "on" == syn_cmd.config["verbose"] http_client.verbose = "on" == syn_cmd.config["verbose"]
......
#
# This file is licensed under the Affero General Public License (AGPL) version 3.
#
# Copyright 2014-2016 OpenMarket Ltd # Copyright 2014-2016 OpenMarket Ltd
# Copyright (C) 2023 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>.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Originally licensed under the Apache License, Version 2.0:
# you may not use this file except in compliance with the License. # <http://www.apache.org/licenses/LICENSE-2.0>.
# You may obtain a copy of the License at #
# [This file includes modifications made by New Vector Limited]
# #
# http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json import json
import urllib import urllib
...@@ -37,7 +44,6 @@ class HttpClient: ...@@ -37,7 +44,6 @@ class HttpClient:
Deferred: Succeeds when we get a 2xx HTTP response. The result Deferred: Succeeds when we get a 2xx HTTP response. The result
will be the decoded JSON body. will be the decoded JSON body.
""" """
pass
def get_json(self, url, args=None): def get_json(self, url, args=None):
"""Gets some json from the given host homeserver and path """Gets some json from the given host homeserver and path
...@@ -53,7 +59,6 @@ class HttpClient: ...@@ -53,7 +59,6 @@ class HttpClient:
Deferred: Succeeds when we get a 2xx HTTP response. The result Deferred: Succeeds when we get a 2xx HTTP response. The result
will be the decoded JSON body. will be the decoded JSON body.
""" """
pass
class TwistedHttpClient(HttpClient): class TwistedHttpClient(HttpClient):
...@@ -73,7 +78,7 @@ class TwistedHttpClient(HttpClient): ...@@ -73,7 +78,7 @@ class TwistedHttpClient(HttpClient):
url, data, headers_dict={"Content-Type": ["application/json"]} url, data, headers_dict={"Content-Type": ["application/json"]}
) )
body = yield readBody(response) body = yield readBody(response)
defer.returnValue((response.code, body)) return response.code, body
@defer.inlineCallbacks @defer.inlineCallbacks
def get_json(self, url, args=None): def get_json(self, url, args=None):
...@@ -83,7 +88,7 @@ class TwistedHttpClient(HttpClient): ...@@ -83,7 +88,7 @@ class TwistedHttpClient(HttpClient):
url = "%s?%s" % (url, qs) url = "%s?%s" % (url, qs)
response = yield self._create_get_request(url) response = yield self._create_get_request(url)
body = yield readBody(response) body = yield readBody(response)
defer.returnValue(json.loads(body)) return json.loads(body)
def _create_put_request(self, url, json_data, headers_dict: Optional[dict] = None): def _create_put_request(self, url, json_data, headers_dict: Optional[dict] = None):
"""Wrapper of _create_request to issue a PUT request""" """Wrapper of _create_request to issue a PUT request"""
...@@ -129,7 +134,7 @@ class TwistedHttpClient(HttpClient): ...@@ -129,7 +134,7 @@ class TwistedHttpClient(HttpClient):
response = yield self._create_request(method, url) response = yield self._create_request(method, url)
body = yield readBody(response) body = yield readBody(response)
defer.returnValue(json.loads(body)) return json.loads(body)
@defer.inlineCallbacks @defer.inlineCallbacks
def _create_request( def _create_request(
...@@ -168,7 +173,7 @@ class TwistedHttpClient(HttpClient): ...@@ -168,7 +173,7 @@ class TwistedHttpClient(HttpClient):
if self.verbose: if self.verbose:
print("Status %s %s" % (response.code, response.phrase)) print("Status %s %s" % (response.code, response.phrase))
print(pformat(list(response.headers.getAllRawHeaders()))) print(pformat(list(response.headers.getAllRawHeaders())))
defer.returnValue(response) return response
def sleep(self, seconds): def sleep(self, seconds):
d = defer.Deferred() d = defer.Deferred()
......
# Schema symlinks
This directory contains symlinks to the latest dump of the postgres full schema. This is useful to have, as it allows IDEs to understand our schema and provide autocomplete, linters, inspections, etc.
In particular, the DataGrip functionality in IntelliJ's products seems to only consider files called `*.sql` when defining a schema from DDL; `*.sql.postgres` will be ignored. To get around this we symlink those files to ones ending in `.sql`. We've chosen to ignore the `.sql.sqlite` schema dumps here, as they're not intended for production use (and are much quicker to test against).
## Example
![](datagrip-aware-of-schema.png)
## Caveats
- Doesn't include temporary tables created ad-hoc by Synapse.
- Postgres only. IDEs will likely be confused by SQLite-specific queries.
- Will not include migrations created after the latest schema dump.
- Symlinks might confuse checkouts on Windows systems.
## Instructions
### Jetbrains IDEs with DataGrip plugin
- View -> Tool Windows -> Database
- `+` Icon -> DDL Data Source
- Pick a name, e.g. `Synapse schema dump`
- Under sources, click `+`.
- Add an entry with Path pointing to this directory, and dialect set to PostgreSQL.
- OK, and OK.
- IDE should now be aware of the schema.
- Try control-clicking on a table name in a bit of SQL e.g. in `_get_forgotten_rooms_for_user_txn`.
\ No newline at end of file
../../synapse/storage/schema/common/full_schemas/72/full.sql.postgres
\ No newline at end of file
contrib/datagrip/datagrip-aware-of-schema.png

13.3 KiB

../../synapse/storage/schema/main/full_schemas/72/full.sql.postgres
\ No newline at end of file
../../synapse/storage/schema/common/schema_version.sql
\ No newline at end of file
../../synapse/storage/schema/state/full_schemas/72/full.sql.postgres
\ No newline at end of file
...@@ -30,3 +30,6 @@ docker-compose up -d ...@@ -30,3 +30,6 @@ docker-compose up -d
### More information ### More information
For more information on required environment variables and mounts, see the main docker documentation at [/docker/README.md](../../docker/README.md) For more information on required environment variables and mounts, see the main docker documentation at [/docker/README.md](../../docker/README.md)
**For a more comprehensive Docker Compose example showcasing a full Matrix 2.0 stack, please see
https://github.com/element-hq/element-docker-demo**
\ No newline at end of file
...@@ -7,8 +7,8 @@ services: ...@@ -7,8 +7,8 @@ services:
synapse: synapse:
build: build:
context: ../.. context: ../..
dockerfile: docker/Dockerfile dockerfile: docker/Dockerfile
image: docker.io/matrixdotorg/synapse:latest image: docker.io/matrixdotorg/synapse:latest
# Since synapse does not retry to connect to the database, restart upon # Since synapse does not retry to connect to the database, restart upon
# failure # failure
...@@ -51,13 +51,13 @@ services: ...@@ -51,13 +51,13 @@ services:
- traefik.http.routers.https-synapse.tls.certResolver=le-ssl - traefik.http.routers.https-synapse.tls.certResolver=le-ssl
db: db:
image: docker.io/postgres:12-alpine image: docker.io/postgres:15-alpine
# Change that password, of course! # Change that password, of course!
environment: environment:
- POSTGRES_USER=synapse - POSTGRES_USER=synapse
- POSTGRES_PASSWORD=changeme - POSTGRES_PASSWORD=changeme
# ensure the database gets created correctly # ensure the database gets created correctly
# https://matrix-org.github.io/synapse/latest/postgres.html#set-up-database # https://element-hq.github.io/synapse/latest/postgres.html#set-up-database
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
volumes: volumes:
# You may store the database tables in a local folder.. # You may store the database tables in a local folder..
......