fix tui os and backups clear
This commit is contained in:
parent
a93da15ae2
commit
19c96140a6
2 changed files with 87 additions and 11 deletions
|
|
@ -1012,6 +1012,54 @@ class ContainerManager:
|
||||||
else:
|
else:
|
||||||
yield False, "Some errors occurred during service restart", False
|
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]]:
|
async def reset_services(self) -> AsyncIterator[tuple[bool, str]]:
|
||||||
"""Reset all services (stop, remove containers/volumes, clear data) and yield progress updates."""
|
"""Reset all services (stop, remove containers/volumes, clear data) and yield progress updates."""
|
||||||
yield False, "Stopping all services..."
|
yield False, "Stopping all services..."
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import asyncio
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Literal, Any, Optional
|
from typing import Literal, Any, Optional, AsyncIterator
|
||||||
|
|
||||||
# Define button variant type
|
# Define button variant type
|
||||||
ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
|
ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
|
||||||
|
|
@ -478,35 +478,36 @@ class MonitorScreen(Screen):
|
||||||
self.notify("Factory reset cancelled", severity="information")
|
self.notify("Factory reset cancelled", severity="information")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Clear config, opensearch-data folders, and conversations.json
|
# Clear config, conversations.json, and flow backups first (before stopping containers)
|
||||||
try:
|
try:
|
||||||
config_path = Path("config")
|
config_path = Path("config")
|
||||||
opensearch_data_path = Path("opensearch-data")
|
|
||||||
conversations_file = Path("conversations.json")
|
conversations_file = Path("conversations.json")
|
||||||
|
flows_backup_path = Path("flows/backup")
|
||||||
|
|
||||||
if config_path.exists():
|
if config_path.exists():
|
||||||
shutil.rmtree(config_path)
|
shutil.rmtree(config_path)
|
||||||
# Recreate empty config directory
|
# Recreate empty config directory
|
||||||
config_path.mkdir(parents=True, exist_ok=True)
|
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():
|
if conversations_file.exists():
|
||||||
conversations_file.unlink()
|
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:
|
except Exception as e:
|
||||||
self.notify(
|
self.notify(
|
||||||
f"Error clearing folders: {str(e)}",
|
f"Error clearing config: {str(e)}",
|
||||||
severity="error",
|
severity="error",
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Show command output in modal dialog
|
# Show command output in modal dialog for stopping services and clearing data
|
||||||
command_generator = self.container_manager.reset_services()
|
command_generator = self._factory_reset_with_data_clear()
|
||||||
modal = CommandOutputModal(
|
modal = CommandOutputModal(
|
||||||
"Factory Resetting Services",
|
"Factory Resetting Services",
|
||||||
command_generator,
|
command_generator,
|
||||||
|
|
@ -516,6 +517,33 @@ class MonitorScreen(Screen):
|
||||||
finally:
|
finally:
|
||||||
self.operation_in_progress = False
|
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:
|
def _check_flow_backups(self) -> bool:
|
||||||
"""Check if there are any flow backups in ./flows/backup directory."""
|
"""Check if there are any flow backups in ./flows/backup directory."""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue