mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 07:41:23 +01:00
add conduit compat mode
This makes it possible to deploy Grapevine while using a database originally created by Conduit, including leaving the admin bot user's localpart the same as before.
This commit is contained in:
parent
33e7a46b53
commit
a25f2ec950
6 changed files with 104 additions and 22 deletions
|
|
@ -45,6 +45,13 @@ in
|
||||||
'';
|
'';
|
||||||
default = "::1";
|
default = "::1";
|
||||||
};
|
};
|
||||||
|
global.conduit_compat = lib.mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether to operate as a drop-in replacement for Conduit.
|
||||||
|
'';
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
global.database_path = lib.mkOption {
|
global.database_path = lib.mkOption {
|
||||||
type = types.nonEmptyStr;
|
type = types.nonEmptyStr;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
|
|
@ -54,7 +61,9 @@ in
|
||||||
Note that this is read-only because this module makes use of
|
Note that this is read-only because this module makes use of
|
||||||
systemd's `StateDirectory` option.
|
systemd's `StateDirectory` option.
|
||||||
'';
|
'';
|
||||||
default = "/var/lib/grapevine";
|
default = if cfg.settings.global.conduit_compat
|
||||||
|
then "/var/lib/matrix-conduit"
|
||||||
|
else "/var/lib/grapevine";
|
||||||
};
|
};
|
||||||
global.port = lib.mkOption {
|
global.port = lib.mkOption {
|
||||||
type = types.port;
|
type = types.port;
|
||||||
|
|
@ -104,12 +113,16 @@ in
|
||||||
RestrictNamespaces = true;
|
RestrictNamespaces = true;
|
||||||
RestrictRealtime = true;
|
RestrictRealtime = true;
|
||||||
StartLimitBurst = 5;
|
StartLimitBurst = 5;
|
||||||
StateDirectory = "grapevine";
|
StateDirectory = if cfg.settings.global.conduit_compat
|
||||||
|
then "matrix-conduit"
|
||||||
|
else "grapevine";
|
||||||
StateDirectoryMode = "0700";
|
StateDirectoryMode = "0700";
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||||
UMask = "077";
|
UMask = "077";
|
||||||
User = "grapevine";
|
User = if cfg.settings.global.conduit_compat
|
||||||
|
then "conduit"
|
||||||
|
else "grapevine";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ use self::proxy::ProxyConfig;
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
|
#[serde(default = "false_fn")]
|
||||||
|
pub(crate) conduit_compat: bool,
|
||||||
#[serde(default = "default_address")]
|
#[serde(default = "default_address")]
|
||||||
pub(crate) address: IpAddr,
|
pub(crate) address: IpAddr,
|
||||||
#[serde(default = "default_port")]
|
#[serde(default = "default_port")]
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,16 @@ impl KeyValueDatabase {
|
||||||
fn check_db_setup(config: &Config) -> Result<()> {
|
fn check_db_setup(config: &Config) -> Result<()> {
|
||||||
let path = Path::new(&config.database_path);
|
let path = Path::new(&config.database_path);
|
||||||
|
|
||||||
let sqlite_exists = path.join("grapevine.db").exists();
|
let sqlite_exists = path
|
||||||
|
.join(format!(
|
||||||
|
"{}.db",
|
||||||
|
if config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.exists();
|
||||||
let rocksdb_exists = path.join("IDENTITY").exists();
|
let rocksdb_exists = path.join("IDENTITY").exists();
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
|
@ -401,9 +410,15 @@ impl KeyValueDatabase {
|
||||||
// Matrix resource ownership is based on the server name; changing it
|
// Matrix resource ownership is based on the server name; changing it
|
||||||
// requires recreating the database from scratch.
|
// requires recreating the database from scratch.
|
||||||
if services().users.count()? > 0 {
|
if services().users.count()? > 0 {
|
||||||
let grapevine_user =
|
let grapevine_user = UserId::parse_with_server_name(
|
||||||
UserId::parse_with_server_name("grapevine", services().globals.server_name())
|
if services().globals.config.conduit_compat {
|
||||||
.expect("@grapevine:server_name is valid");
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
services().globals.server_name(),
|
||||||
|
)
|
||||||
|
.expect("admin bot username should be valid");
|
||||||
|
|
||||||
if !services().users.exists(&grapevine_user)? {
|
if !services().users.exists(&grapevine_user)? {
|
||||||
error!(
|
error!(
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,14 @@ impl Engine {
|
||||||
|
|
||||||
impl KeyValueDatabaseEngine for Arc<Engine> {
|
impl KeyValueDatabaseEngine for Arc<Engine> {
|
||||||
fn open(config: &Config) -> Result<Self> {
|
fn open(config: &Config) -> Result<Self> {
|
||||||
let path = Path::new(&config.database_path).join("grapevine.db");
|
let path = Path::new(&config.database_path).join(format!(
|
||||||
|
"{}.db",
|
||||||
|
if config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
// calculates cache-size per permanent connection
|
// calculates cache-size per permanent connection
|
||||||
// 1. convert MB to KiB
|
// 1. convert MB to KiB
|
||||||
|
|
|
||||||
|
|
@ -212,9 +212,16 @@ impl Service {
|
||||||
// TODO: Use futures when we have long admin commands
|
// TODO: Use futures when we have long admin commands
|
||||||
//let mut futures = FuturesUnordered::new();
|
//let mut futures = FuturesUnordered::new();
|
||||||
|
|
||||||
let grapevine_user =
|
let grapevine_user = UserId::parse(format!(
|
||||||
UserId::parse(format!("@grapevine:{}", services().globals.server_name()))
|
"@{}:{}",
|
||||||
.expect("@grapevine:server_name is valid");
|
if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
services().globals.server_name()
|
||||||
|
))
|
||||||
|
.expect("admin bot username should be valid");
|
||||||
|
|
||||||
if let Ok(Some(grapevine_room)) = services().admin.get_admin_room() {
|
if let Ok(Some(grapevine_room)) = services().admin.get_admin_room() {
|
||||||
loop {
|
loop {
|
||||||
|
|
@ -568,7 +575,11 @@ impl Service {
|
||||||
if !services().users.exists(&user_id)?
|
if !services().users.exists(&user_id)?
|
||||||
|| user_id
|
|| user_id
|
||||||
== UserId::parse_with_server_name(
|
== UserId::parse_with_server_name(
|
||||||
"grapevine",
|
if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
services().globals.server_name(),
|
services().globals.server_name(),
|
||||||
)
|
)
|
||||||
.expect("grapevine user exists")
|
.expect("grapevine user exists")
|
||||||
|
|
@ -866,9 +877,15 @@ impl Service {
|
||||||
// Utility to turn clap's `--help` text to HTML.
|
// Utility to turn clap's `--help` text to HTML.
|
||||||
fn usage_to_html(text: &str, server_name: &ServerName) -> String {
|
fn usage_to_html(text: &str, server_name: &ServerName) -> String {
|
||||||
// Replace `@grapevine:servername:-subcmdname` with `@grapevine:servername: subcmdname`
|
// Replace `@grapevine:servername:-subcmdname` with `@grapevine:servername: subcmdname`
|
||||||
|
let localpart = if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
};
|
||||||
|
|
||||||
let text = text.replace(
|
let text = text.replace(
|
||||||
&format!("@grapevine:{server_name}:-"),
|
&format!("@{localpart}:{server_name}:-"),
|
||||||
&format!("@grapevine:{server_name}: "),
|
&format!("@{localpart}:{server_name}: "),
|
||||||
);
|
);
|
||||||
|
|
||||||
// For the grapevine admin room, subcommands become main commands
|
// For the grapevine admin room, subcommands become main commands
|
||||||
|
|
@ -952,9 +969,16 @@ impl Service {
|
||||||
let state_lock = mutex_state.lock().await;
|
let state_lock = mutex_state.lock().await;
|
||||||
|
|
||||||
// Create a user for the server
|
// Create a user for the server
|
||||||
let grapevine_user =
|
let grapevine_user = UserId::parse(format!(
|
||||||
UserId::parse_with_server_name("grapevine", services().globals.server_name())
|
"@{}:{}",
|
||||||
.expect("@grapevine:server_name is valid");
|
if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
services().globals.server_name()
|
||||||
|
))
|
||||||
|
.expect("admin bot username should be valid");
|
||||||
|
|
||||||
services().users.create(&grapevine_user, None)?;
|
services().users.create(&grapevine_user, None)?;
|
||||||
|
|
||||||
|
|
@ -1218,9 +1242,15 @@ impl Service {
|
||||||
let state_lock = mutex_state.lock().await;
|
let state_lock = mutex_state.lock().await;
|
||||||
|
|
||||||
// Use the server user to grant the new admin's power level
|
// Use the server user to grant the new admin's power level
|
||||||
let grapevine_user =
|
let grapevine_user = UserId::parse_with_server_name(
|
||||||
UserId::parse_with_server_name("grapevine", services().globals.server_name())
|
if services().globals.config.conduit_compat {
|
||||||
.expect("@grapevine:server_name is valid");
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
services().globals.server_name(),
|
||||||
|
)
|
||||||
|
.expect("admin bot username should be valid");
|
||||||
|
|
||||||
// Invite and join the real user
|
// Invite and join the real user
|
||||||
services()
|
services()
|
||||||
|
|
|
||||||
|
|
@ -483,7 +483,15 @@ impl Service {
|
||||||
.search
|
.search
|
||||||
.index_pdu(shortroomid, &pdu_id, &body)?;
|
.index_pdu(shortroomid, &pdu_id, &body)?;
|
||||||
|
|
||||||
let server_user = format!("@grapevine:{}", services().globals.server_name());
|
let server_user = format!(
|
||||||
|
"@{}:{}",
|
||||||
|
if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
services().globals.server_name()
|
||||||
|
);
|
||||||
|
|
||||||
let to_grapevine = body.starts_with(&format!("{server_user}: "))
|
let to_grapevine = body.starts_with(&format!("{server_user}: "))
|
||||||
|| body.starts_with(&format!("{server_user} "))
|
|| body.starts_with(&format!("{server_user} "))
|
||||||
|
|
@ -822,7 +830,14 @@ impl Service {
|
||||||
.filter(|v| v.starts_with('@'))
|
.filter(|v| v.starts_with('@'))
|
||||||
.unwrap_or(sender.as_str());
|
.unwrap_or(sender.as_str());
|
||||||
let server_name = services().globals.server_name();
|
let server_name = services().globals.server_name();
|
||||||
let server_user = format!("@grapevine:{server_name}");
|
let server_user = format!(
|
||||||
|
"@{}:{server_name}",
|
||||||
|
if services().globals.config.conduit_compat {
|
||||||
|
"conduit"
|
||||||
|
} else {
|
||||||
|
"grapevine"
|
||||||
|
},
|
||||||
|
);
|
||||||
let content = serde_json::from_str::<ExtractMembership>(pdu.content.get())
|
let content = serde_json::from_str::<ExtractMembership>(pdu.content.get())
|
||||||
.map_err(|_| Error::bad_database("Invalid content in pdu."))?;
|
.map_err(|_| Error::bad_database("Invalid content in pdu."))?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue