fix tui os and backups clear

This commit is contained in:
phact 2025-12-03 11:32:38 -05:00
parent a93da15ae2
commit 19c96140a6
2 changed files with 87 additions and 11 deletions

View file

@ -1012,6 +1012,54 @@ class ContainerManager:
else:
yield False, "Some errors occurred during service restart", False
async def clear_opensearch_data_volume(self) -> AsyncIterator[tuple[bool, str]]:
"""Clear opensearch data using a temporary container with proper permissions."""
if not self.is_available():
yield False, "No container runtime available"
return
yield False, "Clearing OpenSearch data volume..."
# Get the absolute path to opensearch-data directory
opensearch_data_path = Path("opensearch-data").absolute()
if not opensearch_data_path.exists():
yield True, "OpenSearch data directory does not exist, skipping"
return
# Use the opensearch container with proper volume mount flags
# :Z flag ensures proper SELinux labeling and UID mapping for rootless containers
cmd = [
"run",
"--rm",
"-v", f"{opensearch_data_path}:/usr/share/opensearch/data:Z",
"langflowai/openrag-opensearch:latest",
"bash", "-c",
"rm -rf /usr/share/opensearch/data/* /usr/share/opensearch/data/.[!.]* && echo 'Cleared successfully'"
]
success, stdout, stderr = await self._run_runtime_command(cmd)
if success and "Cleared successfully" in stdout:
yield True, "OpenSearch data cleared successfully"
else:
# If it fails, try with the base opensearch image
yield False, "Retrying with base OpenSearch image..."
cmd = [
"run",
"--rm",
"-v", f"{opensearch_data_path}:/usr/share/opensearch/data:Z",
"opensearchproject/opensearch:3.0.0",
"bash", "-c",
"rm -rf /usr/share/opensearch/data/* /usr/share/opensearch/data/.[!.]* && echo 'Cleared successfully'"
]
success, stdout, stderr = await self._run_runtime_command(cmd)
if success and "Cleared successfully" in stdout:
yield True, "OpenSearch data cleared successfully"
else:
yield False, f"Failed to clear OpenSearch data: {stderr if stderr else 'Unknown error'}"
async def reset_services(self) -> AsyncIterator[tuple[bool, str]]:
"""Reset all services (stop, remove containers/volumes, clear data) and yield progress updates."""
yield False, "Stopping all services..."

View file

@ -4,7 +4,7 @@ import asyncio
import re
import shutil
from pathlib import Path
from typing import Literal, Any, Optional
from typing import Literal, Any, Optional, AsyncIterator
# Define button variant type
ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
@ -478,35 +478,36 @@ class MonitorScreen(Screen):
self.notify("Factory reset cancelled", severity="information")
return
# Clear config, opensearch-data folders, and conversations.json
# Clear config, conversations.json, and flow backups first (before stopping containers)
try:
config_path = Path("config")
opensearch_data_path = Path("opensearch-data")
conversations_file = Path("conversations.json")
flows_backup_path = Path("flows/backup")
if config_path.exists():
shutil.rmtree(config_path)
# Recreate empty config directory
config_path.mkdir(parents=True, exist_ok=True)
if opensearch_data_path.exists():
shutil.rmtree(opensearch_data_path)
# Recreate empty opensearch-data directory
opensearch_data_path.mkdir(parents=True, exist_ok=True)
if conversations_file.exists():
conversations_file.unlink()
# Delete flow backups if they exist
if flows_backup_path.exists():
shutil.rmtree(flows_backup_path)
# Recreate empty backup directory
flows_backup_path.mkdir(parents=True, exist_ok=True)
except Exception as e:
self.notify(
f"Error clearing folders: {str(e)}",
f"Error clearing config: {str(e)}",
severity="error",
timeout=10,
)
return
# Show command output in modal dialog
command_generator = self.container_manager.reset_services()
# Show command output in modal dialog for stopping services and clearing data
command_generator = self._factory_reset_with_data_clear()
modal = CommandOutputModal(
"Factory Resetting Services",
command_generator,
@ -516,6 +517,33 @@ class MonitorScreen(Screen):
finally:
self.operation_in_progress = False
async def _factory_reset_with_data_clear(self) -> AsyncIterator[tuple[bool, str]]:
"""Generator that stops services and clears opensearch data."""
# First stop all services
async for success, message in self.container_manager.reset_services():
yield success, message
if not success and "failed" in message.lower():
return
# Now clear opensearch-data using container
yield False, "Clearing OpenSearch data..."
opensearch_data_path = Path("opensearch-data")
if opensearch_data_path.exists():
async for success, message in self.container_manager.clear_opensearch_data_volume():
yield success, message
if not success and "failed" in message.lower():
return
# Recreate empty opensearch-data directory
try:
opensearch_data_path.mkdir(parents=True, exist_ok=True)
yield True, "OpenSearch data directory recreated"
except Exception as e:
yield False, f"Error recreating opensearch-data directory: {e}"
return
yield True, "Factory reset completed successfully"
def _check_flow_backups(self) -> bool:
"""Check if there are any flow backups in ./flows/backup directory."""
from pathlib import Path