From 8f090c884002c4b806ce9b7ea044525d345b6d39 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Thu, 22 May 2025 16:22:57 +0200 Subject: [PATCH] Updated CHANGELOG and UPGRADING --- CHANGELOG.md | 33 ++++++++++++++++++ UPGRADING.md | 68 +++++++++++++++++++++++++++++++++++++ crates/main/Cargo.toml | 2 ++ crates/migration/src/lib.rs | 26 ++++++++++---- 4 files changed, 122 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06bfa1f6..90cf954f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,39 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.12.0] - 2025-05-XX + +This version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. + +### Added +- [Collaboration](https://stalw.art/docs/collaboration/overview) features including [Calendars over CalDAV](https://stalw.art/docs/http/calendar/), [Contacts over CardDAV](https://stalw.art/docs/http/contact/) and [File Storage over WebDAV](https://stalw.art/docs/http/file-storage/). +- Peer-to-peer [cluster coordination](https://stalw.art/docs/cluster/coordination/overview) or with Apache Kafka, Redpanda, NATS or Redis. +- Incremental caching of emails, calendars, contacts and file metadata. +- Zero-copy deserialization. +- `XOAUTH2` SASL mechanism support (#1194 #1369). +- Support for RFC9698, the `JMAPACCESS` Extension for IMAP. +- Search index for accounts and other principals (#1368). +- Add `description` property to OIDC ID token (#1234). + +### Changed + +- Deprecated gossip protocol in favor of the new [coordinator](https://stalw.art/docs/cluster/coordination/overview) options. +- Renamed Git repository from `stalwartlabs/mail-server` to `stalwartlabs/stalwart` and the Docker image from `stalwartlabs/mail-server` to `stalwartlabs/stalwart`. +- Renamed multiple settings: + - `server.http.*` to `http.*`. + - `jmap.folders.*` to `email.folders.*`. + - `jmap.account.purge.frequency` to `account.purge.frequency`. + - `jmap.email.auto-expunge` to `email.auto-expunge`. + - `jmap.protocol.changes.max-history` to `changes.max-history`. + - `storage.encryption.*` to `email.encryption.*`. + +### Fixed +- Allow undiscovered UIDs to be used in IMAP `COPY`/`MOVE` operations (#1201). +- Refuse loopback SMTP delivery (#1377). +- Hide the current server version (#1435). +- Use the newest `X-Spam-Status` Header (#1308). +- MySQL Driver error: Transactions couldn't be nested (#1271). + ## [0.11.8] - 2025-04-30 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. diff --git a/UPGRADING.md b/UPGRADING.md index 48ff37ee..1d26fb43 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,3 +1,71 @@ +Upgrading from `v0.11.x` to `v0.12.0` +------------------------------------ + +## Important Notes + +Version `0.12.0` introduces significant improvements such as zero-copy deserialization which make the new database layout incompatible with the previous version. As a result, the database must be migrated to the new layout. The migration is done automatically on startup and should not require any manual intervention. However, it is highly recommended to **back up your data** before upgrading since it is not possible to downgrade the database once it has been migrated. You may also want to run a mock migration before upgrading to ensure that everything works as expected. + +In addition to the database layout changes, multiple settings were renamed: + +- `server.http.*` to `http.*`. +- `jmap.folders.*` to `email.folders.*`. +- `jmap.account.purge.frequency` to `account.purge.frequency`. +- `jmap.email.auto-expunge` to `email.auto-expunge`. +- `jmap.protocol.changes.max-history` to `changes.max-history`. +- `storage.encryption.*` to `email.encryption.*`. + +## Step-by-Step Upgrade Process + +- Stop Stalwart: + + ```bash + $ sudo systemctl stop stalwart-mail + ``` + +- Backup your data following your database system's instructions. For example, if you are using RocksDB or SQLite, you can simply copy the `data` directory to a backup location. If you are using PostgreSQL or MySQL, you can use the `pg_dump` or `mysqldump` commands to create a backup of your database. If your database does not support backups, you can use the `--export` command to export your data to a file. For example: + + ```bash + $ sudo /opt/stalwart-mail/bin/stalwart-mail --config /opt/stalwart-mail/etc/config.toml --export /opt/stalwart-mail/export + $ sudo chown -R stalwart-mail:stalwart-mail /opt/stalwart-mail/export + ``` + +- Download the `v0.12.0` binary for your platform (which is now called `stalwart` rather than `mail-server`) from the [releases page](https://github.com/stalwartlabs/stalwart/releases/latest/) and replace the binary in `/opt/stalwart-mail/bin`. If you are using the Docker image, pull the latest image. + +- Start the service: + ```bash + $ sudo systemctl start stalwart-mail + ``` + +- Upgrade the webadmin by clicking on `Manage` > `Maintenance` > `Update Webadmin`. + +## Step-by-Step Upgrade Process (Docker) + +- Stop the Stalwart container: + + ```bash + $ docker stop stalwart-mail + ``` + +- Backup your data following your database system's instructions. For example, if you are using RocksDB or SQLite, you can simply copy the `data` directory to a backup location. If you are using PostgreSQL or MySQL, you can use the `pg_dump` or `mysqldump` commands to create a backup of your database. If your database does not support backups, you can use the `--export` command to export your data to a file. For example: + + ```bash + $ docker run --rm -v :/opt/stalwart-mail -it stalwart-mail /usr/local/bin/stalwart-mail --config /opt/stalwart-mail/etc/config.toml --export /opt/stalwart-mail/export + ``` + +- The Docker image location has now changed to `stalwartlabs/stalwart` instead of `stalwartlabs/mail-server`. Pull the latest image and configure it to use your existing data directory: + + ```bash + $ docker run -d -ti -p 443:443 -p 8080:8080 \ + -p 25:25 -p 587:587 -p 465:465 \ + -p 143:143 -p 993:993 -p 4190:4190 \ + -p 110:110 -p 995:995 \ + -v :/opt/stalwart \ + --name stalwart stalwartlabs/stalwart:latest + ``` +- Download the `v0.12.0` mail-server for your platform from the [releases page](https://github.com/stalwartlabs/stalwart/releases/latest/) and replace the binary in `/opt/stalwart-mail/bin`. If you are using the Docker image, pull the latest image. + +- Upgrade the webadmin by clicking on `Manage` > `Maintenance` > `Update Webadmin`. + Upgrading from `v0.10.x` to `v0.11.0` ------------------------------------ diff --git a/crates/main/Cargo.toml b/crates/main/Cargo.toml index 1023b73b..21bb92ab 100644 --- a/crates/main/Cargo.toml +++ b/crates/main/Cargo.toml @@ -52,6 +52,8 @@ s3 = ["store/s3"] redis = ["store/redis"] nats = ["store/nats"] azure = ["store/azure"] +zenoh = ["store/zenoh"] +kafka = ["store/kafka"] enterprise = [ "jmap/enterprise", "smtp/enterprise", "common/enterprise", diff --git a/crates/migration/src/lib.rs b/crates/migration/src/lib.rs index 6cf55719..4fc6f2ca 100644 --- a/crates/migration/src/lib.rs +++ b/crates/migration/src/lib.rs @@ -4,6 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ +use std::time::Duration; + use changelog::reset_changelog; use common::{DATABASE_SCHEMA_VERSION, KV_LOCK_HOUSEKEEPER, Server}; use jmap_proto::types::{collection::Collection, property::Property}; @@ -33,7 +35,9 @@ pub mod sieve; pub mod submission; pub mod threads; -const LOCK_WAIT_TIME: u64 = 60; +const LOCK_WAIT_TIME_ACCOUNT: u64 = 3 * 60; +const LOCK_WAIT_TIME_CORE: u64 = 5 * 60; +const LOCK_RETRY_TIME: Duration = Duration::from_secs(30); pub async fn try_migrate(server: &Server) -> trc::Result<()> { if server @@ -57,7 +61,11 @@ pub async fn try_migrate(server: &Server) -> trc::Result<()> { loop { if force_lock || in_memory - .try_lock(KV_LOCK_HOUSEKEEPER, b"migrate_core_lock", LOCK_WAIT_TIME) + .try_lock( + KV_LOCK_HOUSEKEEPER, + b"migrate_core_lock", + LOCK_WAIT_TIME_CORE, + ) .await .caused_by(trc::location!())? { @@ -111,10 +119,10 @@ pub async fn try_migrate(server: &Server) -> trc::Result<()> { } else { trc::event!( Server(trc::ServerEvent::Startup), - Details = format!("Migration lock busy, waiting 60 seconds.",) + Details = format!("Migration lock busy, waiting 30 seconds.",) ); - tokio::time::sleep(std::time::Duration::from_secs(LOCK_WAIT_TIME)).await; + tokio::time::sleep(LOCK_RETRY_TIME).await; } } @@ -132,7 +140,11 @@ pub async fn try_migrate(server: &Server) -> trc::Result<()> { if force_lock || in_memory - .try_lock(KV_LOCK_HOUSEKEEPER, lock_key.as_bytes(), LOCK_WAIT_TIME) + .try_lock( + KV_LOCK_HOUSEKEEPER, + lock_key.as_bytes(), + LOCK_WAIT_TIME_ACCOUNT, + ) .await .caused_by(trc::location!())? { @@ -179,11 +191,11 @@ pub async fn try_migrate(server: &Server) -> trc::Result<()> { trc::event!( Server(trc::ServerEvent::Startup), Details = format!( - "Migrated {num_migrated} accounts and {} are locked by another node, waiting 60 seconds.", + "Migrated {num_migrated} accounts and {} are locked by another node, waiting 30 seconds.", skipped_principal_ids.len() ) ); - tokio::time::sleep(std::time::Duration::from_secs(LOCK_WAIT_TIME)).await; + tokio::time::sleep(LOCK_RETRY_TIME).await; principal_ids = skipped_principal_ids; } else { trc::event!(