Store relative accounts path in accounts.toml

This makes it possible to move accounts dir, especially useful for bots.
This commit is contained in:
link2xt
2022-12-12 18:54:30 +00:00
parent d1e3135331
commit 5922fb38da
3 changed files with 34 additions and 20 deletions

View File

@@ -9,6 +9,7 @@
add the new recipients as group members #3781
- Remove `pytest-async` plugin #3846
- Only send the message about ephemeral timer change if the chat is promoted #3847
- Use relative paths in `accounts.toml` #3838
### API-Changes

View File

@@ -14,9 +14,7 @@ class Rpc:
if accounts_dir:
kwargs["env"] = {
**kwargs.get("env", os.environ),
"DC_ACCOUNTS_PATH": os.path.abspath(
os.path.expanduser(str(accounts_dir))
),
"DC_ACCOUNTS_PATH": str(accounts_dir),
}
self._kwargs = kwargs

View File

@@ -64,7 +64,7 @@ impl Accounts {
let events = Events::new();
let stockstrings = StockStrings::new();
let accounts = config
.load_accounts(&events, &stockstrings)
.load_accounts(&events, &stockstrings, &dir)
.await
.context("failed to load accounts")?;
@@ -107,10 +107,11 @@ impl Accounts {
///
/// Returns account ID.
pub async fn add_account(&mut self) -> Result<u32> {
let account_config = self.config.new_account(&self.dir).await?;
let account_config = self.config.new_account().await?;
let dbfile = account_config.dbfile(&self.dir);
let ctx = Context::new(
&account_config.dbfile(),
&dbfile,
account_config.id,
self.events.clone(),
self.stockstrings.clone(),
@@ -123,10 +124,10 @@ impl Accounts {
/// Adds a new closed account.
pub async fn add_closed_account(&mut self) -> Result<u32> {
let account_config = self.config.new_account(&self.dir).await?;
let account_config = self.config.new_account().await?;
let ctx = Context::new_closed(
&account_config.dbfile(),
&account_config.dbfile(&self.dir),
account_config.id,
self.events.clone(),
self.stockstrings.clone(),
@@ -147,6 +148,8 @@ impl Accounts {
drop(ctx);
if let Some(cfg) = self.config.get_account(id) {
let account_path = self.dir.join(cfg.dir);
// Spend up to 1 minute trying to remove the files.
// Files may remain locked up to 30 seconds due to r2d2 bug:
// https://github.com/sfackler/r2d2/issues/99
@@ -154,7 +157,7 @@ impl Accounts {
loop {
counter += 1;
if let Err(err) = fs::remove_dir_all(&cfg.dir)
if let Err(err) = fs::remove_dir_all(&account_path)
.await
.context("failed to remove account data")
{
@@ -187,16 +190,16 @@ impl Accounts {
// create new account
let account_config = self
.config
.new_account(&self.dir)
.new_account()
.await
.context("failed to create new account")?;
let new_dbfile = account_config.dbfile();
let new_dbfile = account_config.dbfile(&self.dir);
let new_blobdir = Context::derive_blobdir(&new_dbfile);
let new_walfile = Context::derive_walfile(&new_dbfile);
let res = {
fs::create_dir_all(&account_config.dir)
fs::create_dir_all(self.dir.join(&account_config.dir))
.await
.context("failed to create dir")?;
fs::rename(&dbfile, &new_dbfile)
@@ -358,8 +361,17 @@ impl Config {
/// Read a configuration from the given file into memory.
pub async fn from_file(file: PathBuf) -> Result<Self> {
let dir = file.parent().context("can't get config file directory")?;
let bytes = fs::read(&file).await.context("failed to read file")?;
let inner: InnerConfig = toml::from_slice(&bytes).context("failed to parse config")?;
let mut inner: InnerConfig = toml::from_slice(&bytes).context("failed to parse config")?;
// Previous versions of the core stored absolute paths in account config.
// Convert them to relative paths.
for account in &mut inner.accounts {
if let Ok(new_dir) = account.dir.strip_prefix(dir) {
account.dir = new_dir.to_path_buf();
}
}
Ok(Config { file, inner })
}
@@ -372,12 +384,13 @@ impl Config {
&self,
events: &Events,
stockstrings: &StockStrings,
dir: &Path,
) -> Result<BTreeMap<u32, Context>> {
let mut accounts = BTreeMap::new();
for account_config in &self.inner.accounts {
let ctx = Context::new(
&account_config.dbfile(),
&account_config.dbfile(dir),
account_config.id,
events.clone(),
stockstrings.clone(),
@@ -386,7 +399,7 @@ impl Config {
.with_context(|| {
format!(
"failed to create context from file {:?}",
account_config.dbfile()
account_config.dbfile(dir)
)
})?;
@@ -396,12 +409,12 @@ impl Config {
Ok(accounts)
}
/// Create a new account in the given root directory.
async fn new_account(&mut self, dir: &Path) -> Result<AccountConfig> {
/// Creates a new account in the account manager directory.
async fn new_account(&mut self) -> Result<AccountConfig> {
let id = {
let id = self.inner.next_id;
let uuid = Uuid::new_v4();
let target_dir = dir.join(uuid.to_string());
let target_dir = PathBuf::from(uuid.to_string());
self.inner.accounts.push(AccountConfig {
id,
@@ -473,14 +486,16 @@ struct AccountConfig {
/// Unique id.
pub id: u32,
/// Root directory for all data for this account.
///
/// The path is relative to the account manager directory.
pub dir: std::path::PathBuf,
pub uuid: Uuid,
}
impl AccountConfig {
/// Get the canoncial dbfile name for this configuration.
pub fn dbfile(&self) -> std::path::PathBuf {
self.dir.join(DB_NAME)
pub fn dbfile(&self, accounts_dir: &Path) -> std::path::PathBuf {
accounts_dir.join(&self.dir).join(DB_NAME)
}
}