feat(oracle): kit de instalare la client + corectarea lipsurilor din instalare

Blocul de instalare/migrare Oracle 21c XE, terminat si validat pe VM 302.

Kit de instalare (nou)

  scripts/build-client-kit.ps1 exporta CONTAFIN_ORACLE si FIRMANOUA de pe
  LXC 108 (PDB ROA2, nu ROA - ROA e productia ROA_CENTRAL), le aduce local
  prin cele trei hopuri container -> LXC -> host -> statie, le redenumeste la
  numele pe care le asteapta scripturile si le impacheteaza cu o copie a
  directorului roa-windows-setup. Citeste logul expdp si raporteaza cate
  firme are NOM_FIRME, ca sa nu plece din greseala datele unui client.

  roa-windows-setup/INSTALEAZA.cmd ruleaza pasii 01..08 fara "set /p", deci
  merge si prin SSH - RunAll.cmd nu poate fi rulat neinteractiv. Trateaza
  corect codul 5 de la pasul 03 si se opreste la prima eroare reala.

Corectii

  01-setup-database.ps1 nu mai scrie SQLNET.RECV_TIMEOUT / SEND_TIMEOUT in
  sqlnet.ora. Le hardcoda la 30 s, iar fisierul e citit si de impdp: in timpul
  unui import serverul poate lucra minute fara sa trimita un pachet, clientul
  murea cu ORA-12609 iar scriptul raporta esec pentru un import care se
  terminase cu bine pe server. Reprodus si reparat pe VM 302.

  01-setup-database.ps1: Step 4c optional (-ResetSystemPassword) care curata
  EXPIRED(GRACE) pe SYSTEM in CDB root; ALTER PROFILE opreste expirarile
  viitoare dar nu reseteaza un cont deja intrat in gratie.

  uninstall-roa.sql: retry la DROP USER dupa KILL SESSION, plus un bloc final
  de verdict care numara ce a ramas si iese cu ORA-20900 daca baza nu e
  curata. Pana acum toate sectiunile prindeau exceptiile in WHEN OTHERS si
  scriptul tiparea "UNINSTALL COMPLETE" chiar si cand un user supravietuise,
  iar instalarea urmatoare dadea ORA-31684 in lant. 99-uninstall-roa.ps1
  propaga codul de iesire.

  08-post-install-config.ps1: Step 7b seteaza SMTP_OUT_SERVER si ACL-ul de
  retea pentru CONTAFIN_ORACLE. UTL_MAIL se instala si primea EXECUTE, adica
  destul cat sa compileze, dar nu si cat sa trimita. Privilegiul resolve nu
  accepta interval de porturi (ORA-24244), deci se acorda separat de connect.

  07-verify-installation.ps1: sectiune noua care verifica prezenta lui
  FIRMANOUA.dmp in DMPDIR si o raporteaza ca eroare daca lipseste. Fara el,
  adaugarea unei firme noi pica in DBMS_DATAPUMP.ADD_FILE peste luni de la
  instalare, cand nimeni nu mai leaga eroarea de instalare.

  configure-profile.sql: antetul spune ca e unealta de remediere manuala, nu
  parte din flux; pas nou la final pentru CDB root.

Documentatie

  README-ul roa-windows-setup descrie acum explicit cele doua scenarii -
  instalare pe curat si migrare - de unde se iau DMP-urile sablon, si capcana
  ORA-12609. Handoff-urile de sesiune au fost sterse; ce era durabil in ele a
  intrat in README-uri si in docs/diagnostic-spatiu-clienti.md.

Validare pe VM 302: ciclu complet din kit, instalare pe curat, verificarea
finala "[OK] All checks passed!".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
This commit is contained in:
Marius
2026-08-25 18:05:56 +03:00
parent 3a7e751fc1
commit 7fce925349
17 changed files with 3329 additions and 1753 deletions

View File

@@ -47,9 +47,11 @@ input/ # Oracle DMP files for import
- **Disaster recovery**: `proxmox/vm109-windows-dr/README.md` - **Disaster recovery**: `proxmox/vm109-windows-dr/README.md`
- **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md` - **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
- **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md` - **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
- **Kit de instalare pentru client (DMP-uri șablon + scripturi, gata de dus la client)**: `proxmox/lxc108-oracle/scripts/build-client-kit.ps1`
- **VM 302 test environment for ROA setup**: `proxmox/vm302-oracle-test/README.md` - **VM 302 test environment for ROA setup**: `proxmox/vm302-oracle-test/README.md`
- **Diagnostic spațiu Oracle la clienți (job zilnic + emailuri)**: `docs/diagnostic-spatiu-clienti.md` - **Diagnostic spațiu Oracle la clienți (job zilnic + emailuri)**: `docs/diagnostic-spatiu-clienti.md`
- **Acces SSH la clienți cu chei publice (angajați noi)**: `docs/acces-ssh-chei-angajati.md` - **Acces SSH la clienți cu chei publice (angajați noi)**: `docs/acces-ssh-chei-angajati.md`
- **Acces administrativ la server client prin Tailscale + SSH (fără forward pe router)**: `docs/acces-client-tailscale-ssh.md`
- **Cazuri clienți (depanare DB)**: `proxmox/lxc108-oracle/clienti/README.md` - **Cazuri clienți (depanare DB)**: `proxmox/lxc108-oracle/clienti/README.md`
- **ROMPETROL ENERGY — recreare PDB Oracle XE 21c după ORA-12954**: `proxmox/lxc108-oracle/clienti/oracle-xe-21c/README.md` - **ROMPETROL ENERGY — recreare PDB Oracle XE 21c după ORA-12954**: `proxmox/lxc108-oracle/clienti/oracle-xe-21c/README.md`

View File

@@ -0,0 +1,199 @@
# Acces administrativ la un server de client prin Tailscale + SSH
De ce: pentru instalări/migrări Oracle la client avem nevoie de **shell text** pe serverul lui.
RustDesk nu ajută — e sesiune grafică, nu se poate automatiza. Iar la mulți clienți **nu se pot
face forward-uri de porturi pe router**. Tailscale rezolvă exact asta: nodul face doar conexiuni
de ieșire (UDP 41641 pentru NAT traversal, cu cădere pe releu DERP peste 443), deci merge și în
spatele CGNAT, fără nicio regulă pe router.
RustDesk rămâne util pentru **bootstrap-ul de o singură dată** — pașii de mai jos se execută
manual, o dată, prin el.
Primul caz aplicat: **VADECO** — `vadeco-server`, Windows Server 2019 Standard, Tailscale
`100.93.100.75` (2026-08-25).
Context conex: `acces-ssh-chei-angajati.md` (Bitvise pe chei, capcana LSA protection).
---
## 1. Tailscale pe serverul clientului
1. Instalezi Tailscale, te loghezi cu contul ROMFAST.
2. **Run unattended** — din tray → Preferences, sau `tailscale up --unattended`. Fără el,
tailscaled pornește abia după ce cineva face login în Windows; pe un server la care nu se
loghează nimeni, accesul e mort după fiecare reboot.
3. Cere acordul clientului înainte — e VPN pe serverul lui.
## 2. Izolarea nodului: tag + ACL
Fără asta, serverul clientului intră în tailnet ca device obișnuit și **vede toată
infrastructura ROMFAST**. Dacă e vreodată compromis, atacatorul sare mai departe.
Modelul Tailscale, pe scurt:
- ACL-ul e **default-deny**: ce nu e permis explicit, e blocat. Nu scrii interdicții.
- Regulile au **direcție**: `src` = cine deschide conexiunea, `dst` = cine o primește.
- Fiecare device are o **identitate**: fie contul care l-a logat (*user-owned*), fie **tag-ul**.
Aplicarea unui tag **înlocuiește** proprietatea contului, nu se adaugă la ea.
- `autogroup:member` = conturile umane din tailnet. Un device tagged **nu** e member.
### Politica
Admin console → Access controls. UI-ul nou are editor vizual (Definitions / Grants); fișierul
HuJSON brut e la `https://login.tailscale.com/admin/acls/file`.
```hujson
{
"tagOwners": {
"tag:client": ["autogroup:admin"],
},
"acls": [
// device-urile noastre (ne-tagged) ajung oriunde
{ "action": "accept", "src": ["autogroup:member"], "dst": ["*:*"] },
// NU exista nicio regula cu "src": ["tag:client"]
// => serverul clientului nu poate initia nimic in tailnet
],
}
```
> **Obligatoriu:** șterge regula implicită `src: ["*"]` → `dst: ["*:*"]`. Cât timp există,
> `*` include și `tag:client` și toată izolarea e degeaba.
> **Înainte de a șterge**, verifică în Machines că niciun nod ROMFAST nu e deja tagged — ar
> rămâne fără acces.
### Aplicarea tag-ului
Machines → nodul → `...` → **Edit ACL tags** → `tag:client`.
Efecte: proprietatea trece la tag (dispare din „owned by you" — normal), iar **expirarea cheii
se dezactivează automat** la device-urile tagged, deci nu mai trebuie dezactivată manual.
Verificare rapidă în `tailscale status` — nodul apare cu owner `tagged-devices`:
```
100.93.100.75 vadeco-server tagged-devices windows -
```
### Testul de izolare
Rulează **aceeași** comandă înainte și după aplicarea tag-ului, de pe serverul clientului:
```powershell
Test-NetConnection 100.95.55.51 -Port 22 # 100.95.55.51 = LXC 171, are sshd pornit
```
- înainte de tag: `TcpTestSucceeded : True` (nodul e încă member) — confirmă că testul e valid
- după tag: `TcpTestSucceeded : False` (~20s până expiră) — confirmă izolarea
> **Nu folosi `tailscale ping` ca test de ACL.** Lucrează sub filtrul de pachete și poate
> reuși chiar când ACL-ul blochează traficul real. Doar un test TCP pe un port concret spune
> adevărul.
Sensul invers (noi → client) se testează la punctul 4, cu serverul SSH pornit.
> „Dacă nodul nu poate ajunge la noi, cum îmi răspunde SSH-ul?" — ACL-ul reglementează **cine
> deschide** o conexiune, nu direcția octeților. Sesiunea deschisă dinspre noi funcționează
> normal în ambele sensuri; clientul doar nu poate iniția el ceva spre tailnet.
## 3. Serverul SSH pe mașina clientului
Două variante; ambele merg, alege după context.
### Bitvise SSH Server (consecvent cu restul clienților)
Control Panel → **Easy settings**:
- **Windows accounts** → `Administrator` (sau alt cont din grupul Administrators) →
**Public keys** → Import cheia publică. Shell access: terminal + exec.
- Conturile **virtuale** rămân pentru tuneluri (la VADECO: `romfast`, `vadeco`, s2c pe 1521/80).
> **Capcana conturilor virtuale:** implicit sunt mapate pe contul Windows `bvssh_virtualusers`,
> cu privilegii minime. Prin ele obții shell, dar `Get-Service`, `Get-CimInstance` și
> `Get-PSDrive` întorc **gol** — nu erori, ci nimic — și nu se poate instala Oracle. Simptom:
> `whoami` întoarce `<host>\bvssh_virtualusers` și verificarea de admin dă `False`.
>
> Fie folosești un cont Windows real (mai simplu), fie mapezi contul virtual pe un cont admin
> din Advanced settings → Access control → grup → **Windows account** + parolă, plus setarea
> **Elevation** (fără ea, token filtrat de UAC și instalarea Oracle pică pe permisiuni obscure).
> Dezavantaj: parola de admin ajunge stocată în configul Bitvise.
> **Capcana LSA protection:** pe Windows recent (~2025+) cu Bitvise < 9.51, autentificarea cu
> cheie pe **conturi Windows** eșuează (parola merge, cheia nu) — vezi
> `acces-ssh-chei-angajati.md`. Pe Server 2019 nu se aplică. Conturile virtuale nu sunt afectate
> niciodată.
### OpenSSH nativ Windows (alternativă, fără licențiere)
```powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic
Start-Service sshd
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-PropertyType String -Force
$f = "$env:ProgramData\ssh\administrators_authorized_keys"
Set-Content -Path $f -Encoding ascii -Value 'ssh-ed25519 AAAA... comentariu'
icacls $f /inheritance:r /grant "*S-1-5-32-544:F" /grant "*S-1-5-18:F"
Restart-Service sshd
```
- `administrators_authorized_keys` e fișierul corect pentru conturi **admin** (nu `~/.ssh`).
- ACL-ul de la `icacls` e obligatoriu: cu moștenire de permisiuni, sshd ignoră fișierul **în
tăcere** și vezi doar „Permission denied". SID-urile evită problema pe Windows localizat.
- `-Encoding ascii` intenționat — `utf8` în PowerShell 5.1 scrie BOM, iar sshd nu digeră cheia.
### Firewall
```powershell
Set-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -RemoteAddress 100.64.0.0/10
# Bitvise:
Get-NetFirewallRule -DisplayName '*Bitvise*' | Set-NetFirewallRule -RemoteAddress 100.64.0.0/10
```
Restricția se face **pe firewall**, nu prin bind pe adresa 100.x în configul serverului SSH: la
boot, interfața Tailscale urcă adesea *după* serviciu, bind-ul eșuează și serverul rămâne mort.
## 4. Testul de acceptanță
De pe orice device ROMFAST din tailnet:
```bash
ssh Administrator@100.93.100.75 "powershell -c (Get-Item 'C:\').FullName"
```
Pentru comenzi mai complexe, ghilimelele se pierd prin lanțul ssh → Bitvise → PowerShell.
Folosește `-EncodedCommand`:
```bash
ENC=$(iconv -f UTF-8 -t UTF-16LE script.ps1 | base64 -w0)
ssh Administrator@100.93.100.75 "powershell -NoProfile -EncodedCommand $ENC"
```
Output-ul PowerShell prin exec vine cu antet `#< CLIXML` și un bloc `<Objs Version=...>` —
se filtrează cu `grep -v`.
## 5. Verificare de mediu înainte de instalarea Oracle
```powershell
"ADMIN = $(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))"
"OS = $((Get-CimInstance Win32_OperatingSystem).Caption)"
"RAM_GB = $([math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory/1GB,1))"
Get-Service | Where-Object {$_.Name -like 'Oracle*'} | Select-Object Name,Status,StartType
Get-PSDrive -PSProvider FileSystem | Select-Object Name,@{n='FreeGB';e={[math]::Round($_.Free/1GB,1)}}
```
`ADMIN = True` e condiția minimă — dacă e `False`, restul câmpurilor vin goale din lipsă de
drepturi, nu pentru că lipsesc, și orice concluzie despre mașină e falsă.
## Revocarea accesului
1. Machines → nodul → **Remove** (îl scoate din tailnet complet); și/sau
2. ștergerea cheii publice din contul de pe serverul SSH.
Pasul 1 e suficient și instantaneu — fără el, ștergerea cheii lasă nodul în rețea.

View File

@@ -330,6 +330,19 @@ in `Y:\ROAUPDATE\_UPDATE\`, care e live pentru toti.
Pointeri incrucisati: [`00-INSTALL-ORACLE-XE.md`](../proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md) Pointeri incrucisati: [`00-INSTALL-ORACLE-XE.md`](../proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md)
si [`00-INSTALL-ORACLE-SE.md`](../proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-SE.md). si [`00-INSTALL-ORACLE-SE.md`](../proxmox/lxc108-oracle/roa-windows-setup/docs/00-INSTALL-ORACLE-SE.md).
## 8b. Ramase de verificat (din blocul 08.08.2026)
- **`SYSTEM` verificat doar la `sigma` si `automotive`.** Ceilalti clienti nu au fost atinsi;
expeditorii cunoscuti sunt `roaupdate_acn@`, `roaupdate-clever@` (lista completa in sectiunea 3).
- **`ACN` — tacere de pe 06.08** dupa curatenie. Neconfirmat ca jobul mai ruleaza. Se verifica cu:
```sql
SELECT MAX(dataora) FROM contafin_oracle.diag_spatiu_log;
```
- **`UPDATEROA_ZILNIC.failure_count`** = 233 la AUTOMOTIVE, 47 la SIGMA, desi toate rularile din
ultimele 7 zile sunt `SUCCEEDED`. Pare contor istoric — neinvestigat, de urmarit, nu de reparat.
- **`SYS.AUTH_DETALII` si `SYS.AUTH_SERII` raman in `SYSTEM`** (`sys-objects.sql`, pasii `[1/11]`
si `[2/11]`). Nu cresc, nu s-au atins.
## 9. Legaturi in acest repo ## 9. Legaturi in acest repo
| Document | Ce e | | Document | Ce e |

View File

@@ -1,117 +0,0 @@
# Handoff — diagnostic spatiu Oracle la clienti (08.08.2026)
Stare la predare. **Fara analize noi** — doar ce s-a facut, ce nu, si capcanele platite.
## 1. Livrabile
### Comise si impinse — `015cd79` pe `master` (ROMFASTSQL)
| Fisier | Ce contine |
|---|---|
| `docs/diagnostic-spatiu-clienti.md` | **documentul principal** (nou, 9 sectiuni): pointeri COMUN, praguri, emailuri, tunel SSH, triaj, starea per client, plafoane la instalare, ce s-a schimbat in installer |
| `CLAUDE.md:51` | linie de index catre documentul de mai sus |
| `proxmox/lxc108-oracle/clienti/README.md` | idem, in tabelul „Proceduri generale" |
| `.../roa-windows-setup/sql/sys-objects.sql` (sectiunea `[3/11]`) | `SYS.INFO` se creeaza in tablespace `ROA` (tabela + LOB), fallback pe `SYSTEM` cu avertisment |
| `.../roa-windows-setup/sql/scheduler-jobs.sql` (SECTION 4, prompturi renumerotate `/5`) | job `SYS.SYSINFO_PURJARE_ZILNIC`, 03:30, retentie 90 zile, transe de 10.000 randuri, **ENABLED** |
| `.../roa-windows-setup/sql/uninstall-roa.sql` | dezinstalarea sterge si jobul |
| `.../roa-windows-setup/docs/00-INSTALL-ORACLE-XE.md` si `-SE.md` | pas post-instalare: plafon `SYSTEM` 2000M + mutarea `SYS.INFO` la instalari vechi |
### In SVN (r18010), **NEPUBLICAT catre clienti** — in afara acestui repo
`D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\sys_2026_08_08_02_SYS_INFO_TABLESPACE_PURJARE.sql`
Doi pasi: **recrearea** tabelei in `ROA` (`drop table sys.info purge` + `create ... tablespace ROA
lob (info) store as (tablespace ROA)` + `alter procedure sys.pinfo compile`) → creare job.
Nivel Oracle 10.2, idempotent, CRLF verificat (103 linii, 0 LF singure, 0 octeti non-ASCII).
**r18009 muta tabela** (`alter table ... move`); **r18010 o recreeaza** — decizia lui Marius:
continutul e log fara valoare, iar `DROP`+`CREATE` nu cere spatiu liber cat segmentul si nu tine
tabela blocata. `PURGE` e obligatoriu (altfel segmentul ramane in recyclebin). Fallback pe `SYSTEM`
daca `CREATE`-ul in `ROA` esueaza, ca tabela sa existe intotdeauna.
Pasul 1 are `EXCEPTION WHEN OTHERS THEN NULL` **intentionat** (o eroare acolo nu are voie sa
opreasca lantul de actualizare; ce n-a mers apare a doua zi in alerta `DIAGSPATIU_ZILNIC`).
**Publicarea catre clienti NU s-a facut si e decizia lui Marius** —
`COMUN\utile\publicare_scripturi.ps1` scrie in `Y:\ROAUPDATE\_UPDATE\`, care e live pentru toti.
## 2. Modificari aplicate in productie
**AUTOMOTIVE (`78.96.115.213`, xe 11.2.0.2 pe host `SERVER`), 08.08.2026 — write-back facut, verificat:**
```sql
alter database datafile 'E:\ORACLEXE\APP\ORACLE\ORADATA\XE\SYSTEM.DBF'
autoextend on next 50M maxsize 2000M; -- ca contafin_oracle
truncate table sys.info; -- ca SYSDBA
```
Rezultat verificat: `SYSTEM` 540 MB alocati / 2000 plafon, 84.94 MB liberi, **1544.94 MB de crestere
(77.2%)** vs prag 300 MB. `SYS.INFO` 552.581 randuri / 80 MB → 0 randuri / 0.06 MB.
**Nicio alta baza de client nu a fost modificata.** SIGMA a fost doar citita.
## 3. Ce NU s-a facut
- scriptul de livrare e in SVN (r18009) dar **nu e publicat catre clienti**;
- **nu s-a verificat `SYSTEM` la ceilalti clienti** — umblat doar la `sigma` si `automotive`;
ceilalti expeditori cunoscuti: `roaupdate-clever@`, `roaupdate_acn@`;
- `ACN` — tacere din 06.08 dupa curatenie; **neconfirmat** ca jobul chiar mai ruleaza (se verifica
cu `max(dataora)` din `contafin_oracle.diag_spatiu_log`);
- `UPDATEROA_ZILNIC.failure_count` = 233 la AUTOMOTIVE, 47 la SIGMA, desi toate rularile din
ultimele 7 zile sunt `SUCCEEDED` si `UPD_ISTORIC` ajunge la `stare = 4` — neinvestigat, pare
contor istoric;
- `SYS.AUTH_DETALII` si `SYS.AUTH_SERII` raman in `SYSTEM` (`sys-objects.sql` `[1/11]`, `[2/11]`) —
nu cresc, nu s-au atins.
## 4. Stare periculoasa la predare
**Niciuna.** Toate tunelurile sunt inchise (`Get-Process stnlc` gol, portul 1521 liber), nu exista
tranzactii deschise, nu exista fisiere editate fara write-back, nimic necomis din ce am atins.
Fisierele `.sh` care apar modificate in `git status` (`migration/*.sh`, `lxc171-claude-agent/*.sh`,
`clone-vm300.sh`, `export-roa2.sh`, `fix-sqlnet.sh`) si `bash.exe.stackdump` **nu sunt ale acestei
sesiuni** — le-a lasat sesiunea paralela. Nu le atinge fara sa intrebi.
## 5. Capcane de mediu platite
- **Alta sesiune lucreaza in acelasi repo.** In timpul lucrului a comis `9475842` si a curatat
working tree-ul, **stergand toate modificarile mele in fisiere urmarite de git**. Au supravietuit
doar fisierul nou (netracked) si scriptul de pe `D:`. A trebuit refacut totul. **Comite des.**
- **Thunderbird**: profilul din `%APPDATA%\Thunderbird\Profiles` e gol si induce in eroare —
instalarea reala e portabila, `D:\UTIL\portable\PortableApps\ThunderbirdPortable`. Contul
`marius.mutu@romfast.ro` = `ImapMail\mail.romfast.ro\INBOX`. Nu da ripgrep pe folder
(`INBOX.sbd\Sent` are 2.5 GB).
- **Bitvise `stnlc`**: `-profile=` nu merge cu host pozitional; **nu da `-c2s`**, regulile de
forwarding vin de la server. Sintaxa care merge:
`& 'C:\Program Files (x86)\Bitvise SSH Client\stnlc.exe' --% -profile=d:\GoogleDrive\<client>.tlp -noRegistry=y`
Profilele: `D:\GoogleDrive\*.tlp` (`sigma`, `automotive`, `clever-motors`, `rompetrole`, …).
- **Toate aliasurile TNS de client tintesc `127.0.0.1:1521`** — un tunel gresit te duce tacut la alt
client. Verifica portul liber inainte (`Get-NetTCPConnection -State Listen -LocalPort 1521`) si
pune `select instance_name, host_name from v$instance` ca prima interogare.
- **Inchide tunelul** cand termini: `Get-Process stnlc | Stop-Process -Force`.
- Regula din `COMUN\docs\local\oracle.md`: tunelul spre productie doar cand acel server e chiar
subiectul investigatiei, si atunci **strict read-only** (exceptia de azi a fost ceruta explicit).
- SQL-ul se da lui `sqlplus` **dintr-un fisier**, nu prin pipe.
## 6. Comenzi
```powershell
# emailurile de diagnostic (expeditor + subiect + alerte)
powershell -File D:\roa\roagest\comun\utile\citeste_email.ps1 -Cauta 'Diagnostic spatiu' -Ultimele 10
# diagnostic manual pe un client, read-only
powershell -File D:\roa\roagest\comun\utile\diag_spatiu.ps1 -Alias ROA_SIGMA [-Disc]
# conectare prin tunel
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'contafin_oracle/ROMFASTSOFT@ROA_SIGMA' '@diag.sql'
```
Fara loguri de rulare — verificarile s-au facut interactiv, iesirea e in conversatie.
## 7. De unde se reia
1. publicarea lui `sys_2026_08_08_02_...` catre clienti (decizie Marius; e deja in SVN la r18009);
2. verificarea preventiva a lui `SYSTEM` la `clever` si `acn`;
3. confirmarea ca `DIAGSPATIU_ZILNIC` mai ruleaza la `acn`.
Contextul complet: [`diagnostic-spatiu-clienti.md`](diagnostic-spatiu-clienti.md).

View File

@@ -1,159 +0,0 @@
# Handoff — granturi dicționar PACK_DIAG_SPATIU + `sys-grants.sql` legat în flux
**Data:** 2026-08-25
**Branch:** `feat/oracle-instalare-migrare-sys-grants`
**Commit:** `afb8266`
**Bloc următor:** testare pe VM 302 (oprit acum, trebuie pornit)
---
## 1. De unde a pornit
Client vechi cu **Oracle XE 11 pe Windows**; se instalează Oracle 21c XE pe un server nou și se
mută `CONTAFIN_ORACLE` + schemele de firme. Întrebarea inițială: care dintre directoarele de
migrare se folosește.
**Răspuns stabilit (nu se mai re-analizează):** `proxmox/lxc108-oracle/roa-windows-setup/`.
Motivele complete sunt în `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`.
`migration/` țintește Oracle în Docker pe LXC 108; `new-roa-oracle-server/` e arhivă istorică.
---
## 2. Livrabile — inventar
### Cod
| Fișier:linie | Ce s-a schimbat |
|---|---|
| `proxmox/lxc108-oracle/roa-windows-setup/sql/sys-grants.sql:107-172` | secțiune nouă `[5/5]` — `GRANT SELECT` direct pe 18 vederi `dba_*`/`v$*` către `CONTAFIN_ORACLE`; bloc PL/SQL idempotent, `ORA-00942` tratat; secțiunile 1-4 renumerotate `[n/4]` → `[n/5]` |
| `proxmox/lxc108-oracle/roa-windows-setup/scripts/04-create-synonyms-grants.ps1:147-166` | STEP 3 nou — execută `sys-grants.sql` ca SYS/SYSDBA, după import |
| `…/04-create-synonyms-grants.ps1:225-258` | verificare `DICT_GRANTS` (avertizează sub 15 din 18) |
| `…/04-create-synonyms-grants.ps1` (header, validare căi, summary) | `$sysGrantsScript`, `Test-Path`, linii de summary |
| `proxmox/lxc108-oracle/roa-windows-setup/scripts/07-verify-installation.ps1:255-305` | secțiune de raport „Dictionary Grants (PACK_DIAG_SPATIU)" — listează nominal care lipsesc |
Ambele `.ps1` trec `[Parser]::ParseFile` fără erori. **Atât s-a verificat.**
### Documentație
- **nou:** `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
- actualizate: `roa-windows-setup/README.md`, `migration/README.md`,
`lxc108-oracle/README.md`, `proxmox/README.md`, `CLAUDE.md`,
`roa-windows-setup/sql/sys-updates/README.md`, `vm302-oracle-test/README.md`,
`vm302-oracle-test/docs/dual-edition-test-plan.md`,
`vm302-oracle-test/docs/issues-se-prod.md`
---
## 3. Ce e terminat și ce nu
**Terminat:** editările pe disc, commit făcut, working tree curat.
**NU e terminat: nimic nu a fost rulat pe o bază Oracle reală.** VM 302 era oprit
(`qm list` → `302 oracle-test-302 stopped`) și nu l-am pornit. Nicio afirmație despre
comportamentul la rulare nu e verificată.
---
## 4. Blocul următor — testare pe VM 302
```bash
ssh root@10.0.20.201 "qm start 302" # ~2-3 min boot
ssh root@10.0.20.201 "qm status 302"
```
VM 302: `oracle-test-302`, **10.0.20.130**, hostname `ROACENTRAL`, Windows 11, Oracle 21c XE
(CDB/PDB, service `XEPDB1`), user `romfast`. RDP: `mstsc /v:10.0.20.130`.
Scripturile pe VM stau în `C:\roa-setup\` — **sunt o copie**, nu un clone al repo-ului.
**Primul pas: sincronizează `C:\roa-setup\` cu branch-ul `feat/oracle-instalare-migrare-sys-grants`**,
altfel testezi versiunea veche. Minimum de copiat:
`sql\sys-grants.sql`, `scripts\04-create-synonyms-grants.ps1`, `scripts\07-verify-installation.ps1`.
DMP-uri deja prezente pe VM în `C:\DMPDIR\`: `contafin_oracle_72001.dmp` (276 MB),
`capidavatour_72001.dmp` (76 MB).
Ciclul de test:
```powershell
cd C:\roa-setup
.\scripts\99-uninstall-roa.ps1 -SystemPassword "romfastsoft" -Force
.\RunAll.cmd # ~8 min
.\Run.cmd 07-verify-installation.ps1
```
Logurile scriu în `C:\roa-setup\logs\<script>_<yyyyMMdd_HHmmss>.log`.
### Ce trebuie să arate testul
1. `04-create-synonyms-grants.ps1` — STEP 3 rulează `sys-grants.sql`; în log:
`Dictionary grants for PACK_DIAG_SPATIU: 18 / 18`.
2. `07-verify-installation.ps1` — secțiunea „Dictionary Grants (PACK_DIAG_SPATIU)" cu
`Status: OK`.
3. Verificare independentă, direct în bază:
```sql
SELECT COUNT(*) FROM dba_tab_privs
WHERE grantee = 'CONTAFIN_ORACLE' AND grantor = 'SYS' AND privilege = 'SELECT';
```
4. Sinonimele SYS care înainte **nu se creau** (regresia găsită la punctul 1 din commit):
```sql
SELECT synonym_name FROM dba_synonyms
WHERE owner = 'PUBLIC' AND table_owner = 'SYS'
AND synonym_name IN ('SYN_NEWSCHEMA','SYN_NEWSCHEMAJOB','EXECUTESCRIPTOS','SYN_PINFO');
```
Trebuie 4 rânduri. Dacă apar 4, e confirmarea că STEP 3 chiar rulează.
**Notă:** DMP-ul de test `contafin_oracle_72001.dmp` s-ar putea să nu conțină
`PACK_DIAG_SPATIU` (pachetul e livrat prin `co_2026_08_*` din repo-ul COMUN). Testul verifică
**granturile**, nu compilarea pachetului. Dacă vrei și compilarea, pachetul trebuie adus separat
din `D:\roa\roagest\comun\docs\PACK_DIAG_SPATIU.pck`.
---
## 5. Stare periculoasă / atenționări
- **Nimic în stare inconsistentă.** Fără tranzacții deschise, fără procese rămase vii, fără
fișiere editate fără write-back.
- **VM 302 rămâne oprit** — dacă îl pornești, oprește-l la final:
`ssh root@10.0.20.201 "qm shutdown 302"`.
- **`99-uninstall-roa.ps1 -Force` e distructiv** — șterge `CONTAFIN_ORACLE`, `CAPIDAVATOUR`,
tablespace-ul `ROA`, sinonimele publice și obiectele SYS. Corect pe VM 302 (e mediu de test).
**Niciodată la client.**
- **Branch, nu master.** Merge-ul nu e făcut:
```bash
git checkout master && git merge feat/oracle-instalare-migrare-sys-grants
```
Nu e împins nicăieri.
- **Diff-ul `.ps1` pare rescriere totală.** Cauză preexistentă: blob-urile din HEAD sunt cu
CRLF, iar `.gitattributes` cere `*.ps1 text eol=crlf`, deci orice atingere declanșează
renormalizarea. Modificarea reală: 66 și 51 de linii. Se vede cu `git diff --ignore-cr-at-eol`.
---
## 6. Ce s-a stabilit deja (nu se reia)
- **Directorul corect e `roa-windows-setup/`.** Analiza comparativă e în
`docs/instalare-si-migrare-oracle.md`; nu se re-face.
- **`sys_2026_01_14_01_AUTH_PACK` e deja acoperit** de `sql/sys-objects.sql` — specificația
pachetului e identică, iar lista de programe din repo e un superset (are în plus
`GENERARESCRIPT.EXE`, `ROAACTUALIZARI.EXE`, `EXP.EXE`, `IMP.EXE`).
- **`sys_2026_08_08_02_SYS_INFO_TABLESPACE_PURJARE` e deja acoperit** de
`sys-objects.sql:94-109` (INFO în tablespace `ROA`) + `scheduler-jobs.sql:176`
(`SYS.SYSINFO_PURJARE_ZILNIC`). A intrat prin commit-ul `015cd79`.
- **Singurele `sys_*` care lipseau** erau cele trei `DIAG_SPATIU_GRANT*` — acum consolidate.
- Sursa scripturilor `sys_*`: `D:\roa\database\SCRIPTURI_CLAR\<an>\<lună>\`. Cel mai recent
la data handoff-ului: `sys_2026_08_08_02`.
---
## 7. De verificat înainte de migrarea reală la client
- **Plafonul XE.** 21c XE: 12 GB date de utilizator, 2 GB RAM, 2 thread-uri. Sursa (11.2 XE)
avea plafon 11 GB, deci teoretic intră, dar cu marjă mică. Se măsoară pe sursă:
```sql
SELECT ROUND(SUM(bytes)/1024/1024/1024, 2) AS gb FROM dba_segments
WHERE owner NOT IN ('SYS','SYSTEM','OUTLN','DBSNMP','XDB','APEX_040000');
```
Peste plafon → Standard Edition, care e **netestată** (`vm302-oracle-test/docs/issues-se-prod.md`).
- **Conectarea la `XEPDB1`**, niciodată la `XE` (CDB root).
- **`sqlnet.ora` + resetarea parolelor**, altfel Instant Client 10/11 al clientului nu se conectează.
- **`expdp` vs `exp`** — formate incompatibile; `exp` se importă doar cu `imp`.

View File

@@ -0,0 +1,205 @@
@echo off
REM =============================================================================
REM ROA Oracle - instalare la client, neinteractiva
REM =============================================================================
REM Ruleaza pasii 01..08 in ordine, din radacina kitului.
REM
REM Spre deosebire de RunAll.cmd, scriptul asta NU foloseste "set /p", deci
REM poate fi rulat si prin SSH / dintr-o sesiune fara tastatura.
REM
REM Utilizare:
REM INSTALEAZA.cmd curat [IdClient] [ServerSMTP]
REM INSTALEAZA.cmd migrare [IdClient] [ServerSMTP]
REM
REM Exemple:
REM INSTALEAZA.cmd curat 138 mail.romfast.ro
REM INSTALEAZA.cmd migrare 214
REM =============================================================================
setlocal enabledelayedexpansion
set "KIT=%~dp0"
set "SCEN=%~1"
set "IDCLIENT=%~2"
set "SMTP=%~3"
set "DMPDEST=C:\DMPDIR"
if /i "%SCEN%"=="curat" goto :scenar_ok
if /i "%SCEN%"=="migrare" goto :scenar_ok
goto :utilizare
:scenar_ok
if "%SMTP%"=="" set "SMTP=mail.romfast.ro"
echo.
echo ============================================================
echo ROA Oracle - instalare (%SCEN%)
echo ============================================================
echo.
echo Kit: %KIT%
echo DMPDIR tinta: %DMPDEST%
echo Id client: %IDCLIENT%
echo Server SMTP: %SMTP%
echo.
REM ---------------------------------------------------------------------------
REM Pregatirea DMPDIR
REM ---------------------------------------------------------------------------
if not exist "%KIT%DMPDIR\FIRMANOUA.dmp" (
echo [EROARE] Lipseste "%KIT%DMPDIR\FIRMANOUA.dmp".
echo Fara sablonul de firma noua, clientul nu va putea adauga firme.
echo Reconstruieste kitul cu build-client-kit.ps1.
exit /b 1
)
dir /b "%KIT%DMPDIR\*contafin*.dmp" >nul 2>&1
if errorlevel 1 (
echo [EROARE] Lipseste un fisier *contafin*.dmp din "%KIT%DMPDIR".
exit /b 1
)
if /i "%SCEN%"=="migrare" (
REM Kitul contine mereu 2 sabloane: *contafin*.dmp si FIRMANOUA.dmp.
REM Orice peste 2 sunt DMP-urile de firma ale clientului.
set /a TOTALDMP=0
for %%F in ("%KIT%DMPDIR\*.dmp") do set /a TOTALDMP+=1
if !TOTALDMP! LEQ 2 (
echo [ATENTIE] In "%KIT%DMPDIR" sunt doar !TOTALDMP! fisiere DMP,
echo adica doar sabloanele. La o migrare ar trebui sa existe
echo si cate un DMP per firma a clientului.
echo Continui - pasul 05 va raporta firmele lipsa.
echo.
)
)
if not exist "%DMPDEST%" mkdir "%DMPDEST%"
echo [1/9] Copiez fisierele DMP in %DMPDEST% ...
copy /Y "%KIT%DMPDIR\*.dmp" "%DMPDEST%\" >nul
if errorlevel 1 (
echo [EROARE] Copierea DMP-urilor a esuat.
exit /b 1
)
REM Serviciul Oracle citeste fisierele cu contul lui, nu cu al tau. Fara
REM drepturi explicite, Data Pump da ORA-39002 / LFI la deschiderea fisierului.
icacls "%DMPDEST%" /grant "NT SERVICE\OracleServiceXE:(OI)(CI)F" /T >nul 2>&1
echo Gata.
REM ---------------------------------------------------------------------------
REM Pasii de instalare
REM ---------------------------------------------------------------------------
echo.
echo [2/9] 01-setup-database.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\01-setup-database.ps1"
if errorlevel 1 goto :esec_01
echo.
echo [3/9] 02-create-sys-objects.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\02-create-sys-objects.ps1"
if errorlevel 1 goto :esec_02
echo.
echo [4/9] 03-import-contafin.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\03-import-contafin.ps1"
set RC=!ERRORLEVEL!
REM Codul 5 e normal aici: Data Pump raporteaza "completed with errors" pentru
REM ORA-31684 (userul e creat deja de pasul 01) si ORA-39082 (warning-uri de
REM compilare, rezolvate la pasul 04). Orice alt cod nenul e esec real.
if "!RC!"=="0" goto :pas_04
if "!RC!"=="5" (
echo [INFO] Cod de iesire 5 - normal pentru Data Pump, se continua.
goto :pas_04
)
echo [EROARE] 03-import-contafin.ps1 a iesit cu codul !RC!.
exit /b !RC!
:pas_04
echo.
echo [5/9] 04-create-synonyms-grants.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\04-create-synonyms-grants.ps1"
if errorlevel 1 goto :esec_04
echo.
echo [6/9] 05-import-companies.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\05-import-companies.ps1"
if errorlevel 1 goto :esec_05
echo.
echo [7/9] 08-post-install-config.ps1
if "%IDCLIENT%"=="" (
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\08-post-install-config.ps1" -EmailSmtp "%SMTP%"
) else (
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\08-post-install-config.ps1" -CustomerId "%IDCLIENT%" -EmailSmtp "%SMTP%"
)
if errorlevel 1 goto :esec_08
echo.
echo [8/9] 07-verify-installation.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%KIT%scripts\07-verify-installation.ps1"
set RCVERIF=!ERRORLEVEL!
echo.
echo [9/9] Rezultat
echo ============================================================
if "!RCVERIF!"=="0" (
echo INSTALARE COMPLETA - verificarea a trecut integral.
) else (
echo INSTALARE TERMINATA, DAR VERIFICAREA A SEMNALAT PROBLEME.
echo Citeste lista din raportul de mai sus si logurile din logs\.
if /i "%SCEN%"=="migrare" (
echo.
echo La migrare, "N company schemas are missing" inseamna ca lipsesc
echo DMP-urile firmelor respective. Copiaza-le in %DMPDEST% si reia
echo doar pasul 05.
)
)
echo ============================================================
echo.
if /i "%SCEN%"=="curat" (
echo PASUL URMATOR - prima firma:
echo.
echo Se creeaza DIN APLICATIA ROA, nu din scripturi. Aplicatia scrie firma
echo in CONTAFIN_ORACLE.NOM_FIRME si apeleaza SYS.NEWSCHEMA, care importa
echo structura din %DMPDEST%\FIRMANOUA.dmp.
echo.
echo NU sterge FIRMANOUA.dmp din %DMPDEST% - e folosit la fiecare firma
echo noua, oricand pe viitor.
echo.
)
endlocal & exit /b %RCVERIF%
REM ---------------------------------------------------------------------------
:esec_01
echo [EROARE] 01-setup-database.ps1 a esuat. Instalarea se opreste.
exit /b 1
:esec_02
echo [EROARE] 02-create-sys-objects.ps1 a esuat. Instalarea se opreste.
exit /b 1
:esec_04
echo [EROARE] 04-create-synonyms-grants.ps1 a esuat. Instalarea se opreste.
exit /b 1
:esec_05
echo [EROARE] 05-import-companies.ps1 a esuat. Instalarea se opreste.
exit /b 1
:esec_08
echo [EROARE] 08-post-install-config.ps1 a esuat. Instalarea se opreste.
exit /b 1
:utilizare
echo.
echo Utilizare:
echo INSTALEAZA.cmd curat [IdClient] [ServerSMTP]
echo INSTALEAZA.cmd migrare [IdClient] [ServerSMTP]
echo.
echo curat Client nou, fara firme anterioare. In DMPDIR trebuie sa fie
echo doar sabloanele: contafin_oracle.dmp si FIRMANOUA.dmp.
echo.
echo migrare Client cu date existente. In DMPDIR trebuie sa fie
echo contafin_oracle.dmp AL CLIENTULUI, cate un DMP per firma,
echo plus sablonul FIRMANOUA.dmp.
echo.
echo ServerSMTP e optional (implicit mail.romfast.ro).
echo.
exit /b 2

View File

@@ -21,9 +21,12 @@ Scripts and documentation for setting up ROA Oracle Database on Windows servers:
| Scenario | Description | | Scenario | Description |
|----------|-------------| |----------|-------------|
| **New Server** | Oracle 21c SE (non-CDB) or XE (CDB/PDB) + CONTAFIN_ORACLE.dmp | | **A. Instalare pe curat** | Client nou, fără firme anterioare. Pornești din șabloanele `contafin_oracle.dmp` + `FIRMANOUA.dmp` |
| **Migration** | Import existing DMP files (CONTAFIN_ORACLE + 30-50 companies), inclusiv de pe Oracle XE 11 / 10g | | **B. Migrare** | Client cu Oracle XE 11 / 10g. Aduci `contafin_oracle.dmp` al clientului + câte un `.dmp` per firmă |
| **Add Company** | Add new company schema to existing server | | **Add Company** | Firmă nouă pe un server deja instalat (normal din aplicație, prin `SYS.NEWSCHEMA`) |
Ambele instalări rulează **aceleași** scripturi în **aceeași** ordine — diferă doar ce pui în
`C:\DMPDIR`. Pașii detaliați: [Cele două scenarii de instalare](#cele-două-scenarii-de-instalare).
--- ---
@@ -40,6 +43,10 @@ Scripts and documentation for setting up ROA Oracle Database on Windows servers:
## Quick Start ## Quick Start
> Care fișiere `.dmp` îți trebuie depinde de scenariu (A pe curat / B migrare) — vezi
> [DMP Files Required](#dmp-files-required). `FIRMANOUA.dmp` trebuie copiat în **ambele**
> cazuri, altfel clientul nu va putea adăuga firme noi.
### Oracle 21c Express Edition (XE) - Gratuit ### Oracle 21c Express Edition (XE) - Gratuit
1. Download și instalează Oracle 21c XE (see `docs/00-INSTALL-ORACLE-XE.md`) 1. Download și instalează Oracle 21c XE (see `docs/00-INSTALL-ORACLE-XE.md`)
2. Copiază fișierele DMP în `C:\DMPDIR\` 2. Copiază fișierele DMP în `C:\DMPDIR\`
@@ -47,6 +54,8 @@ Scripts and documentation for setting up ROA Oracle Database on Windows servers:
```cmd ```cmd
RunAll.cmd RunAll.cmd
``` ```
`RunAll.cmd` e **interactiv** — cere confirmare la tastatură. Pentru rulare automată,
apelează scripturile în ordine (vezi scenariile A / B).
### Oracle 21c Standard Edition (SE) - Licență ### Oracle 21c Standard Edition (SE) - Licență
1. Download și instalează Oracle 21c SE (see `docs/00-INSTALL-ORACLE-SE.md`) 1. Download și instalează Oracle 21c SE (see `docs/00-INSTALL-ORACLE-SE.md`)
@@ -223,12 +232,63 @@ Modern multitenant architecture with Container Database.
## DMP Files Required ## DMP Files Required
### For New Installation Care fișiere îți trebuie depinde de scenariu. **Alege întâi scenariul:**
| Scenariu | Când | DMP-uri necesare |
|---|---|---|
| **A. Instalare pe curat** | Client nou, fără firme anterioare | `contafin_oracle.dmp` (șablon) + `FIRMANOUA.dmp` (șablon) |
| **B. Migrare** | Client cu Oracle XE mai vechi, are deja date | `contafin_oracle.dmp` **al clientului** + câte un `.dmp` per firmă + `FIRMANOUA.dmp` (șablon) |
| File | Description | Size | | File | Description | Size |
|------|-------------|------| |------|-------------|------|
| `contafin_oracle.dmp` | Common schema (rights, updates, etc.) | ~50MB | | `contafin_oracle.dmp` | Schema comună (drepturi, actualizări, `NOM_FIRME`) | ~50-280 MB |
| `[company].dmp` | Company schema (one per company) | ~100-500MB each | | `FIRMANOUA.dmp` | **Șablon de firmă goală.** Sursa din care `SYS.NEWSCHEMA` și `06-add-company.ps1` creează orice firmă nouă | ~24 MB |
| `[company].dmp` | Schema unei firme existente (doar la migrare, una per firmă) | ~100-500 MB fiecare |
> **`FIRMANOUA.dmp` trebuie să ajungă în `C:\DMPDIR` la ORICE instalare, și la A și la B.**
> Nu e folosit de scripturile 01-08, ci mult mai târziu: când clientul adaugă o firmă nouă din
> aplicație, `SYS.NEWSCHEMA` îl caută în directorul Oracle `DMPDIR`
> ([`sql/sys-objects.sql`](sql/sys-objects.sql), `lcSchemaSursa := 'FIRMANOUA'`). Dacă lipsește,
> adăugarea firmei pică în `DBMS_DATAPUMP.ADD_FILE` — peste luni de la instalare, când nimeni
> nu mai leagă eroarea de instalare.
> `07-verify-installation.ps1` verifică prezența lui și raportează lipsa ca eroare.
### De unde iei DMP-urile șablon
Ambele stau pe **LXC 108** (`central-oracle`, 10.0.20.121), în containerul `oracle-xe`:
Sunt **trei** niveluri de scos, nu unul: container Docker → LXC 108 → host pvemini → stația ta.
`docker cp` te scoate doar din container, iar `scp root@10.0.20.201:/tmp/...` citește de pe
**host**, unde fișierul încă nu a ajuns — de aceea e nevoie și de `pct pull`.
```bash
# 1. container oracle-xe -> LXC 108 (fisierul ajunge in /tmp AL CONTAINERULUI 108)
ssh root@10.0.20.201 "pct exec 108 -- docker cp oracle-xe:/tmp/oracle-import-roa2/firmanoua.dmp /tmp/firmanoua.dmp"
# 2. LXC 108 -> host pvemini
ssh root@10.0.20.201 "pct pull 108 /tmp/firmanoua.dmp /tmp/firmanoua.dmp"
# 3. host -> statia ta
scp root@10.0.20.201:/tmp/firmanoua.dmp ./FIRMANOUA.dmp
```
Identic pentru `contafin_oracle.dmp` (înlocuiește numele în toți cei trei pași).
Apoi copiezi fișierele pe serverul clientului, în `C:\DMPDIR`:
```bash
scp ./FIRMANOUA.dmp <user>@<server-client>:C:/DMPDIR/FIRMANOUA.dmp
```
> Numele fișierului pe destinație trebuie să fie **`FIRMANOUA.dmp`** — `SYS.NEWSCHEMA` îl
> construiește ca `lcSchemaSursa || '.dmp'`, cu `lcSchemaSursa := 'FIRMANOUA'`. În container
> fișierul e cu litere mici (`firmanoua.dmp`); pe Windows nu contează, dar redenumește-l oricum
> ca să fie clar.
Copie identică există și în `/opt/oracle/admin/XE/dpdump/<GUID-PDB>/` din același container.
`contafin_oracle.dmp` de acolo este varianta **curată**: `NOM_FIRME` are doar rândul-sămânță
(`FIRMA = 0`, fără schemă) plus o firmă marcată ștearsă — deci
`07-verify-installation.ps1` nu va raporta firme lipsă după instalare.
### Obtaining DMP Files ### Obtaining DMP Files
@@ -251,37 +311,170 @@ scp root@10.0.20.201:/opt/oracle18/oradata/dmpdir/contafin_oracle.dmp C:\DMPDIR\
## Workflow Examples ## Workflow Examples
### New Server Installation ### Cele două scenarii de instalare
Ambele rulează **aceleași** scripturi, în **aceeași** ordine. Diferența e doar în ce pui în
`C:\DMPDIR` înainte de a porni și ce faci după pasul 07.
#### Scenariul A — instalare pe curat (client nou, fără firme anterioare)
Pornești de la șabloanele de pe LXC 108. `NOM_FIRME` vine practic goală, deci pasul 05 nu are
ce importa — îl lași să ruleze, iese cu `0` și „No companies found in NOM_FIRME". Prima firmă o
creezi la final, din șablonul `FIRMANOUA.dmp`.
```powershell ```powershell
# 1. Install Oracle 21c XE (see docs/00-INSTALL-ORACLE-XE.md) # 1. Instalezi Oracle 21c XE (vezi docs/00-INSTALL-ORACLE-XE.md)
# Parola SYS/SYSTEM la instalare: romfastsoft
# 2. Configure # 2. Configurare
Copy-Item config.example.ps1 config.ps1 Copy-Item config.example.ps1 config.ps1
notepad config.ps1 # Edit values notepad config.ps1 # SERVICE_NAME=XEPDB1 pentru XE, ROA pentru SE
# 3. Copy DMP files # 3. DMP-urile SABLON (vezi "De unde iei DMP-urile sablon")
mkdir C:\DMPDIR mkdir C:\DMPDIR
Copy-Item \\server\dmp\*.dmp C:\DMPDIR\ Copy-Item \\server\sabloane\contafin_oracle.dmp C:\DMPDIR\
Copy-Item \\server\sabloane\FIRMANOUA.dmp C:\DMPDIR\
# 4. Run setup scripts # 4. Instalarea propriu-zisa
.\01-setup-database.ps1 Run.cmd 01-setup-database.ps1
.\02-create-sys-objects.ps1 Run.cmd 02-create-sys-objects.ps1
.\03-import-contafin.ps1 Run.cmd 03-import-contafin.ps1 # cod de iesire 5 = NORMAL, vezi mai jos
.\04-create-synonyms-grants.ps1 Run.cmd 04-create-synonyms-grants.ps1
.\05-import-companies.ps1 Run.cmd 05-import-companies.ps1 # no-op: NOM_FIRME e goala
.\08-post-install-config.ps1 Run.cmd 08-post-install-config.ps1 -CustomerId "<id-client>" -EmailSmtp "mail.romfast.ro"
.\07-verify-installation.ps1 Run.cmd 07-verify-installation.ps1
``` ```
**Pasul 5 — prima firmă — se face din aplicația ROA, nu din scripturi.** Aplicația inserează
firma în `CONTAFIN_ORACLE.NOM_FIRME` și apoi apelează `SYS.NEWSCHEMA(schema, luna, an)`, care
creează userul și îi importă structura din `FIRMANOUA.dmp` (`DMPDIR`). De asta fișierul
**rămâne** în `C:\DMPDIR` după instalare — e folosit la fiecare firmă nouă, oricând.
`06-add-company.ps1` este calea manuală, de depanare: creează schema și îi importă șablonul,
dar **nu** scrie în `NOM_FIRME`. Dacă îl folosești, firma nu apare în aplicație până nu o
înregistrezi tu, iar `07-verify-installation.ps1` o raportează ca „Orphan schema (not in
NOM_FIRME)".
```powershell
# doar daca ai nevoie de calea manuala:
Run.cmd 06-add-company.ps1 -CompanyName "FIRMACLIENT" -TemplateDump "C:\DMPDIR\FIRMANOUA.dmp" -TemplateSchema "FIRMANOUA"
# ...urmat de inregistrarea firmei in CONTAFIN_ORACLE.NOM_FIRME
```
#### Scenariul B — migrare de pe un Oracle XE mai vechi
Ai `contafin_oracle.dmp` **al clientului** (cu `NOM_FIRME` populată) plus câte un `.dmp` per
firmă. Pasul 05 citește `NOM_FIRME` din schema deja importată la pasul 03 și potrivește
fiecare firmă cu fișierul ei din `C:\DMPDIR`.
```powershell
# 0. Export de pe serverul VECHI - vezi "Migrare de la un server client existent" mai jos.
# Lista schemelor: SELECT schema FROM CONTAFIN_ORACLE.NOM_FIRME WHERE sters = 0;
# 1-2. Ca la scenariul A (instalare Oracle + config.ps1)
# 3. DMP-urile CLIENTULUI + sablonul de firma noua
mkdir C:\DMPDIR
Copy-Item D:\export-client\contafin_oracle.dmp C:\DMPDIR\
Copy-Item D:\export-client\*.dmp C:\DMPDIR\ # cate unul per firma
Copy-Item \\server\sabloane\FIRMANOUA.dmp C:\DMPDIR\ # NU vine de la client!
# 4. Aceeasi ordine, aceleasi scripturi
Run.cmd 01-setup-database.ps1
Run.cmd 02-create-sys-objects.ps1
Run.cmd 03-import-contafin.ps1 # aduce NOM_FIRME cu firmele clientului
Run.cmd 04-create-synonyms-grants.ps1
Run.cmd 05-import-companies.ps1 # importa toate firmele gasite in NOM_FIRME
Run.cmd 08-post-install-config.ps1 -CustomerId "<id-client>" -EmailSmtp "mail.romfast.ro"
Run.cmd 07-verify-installation.ps1
```
Verificare intermediară utilă înainte de import (nu modifică nimic):
```powershell
Run.cmd 05-import-companies.ps1 -DryRun # arata ce firma se leaga de ce fisier
```
Numele fișierului nu trebuie să fie identic cu schema — pasul 05 potrivește `NOM_FIRME.SCHEMA`
cu fișierele din director, deci `capidavatour_72001.dmp` se leagă de schema `CAPIDAVATOUR`.
#### Ce e comun ambelor scenarii
- **`03-import-contafin.ps1` iese cu codul 5 și asta e normal** — e codul Data Pump pentru
„completed with errors": `ORA-31684 ... already exists` (userul e creat deja de pasul 01) și
`ORA-39082` (warning-uri de compilare, rezolvate la pasul 04). Nu e eșec; citește logul.
- **`RunAll.cmd` nu poate fi rulat neinteractiv** (folosește `set /p`). Pe stdin redirecționat
fie anulează instalarea *ieșind cu codul 0*, fie dă „The syntax of the command is incorrect".
Pentru automatizare apelează scripturile în ordine, ca mai sus.
- **Conectarea se face la `XEPDB1`**, niciodată la `XE` (CDB root).
- La final `07-verify-installation.ps1` trebuie să iasă cu **0**. Cod `1` → citește lista de
probleme din raport; `FIRMANOUA.dmp missing from DMPDIR` e eroare reală în ambele scenarii.
- Dacă reiei instalarea de la zero, `99-uninstall-roa.ps1` trebuie să iasă cu **0**. Cod diferit
de 0 înseamnă că au rămas obiecte (uzual o sesiune activă ținea userul ocupat) — nu porni
instalarea, altfel pasul 05 dă `ORA-31684` în lanț.
### Kit de instalare pentru client (recomandat)
În loc să aduni manual DMP-urile și scripturile, construiește un kit gata de dus la client:
```powershell
cd proxmox\lxc108-oracle\scripts
.\build-client-kit.ps1 -Zip
```
Scriptul exportă `CONTAFIN_ORACLE` și `FIRMANOUA` de pe LXC 108 (PDB **ROA2**, nu ROA — ROA e
producția `ROA_CENTRAL`), le aduce local prin cele trei hopuri, le redenumește la
`contafin_oracle.dmp` / `FIRMANOUA.dmp` și le pune lângă o copie a scripturilor de instalare.
Verifică și **câte firme are `NOM_FIRME`** în dump, citind logul expdp. Un șablon curat are 2
rânduri; dacă vezi zeci, ai prins din greșeală datele unei baze reale și nu ai voie s-o trimiți
mai departe.
Kitul are structura lui `roa-windows-setup/` plus `DMPDIR/`, deci se dezarhivează pe serverul
clientului și se rulează direct:
```cmd
INSTALEAZA.cmd curat 138 mail.romfast.ro
INSTALEAZA.cmd migrare 214
```
`INSTALEAZA.cmd` face ce face `RunAll.cmd`, dar **fără `set /p`** — deci merge și prin SSH, fără
tastatură. Copiază DMP-urile în `C:\DMPDIR`, dă drepturi contului `NT SERVICE\OracleServiceXE`,
rulează pașii în ordine, tratează corect codul 5 de la pasul 03 și se oprește la prima eroare
reală.
Opțiuni utile:
| Parametru | Ce face |
|---|---|
| `-SkipExport` | Refolosește ultimele arhive de pe LXC 108, fără export nou |
| `-Zip` | Produce și o arhivă `.zip` de trimis |
| `-PushTo "user@host:C:/kit"` | Trimite kitul direct pe serverul țintă, prin scp |
| `-OracleVersion 18` | Exportă din `oracle18-xe` (`VERSION=11.2`), pentru baze mai vechi |
> `scp` copiază **conținutul** kitului direct în destinație dacă aceasta nu există, sau kitul ca
> subdirector dacă există deja. Verifică unde a ajuns înainte să rulezi `INSTALEAZA.cmd`.
Fluxul complet, kit → instalare pe curat → `[OK] All checks passed!`, e validat pe VM 302
(2026-08-25).
---
### Post-Installation Configuration (08-post-install-config.ps1) ### Post-Installation Configuration (08-post-install-config.ps1)
This script completes the ROA setup by configuring: This script completes the ROA setup by configuring:
1. **ROAUPDATE Directories**: Creates 54 physical folders and Oracle DIRECTORY objects 1. **ROAUPDATE Directories**: Creates 54 physical folders and Oracle DIRECTORY objects
2. **SERVER_INFO**: Encoded passwords, paths, email settings for PACK_UPDATE 2. **SERVER_INFO**: Encoded passwords, paths, email settings for PACK_UPDATE
3. **Customer ID**: Sets AUTH_DETALII for license verification 3. **SMTP**: setează `SMTP_OUT_SERVER` și ACL-ul de rețea pentru `CONTAFIN_ORACLE`
4. **Scheduler Jobs**: UPDATEROA_ZILNIC and UPDATERTVAI_ZILNIC (disabled by default) 4. **Customer ID**: Sets AUTH_DETALII for license verification
5. **Scheduler Jobs**: UPDATEROA_ZILNIC and UPDATERTVAI_ZILNIC (disabled by default)
> **De ce e nevoie de pasul 3:** `sys-objects.sql` instalează `UTL_MAIL` și `sys-grants.sql` dă
> `EXECUTE` pe el — atât cât să *compileze* codul care trimite mailuri. Ca să și *funcționeze*
> mai trebuie parametrul `SMTP_OUT_SERVER` (altfel `ORA-29278/29279`) și un ACL de rețea către
> serverul SMTP (din 12c încoace orice acces de rețea din PL/SQL trece prin ACL, altfel
> `ORA-24247`). Ambele se pun aici; sari peste cu `-SkipSmtpConfig`.
```powershell ```powershell
# Basic usage (defaults: D:\ROAUPDATE, no Customer ID) # Basic usage (defaults: D:\ROAUPDATE, no Customer ID)
@@ -290,11 +483,11 @@ This script completes the ROA setup by configuring:
# With custom ROAUPDATE path and Customer ID # With custom ROAUPDATE path and Customer ID
.\08-post-install-config.ps1 -RoaUpdatePath "E:\ROAUPDATE" -CustomerId "138" .\08-post-install-config.ps1 -RoaUpdatePath "E:\ROAUPDATE" -CustomerId "138"
# With email configuration # With email configuration (seteaza si SMTP_OUT_SERVER + ACL)
.\08-post-install-config.ps1 -EmailTo "admin@company.ro" -EmailSmtp "mail.company.ro" .\08-post-install-config.ps1 -EmailTo "admin@company.ro" -EmailSmtp "mail.company.ro" -EmailPort 25
# Skip specific parts # Skip specific parts
.\08-post-install-config.ps1 -SkipSchedulerJobs -SkipServerInfo .\08-post-install-config.ps1 -SkipSchedulerJobs -SkipServerInfo -SkipSmtpConfig
``` ```
**Enable automatic updates after verification:** **Enable automatic updates after verification:**
@@ -424,6 +617,22 @@ sqlplus sys/romfastsoft@localhost:1521/XEPDB1 as sysdba @sql/uninstall-roa.sql
> **Warning:** This permanently deletes all ROA data! Use only for testing or before reinstallation. > **Warning:** This permanently deletes all ROA data! Use only for testing or before reinstallation.
**Verifică întotdeauna codul de ieșire.** Fiecare secțiune a scriptului prinde excepțiile în
`WHEN OTHERS` ca să nu se oprească la primul obstacol, deci mesajele intermediare nu spun dacă
a reușit. Verdictul e dat de blocul final, care numără ce a rămas:
| Cod | Înseamnă |
|---|---|
| `0` | Baza e curată. Poți relua instalarea. |
| ≠ `0` | `ORA-20900` — au rămas obiecte ROA. **Nu porni instalarea.** |
Cauza uzuală a unei dezinstalări incomplete e o sesiune activă care ține userul ocupat
(`ORA-01940`); scriptul mai încearcă o dată după `KILL SESSION`, dar dacă aplicația ROA e
pornită nu are ce face. Închide aplicația și sesiunile `sqlplus`, apoi rulează din nou.
Dacă ignori codul de ieșire și pornești instalarea peste o dezinstalare parțială, pasul 05 dă
`ORA-31684 ... already exists` în lanț.
--- ---
## Troubleshooting ## Troubleshooting
@@ -468,6 +677,35 @@ ALTER PLUGGABLE DATABASE XEPDB1 OPEN;
ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE; ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE;
``` ```
### ORA-12609: TNS Receive timeout — importul „eșuează" deși a reușit
**Simptom:** `03-import-contafin.ps1` (sau `05`) se termină cu
`UDI-12609 / ORA-12609: TNS: Receive timeout occurred`, raportează `Objects imported: 0` și iese
cu cod nenul. Dar în logul Data Pump din `C:\DMPDIR` scrie
`Job "SYSTEM"."SYS_IMPORT_SCHEMA_01" completed`.
**Cauză:** `SQLNET.RECV_TIMEOUT` în `sqlnet.ora`. Fișierul e citit și de clienții de pe aceeași
mașină (`impdp`, `expdp`, `sqlplus`), iar în timpul unui import serverul poate lucra minute
întregi fără să trimită vreun pachet — creare de indecși, constrângeri. Clientul `impdp` moare,
jobul de pe server continuă și se termină cu bine, iar scriptul numără obiectele imediat după
moartea clientului și găsește 0.
Pe Oracle 21c fișierul care contează e cel din **read-only home**:
`C:\app\<user>\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora`, nu cel din `dbhomeXE`.
**Rezolvare:** scoate `SQLNET.RECV_TIMEOUT` și `SQLNET.SEND_TIMEOUT`. `01-setup-database.ps1` nu
le mai scrie (le hardcoda pe amândouă la 30 s), dar o instalare mai veche le poate avea încă:
```powershell
$f = "C:\app\romfast\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora"
(Get-Content $f) | Where-Object { $_ -notmatch 'SQLNET\.(RECV|SEND)_TIMEOUT' } | Set-Content $f
```
`SQLNET.INBOUND_CONNECT_TIMEOUT` poate rămâne — limitează doar handshake-ul de conectare.
Importul care „a eșuat" nu trebuie refăcut dacă logul spune `completed`; rulează doar
`07-verify-installation.ps1` ca să confirmi.
### Import Errors ### Import Errors
**ORA-00959: tablespace 'ROA' does not exist:** **ORA-00959: tablespace 'ROA' does not exist:**

View File

@@ -322,7 +322,7 @@ EXIT;
$synData = @{} $synData = @{}
foreach ($line in $synResult -split "`n") { foreach ($line in $synResult -split "`n") {
if ($line -match "^([A-Z_]+):(\d+)$") { if ($line -match "^([A-Z_]+):(\d+)\s*$") {
$synData[$Matches[1]] = [int]$Matches[2] $synData[$Matches[1]] = [int]$Matches[2]
} }
} }
@@ -454,6 +454,70 @@ EXIT;
} }
} }
# Company Template + SMTP
# ------------------------------------------------------------------------
# SYS.NEWSCHEMA (si 06-add-company.ps1) creeaza o firma noua importand
# sablonul FIRMANOUA.dmp din directorul Oracle DMPDIR. Daca fisierul nu e
# acolo, adaugarea de firme noi pica in DBMS_DATAPUMP.ADD_FILE - dar abia
# peste luni, cand clientul chiar adauga o firma. Il verificam la instalare.
Add-ReportSection "Company Template + SMTP"
# Lipsa sablonului e un defect real (blocheaza adaugarea de firme), deci
# intra in $issues si in codul de iesire. SMTP nesetat ramane doar o nota:
# nu toti clientii folosesc notificarile pe email.
$extraIssues = @()
$tmplSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT 'DMPDIR_PATH:' || directory_path FROM dba_directories WHERE directory_name = 'DMPDIR';
SELECT 'SMTP_OUT:' || NVL(value, '<nesetat>') FROM v`$parameter WHERE name = 'smtp_out_server';
EXIT;
"@
$tmplResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $tmplSql -AsSysdba -Silent
$dmpDirPath = $null
$smtpOut = $null
foreach ($line in $tmplResult -split "`n") {
$line = $line.Trim()
if ($line -match "^DMPDIR_PATH:(.+)$") { $dmpDirPath = $Matches[1].Trim() }
if ($line -match "^SMTP_OUT:(.+)$") { $smtpOut = $Matches[1].Trim() }
}
if (-not $dmpDirPath) {
Add-ReportLine "[WARNING] Directorul Oracle DMPDIR nu exista."
$extraIssues += "Oracle directory DMPDIR missing"
}
else {
Add-ReportLine "DMPDIR: $dmpDirPath"
$tmplPath = Join-Path $dmpDirPath "FIRMANOUA.dmp"
if (Test-Path $tmplPath) {
$sizeMb = [math]::Round((Get-Item $tmplPath).Length / 1MB, 1)
Add-ReportLine "FIRMANOUA.dmp: OK ($sizeMb MB)"
}
else {
Add-ReportLine "FIRMANOUA.dmp: LIPSA"
Add-ReportLine ""
Add-ReportLine "[WARNING] Fara sablonul FIRMANOUA.dmp in DMPDIR, adaugarea unei firme"
Add-ReportLine " noi (SYS.NEWSCHEMA / 06-add-company.ps1) va esua la"
Add-ReportLine " DBMS_DATAPUMP.ADD_FILE. Copiaza-l in $dmpDirPath."
Add-ReportLine " Sursa: LXC 108, container oracle-xe,"
Add-ReportLine " /tmp/oracle-import-roa2/firmanoua.dmp"
$extraIssues += "FIRMANOUA.dmp missing from DMPDIR (adding new companies will fail)"
}
}
Add-ReportLine ""
if ($smtpOut -and $smtpOut -ne '<nesetat>') {
Add-ReportLine "SMTP_OUT_SERVER: $smtpOut"
}
else {
Add-ReportLine "SMTP_OUT_SERVER: NESETAT"
Add-ReportLine "[NOTA] UTL_MAIL.SEND va da ORA-29278/29279 pana cand e setat."
Add-ReportLine " Ruleaza 08-post-install-config.ps1 -EmailSmtp <server>."
}
# Network ACL Status # Network ACL Status
Add-ReportSection "Network ACL Status" Add-ReportSection "Network ACL Status"
@@ -531,6 +595,10 @@ EXIT;
$issues += "$($missingCompanies.Count) company schemas are missing" $issues += "$($missingCompanies.Count) company schemas are missing"
} }
if ($extraIssues.Count -gt 0) {
$issues += $extraIssues
}
if ($issues.Count -eq 0) { if ($issues.Count -eq 0) {
Add-ReportLine "[OK] All checks passed!" Add-ReportLine "[OK] All checks passed!"
Add-ReportLine "" Add-ReportLine ""

View File

@@ -1,159 +1,168 @@
# ============================================================================ # ============================================================================
# ROA UNINSTALL SCRIPT # ROA UNINSTALL SCRIPT
# ============================================================================ # ============================================================================
# Removes all ROA application objects from Oracle database # Removes all ROA application objects from Oracle database
# #
# Usage: # Usage:
# .\99-uninstall-roa.ps1 -SystemPassword "yourpassword" # .\99-uninstall-roa.ps1 -SystemPassword "yourpassword"
# .\99-uninstall-roa.ps1 -SystemPassword "yourpassword" -Force # .\99-uninstall-roa.ps1 -SystemPassword "yourpassword" -Force
# .\99-uninstall-roa.ps1 -ServiceName "XEPDB1" -SystemPassword "yourpassword" -Force # .\99-uninstall-roa.ps1 -ServiceName "XEPDB1" -SystemPassword "yourpassword" -Force
# #
# Parameters: # Parameters:
# -SystemPassword : SYS password for database connection (default: romfastsoft) # -SystemPassword : SYS password for database connection (default: romfastsoft)
# -ServiceName : Oracle service name (auto-detected if not specified) # -ServiceName : Oracle service name (auto-detected if not specified)
# -Force : Skip confirmation prompt # -Force : Skip confirmation prompt
# #
# ============================================================================ # ============================================================================
param( param(
[Parameter(Mandatory=$false)] [Parameter(Mandatory=$false)]
[string]$OracleHome, [string]$OracleHome,
[Parameter(Mandatory=$false)] [Parameter(Mandatory=$false)]
[string]$ServiceName, [string]$ServiceName,
[Parameter(Mandatory=$false)] [Parameter(Mandatory=$false)]
[string]$SystemPassword = "romfastsoft", [string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory=$false)] [Parameter(Mandatory=$false)]
[switch]$Force [switch]$Force
) )
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
# ============================================================================ # ============================================================================
# LOAD CONFIGURATION AND LIBRARIES # LOAD CONFIGURATION AND LIBRARIES
# ============================================================================ # ============================================================================
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RootDir = Split-Path -Parent $ScriptDir $RootDir = Split-Path -Parent $ScriptDir
# Load config (optional - script can work with auto-detection) # Load config (optional - script can work with auto-detection)
$ConfigFile = Join-Path $RootDir "config.ps1" $ConfigFile = Join-Path $RootDir "config.ps1"
if (Test-Path $ConfigFile) { if (Test-Path $ConfigFile) {
. $ConfigFile . $ConfigFile
# Use config values if parameters not provided # Use config values if parameters not provided
if (-not $OracleHome -and $ORACLE_HOME) { $OracleHome = $ORACLE_HOME } if (-not $OracleHome -and $ORACLE_HOME) { $OracleHome = $ORACLE_HOME }
if (-not $ServiceName -and $SERVICE_NAME) { $ServiceName = $SERVICE_NAME } if (-not $ServiceName -and $SERVICE_NAME) { $ServiceName = $SERVICE_NAME }
if ($SystemPassword -eq "romfastsoft" -and $SYSTEM_PASSWORD) { $SystemPassword = $SYSTEM_PASSWORD } if ($SystemPassword -eq "romfastsoft" -and $SYSTEM_PASSWORD) { $SystemPassword = $SYSTEM_PASSWORD }
} }
# Load libraries # Load libraries
. (Join-Path $ScriptDir "lib\logging-functions.ps1") . (Join-Path $ScriptDir "lib\logging-functions.ps1")
. (Join-Path $ScriptDir "lib\oracle-functions.ps1") . (Join-Path $ScriptDir "lib\oracle-functions.ps1")
# ============================================================================ # ============================================================================
# MAIN # MAIN
# ============================================================================ # ============================================================================
Write-Host "" Write-Host ""
Write-Host "============================================================" -ForegroundColor Cyan Write-Host "============================================================" -ForegroundColor Cyan
Write-Host " ROA UNINSTALL - REMOVING ALL ROA OBJECTS" -ForegroundColor Cyan Write-Host " ROA UNINSTALL - REMOVING ALL ROA OBJECTS" -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Cyan Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "" Write-Host ""
# Get Oracle Home # Get Oracle Home
$oraHome = Get-OracleHome -OracleHome $OracleHome $oraHome = Get-OracleHome -OracleHome $OracleHome
Write-Host "[INFO] Oracle Home: $oraHome" -ForegroundColor Green Write-Host "[INFO] Oracle Home: $oraHome" -ForegroundColor Green
# Get listener host # Get listener host
$OracleHost = Get-ListenerHost -OracleHome $oraHome $OracleHost = Get-ListenerHost -OracleHome $oraHome
Write-Host "[INFO] Database Host: $OracleHost" -ForegroundColor Green Write-Host "[INFO] Database Host: $OracleHost" -ForegroundColor Green
# Auto-detect service name if not specified # Auto-detect service name if not specified
if (-not $ServiceName) { if (-not $ServiceName) {
$ServiceName = "XEPDB1" # Default for Oracle XE $ServiceName = "XEPDB1" # Default for Oracle XE
} }
Write-Host "[INFO] Service Name: $ServiceName" -ForegroundColor Green Write-Host "[INFO] Service Name: $ServiceName" -ForegroundColor Green
# Build connection string # Build connection string
$OraclePort = 1521 $OraclePort = 1521
$ConnString = "${OracleHost}:${OraclePort}/${ServiceName}" $ConnString = "${OracleHost}:${OraclePort}/${ServiceName}"
Write-Host "" Write-Host ""
Write-Host "Target database: $ConnString" -ForegroundColor Yellow Write-Host "Target database: $ConnString" -ForegroundColor Yellow
Write-Host "" Write-Host ""
# Confirmation # Confirmation
if (-not $Force) { if (-not $Force) {
Write-Host "WARNING: This will PERMANENTLY DELETE all ROA data!" -ForegroundColor Red Write-Host "WARNING: This will PERMANENTLY DELETE all ROA data!" -ForegroundColor Red
Write-Host "" Write-Host ""
Write-Host "Objects to be removed:" -ForegroundColor Yellow Write-Host "Objects to be removed:" -ForegroundColor Yellow
Write-Host " - All company user schemas (using ROA tablespace)" Write-Host " - All company user schemas (using ROA tablespace)"
Write-Host " - CONTAFIN_ORACLE user and all objects" Write-Host " - CONTAFIN_ORACLE user and all objects"
Write-Host " - Public synonyms pointing to CONTAFIN_ORACLE" Write-Host " - Public synonyms pointing to CONTAFIN_ORACLE"
Write-Host " - SYS custom objects (AUTH_PACK, AUTH_SERII, etc.)" Write-Host " - SYS custom objects (AUTH_PACK, AUTH_SERII, etc.)"
Write-Host " - Application context SESIUNE" Write-Host " - Application context SESIUNE"
Write-Host " - Tablespace ROA (including datafile)" Write-Host " - Tablespace ROA (including datafile)"
Write-Host "" Write-Host ""
$confirm = Read-Host "Type 'YES' to confirm uninstall" $confirm = Read-Host "Type 'YES' to confirm uninstall"
if ($confirm -ne "YES") { if ($confirm -ne "YES") {
Write-Host "Uninstall cancelled." -ForegroundColor Yellow Write-Host "Uninstall cancelled." -ForegroundColor Yellow
exit 0 exit 0
} }
} }
Write-Host "" Write-Host ""
Write-Host "Starting uninstall..." -ForegroundColor Cyan Write-Host "Starting uninstall..." -ForegroundColor Cyan
Write-Host "" Write-Host ""
# Find sqlplus # Find sqlplus
$SqlPlus = Join-Path $oraHome "bin\sqlplus.exe" $SqlPlus = Join-Path $oraHome "bin\sqlplus.exe"
if (-not (Test-Path $SqlPlus)) { if (-not (Test-Path $SqlPlus)) {
Write-Host "ERROR: sqlplus.exe not found at $SqlPlus" -ForegroundColor Red Write-Host "ERROR: sqlplus.exe not found at $SqlPlus" -ForegroundColor Red
exit 1 exit 1
} }
# Run uninstall script # Run uninstall script
$SqlScript = Join-Path $RootDir "sql\uninstall-roa.sql" $SqlScript = Join-Path $RootDir "sql\uninstall-roa.sql"
if (-not (Test-Path $SqlScript)) { if (-not (Test-Path $SqlScript)) {
Write-Host "ERROR: uninstall-roa.sql not found at $SqlScript" -ForegroundColor Red Write-Host "ERROR: uninstall-roa.sql not found at $SqlScript" -ForegroundColor Red
exit 1 exit 1
} }
Write-Host "Running uninstall script..." -ForegroundColor Cyan Write-Host "Running uninstall script..." -ForegroundColor Cyan
Write-Host "" Write-Host ""
# Set Oracle environment # Set Oracle environment
$env:ORACLE_HOME = $oraHome $env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH" $env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
# Execute uninstall SQL script # Execute uninstall SQL script
try { try {
& $SqlPlus "sys/${SystemPassword}@${ConnString} as sysdba" "@$SqlScript" & $SqlPlus "sys/${SystemPassword}@${ConnString} as sysdba" "@$SqlScript"
$exitCode = $LASTEXITCODE $exitCode = $LASTEXITCODE
} }
catch { catch {
Write-Host "ERROR: Failed to execute uninstall script: $_" -ForegroundColor Red Write-Host "ERROR: Failed to execute uninstall script: $_" -ForegroundColor Red
exit 1 exit 1
} }
Write-Host "" # uninstall-roa.sql se termina cu un bloc de verdict:
if ($exitCode -eq 0) { # - EXIT SUCCESS daca nu a ramas niciun obiect ROA
Write-Host "============================================================" -ForegroundColor Green # - EXIT FAILURE (ORA-20900) daca a supravietuit ceva
Write-Host " ROA UNINSTALL COMPLETE" -ForegroundColor Green # Codul de iesire e deci autoritar; nu-l suprascrie si nu raporta succes fara el.
Write-Host "============================================================" -ForegroundColor Green Write-Host ""
Write-Host "" if ($exitCode -eq 0) {
Write-Host "Database is now clean. You can re-run the setup scripts." -ForegroundColor Cyan Write-Host "============================================================" -ForegroundColor Green
} Write-Host " ROA UNINSTALL COMPLETE" -ForegroundColor Green
else { Write-Host "============================================================" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Yellow Write-Host ""
Write-Host " ROA UNINSTALL COMPLETED WITH WARNINGS" -ForegroundColor Yellow Write-Host "Database is now clean. You can re-run the setup scripts." -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Yellow exit 0
Write-Host "" }
Write-Host "Some objects may not have been removed. Review output above." -ForegroundColor Yellow else {
} Write-Host "============================================================" -ForegroundColor Red
Write-Host "" Write-Host " ROA UNINSTALL INCOMPLET" -ForegroundColor Red
Write-Host "============================================================" -ForegroundColor Red
Write-Host ""
Write-Host "Au ramas obiecte ROA in baza (vezi ORA-20900 mai sus)." -ForegroundColor Red
Write-Host "Cauza uzuala: o sesiune activa tinea userul ocupat." -ForegroundColor Yellow
Write-Host ""
Write-Host "NU porni instalarea acum - pasul 05 va da ORA-31684 in lant." -ForegroundColor Yellow
Write-Host "Inchide aplicatia ROA / sesiunile sqlplus si ruleaza scriptul din nou." -ForegroundColor Yellow
exit $exitCode
}

View File

@@ -12,10 +12,18 @@
-- WARNING: This reduces security. For production environments, consider -- WARNING: This reduces security. For production environments, consider
-- creating a custom profile with appropriate settings. -- creating a custom profile with appropriate settings.
-- --
-- Usage: -- ATENTIE - UNELTA DE REMEDIERE MANUALA, NU FACE PARTE DIN FLUXUL DE INSTALARE
-- @configure-profile.sql -- ----------------------------------------------------------------------------
-- La o instalare normala NU rulezi scriptul asta: `01-setup-database.ps1` face
-- deja acelasi lucru automat, la Step 4 (in PDB) si Step 4b (in CDB root).
-- Foloseste-l doar cand `07-verify-installation.ps1` / `verify-objects.sql`
-- semnaleaza ca profilul DEFAULT are din nou limite de parola - de exemplu pe o
-- baza configurata inainte ca Step 4b sa existe, sau dupa un patch Oracle.
-- --
-- Connect as: SYSDBA -- Usage:
-- sqlplus sys/<parola>@<host>:1521/XEPDB1 as sysdba @configure-profile.sql
--
-- Connect as: SYSDBA, pe PDB (XEPDB1), NU pe CDB root.
-- ============================================================================ -- ============================================================================
SET ECHO OFF SET ECHO OFF
@@ -97,3 +105,46 @@ WHERE username IN ('CONTAFIN_ORACLE', 'SYSTEM', 'SYS')
OR username LIKE 'TEST%'; OR username LIKE 'TEST%';
PROMPT PROMPT
-- ============================================================================
-- ULTIMUL PAS: ACELASI PROFIL SI IN CDB ROOT
-- ============================================================================
-- ALTER PROFILE dintr-un PDB nu acopera CDB root: acolo DEFAULT ramane cu
-- PASSWORD_LIFE_TIME 180, deci SYSTEM din root expira la ~6 luni de la
-- instalare (ORA-28002, apoi ORA-28001) chiar daca in PDB totul e UNLIMITED.
--
-- DEFAULT din root e un profil LOCAL, deci clauza CONTAINER=ALL NU e valida
-- aici (ORA-65142). Se comuta containerul si se altereaza profilul de acolo.
--
-- Blocul e ULTIMUL din fisier intentionat: dupa ALTER SESSION SET CONTAINER
-- restul scriptului ar rula in root, nu in PDB.
-- Pe o baza non-CDB, ALTER SESSION esueaza inofensiv (WHENEVER SQLERROR
-- CONTINUE) si ALTER PROFILE se aplica pe singurul container existent.
PROMPT
PROMPT ========================================
PROMPT Applying the same profile in CDB root
PROMPT ========================================
PROMPT
ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS UNLIMITED
PASSWORD_LOCK_TIME UNLIMITED;
PROMPT
PROMPT Account status in CDB root:
SELECT username, account_status, expiry_date
FROM dba_users
WHERE username IN ('SYS', 'SYSTEM');
PROMPT
PROMPT NOTA: daca SYSTEM apare EXPIRED(GRACE), statusul NU se curata singur
PROMPT cand profilul devine UNLIMITED - cere o singura data:
PROMPT ALTER USER SYSTEM IDENTIFIED BY <parola>;
PROMPT (sau ruleaza 01-setup-database.ps1 -ResetSystemPassword)
PROMPT

View File

@@ -24,7 +24,7 @@ PROMPT
-- SECTION 1: GRANTS TO CONTAFIN_ORACLE -- SECTION 1: GRANTS TO CONTAFIN_ORACLE
-- ============================================================================ -- ============================================================================
PROMPT PROMPT
PROMPT [1/5] Granting privileges to CONTAFIN_ORACLE... PROMPT [1/6] Granting privileges to CONTAFIN_ORACLE...
-- Execute on SYS packages -- Execute on SYS packages
GRANT EXECUTE ON SYS.AUTH_PACK TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.AUTH_PACK TO CONTAFIN_ORACLE;
@@ -32,9 +32,16 @@ GRANT EXECUTE ON SYS.DBMS_SCHEDULER TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.DBMS_LOCK TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.DBMS_LOCK TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UTL_INADDR TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.UTL_INADDR TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UTL_FILE TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.UTL_FILE TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UTL_MAIL TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UTL_SMTP TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.UTL_SMTP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UTL_TCP TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.UTL_TCP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.DBMS_CRYPTO TO CONTAFIN_ORACLE; GRANT EXECUTE ON SYS.DBMS_CRYPTO TO CONTAFIN_ORACLE;
-- Proceduri SYS proprii ROA. Grant DIRECT, nu prin rol si nu prin sinonim public:
-- CONTAFIN_ORACLE.PACK_UPDATE are drepturi de definitor si apeleaza calificat
-- SYS.Updatesqlplus(...), deci rolurile si sinonimele nu se aplica. Fara ele
-- PACK_UPDATE ramane INVALID (PLS-00201). Confirmat pe ROA_CENTRAL 2026-08-25.
GRANT EXECUTE ON SYS.EXECUTESCRIPTOS TO CONTAFIN_ORACLE;
GRANT EXECUTE ON SYS.UPDATESQLPLUS TO CONTAFIN_ORACLE;
-- Directory privileges -- Directory privileges
GRANT CREATE ANY DIRECTORY TO CONTAFIN_ORACLE; GRANT CREATE ANY DIRECTORY TO CONTAFIN_ORACLE;
@@ -51,7 +58,7 @@ PROMPT Grants to CONTAFIN_ORACLE complete.
-- SECTION 2: PUBLIC GRANTS -- SECTION 2: PUBLIC GRANTS
-- ============================================================================ -- ============================================================================
PROMPT PROMPT
PROMPT [2/5] Granting public privileges... PROMPT [2/6] Granting public privileges...
-- UTL packages for public use -- UTL packages for public use
GRANT EXECUTE ON SYS.UTL_FILE TO PUBLIC; GRANT EXECUTE ON SYS.UTL_FILE TO PUBLIC;
@@ -62,7 +69,7 @@ PROMPT Public grants complete.
-- SECTION 3: SYS PUBLIC SYNONYMS -- SECTION 3: SYS PUBLIC SYNONYMS
-- ============================================================================ -- ============================================================================
PROMPT PROMPT
PROMPT [3/5] Creating SYS public synonyms... PROMPT [3/6] Creating SYS public synonyms...
-- Synonyms for SYS procedures -- Synonyms for SYS procedures
BEGIN EXECUTE IMMEDIATE 'DROP PUBLIC SYNONYM SYN_NEWSCHEMA'; EXCEPTION WHEN OTHERS THEN NULL; END; BEGIN EXECUTE IMMEDIATE 'DROP PUBLIC SYNONYM SYN_NEWSCHEMA'; EXCEPTION WHEN OTHERS THEN NULL; END;
@@ -91,7 +98,7 @@ PROMPT SYS public synonyms complete.
-- SECTION 4: DIRECTORY DMPDIR -- SECTION 4: DIRECTORY DMPDIR
-- ============================================================================ -- ============================================================================
PROMPT PROMPT
PROMPT [4/5] Creating DMPDIR directory... PROMPT [4/6] Creating DMPDIR directory...
BEGIN BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY DMPDIR AS ''C:\DMPDIR'''; EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY DMPDIR AS ''C:\DMPDIR''';
@@ -126,7 +133,7 @@ GRANT READ, WRITE ON DIRECTORY DMPDIR TO PUBLIC;
-- Vederile absente pe versiunea/editia curenta sunt ignorate (ORA-00942). -- Vederile absente pe versiunea/editia curenta sunt ignorate (ORA-00942).
-- ============================================================================ -- ============================================================================
PROMPT PROMPT
PROMPT [5/5] Granting data dictionary reads to CONTAFIN_ORACLE (PACK_DIAG_SPATIU)... PROMPT [5/6] Granting data dictionary reads to CONTAFIN_ORACLE (PACK_DIAG_SPATIU)...
DECLARE DECLARE
TYPE t_lista IS TABLE OF VARCHAR2(30); TYPE t_lista IS TABLE OF VARCHAR2(30);
@@ -170,6 +177,40 @@ END;
PROMPT Dictionary grants complete. PROMPT Dictionary grants complete.
-- ============================================================================
-- SECTION 6: RECOMPILARE CONTAFIN_ORACLE
-- ============================================================================
-- Obiectele venite cu Data Pump raman INVALID: la momentul importului granturile
-- de mai sus inca nu erau puse, de unde ORA-39082 "created with compilation
-- warnings" pe SENDEMAIL, EMAIL*, PACK_UPDATE, PACK_UTILS. Oracle le-ar recompila
-- abia la primul apel, asa ca fara pasul asta 07-verify-installation raporteaza
-- obiecte invalide la fiecare instalare curata.
-- Verificat pe VM 302 (2026-08-25): 2 invalide inainte, 0 dupa.
-- ============================================================================
PROMPT
PROMPT [6/6] Recompiling CONTAFIN_ORACLE...
BEGIN
SYS.UTL_RECOMP.RECOMP_SERIAL('CONTAFIN_ORACLE');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(' Recompilare: ' || SQLERRM);
END;
/
DECLARE
lnInvalid PLS_INTEGER;
BEGIN
SELECT COUNT(*) INTO lnInvalid
FROM dba_objects
WHERE owner = 'CONTAFIN_ORACLE' AND status = 'INVALID';
DBMS_OUTPUT.PUT_LINE(' Obiecte INVALID ramase in CONTAFIN_ORACLE: ' || lnInvalid);
END;
/
PROMPT Recompile complete.
PROMPT PROMPT
PROMPT ============================================================ PROMPT ============================================================
PROMPT SYS Grants and Synonyms Installation Complete PROMPT SYS Grants and Synonyms Installation Complete

View File

@@ -32,7 +32,7 @@ PROMPT
-- SECTION 1: TABLES -- SECTION 1: TABLES
-- ============================================================================ -- ============================================================================
PROMPT [1/11] Creating SYS.AUTH_DETALII table... PROMPT [1/10] Creating SYS.AUTH_DETALII table...
DECLARE DECLARE
v_count NUMBER; v_count NUMBER;
BEGIN BEGIN
@@ -50,7 +50,7 @@ BEGIN
END; END;
/ /
PROMPT [2/11] Creating SYS.AUTH_SERII table... PROMPT [2/10] Creating SYS.AUTH_SERII table...
DECLARE DECLARE
v_count NUMBER; v_count NUMBER;
BEGIN BEGIN
@@ -76,7 +76,7 @@ BEGIN
END; END;
/ /
PROMPT [3/11] Creating SYS.INFO table (logging)... PROMPT [3/10] Creating SYS.INFO table (logging)...
-- IMPORTANT: SYS.INFO e log de aplicatie, nu obiect de dictionar - SYS.pINFO scrie ~7 randuri la -- IMPORTANT: SYS.INFO e log de aplicatie, nu obiect de dictionar - SYS.pINFO scrie ~7 randuri la
-- fiecare conectare (~13.500 randuri / ~2 MB pe luna) si nimic nu o citeste. Tinuta in SYSTEM, -- fiecare conectare (~13.500 randuri / ~2 MB pe luna) si nimic nu o citeste. Tinuta in SYSTEM,
-- umple tablespace-ul dictionarului si **orice** script de actualizare pica apoi cu -- umple tablespace-ul dictionarului si **orice** script de actualizare pica apoi cu
@@ -116,7 +116,7 @@ END;
-- SECTION 2: SEQUENCE -- SECTION 2: SEQUENCE
-- ============================================================================ -- ============================================================================
PROMPT [4/11] Creating SYS.SEQ_AUTH_SERII sequence... PROMPT [4/10] Creating SYS.SEQ_AUTH_SERII sequence...
DECLARE DECLARE
v_count NUMBER; v_count NUMBER;
BEGIN BEGIN
@@ -143,7 +143,7 @@ END;
-- SECTION 3: LOGGING PROCEDURE (pINFO) -- SECTION 3: LOGGING PROCEDURE (pINFO)
-- ============================================================================ -- ============================================================================
PROMPT [5/11] Creating SYS.pINFO procedure (logging)... PROMPT [5/10] Creating SYS.pINFO procedure (logging)...
CREATE OR REPLACE PROCEDURE SYS.pINFO( CREATE OR REPLACE PROCEDURE SYS.pINFO(
p_info IN CLOB, p_info IN CLOB,
p_locatia IN VARCHAR2 DEFAULT NULL p_locatia IN VARCHAR2 DEFAULT NULL
@@ -164,7 +164,7 @@ END pINFO;
-- SECTION 4: AUTH_PACK PACKAGE (Oracle 21c compatible with DBMS_CRYPTO) -- SECTION 4: AUTH_PACK PACKAGE (Oracle 21c compatible with DBMS_CRYPTO)
-- ============================================================================ -- ============================================================================
PROMPT [6/11] Creating SYS.AUTH_PACK package specification... PROMPT [6/10] Creating SYS.AUTH_PACK package specification...
CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS
-- ======================================================================== -- ========================================================================
-- AUTH_PACK - License and Authentication Management -- AUTH_PACK - License and Authentication Management
@@ -229,7 +229,7 @@ CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS
END AUTH_PACK; END AUTH_PACK;
/ /
PROMPT [7/11] Creating SYS.AUTH_PACK package body... PROMPT [7/10] Creating SYS.AUTH_PACK package body...
CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK IS CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK IS
-- ======================================================================== -- ========================================================================
-- MODIFICATION HISTORY: -- MODIFICATION HISTORY:
@@ -769,7 +769,7 @@ END AUTH_PACK;
-- SECTION 5: VIEW -- SECTION 5: VIEW
-- ============================================================================ -- ============================================================================
PROMPT [8/11] Creating SYS.VAUTH_SERII view... PROMPT [8/10] Creating SYS.VAUTH_SERII view...
CREATE OR REPLACE VIEW SYS.VAUTH_SERII ( CREATE OR REPLACE VIEW SYS.VAUTH_SERII (
ID_PROGRAM, ID_PROGRAM,
NUME, NUME,
@@ -791,142 +791,355 @@ WHERE b.sters = 0
-- SECTION 6: ADDITIONAL PROCEDURES -- SECTION 6: ADDITIONAL PROCEDURES
-- ============================================================================ -- ============================================================================
PROMPT [9/11] Creating SYS.EXECUTESCRIPTOS procedure... PROMPT [9/10] Creating SYS.EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS...
CREATE OR REPLACE PROCEDURE SYS.EXECUTESCRIPTOS( -- ============================================================================
p_nume_script IN VARCHAR2, -- Sursa: procedurile SYS de pe ROA_CENTRAL (10.0.20.121:1521/ROA), extrase din
p_param IN VARCHAR2, -- dba_source la 2026-08-25. Versiunile anterioare din acest fisier aveau
p_wait IN VARCHAR2, -- semnaturi inventate, incompatibile cu CONTAFIN_ORACLE.PACK_UPDATE, care apeleaza
p_result OUT NUMBER -- SYS.Updatesqlplus(tcSqlPlusPath, tcScriptPath). Nu modifica semnaturile fara sa
) IS -- verifici intai apelurile din PACK_UPDATE / PACK_UTILS.
v_job_name VARCHAR2(100); -- ============================================================================
v_state VARCHAR2(30);
BEGIN CREATE OR REPLACE PROCEDURE SYS.ExecuteScriptOS(tcPowerShellPath in varchar2,
v_job_name := 'EXECUTESCRIPTOS_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS'); tcScriptPath in varchar2) as
lcJobName varchar2(500);
begin
lcJobName := 'exec_ps_' || SUBSTR(SYS_GUID(), 1, 8);
DBMS_SCHEDULER.CREATE_JOB( DBMS_SCHEDULER.CREATE_JOB(
job_name => v_job_name, job_name => lcJobName,
job_type => 'EXECUTABLE', job_action => tcPowerShellPath,
job_action => p_nume_script, number_of_arguments => 4,
number_of_arguments => 1, job_type => 'executable',
start_date => SYSTIMESTAMP, enabled => FALSE
enabled => FALSE,
auto_drop => TRUE
); );
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 1, '-ExecutionPolicy');
job_name => v_job_name, DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 2, 'Bypass');
argument_position => 1, DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 3, '-File');
argument_value => p_param DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 4, tcScriptPath);
);
DBMS_SCHEDULER.ENABLE(v_job_name); DBMS_SCHEDULER.ENABLE(lcJobName);
end ExecuteScriptOS;
/
IF p_wait = 'Y' THEN CREATE OR REPLACE PROCEDURE SYS.NewSchema(tcSchema varchar2,
LOOP tnLuna number,
BEGIN tnAn number) is
SELECT state INTO v_state lcCommand varchar2(1000);
FROM dba_scheduler_jobs
WHERE job_name = v_job_name;
EXIT WHEN v_state NOT IN ('SCHEDULED', 'RUNNING'); lcSchemaSursa VARCHAR2(100) := 'FIRMANOUA';
EXCEPTION lcSchemaDestinatie VARCHAR2(100) := tcSchema;
WHEN NO_DATA_FOUND THEN lcDumpFile VARCHAR2(100);
EXIT; -- Job completed and was auto-dropped lcDumpDir VARCHAR2(100) := 'DMPDIR';
END; -- lnCount number(10);
DBMS_LOCK.SLEEP(1);
END LOOP;
END IF;
p_result := 0; lcSql varchar2(1000);
EXCEPTION lnAn number := tnAn;
lnLuna number := tnLuna;
ldDataI date;
ldDataF date;
lnZileLucratoare number(10) := 0;
lnOreLucratoare number(10) := 0;
lnMaxAn number(10);
lcLocatie varchar2(100) := 'CREARE FIRMA ' || tcSchema;
h1 NUMBER; -- Data Pump job handle
ind NUMBER; -- Loop index
percent_done NUMBER; -- Percentage of job complete
job_state VARCHAR2(30); -- To keep track of job state
le ku$_LogEntry; -- For WIP and error messages
js ku$_JobStatus; -- The job status from get_status
-- jd ku$_JobDesc; -- The job description from get_status
sts ku$_Status; -- The status object returned by get_status
begin
------------------------------------------------------------------------
-- CREATE THE USER
------------------------------------------------------------------------
/* SELECT COUNT(1)
INTO lnCount
FROM dba_users
WHERE username = UPPER(tcSchema);
IF lnCount <> 0 THEN
EXECUTE IMMEDIATE ('DROP USER ' || tcSchema || ' CASCADE');
END IF;*/
lcCommand := 'create user ' || tcSchema || ' identified by ' || CASE
WHEN upper(tcSchema) like 'TEST%' THEN
'"123"'
ELSE
'ROMFASTSOFT'
END || ' default tablespace ROA
temporary tablespace TEMP
profile DEFAULT';
pinfo(lcCommand, lcLocatie);
execute immediate lcCommand;
------------------------------------------------------------------------
-- GRANT PRIVILEGIES
------------------------------------------------------------------------
lcCommand := 'grant connect to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant resource to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create materialized view to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create procedure to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create sequence to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create table to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create trigger to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create type to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create view to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant debug connect session to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant select any table to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant unlimited tablespace to ' || tcSchema;
execute immediate lcCommand;
------------------------------------------------------------------------
-- IMPORT DUMP
------------------------------------------------------------------------
-- Create a (user-named) Data Pump job to do a "full" import (everything
-- in the dump file without filtering).
lcDumpFile := lcSchemaSursa || '.dmp';
-- h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);
h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);
-- Specify the single dump file for the job (using the handle just returned)
-- and directory object, which must already be defined and accessible
-- to the user running this procedure. This is the dump file created by
-- the export operation in the first example.
-- DBMS_DATAPUMP.ADD_FILE(h1, lcDumpFile, lcDumpDir);
BEGIN
PINFO('DBMS_DATAPUMP.ADD_FILE LOG', lcLocatie);
DBMS_DATAPUMP.ADD_FILE(handle => h1,
filename => lcSchemaDestinatie || '.log',
directory => 'DMPDIR',
filetype => 3);
PINFO('DBMS_DATAPUMP.ADD_FILE DMP', lcLocatie);
DBMS_DATAPUMP.ADD_FILE(handle => h1,
filename => lcDumpFile,
directory => lcDumpDir,
filetype => 1);
-- A metadata remap will map all schema objects from HR to BLAKE.
PINFO('DBMS_DATAPUMP.METADATA_REMAP', lcLocatie);
DBMS_DATAPUMP.METADATA_REMAP(h1,
'REMAP_SCHEMA',
lcSchemaSursa,
lcSchemaDestinatie);
-- If a table already exists in the destination schema, skip it (leave
-- the preexisting table alone). This is the default, but it does not hurt
-- to specify it explicitly.
DBMS_DATAPUMP.SET_PARAMETER(h1, 'TABLE_EXISTS_ACTION', 'SKIP');
-- Start the job. An exception is returned if something is not set up properly.
PINFO('DBMS_DATAPUMP.START_JOB', lcLocatie);
DBMS_DATAPUMP.START_JOB(h1);
------------------------------------------------------------------------
-- The import job should now be running. In the following loop, the job is
-- monitored until it completes. In the meantime, progress information is
-- displayed. Note: this is identical to the export example.
percent_done := 0;
job_state := 'UNDEFINED';
while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
dbms_datapump.get_status(h1,
dbms_datapump.ku$_status_job_error +
dbms_datapump.ku$_status_job_status +
dbms_datapump.ku$_status_wip,
-1,
job_state,
sts);
js := sts.job_status;
-- If the percentage done changed, display the new value.
if js.percent_done != percent_done then
pinfo('*** Job percent done = ' || to_char(js.percent_done),
lcLocatie);
percent_done := js.percent_done;
end if;
-- If any work-in-progress (WIP) or Error messages were received for the job,
-- display them.
if (bitand(sts.mask, dbms_datapump.ku$_status_wip) != 0) then
le := sts.wip;
else
if (bitand(sts.mask, dbms_datapump.ku$_status_job_error) != 0) then
le := sts.error;
else
le := null;
end if;
end if;
if le is not null then
ind := le.FIRST;
while ind is not null loop
-- dbms_output.put_line(le(ind).LogText);
pinfo(le(ind).LogText, lcLocatie);
ind := le.NEXT(ind);
end loop;
end if;
end loop;
-- Indicate that the job finished and gracefully detach from it.
-- dbms_output.put_line('Job has completed');
pinfo('Job has completed', lcLocatie);
-- dbms_output.put_line('Final job state = ' || job_state);
pinfo('Final job state = ' || job_state,
'CREARE FIRMA ' || lcSchemaDestinatie);
------------------------------------------------------------------------
-- POST IMPORT
-- 1. actualizare calendar, sal_calendar, cote_tva
-- CALENDAR
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.CALENDAR SET ANUL = :1, LUNA = :2, AN = TO_CHAR(:3), NL = LPAD(:4, 2, ''0'')';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnAn, lnLuna;
-- SAL_CALENDAR
ldDataI := TO_DATE(lpad(lnAn, 4, '0') || lpad(lnLuna, 2, '0'), 'YYYYMM');
ldDataF := ADD_MONTHS(ldDataI, 1) - 1;
lcSql := 'select ' || lcSchemaDestinatie ||
'.pack_personal.calculeaza_nr_zile(:1, :2) FROM DUAL';
EXECUTE IMMEDIATE lcSql
INTO lnZileLucratoare
USING ldDataI, ldDataF;
lnOreLucratoare := lnZileLucratoare * 8;
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.SAL_CALENDAR SET AN = :1 , LUNA = :2, ZILELUC = :3, ORESTAS = :4, ORELUC = :5';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnZileLucratoare, lnOreLucratoare, lnOreLucratoare;
-- SAL_IMPOZITAR
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.SAL_IMPOZITAR SET AN = :1 , LUNA = :2';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna;
-- PLCONT
lcSql := 'SELECT max(an) as plan from ' || lcSchemaDestinatie ||
'.PLCONT';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
into lnMaxAn;
if lnMaxAn <> lnAn then
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.PLCONT SET AN = :1 WHERE AN = :2';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnMaxAn;
end if;
-- COTE_TVA
lcSql := 'SELECT max(an*12+luna) from ' || lcSchemaDestinatie ||
'.cote_tva';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
into lnMaxAn;
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.COTE_TVA SET AN = :1, LUNA = :2 WHERE AN*12+LUNA = :3';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnMaxAn;
------------------------------------------------------------------------
-- 2. ACTUALIZARE SCHEMA LA ZI
PINFO('Actualizare schema la zi...', lcLocatie);
CONTAFIN_ORACLE.PACK_UPDATE.UpdateROA(tnUpdateApp => 0,
tnUpdateScripturi => 0,
tnUpdateDatabase => 1,
tcSchemaList => tcSchema);
EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
p_result := -1; PINFO(SQLERRM, lcLocatie);
END EXECUTESCRIPTOS; raise_application_error(-20000, SQLERRM);
END;
DBMS_DATAPUMP.DETACH(h1);
end NewSchema;
/ /
PROMPT [10/11] Creating SYS.NEWSCHEMA procedure... CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMAJOB(tcSchema varchar2,
CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMA( tnLuna number,
p_schema_name IN VARCHAR2, tnAn number) as
p_password IN VARCHAR2, lcJobName varchar2(500);
p_result OUT NUMBER begin
) IS lcJobName := 'NEWSCHEMA_' || UPPER(tcSchema);
BEGIN dbms_scheduler.create_job(job_name => lcJobName,
EXECUTE IMMEDIATE 'CREATE USER ' || p_schema_name || job_type => 'STORED_PROCEDURE',
' IDENTIFIED BY ' || p_password || job_action => 'NEWSCHEMA',
' DEFAULT TABLESPACE ROA' || number_of_arguments => 3,
' TEMPORARY TABLESPACE TEMP' || enabled => false);
' QUOTA UNLIMITED ON ROA'; dbms_scheduler.set_job_argument_value(lcJobName, 1, tcSchema);
dbms_scheduler.set_job_argument_value(lcJobName, 2, to_char(tnLuna));
EXECUTE IMMEDIATE 'GRANT CONNECT, RESOURCE TO ' || p_schema_name; dbms_scheduler.set_job_argument_value(lcJobName, 3, to_char(tnAn));
EXECUTE IMMEDIATE 'GRANT CREATE SESSION TO ' || p_schema_name; dbms_scheduler.enable(lcJobName);
EXECUTE IMMEDIATE 'GRANT CREATE TABLE TO ' || p_schema_name; end NEWSCHEMAJOB;
EXECUTE IMMEDIATE 'GRANT CREATE VIEW TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE SEQUENCE TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE PROCEDURE TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE TRIGGER TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE TYPE TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE SYNONYM TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE DATABASE LINK TO ' || p_schema_name;
EXECUTE IMMEDIATE 'GRANT CREATE JOB TO ' || p_schema_name;
DBMS_OUTPUT.PUT_LINE('Schema ' || p_schema_name || ' created successfully!');
p_result := 0;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error creating schema: ' || SQLERRM);
p_result := -1;
END NEWSCHEMA;
/ /
PROMPT [11/11] Creating SYS.NEWSCHEMAJOB and SYS.UPDATESQLPLUS procedures... CREATE OR REPLACE PROCEDURE SYS.UpdateSQLPLUS(tcSqlPlusPath in varchar2,
CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMAJOB( tcScriptPath in varchar2) as
p_schema_name IN VARCHAR2, lcJobName varchar2(500);
p_password IN VARCHAR2 begin
) IS lcJobName := 'updateschema_' || to_char(sysdate, 'YYYYMMDDHH24MISS');
v_job_name VARCHAR2(100); dbms_scheduler.create_job(lcJobName,
BEGIN job_action => tcSqlPlusPath,
v_job_name := 'NEWSCHEMA_' || p_schema_name; number_of_arguments => 2,
job_type => 'executable',
DBMS_SCHEDULER.CREATE_JOB( enabled => false);
job_name => v_job_name, dbms_scheduler.set_job_argument_value(lcJobName, 1, '/nolog');
job_type => 'STORED_PROCEDURE', dbms_scheduler.set_job_argument_value(lcJobName, 2, '@' || tcScriptPath);
job_action => 'SYS.NEWSCHEMA', dbms_scheduler.enable(lcJobName);
number_of_arguments => 3, end;
start_date => SYSTIMESTAMP,
enabled => FALSE,
auto_drop => TRUE
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => v_job_name,
argument_position => 1,
argument_value => p_schema_name
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => v_job_name,
argument_position => 2,
argument_value => p_password
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => v_job_name,
argument_position => 3,
argument_value => '0'
);
DBMS_SCHEDULER.ENABLE(v_job_name);
END NEWSCHEMAJOB;
/ /
CREATE OR REPLACE PROCEDURE SYS.UPDATESQLPLUS IS
v_result NUMBER; -- ============================================================================
BEGIN -- SECTION 7: UTL_MAIL
-- Path may need to be adjusted for your Windows installation -- ============================================================================
EXECUTESCRIPTOS('D:\ROMFAST\UPDATE\UPDATE_SQLPLUS.BAT', '', 'N', v_result); -- UTL_MAIL nu se instaleaza implicit in Oracle 21c. Fara el raman INVALID:
END UPDATESQLPLUS; -- CONTAFIN_ORACLE.SENDEMAIL, EMAILINCASARI, EMAILNOTIFICAREFACTURI,
/ -- EMAILSTOCCRITIC, PACK_UPDATE si PACK_UTILS (PLS-00201: UTL_MAIL.SEND).
-- Un GRANT nu ajuta - pachetul trebuie creat. Pe ROA_CENTRAL (productie)
-- UTL_MAIL este VALID; verificat 2026-08-25.
--
-- Grantul catre CONTAFIN_ORACLE se face in sql\sys-grants.sql, dupa import.
-- Pentru trimiterea efectiva de mailuri mai trebuie setat SMTP_OUT_SERVER.
-- ============================================================================
PROMPT
PROMPT [10/10] Installing UTL_MAIL...
@?/rdbms/admin/utlmail.sql
@?/rdbms/admin/prvtmail.plb
PROMPT UTL_MAIL installed.
-- ============================================================================ -- ============================================================================
-- VERIFICATION -- VERIFICATION

View File

@@ -94,7 +94,8 @@ DECLARE
) )
) )
ORDER BY username; ORDER BY username;
v_count NUMBER := 0; v_count NUMBER := 0;
v_failed NUMBER := 0;
BEGIN BEGIN
FOR r IN c_users LOOP FOR r IN c_users LOOP
BEGIN BEGIN
@@ -107,10 +108,30 @@ BEGIN
v_count := v_count + 1; v_count := v_count + 1;
EXCEPTION EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(' ERROR: ' || SQLERRM); -- O sesiune agatata tine userul ocupat (ORA-01940 "cannot drop a
-- user that is currently connected"). Prima incercare poate pica
-- inainte ca ALTER SYSTEM KILL SESSION sa fi terminat efectiv.
-- Mai incercam o data; ce ramane e raportat si prins de
-- verificarea finala, care iese cu cod de eroare.
DBMS_OUTPUT.PUT_LINE(' WARN (incercarea 1): ' || SQLERRM);
BEGIN
roa_kill_user_sessions(r.username);
DBMS_SESSION.SLEEP(3);
EXECUTE IMMEDIATE 'DROP USER ' || r.username || ' CASCADE';
DBMS_OUTPUT.PUT_LINE(' Dropped user (retry): ' || r.username);
v_count := v_count + 1;
EXCEPTION
WHEN OTHERS THEN
v_failed := v_failed + 1;
DBMS_OUTPUT.PUT_LINE(' ERROR: ' || r.username ||
' NU a fost sters: ' || SQLERRM);
END;
END; END;
END LOOP; END LOOP;
DBMS_OUTPUT.PUT_LINE('Total company users dropped: ' || v_count); DBMS_OUTPUT.PUT_LINE('Total company users dropped: ' || v_count);
IF v_failed > 0 THEN
DBMS_OUTPUT.PUT_LINE('ATENTIE: ' || v_failed || ' user(i) de firma NU au fost stersi.');
END IF;
END; END;
/ /
@@ -137,8 +158,18 @@ BEGIN
END; END;
-- Now drop the user -- Now drop the user
EXECUTE IMMEDIATE 'DROP USER CONTAFIN_ORACLE CASCADE'; BEGIN
DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE dropped successfully.'); EXECUTE IMMEDIATE 'DROP USER CONTAFIN_ORACLE CASCADE';
DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE dropped successfully.');
EXCEPTION
WHEN OTHERS THEN
-- Acelasi motiv ca la sectiunea 1: sesiune inca vie.
DBMS_OUTPUT.PUT_LINE(' WARN (incercarea 1): ' || SQLERRM);
roa_kill_user_sessions('CONTAFIN_ORACLE');
DBMS_SESSION.SLEEP(3);
EXECUTE IMMEDIATE 'DROP USER CONTAFIN_ORACLE CASCADE';
DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE dropped successfully (retry).');
END;
ELSE ELSE
DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE does not exist.'); DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE does not exist.');
END IF; END IF;
@@ -170,7 +201,7 @@ DECLARE
'PACK_UTILS_FILE', 'PACK_ROARTVAI', 'RTVAI_AGENTI', 'RTVAI_ISTORIC', 'PACK_UTILS_FILE', 'PACK_ROARTVAI', 'RTVAI_AGENTI', 'RTVAI_ISTORIC',
'FF_SUME', 'FF_PERSINTRET', 'VANZARI_DETALII_TAB', 'PIVOT_TABLE', 'FF_SUME', 'FF_PERSINTRET', 'VANZARI_DETALII_TAB', 'PIVOT_TABLE',
'PIVOT_ROW', 'TABINCHIDERETVA', 'TABELAVALORITAGURI', 'PIVOT_ROW', 'TABINCHIDERETVA', 'TABELAVALORITAGURI',
'RANDINCHIDERETVA', 'SERVER_INFO' 'RANDINCHIDERETVA', 'SERVER_INFO', 'EXECUTESCRIPTOS'
) )
OR synonym_name LIKE 'SYN_%'); OR synonym_name LIKE 'SYN_%');
v_count NUMBER := 0; v_count NUMBER := 0;
@@ -344,10 +375,100 @@ PROMPT
PROMPT Tablespace ROA: PROMPT Tablespace ROA:
SELECT tablespace_name, status FROM dba_tablespaces WHERE tablespace_name = 'ROA'; SELECT tablespace_name, status FROM dba_tablespaces WHERE tablespace_name = 'ROA';
PROMPT -- ============================================================================
PROMPT ============================================================ -- VERDICT: verificare autoritara, cu cod de iesire
PROMPT ROA UNINSTALL COMPLETE -- ============================================================================
PROMPT ============================================================ -- Toate sectiunile de mai sus prind exceptiile in WHEN OTHERS si doar scriu in
PROMPT -- DBMS_OUTPUT, ca sa nu opreasca dezinstalarea la primul obstacol. Consecinta:
PROMPT Database is now clean. You can re-run the setup scripts. -- scriptul se termina "cu succes" chiar daca un user a supravietuit, iar
PROMPT -- instalarea urmatoare pica in lant cu ORA-31684 ... already exists.
-- Blocul asta numara ce a ramas si iese cu cod de eroare daca nu e curat.
-- Pas 1: raportarea (nu poate pica scriptul, deci output-ul ajunge pe ecran).
DECLARE
v_users NUMBER := 0;
v_contafin NUMBER := 0;
v_sysobj NUMBER := 0;
v_syn NUMBER := 0;
v_tbs NUMBER := 0;
v_total NUMBER := 0;
v_msg VARCHAR2(4000) := '';
BEGIN
SELECT COUNT(*) INTO v_users
FROM dba_users
WHERE default_tablespace = 'ROA'
AND username <> 'CONTAFIN_ORACLE';
SELECT COUNT(*) INTO v_contafin
FROM dba_users WHERE username = 'CONTAFIN_ORACLE';
SELECT COUNT(*) INTO v_sysobj
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN (
'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS',
'PINFO', 'INFO', 'SEQ_AUTH_SERII');
SELECT COUNT(*) INTO v_syn
FROM dba_synonyms
WHERE owner = 'PUBLIC' AND table_owner = 'CONTAFIN_ORACLE';
SELECT COUNT(*) INTO v_tbs
FROM dba_tablespaces WHERE tablespace_name = 'ROA';
IF v_users > 0 THEN v_msg := v_msg || v_users || ' user(i) de firma; '; END IF;
IF v_contafin > 0 THEN v_msg := v_msg || 'CONTAFIN_ORACLE; '; END IF;
IF v_sysobj > 0 THEN v_msg := v_msg || v_sysobj || ' obiecte SYS; '; END IF;
IF v_syn > 0 THEN v_msg := v_msg || v_syn || ' sinonime publice; '; END IF;
IF v_tbs > 0 THEN v_msg := v_msg || 'tablespace ROA; '; END IF;
v_total := v_users + v_contafin + v_sysobj + v_syn + v_tbs;
IF v_total = 0 THEN
DBMS_OUTPUT.PUT_LINE('============================================================');
DBMS_OUTPUT.PUT_LINE(' ROA UNINSTALL COMPLETE');
DBMS_OUTPUT.PUT_LINE('============================================================');
DBMS_OUTPUT.PUT_LINE('Baza este curata. Poti relua scripturile de instalare.');
ELSE
DBMS_OUTPUT.PUT_LINE('============================================================');
DBMS_OUTPUT.PUT_LINE(' ROA UNINSTALL INCOMPLET');
DBMS_OUTPUT.PUT_LINE('============================================================');
DBMS_OUTPUT.PUT_LINE('Au ramas: ' || RTRIM(v_msg, '; '));
DBMS_OUTPUT.PUT_LINE('Cauza uzuala: o sesiune activa tinea userul ocupat.');
DBMS_OUTPUT.PUT_LINE('Inchide aplicatia ROA / sesiunile sqlplus si ruleaza din nou.');
DBMS_OUTPUT.PUT_LINE('NU porni instalarea acum - pasul 05 va da ORA-31684 in lant.');
END IF;
END;
/
-- Pas 2: verdictul propriu-zis. Recalculeaza acelasi total si iese cu cod de
-- eroare daca nu e zero. Diagnosticul detaliat e deja tiparit mai sus.
WHENEVER SQLERROR EXIT FAILURE
DECLARE
v_total NUMBER;
BEGIN
SELECT (SELECT COUNT(*) FROM dba_users
WHERE default_tablespace = 'ROA' AND username <> 'CONTAFIN_ORACLE')
+ (SELECT COUNT(*) FROM dba_users WHERE username = 'CONTAFIN_ORACLE')
+ (SELECT COUNT(*) FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN (
'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS',
'PINFO', 'INFO', 'SEQ_AUTH_SERII'))
+ (SELECT COUNT(*) FROM dba_synonyms
WHERE owner = 'PUBLIC' AND table_owner = 'CONTAFIN_ORACLE')
+ (SELECT COUNT(*) FROM dba_tablespaces WHERE tablespace_name = 'ROA')
INTO v_total
FROM dual;
IF v_total > 0 THEN
RAISE_APPLICATION_ERROR(-20900,
'ROA UNINSTALL INCOMPLET - au ramas ' || v_total ||
' obiect(e). Vezi raportul de mai sus.');
END IF;
END;
/
EXIT SUCCESS

