From 5b5c84adfcfa340ac440858426b813cf029ff840 Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Mon, 26 Jan 2026 01:52:46 +0100 Subject: [PATCH 1/5] tmp farm module (WIP) --- rs/src/main.rs | 4 ++ rs/src/modules/farm.rs | 103 +++++++++++++++++++++++++++++++++++++++++ rs/src/modules/mod.rs | 1 + 3 files changed, 108 insertions(+) create mode 100644 rs/src/modules/farm.rs diff --git a/rs/src/main.rs b/rs/src/main.rs index e4bb621..aab1ad6 100644 --- a/rs/src/main.rs +++ b/rs/src/main.rs @@ -16,6 +16,7 @@ use crate::modules::sql::SqlArgs; use crate::types::RepoOrigin; use anyhow::bail; use clap::{CommandFactory, Parser, Subcommand}; +use crate::modules::farm::FarmArgs; use crate::modules::watch::WatchArgs; mod config; @@ -47,6 +48,8 @@ pub enum Modules { Db(DbArgs), /// Stops containers Down(ContainerActionArgs), + /// Allows managing a wiki farm + Farm(FarmArgs), /// Prints info about the environment Info, /// Runs a linter @@ -107,6 +110,7 @@ impl Modules { Modules::Composer(args) => modules::composer::execute(config.unwrap(), args), Modules::Db(args) => modules::db::execute(config.unwrap(), args), Modules::Down(args) => modules::container_action::down(config.unwrap(), args), + Modules::Farm(args) => modules::farm::execute(config.unwrap(), args), Modules::Info => modules::info::execute(config.unwrap()), Modules::Lint(args) => modules::lint::execute(config.unwrap(), args, true), Modules::ListRepoRemotes => modules::list_repo_remotes::execute(config.unwrap()), diff --git a/rs/src/modules/farm.rs b/rs/src/modules/farm.rs new file mode 100644 index 0000000..9afb9ac --- /dev/null +++ b/rs/src/modules/farm.rs @@ -0,0 +1,103 @@ +use std::fs; +use anyhow::{anyhow, bail, Context}; +use clap::{Args, Subcommand}; +use crate::config::MWUtilConfig; +use crate::constants::MEDIAWIKI_CONTAINER; +use crate::exec::{run_sql_query, DbCommandDatabase, DbCommandUser}; +use crate::Modules; +use crate::modules::run::RunArgs; + +#[derive(Args)] +pub struct FarmArgs { + #[command(subcommand)] + command: FarmCommand, +} + +#[derive(Subcommand)] +pub enum FarmCommand { + /// Install a new wiki + Install(InstallArgs), +} + +#[derive(Args)] +pub struct InstallArgs { + /// The DB name of the wiki that should be installed + db_name: String, +} + +pub fn execute(config: &MWUtilConfig, farm_args: FarmArgs) -> anyhow::Result<()> { + match farm_args.command { + FarmCommand::Install(args) => install_wiki(config, args), + } +} + +fn install_wiki(config: &MWUtilConfig, args: InstallArgs) -> anyhow::Result<()> { + if !args.db_name.ends_with("wiki") { + // TODO maybe we want to allow other suffixes? + bail!("The DB name must end with 'wiki'!"); + } + + // TODO merge with code in db? + let status = run_sql_query( + config, + DbCommandUser::Root, + Some(DbCommandDatabase::None), + format!( + "CREATE DATABASE IF NOT EXISTS `{}`;", + args.db_name, + ).as_str() + ).context("Failed to create database")?; + if !status.success() { + bail!("Failed to create database! Exit code: {:?}", status.code()); + } + + let status = run_sql_query( + config, + DbCommandUser::Root, + Some(DbCommandDatabase::None), + format!( + "GRANT ALL PRIVILEGES ON `{}`.* TO {};", + args.db_name, + config.db_user.clone().ok_or_else(|| anyhow!("DB User not set!"))? + ).as_str() + ).context("Failed to grant privileges")?; + if !status.success() { + bail!("Failed to grant privileges! Exit code: {:?}", status.code()); + } + + println!("Created database."); + + let local_settings = config.core_dir.join("LocalSettings.php"); + let local_settings_tmp = config.core_dir.join("LocalSettings.temp.php"); + fs::rename(&local_settings, &local_settings_tmp)?; + + // TODO merge with same code in reset + let install_args = vec![ + format!("--dbname={}", args.db_name), + format!("--dbuser={}", config.db_user.clone().ok_or_else(|| anyhow!("DB User not set!"))?), + format!("--dbpass={}", config.db_password.clone().ok_or_else(|| anyhow!("DB Password not set!"))?), + format!("--dbserver={}", config.db_type.clone().get_container_name()), + format!("--server={}", config.mw_server.clone().ok_or_else(|| anyhow!("MW Server not set!"))?), + format!("--scriptpath={}", config.mw_script_path.clone().ok_or_else(|| anyhow!("MW Script Path not set!"))?), + format!("--lang={}", config.mw_language.clone().ok_or_else(|| anyhow!("MW Language not set!"))?), + format!("--pass={}", config.mw_password.clone().ok_or_else(|| anyhow!("MW Password not set!"))?), + MEDIAWIKI_CONTAINER.to_string(), + config.mw_user.clone().ok_or_else(|| anyhow!("MW User not set!"))?, + ]; + let result = Modules::Run(RunArgs { + script: "install".to_string(), + extra_args: install_args, + }).run(config); + + fs::rename(local_settings_tmp, local_settings)?; + + result?; + + // TODO add args to Update module instead + Modules::Run(RunArgs { + script: "update".into(), + extra_args: vec!["--wiki".into(), args.db_name], + }).run(config)?; + + Ok(()) +} \ No newline at end of file diff --git a/rs/src/modules/mod.rs b/rs/src/modules/mod.rs index 837f23a..57702d0 100644 --- a/rs/src/modules/mod.rs +++ b/rs/src/modules/mod.rs @@ -15,3 +15,4 @@ pub(crate) mod reset; pub(crate) mod container_action; pub(crate) mod setup_repo; pub(crate) mod watch; +pub(crate) mod farm; From e336bed6bb07357325a21e8bc0173b6a71698eeb Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Mon, 16 Feb 2026 00:27:49 +0100 Subject: [PATCH 2/5] refactor and fix --- rs/src/modules/db.rs | 10 +++++++++- rs/src/modules/farm.rs | 34 ++-------------------------------- rs/src/modules/reset.rs | 28 ++++++++++++++++++++++------ 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/rs/src/modules/db.rs b/rs/src/modules/db.rs index b887192..d1792fc 100644 --- a/rs/src/modules/db.rs +++ b/rs/src/modules/db.rs @@ -154,13 +154,21 @@ pub fn delete_all_dumps(config: &MWUtilConfig) -> anyhow::Result<()> { } pub fn drop_mw_database(config: &MWUtilConfig) -> anyhow::Result<()> { + let db = &config.mw_database.clone().ok_or_else(|| anyhow!("MW database not set!"))?; + drop_database( + config, + db + ) +} + +pub fn drop_database(config: &MWUtilConfig, db: &str) -> anyhow::Result<()> { let status = run_sql_query( config, DbCommandUser::Root, Some(DbCommandDatabase::None), format!( "DROP DATABASE IF EXISTS `{}`;", - config.mw_database.clone().ok_or_else(|| anyhow!("MW database not set!"))? + db ).as_str(), ).context("Failed to drop database")?; if !status.success() { diff --git a/rs/src/modules/farm.rs b/rs/src/modules/farm.rs index 9afb9ac..6745429 100644 --- a/rs/src/modules/farm.rs +++ b/rs/src/modules/farm.rs @@ -5,6 +5,7 @@ use crate::config::MWUtilConfig; use crate::constants::MEDIAWIKI_CONTAINER; use crate::exec::{run_sql_query, DbCommandDatabase, DbCommandUser}; use crate::Modules; +use crate::modules::reset; use crate::modules::run::RunArgs; #[derive(Args)] @@ -37,7 +38,6 @@ fn install_wiki(config: &MWUtilConfig, args: InstallArgs) -> anyhow::Result<()> bail!("The DB name must end with 'wiki'!"); } - // TODO merge with code in db? let status = run_sql_query( config, DbCommandUser::Root, @@ -67,37 +67,7 @@ fn install_wiki(config: &MWUtilConfig, args: InstallArgs) -> anyhow::Result<()> println!("Created database."); - let local_settings = config.core_dir.join("LocalSettings.php"); - let local_settings_tmp = config.core_dir.join("LocalSettings.temp.php"); - fs::rename(&local_settings, &local_settings_tmp)?; - - // TODO merge with same code in reset - let install_args = vec![ - format!("--dbname={}", args.db_name), - format!("--dbuser={}", config.db_user.clone().ok_or_else(|| anyhow!("DB User not set!"))?), - format!("--dbpass={}", config.db_password.clone().ok_or_else(|| anyhow!("DB Password not set!"))?), - format!("--dbserver={}", config.db_type.clone().get_container_name()), - format!("--server={}", config.mw_server.clone().ok_or_else(|| anyhow!("MW Server not set!"))?), - format!("--scriptpath={}", config.mw_script_path.clone().ok_or_else(|| anyhow!("MW Script Path not set!"))?), - format!("--lang={}", config.mw_language.clone().ok_or_else(|| anyhow!("MW Language not set!"))?), - format!("--pass={}", config.mw_password.clone().ok_or_else(|| anyhow!("MW Password not set!"))?), - MEDIAWIKI_CONTAINER.to_string(), - config.mw_user.clone().ok_or_else(|| anyhow!("MW User not set!"))?, - ]; - let result = Modules::Run(RunArgs { - script: "install".to_string(), - extra_args: install_args, - }).run(config); - - fs::rename(local_settings_tmp, local_settings)?; - - result?; - - // TODO add args to Update module instead - Modules::Run(RunArgs { - script: "update".into(), - extra_args: vec!["--wiki".into(), args.db_name], - }).run(config)?; + reset::reset_database(config, &args.db_name, true)?; Ok(()) } \ No newline at end of file diff --git a/rs/src/modules/reset.rs b/rs/src/modules/reset.rs index d21862d..d5ae48a 100644 --- a/rs/src/modules/reset.rs +++ b/rs/src/modules/reset.rs @@ -39,7 +39,7 @@ pub fn execute(config: &MWUtilConfig, args: ResetArgs) -> anyhow::Result<()> { } if actions.contains(&ResetActions::Database) { spinner.next("Resetting database"); - reset_database(config)?; + reset_default_database(config)?; } if actions.contains(&ResetActions::OpenSearch) { spinner.next("Resetting OpenSearch"); @@ -72,15 +72,25 @@ pub fn reset_uploads(config: &MWUtilConfig) -> anyhow::Result<()> { Ok(()) } -pub fn reset_database(config: &MWUtilConfig) -> anyhow::Result<()> { - db::drop_mw_database(config)?; +pub fn reset_default_database(config: &MWUtilConfig) -> anyhow::Result<()> { + reset_database( + config, + &config.mw_database.clone().ok_or_else(|| anyhow!("MW database not set!"))?, + false + ) +} + +pub fn reset_database(config: &MWUtilConfig, db: &str, new: bool) -> anyhow::Result<()> { + if !new { + db::drop_database(config, db)?; + } let local_settings = config.core_dir.join("LocalSettings.php"); let local_settings_tmp = config.core_dir.join("LocalSettings.temp.php"); fs::rename(&local_settings, &local_settings_tmp)?; let install_args = vec![ - format!("--dbname={}", config.mw_database.clone().ok_or_else(|| anyhow!("MW Database not set!"))?), + format!("--dbname={}", db), format!("--dbuser={}", config.db_user.clone().ok_or_else(|| anyhow!("DB User not set!"))?), format!("--dbpass={}", config.db_password.clone().ok_or_else(|| anyhow!("DB Password not set!"))?), format!("--dbserver={}", config.db_type.clone().get_container_name()), @@ -101,8 +111,14 @@ pub fn reset_database(config: &MWUtilConfig) -> anyhow::Result<()> { result?; - Modules::Update.run(config)?; - Modules::Recreate(Default::default()).run(config)?; + Modules::Run(RunArgs { + script: "update".into(), + extra_args: vec!["--wiki".into(), db.into()], + }).run(config)?; + + if !new { + Modules::Recreate(Default::default()).run(config)?; + } Ok(()) } From e09d31ce71ae4f22840cf2d9fff80995497a8168 Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Mon, 16 Feb 2026 00:29:42 +0100 Subject: [PATCH 3/5] fix --- rs/src/modules/reset.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/src/modules/reset.rs b/rs/src/modules/reset.rs index d5ae48a..91604b6 100644 --- a/rs/src/modules/reset.rs +++ b/rs/src/modules/reset.rs @@ -113,7 +113,7 @@ pub fn reset_database(config: &MWUtilConfig, db: &str, new: bool) -> anyhow::Res Modules::Run(RunArgs { script: "update".into(), - extra_args: vec!["--wiki".into(), db.into()], + extra_args: vec!["--wiki".into(), db.into(), "--quick"], }).run(config)?; if !new { From a14d7da7dc408aa0473c9e44496e638f20b00e78 Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Mon, 16 Feb 2026 00:31:05 +0100 Subject: [PATCH 4/5] fix again --- rs/src/modules/reset.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/src/modules/reset.rs b/rs/src/modules/reset.rs index 91604b6..3f7a64d 100644 --- a/rs/src/modules/reset.rs +++ b/rs/src/modules/reset.rs @@ -113,7 +113,7 @@ pub fn reset_database(config: &MWUtilConfig, db: &str, new: bool) -> anyhow::Res Modules::Run(RunArgs { script: "update".into(), - extra_args: vec!["--wiki".into(), db.into(), "--quick"], + extra_args: vec!["--wiki".into(), db.into(), "--quick".into()], }).run(config)?; if !new { From 8f68614fc1009b598009c182f6232dd8b1ea3ec8 Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Mon, 16 Feb 2026 00:31:24 +0100 Subject: [PATCH 5/5] remove unused --- rs/src/modules/farm.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rs/src/modules/farm.rs b/rs/src/modules/farm.rs index 6745429..5459052 100644 --- a/rs/src/modules/farm.rs +++ b/rs/src/modules/farm.rs @@ -1,12 +1,8 @@ -use std::fs; use anyhow::{anyhow, bail, Context}; use clap::{Args, Subcommand}; use crate::config::MWUtilConfig; -use crate::constants::MEDIAWIKI_CONTAINER; use crate::exec::{run_sql_query, DbCommandDatabase, DbCommandUser}; -use crate::Modules; use crate::modules::reset; -use crate::modules::run::RunArgs; #[derive(Args)] pub struct FarmArgs {