Spaces:
Running
Running
| import asyncio | |
| import shutil | |
| import tempfile | |
| import os | |
| import sys | |
| import subprocess | |
| from pathlib import Path | |
| from typing import Literal | |
| from backend.services.usb_vault import encrypt_directory | |
| from backend.security.vault_sanitizer import strip_personal_data | |
| async def stage_full_environment(source_path: str, staging_dir: str): | |
| omega_root = source_path | |
| # ββ 1. MAIN CODEBASE βββββββββββββββββββββββββββββββββββββββββββββ | |
| if getattr(sys, 'frozen', False): | |
| shutil.copy2(sys.executable, os.path.join(staging_dir, "JARVIS_OMEGA.exe")) | |
| else: | |
| code_staging = os.path.join(staging_dir, "F.R.I.D.A.Y - OMEGA") | |
| shutil.copytree(omega_root, code_staging, dirs_exist_ok=True) | |
| # ββ 2. HF DEPLOY STAGE SERVER ββββββββββββββββββββββββββββββββββββ | |
| hf_stage = os.path.join(omega_root, "scratch", "hf_deploy_stage") | |
| if os.path.exists(hf_stage): | |
| shutil.copytree(hf_stage, os.path.join(staging_dir, "hf_deploy_stage"), dirs_exist_ok=True) | |
| # ββ 3. CLOUD DEPLOYMENT SERVER βββββββββββββββββββββββββββββββββββ | |
| cloud_dir = os.path.join(omega_root, "cloud_deployment") | |
| if os.path.exists(cloud_dir): | |
| shutil.copytree(cloud_dir, os.path.join(staging_dir, "cloud_deployment"), dirs_exist_ok=True) | |
| # ββ 4. ANDROID APK SERVER (phone guardian) βββββββββββββββββββββββ | |
| phone_dir = os.path.join(omega_root, "phone") | |
| if os.path.exists(phone_dir): | |
| shutil.copytree(phone_dir, os.path.join(staging_dir, "phone"), dirs_exist_ok=True) | |
| # ββ 5. CONFIG + SECRETS ββββββββββββββββββββββββββββββββββββββββββ | |
| for cfg_file in ["config.local.json", "config.json", ".env.example"]: | |
| cfg_path = os.path.join(omega_root, cfg_file) | |
| if os.path.exists(cfg_path): | |
| shutil.copy2(cfg_path, os.path.join(staging_dir, cfg_file)) | |
| # ββ 6. APPDATA: SQLite DB + allowlist + vault_keys βββββββββββββββ | |
| appdata_path = os.path.join(os.environ.get('APPDATA', os.path.expanduser('~')), 'JARVIS_OS') | |
| if os.path.exists(appdata_path): | |
| shutil.copytree(appdata_path, os.path.join(staging_dir, "JARVIS_OS_APPDATA"), dirs_exist_ok=True) | |
| # ββ 7. LOCAL memory.db (dev mode) & Chroma & Dumps βββββββββββββββ | |
| local_db = os.path.join(omega_root, "memory.db") | |
| if os.path.exists(local_db): | |
| shutil.copy2(local_db, os.path.join(staging_dir, "memory.db")) | |
| try: | |
| subprocess.run(f"sqlite3 \"{local_db}\" .dump > \"{os.path.join(staging_dir, 'sqlite_backup.sql')}\"", shell=True) | |
| except Exception as e: | |
| import logging; logging.getLogger(__name__).error(f"Swallowed exception: {e}") | |
| chroma_dir = os.path.join(omega_root, "memory_chroma") | |
| if os.path.exists(chroma_dir): | |
| shutil.copytree(chroma_dir, os.path.join(staging_dir, "chroma"), dirs_exist_ok=True) | |
| try: | |
| subprocess.run(f"pip freeze > \"{os.path.join(staging_dir, 'requirements_frozen.txt')}\"", shell=True) | |
| except Exception as e: | |
| import logging; logging.getLogger(__name__).error(f"Swallowed exception: {e}") | |
| try: | |
| mongo_uri = os.environ.get("MONGO_URI", "") | |
| if not mongo_uri: | |
| env_path = os.path.join(omega_root, ".env") | |
| if os.path.exists(env_path): | |
| with open(env_path, "r", encoding="utf-8") as f: | |
| for line in f: | |
| if line.startswith("MONGO_URI="): | |
| mongo_uri = line.split("=", 1)[1].strip() | |
| break | |
| if mongo_uri: | |
| subprocess.run(f"mongoexport --uri=\"{mongo_uri}\" --out=\"{os.path.join(staging_dir, 'mongo_backup.json')}\"", shell=True) | |
| except Exception as e: | |
| import logging; logging.getLogger(__name__).error(f"Swallowed exception: {e}") | |
| async def build_vault(mode: Literal["full", "sanitized"], source_path: str, target_path: str): | |
| def _sync(): | |
| # First we stage into a temp dir | |
| temp_base = tempfile.mkdtemp() | |
| staging_dir = os.path.join(temp_base, "staging") | |
| os.makedirs(staging_dir, exist_ok=True) | |
| return temp_base, staging_dir | |
| temp_base, staging_dir = await asyncio.to_thread(_sync) | |
| try: | |
| await asyncio.to_thread(lambda: asyncio.run(stage_full_environment(source_path, staging_dir))) | |
| except RuntimeError: | |
| await stage_full_environment(source_path, staging_dir) | |
| final_dir_to_encrypt = staging_dir | |
| if mode == "sanitized": | |
| # Run sanitizer which creates a new directory beside staging | |
| final_dir_to_encrypt = await strip_personal_data(Path(staging_dir)) | |
| final_dir_to_encrypt = str(final_dir_to_encrypt) | |
| def _encrypt(): | |
| encrypt_directory(final_dir_to_encrypt, target_path) | |
| await asyncio.to_thread(_encrypt) | |
| def _cleanup(): | |
| shutil.rmtree(temp_base, ignore_errors=True) | |
| await asyncio.to_thread(_cleanup) | |
| return target_path | |