View File

@@ -0,0 +1,459 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Construieste kitul de instalare ROA pentru un client: DMP-urile sablon
exportate din LXC 108 + scripturile de instalare/migrare, intr-un singur
director gata de copiat pe serverul clientului.
.DESCRIPTION
Ce face, in ordine:
1. Ruleaza exportul pe LXC 108 (`export-roa2.sh`, acelasi script folosit
de `export-roa2.ps1`). Sursa e PDB-ul ROA2, nu ROA - ROA e instanta
de productie ROA_CENTRAL si nu se scrie in ea.
2. Aduce arhivele .tar.gz pe statia locala. Sunt trei niveluri:
container Docker -> LXC 108 -> host pvemini -> statia ta. `docker cp`
te scoate doar din container, de aceea e nevoie si de `pct pull`.
3. Despacheteaza si redenumeste DMP-urile la numele pe care le asteapta
scripturile: `contafin_oracle.dmp` si `FIRMANOUA.dmp`.
4. Citeste logul expdp si raporteaza cate firme are NOM_FIRME in dump.
Asa vezi daca ai construit un sablon curat sau ai prins din greseala
datele unui client.
5. Copiaza peste ele continutul din `roa-windows-setup/`.
Rezultatul e un director care se dezarhiveaza la client si se ruleaza cu
`INSTALEAZA.cmd curat` sau `INSTALEAZA.cmd migrare`.
.PARAMETER OracleVersion
Sursa exportului: '21' (PDB ROA2, VERSION=19) sau '18' (container
oracle18-xe, VERSION=11.2, pentru baze mai vechi). Implicit '21'.
.PARAMETER OutputDir
Directorul parinte in care se creeaza kitul. Implicit E:\backups\roa-kit.
.PARAMETER KitName
Numele directorului de kit. Implicit roa-kit-<data>.
.PARAMETER SkipExport
Nu ruleaza export nou; foloseste cele mai recente arhive deja prezente pe
LXC 108. Util cand ai exportat deja si vrei doar sa reconstruiesti kitul.
.PARAMETER Zip
Creeaza si o arhiva .zip a kitului, langa director.
.PARAMETER PushTo
Optional, destinatie scp pentru kit dupa constructie, in forma
`utilizator@gazda:/cale`. Se trimite directorul intreg, recursiv.
.EXAMPLE
.\build-client-kit.ps1
Export nou din ROA2 si kit in E:\backups\roa-kit\roa-kit-<data>.
.EXAMPLE
.\build-client-kit.ps1 -Zip -KitName "roa-kit-clientX"
Kit cu nume fix, plus arhiva .zip de trimis clientului.
.EXAMPLE
.\build-client-kit.ps1 -SkipExport -PushTo "romfast@10.0.20.130:C:/roa-kit"
Refoloseste ultimele arhive si trimite kitul direct pe serverul tinta.
.NOTES
Necesita ssh/scp (OpenSSH din Windows 10+) si tar (bsdtar, tot din Windows).
Acces cu cheie la host-ul Proxmox - vezi docs/acces-ssh-chei-angajati.md.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[ValidateSet('21', '18')]
[string]$OracleVersion = '21',
[Parameter(Mandatory = $false)]
[string]$OutputDir = 'E:\backups\roa-kit',
[Parameter(Mandatory = $false)]
[string]$KitName,
[Parameter(Mandatory = $false)]
[switch]$SkipExport,
[Parameter(Mandatory = $false)]
[switch]$Zip,
[Parameter(Mandatory = $false)]
[string]$PushTo,
[Parameter(Mandatory = $false)]
[string]$ProxmoxHost = 'root@10.0.20.201',
[Parameter(Mandatory = $false)]
[int]$Ctid = 108
)
$ErrorActionPreference = 'Stop'
# Schemele exportate si numele sub care ajung in kit. FIRMANOUA.dmp trebuie sa
# aiba exact numele asta: SYS.NEWSCHEMA il compune ca <schema-sursa> || '.dmp'.
$SchemaMap = [ordered]@{
'CONTAFIN_ORACLE' = 'contafin_oracle.dmp'
'FIRMANOUA' = 'FIRMANOUA.dmp'
}
if ($OracleVersion -eq '18') {
$Container = 'oracle18-xe'
$RemoteDmpDir = '/opt/oracle18/oradata/dmpdir'
$SourceLabel = 'Oracle 18c (XEPDB1), VERSION=11.2'
}
else {
$Container = 'oracle-xe'
$RemoteDmpDir = '/opt/oracle/oradata/dmpdir'
$SourceLabel = 'Oracle 21c (PDB ROA2), VERSION=19'
}
function Write-Step { param([string]$m) Write-Host "`n=== $m ===" -ForegroundColor Cyan }
function Write-Ok { param([string]$m) Write-Host " [OK] $m" -ForegroundColor Green }
function Write-Info { param([string]$m) Write-Host " $m" }
function Write-Warn { param([string]$m) Write-Host " [ATENTIE] $m" -ForegroundColor Yellow }
function Invoke-Remote {
<# Ruleaza o comanda pe host-ul Proxmox si intoarce iesirea.
Opreste scriptul daca ssh iese cu cod nenul. #>
param(
[Parameter(Mandatory = $true)][string]$Command,
[switch]$AllowFailure
)
# Fara "2>&1": in Windows PowerShell 5.1 redirectarea stderr-ului unei
# comenzi native impacheteaza fiecare linie intr-un ErrorRecord, iar
# mesajul de eroare devine "System.Management.Automation.RemoteException".
# Lasam stderr sa curga direct in consola si ne bazam pe codul de iesire.
$out = & ssh -o BatchMode=yes $ProxmoxHost $Command
if ($LASTEXITCODE -ne 0 -and -not $AllowFailure) {
throw "Comanda pe $ProxmoxHost a esuat (cod $LASTEXITCODE): $Command"
}
return $out
}
# =============================================================================
# 0. Validari locale
# =============================================================================
Write-Step "Verificari initiale"
$SetupDir = Join-Path (Split-Path $PSScriptRoot -Parent) 'roa-windows-setup'
if (-not (Test-Path $SetupDir -PathType Container)) {
throw "Nu gasesc directorul cu scripturile de instalare: $SetupDir"
}
$InstallCmd = Join-Path $SetupDir 'INSTALEAZA.cmd'
if (-not (Test-Path $InstallCmd)) {
throw "Nu gasesc $InstallCmd - kitul ar fi inutilizabil fara el."
}
Write-Ok "Scripturi de instalare: $SetupDir"
foreach ($tool in @('ssh', 'scp', 'tar')) {
if (-not (Get-Command $tool -ErrorAction SilentlyContinue)) {
throw "Lipseste '$tool' din PATH. Pe Windows 10+ vine cu OpenSSH / bsdtar."
}
}
Write-Ok "ssh, scp, tar disponibile"
if (-not $KitName) {
$KitName = "roa-kit-$(Get-Date -Format 'yyyyMMdd_HHmmss')"
}
$KitDir = Join-Path $OutputDir $KitName
if (Test-Path $KitDir) {
throw "Directorul $KitDir exista deja. Sterge-l sau foloseste alt -KitName."
}
$Staging = Join-Path ([System.IO.Path]::GetTempPath()) "roa-kit-staging-$([System.Guid]::NewGuid().ToString('N').Substring(0,8))"
New-Item -ItemType Directory -Path $Staging -Force | Out-Null
try {
# =========================================================================
# 1. Starea LXC 108 si a containerului Oracle
# =========================================================================
Write-Step "Starea LXC $Ctid si a containerului $Container"
$lxcStatus = Invoke-Remote "pct status $Ctid"
if ($lxcStatus -notmatch 'running') {
throw "LXC $Ctid nu ruleaza ($lxcStatus). Porneste-l cu: ssh $ProxmoxHost `"pct start $Ctid`""
}
Write-Ok "LXC $Ctid ruleaza"
$running = Invoke-Remote "pct exec $Ctid -- docker ps --format '{{.Names}}'"
if ($running -notcontains $Container) {
throw "Containerul $Container nu ruleaza in LXC $Ctid. Porneste-l cu: ssh $ProxmoxHost `"pct exec $Ctid -- docker start $Container`" si asteapta ~60s."
}
Write-Ok "Containerul $Container ruleaza"
Write-Info "Sursa exportului: $SourceLabel"
# =========================================================================
# 2. Exportul
# =========================================================================
if ($SkipExport) {
Write-Step "Export sarit (-SkipExport) - folosesc arhivele existente"
}
else {
Write-Step "Export din $SourceLabel"
Write-Info "Dureaza cateva minute. Ruleaza export-roa2.sh pe LXC $Ctid..."
$exportOut = Invoke-Remote "pct exec $Ctid -- bash /opt/oracle/oradata/export-roa2.sh $OracleVersion"
$exportOut | Where-Object { $_ -match 'EROARE|ORA-|successfully completed|elapsed' } |
ForEach-Object { Write-Info $_ }
Write-Ok "Export terminat"
}
# =========================================================================
# 3. Aducerea arhivelor: container -> LXC -> host -> statie
# =========================================================================
Write-Step "Aduc arhivele pe statia locala"
$archives = @{}
foreach ($schema in $SchemaMap.Keys) {
$newest = (Invoke-Remote "pct exec $Ctid -- bash -c 'ls -t $RemoteDmpDir/${schema}*.tar.gz 2>/dev/null | head -1'" | Select-Object -First 1)
if ([string]::IsNullOrWhiteSpace($newest)) {
throw "Nu am gasit nicio arhiva ${schema}*.tar.gz in $RemoteDmpDir. Ruleaza fara -SkipExport."
}
$newest = $newest.Trim()
$leaf = Split-Path $newest -Leaf
# pct pull scoate fisierul din LXC pe host-ul Proxmox; scp il aduce mai
# departe. Fara pct pull, scp ar citi de pe host, unde nu exista nimic.
Invoke-Remote "pct pull $Ctid $newest /tmp/$leaf" | Out-Null
& scp -o BatchMode=yes "${ProxmoxHost}:/tmp/$leaf" (Join-Path $Staging $leaf) | Out-Null
if ($LASTEXITCODE -ne 0) { throw "scp a esuat pentru $leaf" }
Invoke-Remote "rm -f /tmp/$leaf" -AllowFailure | Out-Null
$localArchive = Join-Path $Staging $leaf
$sizeMb = [math]::Round((Get-Item $localArchive).Length / 1MB, 1)
Write-Ok "$leaf ($sizeMb MB)"
$archives[$schema] = $localArchive
}
# =========================================================================
# 4. Despachetare, redenumire, verificarea continutului
# =========================================================================
Write-Step "Despachetez si verific"
$KitDmpDir = Join-Path $KitDir 'DMPDIR'
New-Item -ItemType Directory -Path $KitDmpDir -Force | Out-Null
$nomFirmeRows = $null
foreach ($schema in $SchemaMap.Keys) {
$extractDir = Join-Path $Staging "x_$schema"
New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
& tar -xzf $archives[$schema] -C $extractDir | Out-Null
if ($LASTEXITCODE -ne 0) { throw "tar a esuat la despachetarea $($archives[$schema])" }
$dmp = Get-ChildItem -Path $extractDir -Filter '*.dmp' -File | Select-Object -First 1
if (-not $dmp) { throw "Arhiva pentru $schema nu contine niciun fisier .dmp" }
$target = Join-Path $KitDmpDir $SchemaMap[$schema]
Copy-Item -Path $dmp.FullName -Destination $target -Force
$sizeMb = [math]::Round((Get-Item $target).Length / 1MB, 1)
Write-Ok "$($SchemaMap[$schema]) ($sizeMb MB)"
# Logul expdp spune exact cate randuri are fiecare tabela. Pentru
# CONTAFIN_ORACLE, NOM_FIRME e indicatorul care separa un sablon curat
# de datele unui client.
$log = Get-ChildItem -Path $extractDir -Filter '*.log' -File | Select-Object -First 1
if ($log -and $schema -eq 'CONTAFIN_ORACLE') {
$m = Select-String -Path $log.FullName -Pattern '"NOM_FIRME"\s+\S+\s+\S+\s+(\d+)\s+rows' |
Select-Object -First 1
if ($m) { $nomFirmeRows = [int]$m.Matches[0].Groups[1].Value }
}
}
if ($null -eq $nomFirmeRows) {
Write-Warn "Nu am putut citi numarul de firme din logul expdp. Verifica manual continutul lui NOM_FIRME."
}
elseif ($nomFirmeRows -le 5) {
Write-Ok "NOM_FIRME: $nomFirmeRows randuri - sablon curat, potrivit pentru instalare pe curat"
}
else {
Write-Warn "NOM_FIRME are $nomFirmeRows randuri - NU e un sablon curat!"
Write-Warn "Dump-ul contine firmele unei baze reale. Nu-l trimite altui client."
}
# =========================================================================
# 5. Scripturile de instalare
# =========================================================================
Write-Step "Copiez scripturile de instalare"
# Kitul are structura lui roa-windows-setup direct in radacina, plus DMPDIR:
# Run.cmd si INSTALEAZA.cmd se bazeaza pe %~dp0scripts, deci trebuie sa fie
# la acelasi nivel cu scripts\.
$excludeNames = @('logs', 'test')
# Gunoiul din working tree nu are ce cauta la client. *.dmp e exclus ca
# masura de siguranta: daca cineva a lasat dump-ul unui client in
# roa-windows-setup, nu vrem sa plece mai departe.
$excludePatterns = @('*.stackdump', '*.zip', '*.dmp', '*.log', 'config.ps1')
Get-ChildItem -Path $SetupDir -Force | Where-Object {
$item = $_
($excludeNames -notcontains $item.Name) -and
(-not ($excludePatterns | Where-Object { $item.Name -like $_ }))
} | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $KitDir -Recurse -Force
}
# Acelasi filtru, aplicat si in subdirectoare (config.ps1 poate contine
# parolele altui client, logurile pot contine nume de firme).
# DMPDIR e scutit: acolo tocmai am pus sabloanele, iar '*.dmp' e in lista de
# excluderi. Fara filtrul asta, pasul de curatare isi sterge propriul rezultat.
foreach ($pat in $excludePatterns) {
Get-ChildItem -Path $KitDir -Filter $pat -Recurse -File -Force -ErrorAction SilentlyContinue |
Where-Object { $_.DirectoryName -ne $KitDmpDir } |
Remove-Item -Force -ErrorAction SilentlyContinue
}
New-Item -ItemType Directory -Path (Join-Path $KitDir 'logs') -Force | Out-Null
# Plasa de siguranta: in kit au voie exact cele doua sabloane, nimic altceva.
$strayDmp = Get-ChildItem -Path $KitDir -Filter '*.dmp' -Recurse -File |
Where-Object { $_.DirectoryName -ne $KitDmpDir }
if ($strayDmp) {
throw "Fisiere .dmp neasteptate in kit, in afara DMPDIR: $($strayDmp.FullName -join ', ')"
}
# ...si invers: sabloanele TREBUIE sa fie acolo. Verificarea asta prinde
# orice pas ulterior care le-ar sterge din greseala.
foreach ($expected in $SchemaMap.Values) {
$p = Join-Path $KitDmpDir $expected
if (-not (Test-Path $p)) {
throw "Lipseste $expected din kit - constructia e incompleta."
}
if ((Get-Item $p).Length -lt 1MB) {
throw "$expected are sub 1 MB - fisier trunchiat sau gresit."
}
}
$copied = (Get-ChildItem -Path $KitDir -Recurse -File).Count
Write-Ok "$copied fisiere in kit"
# =========================================================================
# 6. Instructiunile
# =========================================================================
$sursa = if ($SkipExport) { "$SourceLabel (arhive existente, neexportate acum)" } else { $SourceLabel }
$firme = if ($null -ne $nomFirmeRows) { "$nomFirmeRows" } else { "necunoscut" }
$citeste = @"
KIT DE INSTALARE ROA ORACLE
===========================
Construit: $(Get-Date -Format 'yyyy-MM-dd HH:mm')
Sursa DMP-urilor: $sursa
Firme in NOM_FIRME din contafin_oracle.dmp: $firme
CE E IN KIT
-----------
DMPDIR\contafin_oracle.dmp schema comuna (drepturi, actualizari, NOM_FIRME)
DMPDIR\FIRMANOUA.dmp sablon de firma goala
scripts\, sql\, config\ scripturile de instalare
INSTALEAZA.cmd ruleaza toti pasii, in ordine
README.md documentatia completa
CUM SE INSTALEAZA
-----------------
Inainte de orice: instaleaza Oracle 21c XE pe server (docs\00-INSTALL-ORACLE-XE.md),
cu parola SYS/SYSTEM 'romfastsoft'. Apoi, din radacina kitului:
A. CLIENT NOU, fara firme anterioare:
INSTALEAZA.cmd curat <IdClient> [ServerSMTP]
Prima firma se creeaza DUPA aceea, DIN APLICATIA ROA - nu din scripturi.
Aplicatia scrie firma in CONTAFIN_ORACLE.NOM_FIRME si apeleaza
SYS.NEWSCHEMA, care ii importa structura din FIRMANOUA.dmp.
B. MIGRARE de pe un Oracle mai vechi:
1. Inlocuieste DMPDIR\contafin_oracle.dmp cu cel exportat de la client
(cel din kit are NOM_FIRME goala).
2. Pune in DMPDIR si cate un .dmp per firma a clientului.
3. LASA FIRMANOUA.dmp pe loc - nu vine de la client, dar e obligatoriu.
4. INSTALEAZA.cmd migrare <IdClient> [ServerSMTP]
Instalarea e gata cand ultimul pas (07-verify-installation) iese cu codul 0.
DE STIUT
--------
- FIRMANOUA.dmp ramane in C:\DMPDIR si dupa instalare. E folosit la fiecare
firma noua, oricand pe viitor. Daca il stergi, adaugarea de firme va esua
cu o eroare in DBMS_DATAPUMP.ADD_FILE.
- Pasul 03 (import contafin) iese cu codul 5 si asta e NORMAL: e codul Data
Pump pentru "completed with errors", din ORA-31684 (userul exista deja,
creat de pasul 01) si ORA-39082 (warning-uri de compilare, rezolvate la
pasul 04). INSTALEAZA.cmd il trateaza corect.
- Conectarea se face la serviciul XEPDB1, niciodata la XE (CDB root).
- Daca reiei instalarea de la zero: scripts\99-uninstall-roa.ps1 trebuie sa
iasa cu codul 0. Orice alt cod inseamna ca au ramas obiecte in baza (uzual
o sesiune activa tinea userul ocupat) - nu porni instalarea peste ele.
- Logurile fiecarui pas sunt in logs\.
"@
Set-Content -Path (Join-Path $KitDir 'CITESTE-MA.txt') -Value $citeste -Encoding UTF8
# =========================================================================
# 7. Arhivare si livrare
# =========================================================================
$zipPath = $null
if ($Zip) {
Write-Step "Creez arhiva .zip"
$zipPath = Join-Path $OutputDir "$KitName.zip"
if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
Compress-Archive -Path (Join-Path $KitDir '*') -DestinationPath $zipPath -CompressionLevel Optimal
$zipMb = [math]::Round((Get-Item $zipPath).Length / 1MB, 1)
Write-Ok "$zipPath ($zipMb MB)"
}
if ($PushTo) {
Write-Step "Trimit kitul catre $PushTo"
& scp -o BatchMode=yes -r $KitDir $PushTo | Out-Null
if ($LASTEXITCODE -ne 0) { throw "scp catre $PushTo a esuat (cod $LASTEXITCODE)" }
Write-Ok "Kit trimis"
}
# =========================================================================
# 8. Sumar
# =========================================================================
$totalMb = [math]::Round(((Get-ChildItem -Path $KitDir -Recurse -File | Measure-Object Length -Sum).Sum) / 1MB, 1)
Write-Host ""
Write-Host "============================================================" -ForegroundColor Green
Write-Host " KIT GATA" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Green
Write-Host ""
Write-Host " Director: $KitDir"
if ($zipPath) { Write-Host " Arhiva: $zipPath" }
Write-Host " Marime: $totalMb MB"
Write-Host " NOM_FIRME: $firme randuri in contafin_oracle.dmp"
Write-Host ""
Write-Host " La client, din radacina kitului:"
Write-Host " INSTALEAZA.cmd curat <IdClient> (client nou)" -ForegroundColor Cyan
Write-Host " INSTALEAZA.cmd migrare <IdClient> (are date existente)" -ForegroundColor Cyan
Write-Host ""
Write-Host " Detalii complete: $KitDir\CITESTE-MA.txt"
Write-Host ""
}
catch {
Write-Host ""
Write-Host "[EROARE] $_" -ForegroundColor Red
if (Test-Path $KitDir) {
Write-Host "[INFO] Kit incomplet la $KitDir - sterge-l inainte de a relua." -ForegroundColor Yellow
}
exit 1
}
finally {
if (Test-Path $Staging) {
Remove-Item -Path $Staging -Recurse -Force -ErrorAction SilentlyContinue
}
}

