From b86e46fe00f44f2c0b68e712a497290c098169dd Mon Sep 17 00:00:00 2001 From: Micheal Smith Date: Mon, 11 Aug 2025 19:31:38 -0500 Subject: [PATCH] Added chroot support. --- config.toml | 4 ++++ src/command.rs | 0 src/main.rs | 18 ++++++++++++++---- src/setup.rs | 10 ++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) delete mode 100644 src/command.rs diff --git a/config.toml b/config.toml index d3affcf..b0c8b68 100644 --- a/config.toml +++ b/config.toml @@ -2,6 +2,10 @@ api-key = "" base-url = "api.openai.com" +chroot-dir = "/home/bot/root" + +# If using chroot (recommended) then this will be relative. +command-path = "/cmds" # If you don't already know the model name you can generally find a listing # on the models API pages. diff --git a/src/command.rs b/src/command.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/main.rs b/src/main.rs index 270c344..b639706 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use color_eyre::{ eyre::WrapErr, }; use human_panic::setup_panic; +use std::os::unix::fs; use tracing::{ Level, info, @@ -10,12 +11,12 @@ use tracing::{ use tracing_subscriber::FmtSubscriber; mod chat; -mod command; +mod commands; mod qna; mod setup; -const DEFAULT_INSTRUCT: &'static str = -"You are a shady, yet helpful IRC bot. You try to give responses that can +const DEFAULT_INSTRUCT: &str = + "You are a shady, yet helpful IRC bot. You try to give responses that can be sent in a single IRC response according to the specification."; #[tokio::main] @@ -36,6 +37,13 @@ async fn main() -> Result<()> { let settings = setup::init().await.wrap_err("Failed to initialize.")?; let config = settings.config; + // chroot if applicable. + if let Ok(chroot_path) = config.get_string("chroot-dir") { + fs::chroot(&chroot_path) + .wrap_err_with(|| format!("Failed setting chroot '{}'", chroot_path.to_string()))?; + std::env::set_current_dir("/").wrap_err("Couldn't change directory after chroot.")?; + } + let handle = qna::new( config.get_string("api-key").wrap_err("API missing.")?, config @@ -44,7 +52,9 @@ async fn main() -> Result<()> { config .get_string("model") .wrap_err("model string missing.")?, - config.get_string("instruct").unwrap_or_else(|_| DEFAULT_INSTRUCT.to_string()), + config + .get_string("instruct") + .unwrap_or_else(|_| DEFAULT_INSTRUCT.to_string()), ) .wrap_err("Couldn't initialize LLM handle.")?; let mut c = chat::new(&config, &handle).await?; diff --git a/src/setup.rs b/src/setup.rs index 7453afa..7c29ecf 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -23,6 +23,14 @@ pub(crate) struct Args { /// Base URL for the LLM API to use. pub(crate) base_url: Option, + /// Directory to use for chroot (recommended). + #[arg(long)] + pub(crate) chroot_dir: Option, + + /// Root directory for file based command structure. + #[arg(long)] + pub(crate) command_dir: Option, + #[arg(long)] /// Instructions to the model on how to behave. pub(crate) intruct: Option, @@ -93,6 +101,8 @@ pub async fn init() -> Result { // but a derive macro could do this a bit better if this becomes too large. .set_override_option("api-key", args.api_key.clone())? .set_override_option("base-url", args.base_url.clone())? + .set_override_option("chroot-dir", args.chroot_dir.clone())? + .set_override_option("command-path", args.command_dir.clone())? .set_override_option("model", args.model.clone())? .set_override_option("instruct", args.model.clone())? .set_override_option("channels", args.channels.clone())?