summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kösters <timo@koesters.xyz>2023-07-29 20:01:38 +0200
committerTimo Kösters <timo@koesters.xyz>2023-07-29 21:53:57 +0200
commitb8c164dc6027844d665158dc8906dd5c89f9238b (patch)
tree4af8afde123e6d9853819d3e1ff8d7e767c534d1
parentda907451e77648b8fce022f0d7fa536a6f678267 (diff)
downloadconduit-b8c164dc6027844d665158dc8906dd5c89f9238b.zip
feat: version checker
-rw-r--r--DEPLOY.md1
-rw-r--r--complement/Dockerfile1
-rw-r--r--conduit-example.toml1
-rw-r--r--debian/postinst1
-rw-r--r--docker-compose.yml1
-rw-r--r--docker/docker-compose.for-traefik.yml1
-rw-r--r--docker/docker-compose.with-traefik.yml5
-rw-r--r--src/config/mod.rs2
-rw-r--r--src/database/key_value/globals.rs18
-rw-r--r--src/database/mod.rs62
-rw-r--r--src/service/globals/data.rs2
-rw-r--r--src/service/globals/mod.rs14
12 files changed, 105 insertions, 4 deletions
diff --git a/DEPLOY.md b/DEPLOY.md
index ec7dd46..4605a98 100644
--- a/DEPLOY.md
+++ b/DEPLOY.md
@@ -172,6 +172,7 @@ max_request_size = 20_000_000 # in bytes
allow_registration = true
allow_federation = true
+allow_check_for_updates = true
# Server to get public keys from. You probably shouldn't change this
trusted_servers = ["matrix.org"]
diff --git a/complement/Dockerfile b/complement/Dockerfile
index 43416fa..50173a1 100644
--- a/complement/Dockerfile
+++ b/complement/Dockerfile
@@ -30,6 +30,7 @@ ENV CONDUIT_CONFIG=/workdir/conduit.toml
RUN sed -i "s/port = 6167/port = 8008/g" conduit.toml
RUN echo "allow_federation = true" >> conduit.toml
+RUN echo "allow_check_for_updates = true" >> conduit.toml
RUN echo "allow_encryption = true" >> conduit.toml
RUN echo "allow_registration = true" >> conduit.toml
RUN echo "log = \"warn,_=off,sled=off\"" >> conduit.toml
diff --git a/conduit-example.toml b/conduit-example.toml
index 6089aa5..836db65 100644
--- a/conduit-example.toml
+++ b/conduit-example.toml
@@ -39,6 +39,7 @@ max_request_size = 20_000_000 # in bytes
allow_registration = true
allow_federation = true
+allow_check_for_updates = true
# Enable the display name lightning bolt on registration.
enable_lightning_bolt = true
diff --git a/debian/postinst b/debian/postinst
index dfa599d..69a766a 100644
--- a/debian/postinst
+++ b/debian/postinst
@@ -73,6 +73,7 @@ max_request_size = 20_000_000 # in bytes
allow_registration = true
allow_federation = true
+allow_check_for_updates = true
trusted_servers = ["matrix.org"]
diff --git a/docker-compose.yml b/docker-compose.yml
index d9c32b5..5bcf84f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -29,6 +29,7 @@ services:
CONDUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
CONDUIT_ALLOW_REGISTRATION: 'true'
CONDUIT_ALLOW_FEDERATION: 'true'
+ CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
#CONDUIT_MAX_CONCURRENT_REQUESTS: 100
#CONDUIT_LOG: warn,rocket=off,_=off,sled=off
diff --git a/docker/docker-compose.for-traefik.yml b/docker/docker-compose.for-traefik.yml
index 474299f..bed734f 100644
--- a/docker/docker-compose.for-traefik.yml
+++ b/docker/docker-compose.for-traefik.yml
@@ -29,6 +29,7 @@ services:
CONDUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
CONDUIT_ALLOW_REGISTRATION: 'true'
CONDUIT_ALLOW_FEDERATION: 'true'
+ CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
#CONDUIT_MAX_CONCURRENT_REQUESTS: 100
#CONDUIT_LOG: warn,rocket=off,_=off,sled=off
diff --git a/docker/docker-compose.with-traefik.yml b/docker/docker-compose.with-traefik.yml
index 79ebef4..fda942b 100644
--- a/docker/docker-compose.with-traefik.yml
+++ b/docker/docker-compose.with-traefik.yml
@@ -35,8 +35,9 @@ services:
# Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging
# CONDUIT_LOG: info # default is: "warn,_=off,sled=off"
# CONDUIT_ALLOW_JAEGER: 'false'
- # CONDUIT_ALLOW_ENCRYPTION: 'false'
- # CONDUIT_ALLOW_FEDERATION: 'false'
+ # CONDUIT_ALLOW_ENCRYPTION: 'true'
+ # CONDUIT_ALLOW_FEDERATION: 'true'
+ # CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
# CONDUIT_DATABASE_PATH: /srv/conduit/.local/share/conduit
# CONDUIT_WORKERS: 10
# CONDUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 4dad9f7..e2c2ff1 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -28,6 +28,8 @@ pub struct Config {
pub db_cache_capacity_mb: f64,
#[serde(default = "true_fn")]
pub enable_lightning_bolt: bool,
+ #[serde(default = "true_fn")]
+ pub allow_check_for_updates: bool,
#[serde(default = "default_conduit_cache_capacity_modifier")]
pub conduit_cache_capacity_modifier: f64,
#[serde(default = "default_rocksdb_max_open_files")]
diff --git a/src/database/key_value/globals.rs b/src/database/key_value/globals.rs
index 1e02459..11aa064 100644
--- a/src/database/key_value/globals.rs
+++ b/src/database/key_value/globals.rs
@@ -12,6 +12,7 @@ use ruma::{
use crate::{database::KeyValueDatabase, service, services, utils, Error, Result};
pub const COUNTER: &[u8] = b"c";
+pub const LAST_CHECK_FOR_UPDATES_COUNT: &[u8] = b"u";
#[async_trait]
impl service::globals::Data for KeyValueDatabase {
@@ -27,6 +28,23 @@ impl service::globals::Data for KeyValueDatabase {
})
}
+ fn last_check_for_updates_id(&self) -> Result<u64> {
+ self.global
+ .get(LAST_CHECK_FOR_UPDATES_COUNT)?
+ .map_or(Ok(0_u64), |bytes| {
+ utils::u64_from_bytes(&bytes).map_err(|_| {
+ Error::bad_database("last check for updates count has invalid bytes.")
+ })
+ })
+ }
+
+ fn update_check_for_updates_id(&self, id: u64) -> Result<()> {
+ self.global
+ .insert(LAST_CHECK_FOR_UPDATES_COUNT, &id.to_be_bytes())?;
+
+ Ok(())
+ }
+
async fn watch(&self, user_id: &UserId, device_id: &DeviceId) -> Result<()> {
let userid_bytes = user_id.as_bytes().to_vec();
let mut userid_prefix = userid_bytes.clone();
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 4e7bda6..b36347d 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -18,6 +18,7 @@ use ruma::{
CanonicalJsonValue, EventId, OwnedDeviceId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId,
UserId,
};
+use serde::Deserialize;
use std::{
collections::{BTreeMap, HashMap, HashSet},
fs::{self, remove_dir_all},
@@ -25,7 +26,9 @@ use std::{
mem::size_of,
path::Path,
sync::{Arc, Mutex, RwLock},
+ time::Duration,
};
+use tokio::time::interval;
use tracing::{debug, error, info, warn};
@@ -982,6 +985,9 @@ impl KeyValueDatabase {
services().sending.start_handler();
Self::start_cleanup_task().await;
+ if services().globals.allow_check_for_updates() {
+ Self::start_check_for_updates_task();
+ }
Ok(())
}
@@ -998,9 +1004,61 @@ impl KeyValueDatabase {
}
#[tracing::instrument]
- pub async fn start_cleanup_task() {
- use tokio::time::interval;
+ pub fn start_check_for_updates_task() {
+ tokio::spawn(async move {
+ let timer_interval = Duration::from_secs(60 * 60);
+ let mut i = interval(timer_interval);
+ loop {
+ i.tick().await;
+ let _ = Self::try_handle_updates().await;
+ }
+ });
+ }
+ async fn try_handle_updates() -> Result<()> {
+ let response = services()
+ .globals
+ .default_client()
+ .get("https://conduit.rs/check-for-updates/stable")
+ .send()
+ .await?;
+
+ #[derive(Deserialize)]
+ struct CheckForUpdatesResponseEntry {
+ id: u64,
+ date: String,
+ message: String,
+ }
+ #[derive(Deserialize)]
+ struct CheckForUpdatesResponse {
+ updates: Vec<CheckForUpdatesResponseEntry>,
+ }
+
+ let response = serde_json::from_str::<CheckForUpdatesResponse>(&response.text().await?)
+ .map_err(|_| Error::BadServerResponse("Bad version check response"))?;
+
+ let mut last_update_id = services().globals.last_check_for_updates_id()?;
+ for update in response.updates {
+ last_update_id = last_update_id.max(update.id);
+ if update.id > services().globals.last_check_for_updates_id()? {
+ println!("{}", update.message);
+ services()
+ .admin
+ .send_message(RoomMessageEventContent::text_plain(format!(
+ "@room: The following is a message from the Conduit developers. It was sent on '{}':\n\n{}",
+ update.date, update.message
+ )))
+ }
+ }
+ services()
+ .globals
+ .update_check_for_updates_id(last_update_id)?;
+
+ Ok(())
+ }
+
+ #[tracing::instrument]
+ pub async fn start_cleanup_task() {
#[cfg(unix)]
use tokio::signal::unix::{signal, SignalKind};
diff --git a/src/service/globals/data.rs b/src/service/globals/data.rs
index 171b3fe..8a66751 100644
--- a/src/service/globals/data.rs
+++ b/src/service/globals/data.rs
@@ -13,6 +13,8 @@ use crate::Result;
pub trait Data: Send + Sync {
fn next_count(&self) -> Result<u64>;
fn current_count(&self) -> Result<u64>;
+ fn last_check_for_updates_id(&self) -> Result<u64>;
+ fn update_check_for_updates_id(&self, id: u64) -> Result<()>;
async fn watch(&self, user_id: &UserId, device_id: &DeviceId) -> Result<()>;
fn cleanup(&self) -> Result<()>;
fn memory_usage(&self) -> String;
diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs
index 44235b3..875a457 100644
--- a/src/service/globals/mod.rs
+++ b/src/service/globals/mod.rs
@@ -209,6 +209,16 @@ impl Service {
self.db.current_count()
}
+ #[tracing::instrument(skip(self))]
+ pub fn last_check_for_updates_id(&self) -> Result<u64> {
+ self.db.last_check_for_updates_id()
+ }
+
+ #[tracing::instrument(skip(self))]
+ pub fn update_check_for_updates_id(&self, id: u64) -> Result<()> {
+ self.db.update_check_for_updates_id(id)
+ }
+
pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) -> Result<()> {
self.db.watch(user_id, device_id).await
}
@@ -257,6 +267,10 @@ impl Service {
self.config.enable_lightning_bolt
}
+ pub fn allow_check_for_updates(&self) -> bool {
+ self.config.allow_check_for_updates
+ }
+
pub fn trusted_servers(&self) -> &[OwnedServerName] {
&self.config.trusted_servers
}