View File

@@ -163,6 +163,62 @@ C:\roa-setup\
--- ---
### Capcane de mediu (verificate 2026-08-25)
**1. VM-ul își poate pierde IP-ul static la boot.** La pornirea din 2026-08-25 adaptorul
s-a re-enumerat ca `Ethernet 2` și a venit pe DHCP (`10.0.20.118`). `listener.ora` are
`HOST=10.0.20.130` scris în clar, deci serviciul listener pornește („Running") dar nu
leagă portul, iar orice conectare dă `ORA-12541: TNS:no listener`. Verifică IP-ul
**înainte** de a începe testul:
```bash
ssh root@10.0.20.201 "qm agent 302 network-get-interfaces" | grep ip-address
```
Dacă nu e `10.0.20.130`, restaurează-l (comanda rupe sesiunea SSH curentă, de aceea
rulează printr-un task programat):
```powershell
Set-NetIPInterface -InterfaceAlias 'Ethernet 2' -Dhcp Disabled
Get-NetIPAddress -InterfaceAlias 'Ethernet 2' -AddressFamily IPv4 | Remove-NetIPAddress -Confirm:$false
New-NetIPAddress -InterfaceAlias 'Ethernet 2' -IPAddress 10.0.20.130 -PrefixLength 24 -DefaultGateway 10.0.20.1
Set-DnsClientServerAddress -InterfaceAlias 'Ethernet 2' -ServerAddresses 10.0.20.1
```
Apoi `Restart-Service OracleOraDB21Home1TNSListener`. Listener-ul mai are nevoie de
~60 s ca instanța să se înregistreze (PMON), altfel primești `ORA-12514`.
**2. `C:\roa-setup\` este o copie, nu un clone al repo-ului.** La 2026-08-25 era în urmă
cu două commit-uri (`sys-objects.sql`, `scheduler-jobs.sql`, `uninstall-roa.sql` erau
dinainte de `015cd79`). Sincronizează **tot** directorul, nu doar fișierele pe care
crezi că le-ai atins, și confirmă cu hash-uri:
```bash
cd proxmox/lxc108-oracle/roa-windows-setup
scp sql/*.sql romfast@10.0.20.130:C:/roa-setup/sql/
scp scripts/*.ps1 romfast@10.0.20.130:C:/roa-setup/scripts/
scp scripts/lib/*.ps1 romfast@10.0.20.130:C:/roa-setup/scripts/lib/
scp Run.cmd RunAll.cmd romfast@10.0.20.130:C:/roa-setup/
```
**3. `RunAll.cmd` nu poate fi condus neinteractiv.** Folosește `set /p` pentru
confirmări; pe stdin redirecționat (`< NUL` sau prin `ssh`) fie se anulează cu
„Installation cancelled" **și iese cu codul 0**, fie crapă cu „The syntax of the command
is incorrect". Nu te lua după codul de ieșire — verifică logul. Pentru rulare automată,
apelează scripturile în ordine direct:
```
01-setup-database.ps1 → 02-create-sys-objects.ps1 → 03-import-contafin.ps1
→ 04-create-synonyms-grants.ps1 → 05-import-companies.ps1
→ 08-post-install-config.ps1 → 07-verify-installation.ps1
```
**4. `03-import-contafin.ps1` iese normal cu codul 5.** E codul Data Pump pentru
„completat cu erori"; erorile sunt `ORA-31684 already exists` (userul e creat de scriptul
01) și `ORA-39082` (warning-uri de compilare). Nu e un eșec.
---
## Testing Workflow ## Testing Workflow
### Full Installation Test ### Full Installation Test