diff --git a/claude-mcp-manager/README.md b/claude-mcp-manager/README.md deleted file mode 100644 index 38d04fb..0000000 --- a/claude-mcp-manager/README.md +++ /dev/null @@ -1,244 +0,0 @@ -# Claude Code MCP Server Toggle Utility - -Utility CLI pentru gestionarea serverelor MCP (Model Context Protocol) în Claude Code. - -## Caracteristici - -✅ Enable/disable servere MCP individuale -✅ Enable/disable toate serverele -✅ Activare selectivă (doar anumite servere) -✅ List servere cu status (enabled/disabled) -✅ Mod interactiv când rulezi fără parametri -✅ Păstrează configurația când dezactivezi servere - -## Instalare - -Scriptul este deja în `utils/claude-mcp-toggle` și poate fi rulat direct: - -```bash -./utils/claude-mcp-toggle -``` - -Sau îl poți instala global: - -```bash -sudo cp utils/claude-mcp-toggle /usr/local/bin/ -# sau -cp utils/claude-mcp-toggle ~/.local/bin/ -``` - -## Comenzi - -### List Servere - -```bash -# Listează toate proiectele cu MCP servers -claude-mcp-toggle list - -# Listează servere pentru proiect curent -claude-mcp-toggle list . - -# Listează servere pentru proiect specific -claude-mcp-toggle list /path/to/project -``` - -**Output:** -``` -📁 Project: /mnt/e/proiecte/ROMFASTSQL -============================================================ - -✅ Enabled Servers: - • chrome-devtools - Command: npx - Args: ['chrome-devtools-mcp@latest'] - -❌ Disabled Servers: - • filesystem - Command: npx - Args: ['-y', '@modelcontextprotocol/server-filesystem', '.'] -``` - -### Enable/Disable Individual - -```bash -# Enable un server dezactivat -claude-mcp-toggle enable . chrome-devtools - -# Disable un server activ -claude-mcp-toggle disable . chrome-devtools -``` - -### Enable/Disable Toate - -```bash -# Dezactivează toate serverele -claude-mcp-toggle disable-all . - -# Activează toate serverele -claude-mcp-toggle enable-all . -``` - -### Set - Activare Selectivă - -**Cea mai utilă comandă!** Dezactivează toate serverele, apoi activează doar pe cele specificate: - -```bash -# Activează doar chrome-devtools (restul disabled) -claude-mcp-toggle set . chrome-devtools - -# Activează chrome-devtools și filesystem (restul disabled) -claude-mcp-toggle set . chrome-devtools filesystem - -# Activează 3 servere specific -claude-mcp-toggle set . server1 server2 server3 -``` - -### Mod Interactiv - -Rulează fără parametri din directorul proiectului: - -```bash -cd /mnt/e/proiecte/ROMFASTSQL -claude-mcp-toggle -``` - -**Output interactiv:** -``` -📁 Current Project: /mnt/e/proiecte/ROMFASTSQL -============================================================ - -✅ Enabled Servers: - 1. chrome-devtools - -❌ Disabled Servers: - 2. filesystem - -============================================================ -Commands: - [e]nable - Enable a disabled server - [d]isable - Disable an enabled server - [l]ist - Show all servers with details - [q]uit - Exit -============================================================ - -Enter command: -``` - -Comenzi interactive: -- `d 1` - dezactivează serverul #1 -- `e 2` - activează serverul #2 -- `l` - listare detaliată -- `q` - ieșire - -## Use Cases - -### Development cu Tools Specifice - -```bash -# Lucrezi doar cu Chrome DevTools -claude-mcp-toggle set . chrome-devtools - -# Ai nevoie și de filesystem -claude-mcp-toggle set . chrome-devtools filesystem -``` - -### Testing - -```bash -# Disable toate pentru performance testing -claude-mcp-toggle disable-all . - -# Enable doar ce testezi -claude-mcp-toggle set . test-server -``` - -### Production - -```bash -# Enable toate -claude-mcp-toggle enable-all . -``` - -### După Lucru - -```bash -# Disable toate pentru a nu încărca servere inutile -claude-mcp-toggle disable-all . -``` - -## Cum Funcționează - -Scriptul editează `~/.claude.json` care conține configurația Claude Code pentru fiecare proiect: - -- **Servere active**: stocate în `projects[path].mcpServers` -- **Servere disabled**: mutate în `projects[path]._disabledServers` - -Când disable un server: -1. Configurația este mutată din `mcpServers` în `_disabledServers` -2. Nu pierzi configurația (env vars, args, etc.) - -Când enable un server: -1. Configurația este mutată înapoi din `_disabledServers` în `mcpServers` -2. Claude Code va încărca serverul la următoarea rulare - -## Exemple Complete - -```bash -# 1. Vezi ce servere ai -./utils/claude-mcp-toggle list . - -# 2. Activează doar chrome-devtools -./utils/claude-mcp-toggle set . chrome-devtools - -# 3. Verifică -./utils/claude-mcp-toggle list . - -# 4. Adaugă filesystem -./utils/claude-mcp-toggle set . chrome-devtools filesystem - -# 5. Când termini, disable toate -./utils/claude-mcp-toggle disable-all . - -# 6. Mâine, enable toate -./utils/claude-mcp-toggle enable-all . -``` - -## Troubleshooting - -### Error: Project not found - -Asigură-te că directorul este un proiect Claude Code (are intrare în `~/.claude.json`): - -```bash -# Verifică ce proiecte există -claude-mcp-toggle list -``` - -### Error: Server not found - -Listează serverele disponibile: - -```bash -claude-mcp-toggle list . -``` - -### Serverele nu se încarcă în Claude Code - -După modificări, trebuie să **repornești Claude Code** sau să rulezi din nou în proiect: - -```bash -# Claude Code va detecta modificările la următoarea rulare -claude -``` - -## Note - -- Serverele disabled păstrează configurația completă -- `_disabledServers` este o cheie custom adăugată de acest script -- Compatible cu Claude Code CLI (nu Claude Desktop) -- Editează direct `~/.claude.json` (fă backup dacă modifici manual) - -## Autor - -Created pentru proiectul ROMFASTSQL -Data: 2025-10-08 diff --git a/claude-mcp-manager/claude-mcp-toggle b/claude-mcp-manager/claude-mcp-toggle deleted file mode 100644 index 17c1406..0000000 --- a/claude-mcp-manager/claude-mcp-toggle +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/env python3 -""" -Claude Code MCP Server Toggle Utility -Enables/disables MCP servers in ~/.claude.json for specific projects -""" - -import json -import sys -import os -from pathlib import Path - -CLAUDE_CONFIG = Path.home() / ".claude.json" - -def load_config(): - if not CLAUDE_CONFIG.exists(): - print(f"Error: {CLAUDE_CONFIG} not found") - sys.exit(1) - - with open(CLAUDE_CONFIG, 'r') as f: - return json.load(f) - -def save_config(data): - with open(CLAUDE_CONFIG, 'w') as f: - json.dump(data, f, indent=2, ensure_ascii=False) - -def list_servers(project_path=None): - data = load_config() - - if project_path: - project_path = str(Path(project_path).resolve()) - if project_path not in data.get('projects', {}): - print(f"Project not found: {project_path}") - return - - project = data['projects'][project_path] - enabled_servers = project.get('mcpServers', {}) - disabled_servers = project.get('_disabledServers', {}) - - print(f"\n📁 Project: {project_path}") - print(f"{'='*60}") - - if not enabled_servers and not disabled_servers: - print("No MCP servers configured for this project") - return - - if enabled_servers: - print("\n✅ Enabled Servers:") - for name, config in enabled_servers.items(): - print(f" • {name}") - print(f" Command: {config.get('command', 'N/A')}") - print(f" Args: {config.get('args', [])}") - - if disabled_servers: - print("\n❌ Disabled Servers:") - for name, config in disabled_servers.items(): - print(f" • {name}") - print(f" Command: {config.get('command', 'N/A')}") - print(f" Args: {config.get('args', [])}") - else: - print("\n🔧 All Projects with MCP Servers:") - print(f"{'='*60}") - - for proj_path, proj_data in data.get('projects', {}).items(): - enabled_servers = proj_data.get('mcpServers', {}) - disabled_servers = proj_data.get('_disabledServers', {}) - if enabled_servers or disabled_servers: - print(f"\n📁 {proj_path}") - if enabled_servers: - print(" ✅ Enabled:") - for name in enabled_servers.keys(): - print(f" - {name}") - if disabled_servers: - print(" ❌ Disabled:") - for name in disabled_servers.keys(): - print(f" - {name}") - -def disable_server(project_path, server_name): - data = load_config() - project_path = str(Path(project_path).resolve()) - - if project_path not in data.get('projects', {}): - print(f"Error: Project not found: {project_path}") - sys.exit(1) - - project = data['projects'][project_path] - - if 'mcpServers' not in project or server_name not in project['mcpServers']: - print(f"Error: Server '{server_name}' not found in project") - sys.exit(1) - - # Store config in disabled state - if '_disabledServers' not in project: - project['_disabledServers'] = {} - - project['_disabledServers'][server_name] = project['mcpServers'][server_name] - del project['mcpServers'][server_name] - - save_config(data) - print(f"✅ Disabled MCP server: {server_name}") - -def enable_server(project_path, server_name): - data = load_config() - project_path = str(Path(project_path).resolve()) - - if project_path not in data.get('projects', {}): - print(f"Error: Project not found: {project_path}") - sys.exit(1) - - project = data['projects'][project_path] - - if '_disabledServers' not in project or server_name not in project['_disabledServers']: - print(f"Error: Server '{server_name}' not found in disabled servers") - sys.exit(1) - - # Restore config from disabled state - if 'mcpServers' not in project: - project['mcpServers'] = {} - - project['mcpServers'][server_name] = project['_disabledServers'][server_name] - del project['_disabledServers'][server_name] - - save_config(data) - print(f"✅ Enabled MCP server: {server_name}") - -def disable_all_servers(project_path): - data = load_config() - project_path = str(Path(project_path).resolve()) - - if project_path not in data.get('projects', {}): - print(f"Error: Project not found: {project_path}") - sys.exit(1) - - project = data['projects'][project_path] - enabled_servers = project.get('mcpServers', {}) - - if not enabled_servers: - print("No enabled servers to disable") - return - - # Move all to disabled - if '_disabledServers' not in project: - project['_disabledServers'] = {} - - for name, config in enabled_servers.items(): - project['_disabledServers'][name] = config - - project['mcpServers'] = {} - - save_config(data) - print(f"✅ Disabled all {len(enabled_servers)} MCP servers") - -def enable_all_servers(project_path): - data = load_config() - project_path = str(Path(project_path).resolve()) - - if project_path not in data.get('projects', {}): - print(f"Error: Project not found: {project_path}") - sys.exit(1) - - project = data['projects'][project_path] - disabled_servers = project.get('_disabledServers', {}) - - if not disabled_servers: - print("No disabled servers to enable") - return - - # Move all to enabled - if 'mcpServers' not in project: - project['mcpServers'] = {} - - for name, config in disabled_servers.items(): - project['mcpServers'][name] = config - - project['_disabledServers'] = {} - - save_config(data) - print(f"✅ Enabled all {len(disabled_servers)} MCP servers") - -def set_servers(project_path, server_names): - """Disable all servers, then enable only the specified ones""" - data = load_config() - project_path = str(Path(project_path).resolve()) - - if project_path not in data.get('projects', {}): - print(f"Error: Project not found: {project_path}") - sys.exit(1) - - project = data['projects'][project_path] - enabled_servers = project.get('mcpServers', {}) - disabled_servers = project.get('_disabledServers', {}) - - # Collect all servers - all_servers = {**enabled_servers, **disabled_servers} - - # Validate requested servers exist - for name in server_names: - if name not in all_servers: - print(f"Error: Server '{name}' not found in project") - print(f"Available servers: {', '.join(all_servers.keys())}") - sys.exit(1) - - # Move all to disabled - if '_disabledServers' not in project: - project['_disabledServers'] = {} - - project['_disabledServers'].update(all_servers) - project['mcpServers'] = {} - - # Enable only requested servers - for name in server_names: - project['mcpServers'][name] = project['_disabledServers'][name] - del project['_disabledServers'][name] - - save_config(data) - print(f"✅ Enabled {len(server_names)} servers: {', '.join(server_names)}") - print(f" Disabled {len(all_servers) - len(server_names)} other servers") - -def show_usage(): - print(""" -Usage: claude-mcp-toggle [options] - -Commands: - list [project_path] List all MCP servers (optionally for specific project) - disable Disable MCP server for project - enable Enable MCP server for project - disable-all Disable all MCP servers for project - enable-all Enable all MCP servers for project - set Disable all, then enable only specified servers - -Examples: - claude-mcp-toggle list - claude-mcp-toggle list /mnt/e/proiecte/ROMFASTSQL - claude-mcp-toggle disable . chrome-devtools - claude-mcp-toggle enable . chrome-devtools - claude-mcp-toggle disable-all . - claude-mcp-toggle set . chrome-devtools filesystem -""") - -def interactive_mode(): - """Interactive mode when no arguments provided""" - cwd = os.getcwd() - data = load_config() - - project_path = str(Path(cwd).resolve()) - if project_path not in data.get('projects', {}): - print(f"❌ Current directory is not a Claude Code project: {project_path}") - print("\nAvailable projects:") - for proj in data.get('projects', {}).keys(): - print(f" - {proj}") - sys.exit(1) - - project = data['projects'][project_path] - enabled_servers = project.get('mcpServers', {}) - disabled_servers = project.get('_disabledServers', {}) - - if not enabled_servers and not disabled_servers: - print(f"No MCP servers configured for project: {project_path}") - sys.exit(0) - - print(f"\n📁 Current Project: {project_path}") - print(f"{'='*60}\n") - - # Show current state - if enabled_servers: - print("✅ Enabled Servers:") - for i, name in enumerate(enabled_servers.keys(), 1): - print(f" {i}. {name}") - - if disabled_servers: - print("\n❌ Disabled Servers:") - for i, name in enumerate(disabled_servers.keys(), len(enabled_servers) + 1): - print(f" {i}. {name}") - - # Interactive menu - print("\n" + "="*60) - print("Commands:") - print(" [e]nable - Enable a disabled server") - print(" [d]isable - Disable an enabled server") - print(" [l]ist - Show all servers with details") - print(" [q]uit - Exit") - print("="*60) - - try: - choice = input("\nEnter command: ").strip().lower() - - if choice == 'q' or choice == 'quit': - print("Goodbye!") - sys.exit(0) - elif choice == 'l' or choice == 'list': - list_servers(project_path) - elif choice.startswith('e') or choice.startswith('d'): - parts = choice.split() - if len(parts) < 2: - print("❌ Please specify server number") - sys.exit(1) - - try: - server_num = int(parts[1]) - all_servers = list(enabled_servers.keys()) + list(disabled_servers.keys()) - - if server_num < 1 or server_num > len(all_servers): - print(f"❌ Invalid server number. Choose 1-{len(all_servers)}") - sys.exit(1) - - server_name = all_servers[server_num - 1] - - if choice.startswith('e'): - enable_server(project_path, server_name) - else: - disable_server(project_path, server_name) - except ValueError: - print("❌ Invalid number") - sys.exit(1) - else: - print("❌ Unknown command") - sys.exit(1) - except (EOFError, KeyboardInterrupt): - print("\n\nGoodbye!") - sys.exit(0) - -def main(): - if len(sys.argv) < 2: - interactive_mode() - return - - command = sys.argv[1] - - if command == "list": - project_path = sys.argv[2] if len(sys.argv) > 2 else None - list_servers(project_path) - elif command == "disable": - if len(sys.argv) < 4: - print("Error: Missing arguments") - show_usage() - sys.exit(1) - disable_server(sys.argv[2], sys.argv[3]) - elif command == "enable": - if len(sys.argv) < 4: - print("Error: Missing arguments") - show_usage() - sys.exit(1) - enable_server(sys.argv[2], sys.argv[3]) - elif command == "disable-all": - if len(sys.argv) < 3: - print("Error: Missing project path") - show_usage() - sys.exit(1) - disable_all_servers(sys.argv[2]) - elif command == "enable-all": - if len(sys.argv) < 3: - print("Error: Missing project path") - show_usage() - sys.exit(1) - enable_all_servers(sys.argv[2]) - elif command == "set": - if len(sys.argv) < 4: - print("Error: Missing arguments (project_path and at least one server)") - show_usage() - sys.exit(1) - project_path = sys.argv[2] - server_names = sys.argv[3:] - set_servers(project_path, server_names) - else: - print(f"Error: Unknown command: {command}") - show_usage() - sys.exit(1) - -if __name__ == "__main__": - main() diff --git a/proxmox/lxc108-oracle/README.md b/proxmox/lxc108-oracle/README.md index 61f9d9b..0a01fc4 100644 --- a/proxmox/lxc108-oracle/README.md +++ b/proxmox/lxc108-oracle/README.md @@ -7,11 +7,11 @@ - **IP:** 10.0.20.121 - **Host Proxmox:** 10.0.20.201 (pvemini) - **CPU:** 2 cores -- **RAM:** 4 GB +- **RAM:** 8 GB (+ 2GB swap) - **Storage:** 50 GB (local-zfs) -- **Status:** Running +- **Status:** Stopped (pornire manuală la nevoie) - **OS:** Ubuntu/Debian (LXC) -- **Docker Containers:** oracle-xe (21c), oracle18-xe (18c) +- **Docker Containers:** oracle-xe (21c), oracle18-xe (18c) - oprite implicit ## 📋 Sumar Containere Docker @@ -20,6 +20,60 @@ | oracle-xe | 1521 | 21c | 35 | Dezvoltare, ROA, ROA2 | | oracle18-xe | 1522 | 18c | 31 | Export compatibil 11g/18c/19c | +> **Notă:** Containerele Docker sunt oprite implicit pentru a economisi resurse. +> Pornește-le manual când ai nevoie (vezi secțiunea Pornire/Oprire). + +--- + +## 🚀 Pornire și Oprire LXC + Oracle + +### Pornire completă (LXC + Oracle 21c) +```bash +# De pe Proxmox (10.0.20.201): +pct start 108 +sleep 10 +pct exec 108 -- docker start oracle-xe + +# Sau dintr-o singură comandă SSH: +ssh root@10.0.20.201 "pct start 108 && sleep 10 && pct exec 108 -- docker start oracle-xe" + +# Verificare: +ssh root@10.0.20.201 "pct exec 108 -- docker ps" +``` + +### Pornire Oracle 18c (pentru export compatibil) +```bash +# Presupune că LXC 108 rulează deja +ssh root@10.0.20.201 "pct exec 108 -- docker start oracle18-xe" + +# Așteaptă ~60s pentru startup, apoi verifică: +ssh root@10.0.20.201 "pct exec 108 -- docker logs oracle18-xe --tail 5" +``` + +### Oprire containere Oracle +```bash +# Oprește ambele containere: +ssh root@10.0.20.201 "pct exec 108 -- docker stop oracle-xe oracle18-xe" + +# Sau doar unul: +ssh root@10.0.20.201 "pct exec 108 -- docker stop oracle18-xe" +``` + +### Oprire completă LXC +```bash +# Oprește containerele Docker apoi LXC: +ssh root@10.0.20.201 "pct exec 108 -- docker stop oracle-xe oracle18-xe 2>/dev/null; pct stop 108" +``` + +### Script rapid PowerShell (pentru Windows) +```powershell +# Pornire LXC + Oracle 21c +ssh root@10.0.20.201 "pct start 108; sleep 15; pct exec 108 -- docker start oracle-xe" + +# Oprire +ssh root@10.0.20.201 "pct exec 108 -- docker stop oracle-xe oracle18-xe; pct stop 108" +``` + --- ## 🐳 Oracle XE 21c în Docker @@ -28,7 +82,7 @@ - **Container Name:** oracle-xe - **Image:** container-registry.oracle.com/database/express:21.3.0-xe - **Versiune:** Oracle Database 21c Express Edition -- **Status:** Running (Up 3+ weeks, healthy) +- **Status:** Pornire manuală (docker start oracle-xe) - **Portainer:** http://10.0.20.121:9000 (admin / parola281234) ### Porturi Expuse @@ -50,52 +104,230 @@ ## 🐳 Oracle XE 18c în Docker (Export Compatibil) > **Scop:** Export DMP compatibil cu Oracle 11g, 18c, 19c (TSTZ version 31) +> +> **De ce Oracle 18c separat?** Oracle 21c are TSTZ version 35, iar clienții cu Oracle 11g/18c/19c +> nu pot importa DMP-uri exportate din 21c (eroare ORA-39405). Containerul oracle18-xe permite +> export cu VERSION=11.2 compatibil cu versiunile vechi. ### Informații Container Docker - **Container Name:** oracle18-xe - **Image:** gvenzl/oracle-xe:18 -- **Versiune:** Oracle Database 18c Express Edition -- **Port:** 1522 +- **Versiune:** Oracle Database 18c Express Edition (18.4.0.0.0) +- **Port Extern:** 1522 (mapează la 1521 intern) +- **Port EM Express:** 5502 (mapează la 5500 intern) - **TSTZ Version:** 31 (compatibil cu 11g/18c/19c) +- **SID:** XE (non-CDB, nu are PDB-uri) +- **Character Set:** WE8MSWIN1252 + +### Scheme Importate +| Schema | Parola | Obiecte | Utilizare | +|--------|--------|---------|-----------| +| CONTAFIN_ORACLE | ROMFASTSOFT | ~330 | Schema common (drepturi, update, etc.) | +| FIRMANOUA | ROMFASTSOFT | ~3400 | Schema client template (gestiune, contab, salarii) | ### Volume Docker Montate (oracle18-xe) | Container Path | LXC 108 Path | Descriere | |----------------|--------------|-----------| -| /opt/oracle/oradata | /opt/oracle/oradata18 | Date Oracle 18c | -| /opt/oracle/oradata/dmpdir | /opt/oracle/oradata/dmpdir | Export/Import DMP (partajat) | +| /opt/oracle/oradata | /opt/oracle18/oradata | Date Oracle 18c (datafiles, redo) | +| /opt/oracle/oradata/dmpdir | /opt/oracle18/oradata/dmpdir | Export/Import DMP | + +> **Notă:** Oracle 18c folosește un volum **separat** (`/opt/oracle18/`) pentru a evita +> conflicte cu Oracle 21c. Directorul DMPDIR este în volumul 18c. + +### Arhitectură CDB/PDB Oracle 18c + +Oracle 18c XE folosește arhitectura **multitenant** (la fel ca 21c): + +| Container | Tip | Descriere | +|-----------|-----|-----------| +| CDB$ROOT | CDB | Container root (admin, SYS objects) | +| PDB$SEED | PDB | Template read-only pentru creare PDB-uri noi | +| XEPDB1 | PDB | PDB implicit pentru aplicații și date | + +> **Diferență față de Oracle 21c:** +> - Oracle 21c are PDB-uri custom: **ROA**, **ROA2** +> - Oracle 18c are PDB-ul implicit: **XEPDB1** +> - Schemele CONTAFIN_ORACLE și FIRMANOUA sunt în **XEPDB1** (nu în CDB!) +> +> **IMPORTANT:** Conectează-te la **XEPDB1**, nu la **XE**! ### Conexiune Oracle 18c -```bash -# SQL*Plus -sqlplus sys/romfastsoft@10.0.20.121:1522/XE as sysdba -sqlplus system/romfastsoft@10.0.20.121:1522/XE -# JDBC -jdbc:oracle:thin:@10.0.20.121:1522/XE +**Conectare la CDB (admin):** +```bash +# SYS la CDB root +sqlplus sys/romfastsoft@10.0.20.121:1522/XE as sysdba + +# SYSTEM la CDB root +sqlplus system/romfastsoft@10.0.20.121:1522/XE ``` +**Conectare la PDB XEPDB1 (aplicații):** +```bash +# SYS la PDB +sqlplus sys/romfastsoft@10.0.20.121:1522/XEPDB1 as sysdba + +# Schema FIRMANOUA (pentru aplicații) +sqlplus FIRMANOUA/ROMFASTSOFT@10.0.20.121:1522/XEPDB1 + +# Schema CONTAFIN_ORACLE +sqlplus CONTAFIN_ORACLE/ROMFASTSOFT@10.0.20.121:1522/XEPDB1 +``` + +**JDBC:** +``` +# Conectare la CDB (admin) +jdbc:oracle:thin:@10.0.20.121:1522/XE + +# Conectare la PDB XEPDB1 (aplicații - recomandat) +jdbc:oracle:thin:@10.0.20.121:1522/XEPDB1 +``` + +**TNS Entries:** +``` +# PDB XEPDB1 (pentru aplicații - RECOMANDAT) +ROA_CENTRAL3 = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.20.121)(PORT = 1522)) + (CONNECT_DATA = (SERVICE_NAME = XEPDB1)) + ) + +# Alias alternativ +XEPDB1 = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.20.121)(PORT = 1522)) + (CONNECT_DATA = (SERVICE_NAME = XEPDB1)) + ) + +# CDB root (doar pentru admin) +XE18 = + (DESCRIPTION = + (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.20.121)(PORT = 1522)) + (CONNECT_DATA = (SERVICE_NAME = XE)) + ) +``` + +> **Atenție:** Folosește `SERVICE_NAME = XEPDB1` pentru aplicații, NU `SID = XE`! + ### Export Compatibil din Oracle 18c ```bash -# Export schema (compatibil cu Oracle 11g, 18c, 19c) +# Export FIRMANOUA (compatibil Oracle 11g, 18c, 19c) docker exec oracle18-xe expdp system/romfastsoft@localhost:1521/XE \ - SCHEMAS=FIRMANOUA DIRECTORY=DMPDIR DUMPFILE=firmanoua_v18.dmp VERSION=11.2 + SCHEMAS=FIRMANOUA DIRECTORY=DMPDIR DUMPFILE=firmanoua_v11.2.dmp \ + LOGFILE=export_firmanoua.log VERSION=11.2 + +# Export CONTAFIN_ORACLE (compatibil Oracle 11g, 18c, 19c) +docker exec oracle18-xe expdp system/romfastsoft@localhost:1521/XE \ + SCHEMAS=CONTAFIN_ORACLE DIRECTORY=DMPDIR DUMPFILE=contafin_v11.2.dmp \ + LOGFILE=export_contafin.log VERSION=11.2 + +# Export ambele scheme +docker exec oracle18-xe expdp system/romfastsoft@localhost:1521/XE \ + SCHEMAS=CONTAFIN_ORACLE,FIRMANOUA DIRECTORY=DMPDIR \ + DUMPFILE=roa_export_v11.2.dmp LOGFILE=export_roa.log VERSION=11.2 +``` + +### Scripturi Export Automatizate +```bash +# Din LXC 108 sau remote +./export-roa2.sh 18 # Export din Oracle 18c (port 1522) +./export-roa2.sh 21 # Export din Oracle 21c PDB roa2 (port 1521) + +# Din PowerShell Windows +.\export-roa2.ps1 # Meniu interactiv +``` +**Locații scripturi:** `proxmox/lxc108-oracle/scripts/export-roa2.sh`, `proxmox/lxc108-oracle/scripts/export-roa2.ps1` + +### Import în Oracle 18c +```bash +# Import schema cu remap tablespace (dacă nu există tablespace ROA) +docker exec oracle18-xe impdp system/romfastsoft@localhost:1521/XE \ + SCHEMAS=FIRMANOUA DIRECTORY=DMPDIR DUMPFILE=firmanoua.dmp \ + LOGFILE=import.log REMAP_TABLESPACE=ROA:USERS,ROA2:USERS ``` ### Recreare Container Oracle 18c (dacă e necesar) ```bash -docker pull gvenzl/oracle-xe:18 +# 1. Stop și remove container vechi +docker stop oracle18-xe 2>/dev/null +docker rm oracle18-xe 2>/dev/null + +# 2. Creează directorul volum (prima dată) +mkdir -p /opt/oracle18/oradata +chmod 777 /opt/oracle18/oradata + +# 3. Creează container docker run -d --name oracle18-xe \ + --restart unless-stopped \ -p 1522:1521 \ + -p 5502:5500 \ -e ORACLE_PASSWORD=romfastsoft \ - -v /opt/oracle/oradata18:/opt/oracle/oradata \ - -v /opt/oracle/oradata/dmpdir:/opt/oracle/oradata/dmpdir \ + -e ORACLE_CHARACTERSET=WE8MSWIN1252 \ + -v /opt/oracle18/oradata:/opt/oracle/oradata \ + --shm-size=1g \ gvenzl/oracle-xe:18 -# Creare DMPDIR -docker exec oracle18-xe bash -c "sqlplus -s sys/romfastsoft@localhost:1521/XE as sysdba < SELECT name FROM v$pdbs; -- arată: ROA, ROA2 + +# Conectare la PDB ROA - vezi doar schemele din ROA +sqlplus sys/romfastsoft@10.0.20.121:1521/ROA as sysdba +SQL> SELECT username FROM dba_users; -- arată userii din ROA +``` + ### Compatibilitate TSTZ (Time Zone) | Versiune | TSTZ | Compatibilitate Import | |----------|------|------------------------| @@ -509,9 +786,29 @@ SQL-uri și packages Oracle: - `sql/roa-romconstruct/` - Package PACK_CONTAFIN.pck ### scripts/ -Scripturi operaționale: -- `export-roa2.sh` - Export PDB roa2 -- `export-roa2.ps1` - Export pentru Windows +Scripturi operaționale pentru export: +- `export-roa2.sh` - Export din Oracle 18c sau 21c (bash) + - `./export-roa2.sh 18` - Export compatibil 11g/18c/19c din Oracle 18c + - `./export-roa2.sh 21` - Export din Oracle 21c PDB roa2 +- `export-roa2.ps1` - Export pentru Windows (PowerShell, meniu interactiv) + +**Copiere manuală a scriptului pe LXC 108:** +```bash +# Din WSL/Linux local: +scp proxmox/lxc108-oracle/scripts/export-roa2.sh root@10.0.20.201:/tmp/ + +# Pe Proxmox (10.0.20.201): +pct push 108 /tmp/export-roa2.sh /opt/oracle/oradata/export-roa2.sh +pct exec 108 -- chmod +x /opt/oracle/oradata/export-roa2.sh + +# Sau într-o singură comandă din WSL: +scp proxmox/lxc108-oracle/scripts/export-roa2.sh root@10.0.20.201:/tmp/ && \ +ssh root@10.0.20.201 "pct push 108 /tmp/export-roa2.sh /opt/oracle/oradata/export-roa2.sh && \ +pct exec 108 -- chmod +x /opt/oracle/oradata/export-roa2.sh" +``` + +**Notă warning-uri export:** La export vor apărea warning-uri `ORA-31642: DBMS_CUBE_EXP` - +acestea sunt **inofensive** (Oracle XE nu include modulul OLAP). Exportul se finalizează corect. --- diff --git a/proxmox/lxc108-oracle/scripts/export-roa2.ps1 b/proxmox/lxc108-oracle/scripts/export-roa2.ps1 index 4eed17c..1b3b97a 100644 --- a/proxmox/lxc108-oracle/scripts/export-roa2.ps1 +++ b/proxmox/lxc108-oracle/scripts/export-roa2.ps1 @@ -3,7 +3,8 @@ $BackupDir = "E:\backups\oracle" $Proxmox = "root@10.0.20.201" -$DmpDir = "/opt/oracle/oradata/dmpdir" +$DmpDir21 = "/opt/oracle/oradata/dmpdir" # Oracle 21c +$DmpDir18 = "/opt/oracle18/oradata/dmpdir" # Oracle 18c # Creează directorul backup dacă nu există if (!(Test-Path $BackupDir)) { @@ -11,7 +12,16 @@ if (!(Test-Path $BackupDir)) { } function Get-RemoteArchives { - $result = ssh $Proxmox "pct exec 108 -- bash -c 'ls -lt $DmpDir/*.tar.gz 2>/dev/null'" 2>$null + param([string]$DmpDir = "") + + # Dacă nu e specificat, caută în ambele directoare + if ([string]::IsNullOrEmpty($DmpDir)) { + $dirs = "$DmpDir18 $DmpDir21" + } else { + $dirs = $DmpDir + } + + $result = ssh $Proxmox "pct exec 108 -- bash -c 'for d in $dirs; do ls -lt `$d/*.tar.gz 2>/dev/null; done'" 2>$null if ($result) { $archives = @() foreach ($line in $result) { @@ -42,6 +52,25 @@ function Copy-Archive($archivePath) { Write-Host " Done" -ForegroundColor Green } +function Start-OracleContainer { + param([string]$Container) + + Write-Host "Pornesc containerul $Container..." -ForegroundColor Yellow + ssh $Proxmox "pct exec 108 -- docker start $Container" + Write-Host "Astept 60s pentru startup Oracle..." -ForegroundColor Yellow + Start-Sleep -Seconds 60 + + # Verifică dacă e pornit + $status = ssh $Proxmox "pct exec 108 -- docker ps --format '{{.Names}}' | grep $Container" + if ($status) { + Write-Host "Container $Container pornit cu succes!" -ForegroundColor Green + return $true + } else { + Write-Host "EROARE: Container $Container nu a pornit!" -ForegroundColor Red + return $false + } +} + function Run-Export { Write-Host "`nSelecteaza sursa Oracle:" -ForegroundColor Cyan Write-Host " 1. Oracle 18c (port 1522) - Compatibil 11g/18c/19c (Recomandat)" @@ -49,8 +78,52 @@ function Run-Export { $srcChoice = Read-Host "Selecteaza sursa [1]" $oracleVer = switch ($srcChoice) { - '2' { '21' } - default { '18' } + '2' { '21'; $containerName = 'oracle-xe' } + default { '18'; $containerName = 'oracle18-xe' } + } + + if ($oracleVer -eq '18') { + $containerName = 'oracle18-xe' + $currentDmpDir = $DmpDir18 + } else { + $containerName = 'oracle-xe' + $currentDmpDir = $DmpDir21 + } + + # Verifică dacă LXC 108 rulează + Write-Host "`nVerific LXC 108..." -NoNewline + $lxcStatus = ssh $Proxmox "pct status 108" 2>$null + if ($lxcStatus -notmatch "running") { + Write-Host " OPRIT" -ForegroundColor Red + $start = Read-Host "Pornesc LXC 108? (D/n)" + if ($start -ne 'n') { + Write-Host "Pornesc LXC 108..." -ForegroundColor Yellow + ssh $Proxmox "pct start 108" + Start-Sleep -Seconds 10 + } else { + Write-Host "Anulat." -ForegroundColor Gray + return + } + } else { + Write-Host " OK" -ForegroundColor Green + } + + # Verifică dacă containerul Oracle rulează + Write-Host "Verific container $containerName..." -NoNewline + $containerStatus = ssh $Proxmox "pct exec 108 -- docker ps --format '{{.Names}}' | grep $containerName" 2>$null + if (-not $containerStatus) { + Write-Host " OPRIT" -ForegroundColor Red + $start = Read-Host "Pornesc $containerName? (D/n)" + if ($start -ne 'n') { + if (-not (Start-OracleContainer -Container $containerName)) { + return + } + } else { + Write-Host "Anulat." -ForegroundColor Gray + return + } + } else { + Write-Host " OK" -ForegroundColor Green } if ($oracleVer -eq '18') { @@ -61,9 +134,9 @@ function Run-Export { ssh $Proxmox "pct exec 108 -- bash /opt/oracle/oradata/export-roa2.sh $oracleVer" - # Copiază cele mai noi 2 arhive + # Copiază cele mai noi 2 arhive din directorul corect Write-Host "`nCopying new archives..." -ForegroundColor Yellow - $archives = Get-RemoteArchives | Select-Object -First 2 + $archives = Get-RemoteArchives -DmpDir $currentDmpDir | Select-Object -First 2 foreach ($archive in $archives) { Copy-Archive $archive.Path } diff --git a/proxmox/lxc108-oracle/scripts/export-roa2.sh b/proxmox/lxc108-oracle/scripts/export-roa2.sh index 3ea33da..4ca90f8 100644 --- a/proxmox/lxc108-oracle/scripts/export-roa2.sh +++ b/proxmox/lxc108-oracle/scripts/export-roa2.sh @@ -2,26 +2,58 @@ # Export CONTAFIN_ORACLE și FIRMANOUA, arhive separate tar.gz # Rulează din LXC 108: ./export-roa2.sh [18|21] # 18 = Oracle 18c (compatibil 11g/18c/19c) | 21 = Oracle 21c (default) +# +# Exemple: +# ./export-roa2.sh 18 # Export din Oracle 18c pe port 1522 +# ./export-roa2.sh 21 # Export din Oracle 21c PDB roa2 pe port 1521 +# ./export-roa2.sh # Default: Oracle 21c -DMPDIR="/opt/oracle/oradata/dmpdir" DATE=$(date +%Y%m%d_%H%M%S) SCHEMAS="CONTAFIN_ORACLE FIRMANOUA" ORACLE_VER=${1:-21} if [ "$ORACLE_VER" == "18" ]; then CONTAINER="oracle18-xe" - PORT="1521" - SERVICE="XE" - SUFFIX="_v18" + PORT="1521" # Port intern container (extern e 1522) + SERVICE="XEPDB1" # Oracle 18c PDB (nu CDB!) + DMPDIR="/opt/oracle18/oradata/dmpdir" # Volum separat pentru 18c + SUFFIX="_v11.2" VERSION="11.2" - echo "=== Export Oracle 18c (compatibil 11g/18c/19c) - $DATE ===" + echo "=== Export Oracle 18c PDB XEPDB1 (compatibil 11g/18c/19c) - $DATE ===" else CONTAINER="oracle-xe" PORT="1521" - SERVICE="roa2" - SUFFIX="_v21" - VERSION="12" - echo "=== Export Oracle 21c - $DATE ===" + SERVICE="roa2" # Oracle 21c PDB roa2 + DMPDIR="/opt/oracle/oradata/dmpdir" # Volum pentru 21c + SUFFIX="_v19" + VERSION="19" + echo "=== Export Oracle 21c PDB roa2 - $DATE ===" +fi + +# Verifică că containerul Docker rulează +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "EROARE: Containerul $CONTAINER nu rulează!" + echo "" + echo "Pornește-l cu: docker start $CONTAINER" + echo "Apoi așteaptă ~60s pentru startup Oracle." + exit 1 +fi + +# Verifică că baza de date Oracle e OPEN +DB_STATUS=$(docker exec $CONTAINER bash -c "echo 'SELECT status FROM v\$instance;' | sqlplus -s / as sysdba" 2>/dev/null | grep -E "OPEN|MOUNTED") +if [ -z "$DB_STATUS" ]; then + echo "EROARE: Baza de date Oracle nu e disponibilă!" + echo "Containerul rulează dar Oracle nu e OPEN." + echo "Verifică: docker logs $CONTAINER --tail 20" + exit 1 +fi +echo "Oracle status: $DB_STATUS" + +# Verifică că DMPDIR există +if [ ! -d "$DMPDIR" ]; then + echo "EROARE: Director $DMPDIR nu există!" + echo "Creează-l cu: mkdir -p $DMPDIR && chmod 777 $DMPDIR" + exit 1 fi cd $DMPDIR