diff --git a/INSTALL.md b/INSTALL.md index b8f8a6732904..ef80a26c3fab 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -180,35 +180,41 @@ sudo zypper in python-pip python-setuptools sqlite3 python-virtualenv \ #### OpenBSD -Installing prerequisites on OpenBSD: +A port of Synapse is available under `net/synapse`. The filesystem +underlying the homeserver directory (defaults to `/var/synapse`) has to be +mounted with `wxallowed` (cf. `mount(8)`), so creating a separate filesystem +and mounting it to `/var/synapse` should be taken into consideration. + +To be able to build Synapse's dependency on python the `WRKOBJDIR` +(cf. `bsd.port.mk(5)`) for building python, too, needs to be on a filesystem +mounted with `wxallowed` (cf. `mount(8)`). + +Creating a `WRKOBJDIR` for building python under `/usr/local` (which on a +default OpenBSD installation is mounted with `wxallowed`): ``` -doas pkg_add python libffi py-pip py-setuptools sqlite3 py-virtualenv \ - libxslt jpeg +doas mkdir /usr/local/pobj_wxallowed ``` -There is currently no port for OpenBSD. Additionally, OpenBSD's security -settings require a slightly more difficult installation process. +Assuming `PORTS_PRIVSEP=Yes` (cf. `bsd.port.mk(5)`) and `SUDO=doas` are +configured in `/etc/mk.conf`: + +``` +doas chown _pbuild:_pbuild /usr/local/pobj_wxallowed +``` -(XXX: I suspect this is out of date) +Setting the `WRKOBJDIR` for building python: -1. Create a new directory in `/usr/local` called `_synapse`. Also, create a - new user called `_synapse` and set that directory as the new user's home. - This is required because, by default, OpenBSD only allows binaries which need - write and execute permissions on the same memory space to be run from - `/usr/local`. -2. `su` to the new `_synapse` user and change to their home directory. -3. Create a new virtualenv: `virtualenv -p python3 ~/.synapse` -4. Source the virtualenv configuration located at - `/usr/local/_synapse/.synapse/bin/activate`. This is done in `ksh` by - using the `.` command, rather than `bash`'s `source`. -5. Optionally, use `pip` to install `lxml`, which Synapse needs to parse - webpages for their titles. -6. Use `pip` to install this repository: `pip install matrix-synapse` -7. Optionally, change `_synapse`'s shell to `/bin/false` to reduce the - chance of a compromised Synapse server being used to take over your box. +``` +echo WRKOBJDIR_lang/python/3.7=/usr/local/pobj_wxallowed \\nWRKOBJDIR_lang/python/2.7=/usr/local/pobj_wxallowed >> /etc/mk.conf +``` -After this, you may proceed with the rest of the install directions. +Building Synapse: + +``` +cd /usr/ports/net/synapse +make install +``` #### Windows @@ -350,6 +356,18 @@ Synapse can be installed via FreeBSD Ports or Packages contributed by Brendan Mo - Ports: `cd /usr/ports/net-im/py-matrix-synapse && make install clean` - Packages: `pkg install py37-matrix-synapse` +### OpenBSD + +As of OpenBSD 6.7 Synapse is available as a pre-compiled binary. The filesystem +underlying the homeserver directory (defaults to `/var/synapse`) has to be +mounted with `wxallowed` (cf. `mount(8)`), so creating a separate filesystem +and mounting it to `/var/synapse` should be taken into consideration. + +Installing Synapse: + +``` +doas pkg_add synapse +``` ### NixOS diff --git a/changelog.d/7587.doc b/changelog.d/7587.doc new file mode 100644 index 000000000000..ec4a43043678 --- /dev/null +++ b/changelog.d/7587.doc @@ -0,0 +1 @@ +Update the OpenBSD installation instructions. \ No newline at end of file diff --git a/changelog.d/7599.bugfix b/changelog.d/7599.bugfix new file mode 100644 index 000000000000..deefe5680f3f --- /dev/null +++ b/changelog.d/7599.bugfix @@ -0,0 +1 @@ +Fix bug where returning rooms for a group would fail if it included a room that the server was not in. diff --git a/changelog.d/7607.bugfix b/changelog.d/7607.bugfix new file mode 100644 index 000000000000..04b22e5ffe8f --- /dev/null +++ b/changelog.d/7607.bugfix @@ -0,0 +1 @@ +Fix duplicate key violation when persisting read markers. diff --git a/changelog.d/7609.bugfix b/changelog.d/7609.bugfix new file mode 100644 index 000000000000..e2eceeef0ca8 --- /dev/null +++ b/changelog.d/7609.bugfix @@ -0,0 +1 @@ +Prevent an entire iteration of the device list resync loop from failing if one server responds with a malformed result. diff --git a/synapse/handlers/device.py b/synapse/handlers/device.py index 29a19b457207..2cbb695bb162 100644 --- a/synapse/handlers/device.py +++ b/synapse/handlers/device.py @@ -704,22 +704,27 @@ def _maybe_retry_device_resync(self): need_resync = yield self.store.get_user_ids_requiring_device_list_resync() # Iterate over the set of user IDs. for user_id in need_resync: - # Try to resync the current user's devices list. Exception handling - # isn't necessary here, since user_device_resync catches all instances - # of "Exception" that might be raised from the federation request. This - # means that if an exception is raised by this function, it must be - # because of a database issue, which means _maybe_retry_device_resync - # probably won't be able to go much further anyway. - result = yield self.user_device_resync( - user_id=user_id, mark_failed_as_stale=False, - ) - # user_device_resync only returns a result if it managed to successfully - # resync and update the database. Updating the table of users requiring - # resync isn't necessary here as user_device_resync already does it - # (through self.store.update_remote_device_list_cache). - if result: + try: + # Try to resync the current user's devices list. + result = yield self.user_device_resync( + user_id=user_id, mark_failed_as_stale=False, + ) + + # user_device_resync only returns a result if it managed to + # successfully resync and update the database. Updating the table + # of users requiring resync isn't necessary here as + # user_device_resync already does it (through + # self.store.update_remote_device_list_cache). + if result: + logger.debug( + "Successfully resynced the device list for %s", user_id, + ) + except Exception as e: + # If there was an issue resyncing this user, e.g. if the remote + # server sent a malformed result, just log the error instead of + # aborting all the subsequent resyncs. logger.debug( - "Successfully resynced the device list for %s" % user_id, + "Could not resync the device list for %s: %s", user_id, e, ) finally: # Allow future calls to retry resyncinc out of sync device lists. @@ -738,6 +743,7 @@ def user_device_resync(self, user_id, mark_failed_as_stale=True): request: https://matrix.org/docs/spec/server_server/r0.1.2#get-matrix-federation-v1-user-devices-userid """ + logger.debug("Attempting to resync the device list for %s", user_id) log_kv({"message": "Doing resync to update device list."}) # Fetch all devices for the user. origin = get_domain_from_id(user_id) diff --git a/synapse/handlers/room_list.py b/synapse/handlers/room_list.py index 2aeceeaa6c25..e42b12a46d0a 100644 --- a/synapse/handlers/room_list.py +++ b/synapse/handlers/room_list.py @@ -254,10 +254,21 @@ def generate_room_entry( """ result = {"room_id": room_id, "num_joined_members": num_joined_users} + if with_alias: + aliases = yield self.store.get_aliases_for_room( + room_id, on_invalidate=cache_context.invalidate + ) + if aliases: + result["aliases"] = aliases + current_state_ids = yield self.store.get_current_state_ids( room_id, on_invalidate=cache_context.invalidate ) + if not current_state_ids: + # We're not in the room, so may as well bail out here. + return result + event_map = yield self.store.get_events( [ event_id @@ -290,14 +301,7 @@ def generate_room_entry( create_event = current_state.get((EventTypes.Create, "")) result["m.federate"] = create_event.content.get("m.federate", True) - if with_alias: - aliases = yield self.store.get_aliases_for_room( - room_id, on_invalidate=cache_context.invalidate - ) - if aliases: - result["aliases"] = aliases - - name_event = yield current_state.get((EventTypes.Name, "")) + name_event = current_state.get((EventTypes.Name, "")) if name_event: name = name_event.content.get("name", None) if name: diff --git a/synapse/storage/data_stores/main/receipts.py b/synapse/storage/data_stores/main/receipts.py index 0d932a06728d..cebdcd409f13 100644 --- a/synapse/storage/data_stores/main/receipts.py +++ b/synapse/storage/data_stores/main/receipts.py @@ -391,7 +391,7 @@ def insert_linearized_receipt_txn( (user_id, room_id, receipt_type), ) - self.db.simple_delete_txn( + self.db.simple_upsert_txn( txn, table="receipts_linearized", keyvalues={ @@ -399,19 +399,14 @@ def insert_linearized_receipt_txn( "receipt_type": receipt_type, "user_id": user_id, }, - ) - - self.db.simple_insert_txn( - txn, - table="receipts_linearized", values={ "stream_id": stream_id, - "room_id": room_id, - "receipt_type": receipt_type, - "user_id": user_id, "event_id": event_id, "data": json.dumps(data), }, + # receipts_linearized has a unique constraint on + # (user_id, room_id, receipt_type), so no need to lock + lock=False, ) if receipt_type == "m.read" and stream_ordering is not None: