Persist open-webui state to app data dir
This commit is contained in:
parent
482eec9d1f
commit
1b16301a17
@ -1,4 +1,5 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from open_webui import app
|
from open_webui import app
|
||||||
|
|
||||||
@ -14,6 +15,23 @@ def main():
|
|||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Set up Open WebUI environment variables if they're provided
|
||||||
|
# These will be set by the Tauri app for proper data persistence
|
||||||
|
data_dir = os.environ.get("DATA_DIR")
|
||||||
|
if data_dir:
|
||||||
|
print(f"Using data directory: {data_dir}")
|
||||||
|
# Ensure the data directory exists
|
||||||
|
os.makedirs(data_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Set additional Open WebUI environment variables for persistence
|
||||||
|
os.environ.setdefault("WEBUI_DATA_DIR", data_dir)
|
||||||
|
os.environ.setdefault("WEBUI_UPLOAD_DIR", os.path.join(data_dir, "uploads"))
|
||||||
|
os.environ.setdefault("WEBUI_CACHE_DIR", os.path.join(data_dir, "cache"))
|
||||||
|
|
||||||
|
# Create subdirectories
|
||||||
|
os.makedirs(os.environ["WEBUI_UPLOAD_DIR"], exist_ok=True)
|
||||||
|
os.makedirs(os.environ["WEBUI_CACHE_DIR"], exist_ok=True)
|
||||||
|
|
||||||
# Run the FastAPI app using uvicorn
|
# Run the FastAPI app using uvicorn
|
||||||
uvicorn.run(app, host=args.host, port=args.port, log_level="info")
|
uvicorn.run(app, host=args.host, port=args.port, log_level="info")
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,22 @@ struct AppState {
|
|||||||
backend_process: Arc<Mutex<Option<tauri_plugin_shell::process::CommandChild>>>,
|
backend_process: Arc<Mutex<Option<tauri_plugin_shell::process::CommandChild>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a secure secret key for Open WebUI
|
||||||
|
fn generate_secret_key() -> String {
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_nanos()
|
||||||
|
.hash(&mut hasher);
|
||||||
|
|
||||||
|
format!("{:x}", hasher.finish())
|
||||||
|
}
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn greet(name: &str) -> String {
|
fn greet(name: &str) -> String {
|
||||||
@ -38,12 +54,33 @@ async fn start_backend(app: tauri::AppHandle) -> Result<u16, String> {
|
|||||||
// Find an available port
|
// Find an available port
|
||||||
let port = find_available_port().map_err(|e| e.to_string())?;
|
let port = find_available_port().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Start the backend sidecar
|
// Get the app data directory for persistence
|
||||||
|
let app_data_dir = app
|
||||||
|
.path()
|
||||||
|
.app_data_dir()
|
||||||
|
.map_err(|e| format!("Failed to get app data directory: {}", e))?;
|
||||||
|
|
||||||
|
// Create the data directory if it doesn't exist
|
||||||
|
std::fs::create_dir_all(&app_data_dir)
|
||||||
|
.map_err(|e| format!("Failed to create app data directory: {}", e))?;
|
||||||
|
|
||||||
|
// Set up Open WebUI data directory
|
||||||
|
let webui_data_dir = app_data_dir.join("open-webui");
|
||||||
|
std::fs::create_dir_all(&webui_data_dir)
|
||||||
|
.map_err(|e| format!("Failed to create Open WebUI data directory: {}", e))?;
|
||||||
|
|
||||||
|
// Start the backend sidecar with proper environment variables
|
||||||
let sidecar_command = app
|
let sidecar_command = app
|
||||||
.shell()
|
.shell()
|
||||||
.sidecar("glowpath-backend")
|
.sidecar("glowpath-backend")
|
||||||
.map_err(|e| format!("Failed to create sidecar command: {}", e))?
|
.map_err(|e| format!("Failed to create sidecar command: {}", e))?
|
||||||
.args(&["serve", "--port", &port.to_string()]);
|
.args(&["serve", "--port", &port.to_string()])
|
||||||
|
.env("WEBUI_SECRET_KEY", &generate_secret_key()) // Generate a proper secret
|
||||||
|
.env("DATA_DIR", &webui_data_dir)
|
||||||
|
.env(
|
||||||
|
"WEBUI_DATABASE_URL",
|
||||||
|
format!("sqlite:///{}/webui.db", webui_data_dir.to_string_lossy()),
|
||||||
|
);
|
||||||
|
|
||||||
let (mut rx, child) = sidecar_command
|
let (mut rx, child) = sidecar_command
|
||||||
.spawn()
|
.spawn()
|
||||||
@ -126,6 +163,16 @@ async fn stop_backend(app: tauri::AppHandle) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_data_directory(app: tauri::AppHandle) -> Result<String, String> {
|
||||||
|
let app_data_dir = app
|
||||||
|
.path()
|
||||||
|
.app_data_dir()
|
||||||
|
.map_err(|e| format!("Failed to get app data directory: {}", e))?;
|
||||||
|
|
||||||
|
Ok(app_data_dir.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
fn find_available_port() -> Result<u16, Box<dyn std::error::Error>> {
|
fn find_available_port() -> Result<u16, Box<dyn std::error::Error>> {
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
|
||||||
@ -146,7 +193,8 @@ pub fn run() {
|
|||||||
ollama_status,
|
ollama_status,
|
||||||
start_backend,
|
start_backend,
|
||||||
get_backend_port,
|
get_backend_port,
|
||||||
stop_backend
|
stop_backend,
|
||||||
|
get_data_directory
|
||||||
])
|
])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
// Optionally start backend on app startup
|
// Optionally start backend on app startup
|
||||||
|
|||||||
@ -75,6 +75,10 @@ class BackendService {
|
|||||||
return this.baseUrl !== null;
|
return this.baseUrl !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getDataDirectory(): Promise<string> {
|
||||||
|
return await invoke<string>("get_data_directory");
|
||||||
|
}
|
||||||
|
|
||||||
async fetch(path: string, options?: RequestInit): Promise<Response> {
|
async fetch(path: string, options?: RequestInit): Promise<Response> {
|
||||||
if (!this.baseUrl) {
|
if (!this.baseUrl) {
|
||||||
throw new Error("Backend service not initialized");
|
throw new Error("Backend service not initialized");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user