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:
@@ -47,9 +47,11 @@ input/ # Oracle DMP files for import
|
||||
- **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`
|
||||
- **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`
|
||||
- **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 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`
|
||||
- **ROMPETROL ENERGY — recreare PDB Oracle XE 21c după ORA-12954**: `proxmox/lxc108-oracle/clienti/oracle-xe-21c/README.md`
|
||||
|
||||
|
||||
199
docs/acces-client-tailscale-ssh.md
Normal file
199
docs/acces-client-tailscale-ssh.md
Normal 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.
|
||||
@@ -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)
|
||||
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
|
||||
|
||||
| Document | Ce e |
|
||||
|
||||
@@ -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).
|
||||
@@ -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`.
|
||||
205
proxmox/lxc108-oracle/roa-windows-setup/INSTALEAZA.cmd
Normal file
205
proxmox/lxc108-oracle/roa-windows-setup/INSTALEAZA.cmd
Normal 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
|
||||
@@ -21,9 +21,12 @@ Scripts and documentation for setting up ROA Oracle Database on Windows servers:
|
||||
|
||||
| Scenario | Description |
|
||||
|----------|-------------|
|
||||
| **New Server** | Oracle 21c SE (non-CDB) or XE (CDB/PDB) + CONTAFIN_ORACLE.dmp |
|
||||
| **Migration** | Import existing DMP files (CONTAFIN_ORACLE + 30-50 companies), inclusiv de pe Oracle XE 11 / 10g |
|
||||
| **Add Company** | Add new company schema to existing server |
|
||||
| **A. Instalare pe curat** | Client nou, fără firme anterioare. Pornești din șabloanele `contafin_oracle.dmp` + `FIRMANOUA.dmp` |
|
||||
| **B. Migrare** | Client cu Oracle XE 11 / 10g. Aduci `contafin_oracle.dmp` al clientului + câte un `.dmp` per firmă |
|
||||
| **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
|
||||
|
||||
> 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
|
||||
1. Download și instalează Oracle 21c XE (see `docs/00-INSTALL-ORACLE-XE.md`)
|
||||
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
|
||||
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ță
|
||||
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
|
||||
|
||||
### 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 |
|
||||
|------|-------------|------|
|
||||
| `contafin_oracle.dmp` | Common schema (rights, updates, etc.) | ~50MB |
|
||||
| `[company].dmp` | Company schema (one per company) | ~100-500MB each |
|
||||
| `contafin_oracle.dmp` | Schema comună (drepturi, actualizări, `NOM_FIRME`) | ~50-280 MB |
|
||||
| `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
|
||||
|
||||
@@ -251,37 +311,170 @@ scp root@10.0.20.201:/opt/oracle18/oradata/dmpdir/contafin_oracle.dmp C:\DMPDIR\
|
||||
|
||||
## 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
|
||||
# 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
|
||||
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
|
||||
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
|
||||
.\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. Instalarea propriu-zisa
|
||||
Run.cmd 01-setup-database.ps1
|
||||
Run.cmd 02-create-sys-objects.ps1
|
||||
Run.cmd 03-import-contafin.ps1 # cod de iesire 5 = NORMAL, vezi mai jos
|
||||
Run.cmd 04-create-synonyms-grants.ps1
|
||||
Run.cmd 05-import-companies.ps1 # no-op: NOM_FIRME e goala
|
||||
Run.cmd 08-post-install-config.ps1 -CustomerId "<id-client>" -EmailSmtp "mail.romfast.ro"
|
||||
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)
|
||||
|
||||
This script completes the ROA setup by configuring:
|
||||
|
||||
1. **ROAUPDATE Directories**: Creates 54 physical folders and Oracle DIRECTORY objects
|
||||
2. **SERVER_INFO**: Encoded passwords, paths, email settings for PACK_UPDATE
|
||||
3. **Customer ID**: Sets AUTH_DETALII for license verification
|
||||
4. **Scheduler Jobs**: UPDATEROA_ZILNIC and UPDATERTVAI_ZILNIC (disabled by default)
|
||||
3. **SMTP**: setează `SMTP_OUT_SERVER` și ACL-ul de rețea pentru `CONTAFIN_ORACLE`
|
||||
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
|
||||
# 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
|
||||
.\08-post-install-config.ps1 -RoaUpdatePath "E:\ROAUPDATE" -CustomerId "138"
|
||||
|
||||
# With email configuration
|
||||
.\08-post-install-config.ps1 -EmailTo "admin@company.ro" -EmailSmtp "mail.company.ro"
|
||||
# With email configuration (seteaza si SMTP_OUT_SERVER + ACL)
|
||||
.\08-post-install-config.ps1 -EmailTo "admin@company.ro" -EmailSmtp "mail.company.ro" -EmailPort 25
|
||||
|
||||
# Skip specific parts
|
||||
.\08-post-install-config.ps1 -SkipSchedulerJobs -SkipServerInfo
|
||||
.\08-post-install-config.ps1 -SkipSchedulerJobs -SkipServerInfo -SkipSmtpConfig
|
||||
```
|
||||
|
||||
**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.
|
||||
|
||||
**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
|
||||
@@ -468,6 +677,35 @@ ALTER PLUGGABLE DATABASE XEPDB1 OPEN;
|
||||
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
|
||||
|
||||
**ORA-00959: tablespace 'ROA' does not exist:**
|
||||
|
||||
@@ -34,6 +34,14 @@
|
||||
.PARAMETER SkipSqlnetConfig
|
||||
Skip sqlnet.ora configuration.
|
||||
|
||||
.PARAMETER ResetSystemPassword
|
||||
Reseteaza parola lui SYSTEM in CDB root, cu aceeasi valoare ($SystemPassword).
|
||||
Necesar DOAR pe o baza mai veche, unde SYSTEM a apucat sa intre in
|
||||
EXPIRED(GRACE) inainte ca profilul din CDB root sa fie corectat (Step 4b):
|
||||
statusul nu se curata singur cand profilul devine UNLIMITED, cere un
|
||||
ALTER USER. Pe o instalare noua nu e nevoie - contul nu apuca sa expire.
|
||||
Implicit OFF, pentru ca schimba o parola.
|
||||
|
||||
.EXAMPLE
|
||||
.\01-setup-database.ps1
|
||||
|
||||
@@ -76,7 +84,10 @@ param(
|
||||
[int]$TablespaceSize = 1000,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$SkipSqlnetConfig
|
||||
[switch]$SkipSqlnetConfig,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$ResetSystemPassword
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
@@ -199,6 +210,72 @@ EXIT;
|
||||
Write-LogDebug $result
|
||||
}
|
||||
|
||||
# Step 4b: 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). Verificat pe VM 302: SYSTEM era EXPIRED(GRACE).
|
||||
# Se comuta pe CDB$ROOT ca SYSDBA si se altereaza profilul local de acolo.
|
||||
if ($containerInfo.IsPDB) {
|
||||
Write-Log "Applying DEFAULT_PROFILE in CDB root as well..."
|
||||
|
||||
$profileCdbSql = @"
|
||||
SET ECHO OFF FEEDBACK ON VERIFY OFF
|
||||
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;
|
||||
SELECT 'PROFILE_CDB_CONFIGURED' FROM dual;
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$resultCdb = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName -DbHost $DbHost -Port $Port `
|
||||
-Username "SYS" -Password $SystemPassword -SqlCommand $profileCdbSql -AsSysdba
|
||||
|
||||
if ($resultCdb -match "PROFILE_CDB_CONFIGURED" -and $resultCdb -notmatch "ORA-") {
|
||||
Write-LogSuccess "DEFAULT_PROFILE configured in CDB root"
|
||||
}
|
||||
else {
|
||||
Write-LogWarning "Could not configure DEFAULT_PROFILE in CDB root"
|
||||
Write-LogWarning "SYSTEM din CDB root va expira la ~180 de zile. Manual:"
|
||||
Write-LogWarning " ALTER SESSION SET CONTAINER=CDB`$ROOT;"
|
||||
Write-LogWarning " ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED CONTAINER=ALL;"
|
||||
Write-LogDebug $resultCdb
|
||||
}
|
||||
|
||||
# Step 4c (optional): curata EXPIRED(GRACE) pe SYSTEM din CDB root.
|
||||
# ALTER PROFILE opreste expirarile viitoare, dar NU reseteaza statusul
|
||||
# unui cont deja intrat in perioada de gratie - asta cere un ALTER USER.
|
||||
# Opt-in, fiindca scrie o parola.
|
||||
if ($ResetSystemPassword) {
|
||||
Write-Log "Resetting SYSTEM password in CDB root (clears EXPIRED(GRACE))..."
|
||||
|
||||
$resetSql = @"
|
||||
SET ECHO OFF FEEDBACK ON VERIFY OFF
|
||||
ALTER SESSION SET CONTAINER = CDB`$ROOT;
|
||||
ALTER USER SYSTEM IDENTIFIED BY "$SystemPassword";
|
||||
SELECT 'SYSTEM_STATUS:' || account_status AS rez FROM dba_users WHERE username = 'SYSTEM';
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$resetResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName -DbHost $DbHost -Port $Port `
|
||||
-Username "SYS" -Password $SystemPassword -SqlCommand $resetSql -AsSysdba
|
||||
|
||||
if ($resetResult -match "SYSTEM_STATUS:OPEN" -and $resetResult -notmatch "ORA-") {
|
||||
Write-LogSuccess "SYSTEM in CDB root: OPEN"
|
||||
}
|
||||
else {
|
||||
Write-LogWarning "Nu am putut confirma resetarea lui SYSTEM in CDB root. Manual:"
|
||||
Write-LogWarning " ALTER SESSION SET CONTAINER=CDB`$ROOT;"
|
||||
Write-LogWarning " ALTER USER SYSTEM IDENTIFIED BY <parola>;"
|
||||
Write-LogDebug $resetResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Step 5: Configure sqlnet.ora for old client compatibility
|
||||
if (-not $SkipSqlnetConfig) {
|
||||
Write-LogSection "Configuring sqlnet.ora"
|
||||
@@ -255,10 +332,20 @@ SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
|
||||
SQLNET.ENCRYPTION_SERVER = ACCEPTED
|
||||
SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED
|
||||
|
||||
# Connection timeout settings
|
||||
# Timp maxim pentru finalizarea handshake-ului de conectare (setare de server).
|
||||
# Nu limiteaza durata operatiilor de dupa conectare.
|
||||
SQLNET.INBOUND_CONNECT_TIMEOUT = 60
|
||||
SQLNET.RECV_TIMEOUT = 30
|
||||
SQLNET.SEND_TIMEOUT = 30
|
||||
|
||||
# ATENTIE: NU pune aici SQLNET.RECV_TIMEOUT / SQLNET.SEND_TIMEOUT.
|
||||
# Fisierul asta e citit si de clientii de pe aceeasi masina (sqlplus, impdp,
|
||||
# expdp). RECV_TIMEOUT limiteaza cat asteapta CLIENTUL un pachet de raspuns,
|
||||
# iar in timpul unui import Data Pump serverul poate lucra minute intregi fara
|
||||
# sa trimita nimic (creare de indecsi, constrangeri). Cu RECV_TIMEOUT = 30,
|
||||
# clientul impdp moare cu ORA-12609 "TNS: Receive timeout occurred", desi jobul
|
||||
# de pe server continua si se termina cu bine. Rezultatul e si mai perfid decat
|
||||
# un esec curat: 03-import-contafin.ps1 numara obiectele imediat dupa moartea
|
||||
# clientului, gaseste 0 si raporteaza esec pentru un import care a reusit.
|
||||
# Verificat pe VM 302 (2026-08-25).
|
||||
|
||||
# TNS Names directory
|
||||
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
|
||||
|
||||
@@ -322,7 +322,7 @@ EXIT;
|
||||
|
||||
$synData = @{}
|
||||
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]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Add-ReportSection "Network ACL Status"
|
||||
|
||||
@@ -531,6 +595,10 @@ EXIT;
|
||||
$issues += "$($missingCompanies.Count) company schemas are missing"
|
||||
}
|
||||
|
||||
if ($extraIssues.Count -gt 0) {
|
||||
$issues += $extraIssues
|
||||
}
|
||||
|
||||
if ($issues.Count -eq 0) {
|
||||
Add-ReportLine "[OK] All checks passed!"
|
||||
Add-ReportLine ""
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
.PARAMETER EmailSmtp
|
||||
SMTP server hostname for update notifications.
|
||||
|
||||
.PARAMETER EmailPort
|
||||
SMTP port. Default: 25. Foloseste si la SMTP_OUT_SERVER si la ACL-ul de retea.
|
||||
|
||||
.PARAMETER SkipSmtpConfig
|
||||
Sare peste configurarea SMTP_OUT_SERVER + ACL pentru UTL_MAIL.
|
||||
|
||||
.PARAMETER EmailUsername
|
||||
SMTP authentication username (optional).
|
||||
|
||||
@@ -105,6 +111,9 @@ param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$EmailSmtp = "mail.romfast.ro",
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[int]$EmailPort = 25,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$EmailUsername,
|
||||
|
||||
@@ -118,7 +127,10 @@ param(
|
||||
[switch]$SkipServerInfo,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$SkipSchedulerJobs
|
||||
[switch]$SkipSchedulerJobs,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$SkipSmtpConfig
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
@@ -420,7 +432,7 @@ WHEN MATCHED THEN UPDATE SET t.value = s.value
|
||||
WHEN NOT MATCHED THEN INSERT (id_server_info, name, value) VALUES ((SELECT NVL(MAX(id_server_info),0)+1 FROM server_info), s.name, s.value);
|
||||
|
||||
MERGE INTO server_info t
|
||||
USING (SELECT 'EMAIL_PORT' AS name, '25' AS value FROM dual) s
|
||||
USING (SELECT 'EMAIL_PORT' AS name, '$EmailPort' AS value FROM dual) s
|
||||
ON (t.name = s.name)
|
||||
WHEN MATCHED THEN UPDATE SET t.value = s.value
|
||||
WHEN NOT MATCHED THEN INSERT (id_server_info, name, value) VALUES ((SELECT NVL(MAX(id_server_info),0)+1 FROM server_info), s.name, s.value);
|
||||
@@ -481,6 +493,84 @@ EXIT;
|
||||
Write-Log "Skipping SERVER_INFO initialization as requested"
|
||||
}
|
||||
|
||||
# Step 7b: SMTP_OUT_SERVER + ACL de retea (necesare pentru UTL_MAIL)
|
||||
# ------------------------------------------------------------------------
|
||||
# sys-objects.sql instaleaza UTL_MAIL, iar sys-grants.sql da EXECUTE pe el.
|
||||
# Atat ajunge ca sa COMPILEZE codul care trimite mailuri; ca sa si FUNCTIONEZE
|
||||
# mai trebuie doua lucruri, care lipseau complet:
|
||||
# 1. parametrul SMTP_OUT_SERVER - fara el UTL_MAIL.SEND da ORA-29278/29279;
|
||||
# 2. un ACL de retea pentru host-ul SMTP - din 12c incoace orice acces de
|
||||
# retea din PL/SQL trece prin ACL, altfel ORA-24247 "network access
|
||||
# denied by access control list".
|
||||
if (-not $SkipSmtpConfig -and $EmailSmtp) {
|
||||
Write-LogSection "Configuring SMTP (SMTP_OUT_SERVER + network ACL)"
|
||||
|
||||
$smtpSql = @"
|
||||
SET ECHO OFF FEEDBACK ON VERIFY OFF SERVEROUTPUT ON
|
||||
WHENEVER SQLERROR CONTINUE
|
||||
|
||||
ALTER SYSTEM SET SMTP_OUT_SERVER = '${EmailSmtp}:${EmailPort}' SCOPE = BOTH;
|
||||
|
||||
BEGIN
|
||||
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
|
||||
host => '$EmailSmtp',
|
||||
lower_port => $EmailPort,
|
||||
upper_port => $EmailPort,
|
||||
ace => xs`$ace_type(
|
||||
privilege_list => xs`$name_list('connect'),
|
||||
principal_name => 'CONTAFIN_ORACLE',
|
||||
principal_type => xs_acl.ptype_db));
|
||||
DBMS_OUTPUT.PUT_LINE('ACL_CONNECT_OK');
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
DBMS_OUTPUT.PUT_LINE('ACL_ERROR: ' || SQLERRM);
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
-- 'resolve' NU accepta interval de porturi - cu lower/upper_port da
|
||||
-- ORA-24244 "invalid host or port for ACL assignment". Se acorda separat,
|
||||
-- fara porturi. (Verificat pe VM 302.)
|
||||
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
|
||||
host => '$EmailSmtp',
|
||||
ace => xs`$ace_type(
|
||||
privilege_list => xs`$name_list('resolve'),
|
||||
principal_name => 'CONTAFIN_ORACLE',
|
||||
principal_type => xs_acl.ptype_db));
|
||||
DBMS_OUTPUT.PUT_LINE('ACL_RESOLVE_OK');
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
DBMS_OUTPUT.PUT_LINE('ACL_ERROR: ' || SQLERRM);
|
||||
END;
|
||||
/
|
||||
COMMIT;
|
||||
|
||||
SELECT 'SMTP_VALUE:' || value AS rez FROM v`$parameter WHERE name = 'smtp_out_server';
|
||||
EXIT;
|
||||
"@
|
||||
|
||||
$smtpResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName -DbHost $DbHost -Port $Port `
|
||||
-Username "SYS" -Password $SystemPassword -SqlCommand $smtpSql -AsSysdba
|
||||
|
||||
if ($smtpResult -match "SMTP_VALUE:\s*$([regex]::Escape($EmailSmtp))") {
|
||||
Write-LogSuccess "SMTP_OUT_SERVER = ${EmailSmtp}:${EmailPort}"
|
||||
} else {
|
||||
Write-LogWarning "Nu am putut confirma SMTP_OUT_SERVER. Manual, ca SYSDBA:"
|
||||
Write-LogWarning " ALTER SYSTEM SET SMTP_OUT_SERVER='${EmailSmtp}:${EmailPort}' SCOPE=BOTH;"
|
||||
Write-LogDebug $smtpResult
|
||||
}
|
||||
|
||||
if ($smtpResult -match "ACL_CONNECT_OK" -and $smtpResult -match "ACL_RESOLVE_OK") {
|
||||
Write-LogSuccess "ACL de retea acordat lui CONTAFIN_ORACLE pentru $EmailSmtp`:$EmailPort"
|
||||
} else {
|
||||
Write-LogWarning "ACL de retea neconfirmat - UTL_MAIL.SEND poate da ORA-24247."
|
||||
Write-LogDebug $smtpResult
|
||||
}
|
||||
}
|
||||
elseif ($SkipSmtpConfig) {
|
||||
Write-Log "Skipping SMTP configuration as requested"
|
||||
}
|
||||
|
||||
# Step 8: Initialize AUTH_DETALII.CUSTOMER_ID
|
||||
if ($CustomerId) {
|
||||
Write-LogSection "Setting AUTH_DETALII Customer ID"
|
||||
|
||||
@@ -141,6 +141,10 @@ catch {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# uninstall-roa.sql se termina cu un bloc de verdict:
|
||||
# - EXIT SUCCESS daca nu a ramas niciun obiect ROA
|
||||
# - EXIT FAILURE (ORA-20900) daca a supravietuit ceva
|
||||
# Codul de iesire e deci autoritar; nu-l suprascrie si nu raporta succes fara el.
|
||||
Write-Host ""
|
||||
if ($exitCode -eq 0) {
|
||||
Write-Host "============================================================" -ForegroundColor Green
|
||||
@@ -148,12 +152,17 @@ if ($exitCode -eq 0) {
|
||||
Write-Host "============================================================" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Database is now clean. You can re-run the setup scripts." -ForegroundColor Cyan
|
||||
exit 0
|
||||
}
|
||||
else {
|
||||
Write-Host "============================================================" -ForegroundColor Yellow
|
||||
Write-Host " ROA UNINSTALL COMPLETED WITH WARNINGS" -ForegroundColor Yellow
|
||||
Write-Host "============================================================" -ForegroundColor Yellow
|
||||
Write-Host "============================================================" -ForegroundColor Red
|
||||
Write-Host " ROA UNINSTALL INCOMPLET" -ForegroundColor Red
|
||||
Write-Host "============================================================" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Some objects may not have been removed. Review output above." -ForegroundColor Yellow
|
||||
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
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
@@ -12,10 +12,18 @@
|
||||
-- WARNING: This reduces security. For production environments, consider
|
||||
-- creating a custom profile with appropriate settings.
|
||||
--
|
||||
-- Usage:
|
||||
-- @configure-profile.sql
|
||||
-- ATENTIE - UNELTA DE REMEDIERE MANUALA, NU FACE PARTE DIN FLUXUL DE INSTALARE
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 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
|
||||
@@ -97,3 +105,46 @@ WHERE username IN ('CONTAFIN_ORACLE', 'SYSTEM', 'SYS')
|
||||
OR username LIKE 'TEST%';
|
||||
|
||||
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
|
||||
|
||||
@@ -24,7 +24,7 @@ PROMPT
|
||||
-- SECTION 1: GRANTS TO CONTAFIN_ORACLE
|
||||
-- ============================================================================
|
||||
PROMPT
|
||||
PROMPT [1/5] Granting privileges to CONTAFIN_ORACLE...
|
||||
PROMPT [1/6] Granting privileges to CONTAFIN_ORACLE...
|
||||
|
||||
-- Execute on SYS packages
|
||||
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.UTL_INADDR 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_TCP 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
|
||||
GRANT CREATE ANY DIRECTORY TO CONTAFIN_ORACLE;
|
||||
@@ -51,7 +58,7 @@ PROMPT Grants to CONTAFIN_ORACLE complete.
|
||||
-- SECTION 2: PUBLIC GRANTS
|
||||
-- ============================================================================
|
||||
PROMPT
|
||||
PROMPT [2/5] Granting public privileges...
|
||||
PROMPT [2/6] Granting public privileges...
|
||||
|
||||
-- UTL packages for public use
|
||||
GRANT EXECUTE ON SYS.UTL_FILE TO PUBLIC;
|
||||
@@ -62,7 +69,7 @@ PROMPT Public grants complete.
|
||||
-- SECTION 3: SYS PUBLIC SYNONYMS
|
||||
-- ============================================================================
|
||||
PROMPT
|
||||
PROMPT [3/5] Creating SYS public synonyms...
|
||||
PROMPT [3/6] Creating SYS public synonyms...
|
||||
|
||||
-- Synonyms for SYS procedures
|
||||
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
|
||||
-- ============================================================================
|
||||
PROMPT
|
||||
PROMPT [4/5] Creating DMPDIR directory...
|
||||
PROMPT [4/6] Creating DMPDIR directory...
|
||||
|
||||
BEGIN
|
||||
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).
|
||||
-- ============================================================================
|
||||
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
|
||||
TYPE t_lista IS TABLE OF VARCHAR2(30);
|
||||
@@ -170,6 +177,40 @@ END;
|
||||
|
||||
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 SYS Grants and Synonyms Installation Complete
|
||||
|
||||
@@ -32,7 +32,7 @@ PROMPT
|
||||
-- SECTION 1: TABLES
|
||||
-- ============================================================================
|
||||
|
||||
PROMPT [1/11] Creating SYS.AUTH_DETALII table...
|
||||
PROMPT [1/10] Creating SYS.AUTH_DETALII table...
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
@@ -50,7 +50,7 @@ BEGIN
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT [2/11] Creating SYS.AUTH_SERII table...
|
||||
PROMPT [2/10] Creating SYS.AUTH_SERII table...
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
@@ -76,7 +76,7 @@ BEGIN
|
||||
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
|
||||
-- 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
|
||||
@@ -116,7 +116,7 @@ END;
|
||||
-- SECTION 2: SEQUENCE
|
||||
-- ============================================================================
|
||||
|
||||
PROMPT [4/11] Creating SYS.SEQ_AUTH_SERII sequence...
|
||||
PROMPT [4/10] Creating SYS.SEQ_AUTH_SERII sequence...
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
@@ -143,7 +143,7 @@ END;
|
||||
-- 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(
|
||||
p_info IN CLOB,
|
||||
p_locatia IN VARCHAR2 DEFAULT NULL
|
||||
@@ -164,7 +164,7 @@ END pINFO;
|
||||
-- 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
|
||||
-- ========================================================================
|
||||
-- AUTH_PACK - License and Authentication Management
|
||||
@@ -229,7 +229,7 @@ CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS
|
||||
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
|
||||
-- ========================================================================
|
||||
-- MODIFICATION HISTORY:
|
||||
@@ -769,7 +769,7 @@ END AUTH_PACK;
|
||||
-- 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 (
|
||||
ID_PROGRAM,
|
||||
NUME,
|
||||
@@ -791,143 +791,356 @@ WHERE b.sters = 0
|
||||
-- SECTION 6: ADDITIONAL PROCEDURES
|
||||
-- ============================================================================
|
||||
|
||||
PROMPT [9/11] Creating SYS.EXECUTESCRIPTOS procedure...
|
||||
CREATE OR REPLACE PROCEDURE SYS.EXECUTESCRIPTOS(
|
||||
p_nume_script IN VARCHAR2,
|
||||
p_param IN VARCHAR2,
|
||||
p_wait IN VARCHAR2,
|
||||
p_result OUT NUMBER
|
||||
) IS
|
||||
v_job_name VARCHAR2(100);
|
||||
v_state VARCHAR2(30);
|
||||
BEGIN
|
||||
v_job_name := 'EXECUTESCRIPTOS_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS');
|
||||
PROMPT [9/10] Creating SYS.EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS...
|
||||
-- ============================================================================
|
||||
-- Sursa: procedurile SYS de pe ROA_CENTRAL (10.0.20.121:1521/ROA), extrase din
|
||||
-- dba_source la 2026-08-25. Versiunile anterioare din acest fisier aveau
|
||||
-- semnaturi inventate, incompatibile cu CONTAFIN_ORACLE.PACK_UPDATE, care apeleaza
|
||||
-- SYS.Updatesqlplus(tcSqlPlusPath, tcScriptPath). Nu modifica semnaturile fara sa
|
||||
-- verifici intai apelurile din PACK_UPDATE / PACK_UTILS.
|
||||
-- ============================================================================
|
||||
|
||||
CREATE OR REPLACE PROCEDURE SYS.ExecuteScriptOS(tcPowerShellPath in varchar2,
|
||||
tcScriptPath in varchar2) as
|
||||
lcJobName varchar2(500);
|
||||
begin
|
||||
lcJobName := 'exec_ps_' || SUBSTR(SYS_GUID(), 1, 8);
|
||||
|
||||
DBMS_SCHEDULER.CREATE_JOB(
|
||||
job_name => v_job_name,
|
||||
job_type => 'EXECUTABLE',
|
||||
job_action => p_nume_script,
|
||||
number_of_arguments => 1,
|
||||
start_date => SYSTIMESTAMP,
|
||||
enabled => FALSE,
|
||||
auto_drop => TRUE
|
||||
job_name => lcJobName,
|
||||
job_action => tcPowerShellPath,
|
||||
number_of_arguments => 4,
|
||||
job_type => 'executable',
|
||||
enabled => FALSE
|
||||
);
|
||||
|
||||
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
|
||||
job_name => v_job_name,
|
||||
argument_position => 1,
|
||||
argument_value => p_param
|
||||
);
|
||||
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 1, '-ExecutionPolicy');
|
||||
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 2, 'Bypass');
|
||||
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 3, '-File');
|
||||
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 4, tcScriptPath);
|
||||
|
||||
DBMS_SCHEDULER.ENABLE(v_job_name);
|
||||
DBMS_SCHEDULER.ENABLE(lcJobName);
|
||||
end ExecuteScriptOS;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE SYS.NewSchema(tcSchema varchar2,
|
||||
tnLuna number,
|
||||
tnAn number) is
|
||||
lcCommand varchar2(1000);
|
||||
|
||||
lcSchemaSursa VARCHAR2(100) := 'FIRMANOUA';
|
||||
lcSchemaDestinatie VARCHAR2(100) := tcSchema;
|
||||
lcDumpFile VARCHAR2(100);
|
||||
lcDumpDir VARCHAR2(100) := 'DMPDIR';
|
||||
-- lnCount number(10);
|
||||
|
||||
lcSql varchar2(1000);
|
||||
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);
|
||||
|
||||
IF p_wait = 'Y' THEN
|
||||
LOOP
|
||||
BEGIN
|
||||
SELECT state INTO v_state
|
||||
FROM dba_scheduler_jobs
|
||||
WHERE job_name = v_job_name;
|
||||
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);
|
||||
|
||||
EXIT WHEN v_state NOT IN ('SCHEDULED', 'RUNNING');
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
EXIT; -- Job completed and was auto-dropped
|
||||
WHEN OTHERS THEN
|
||||
PINFO(SQLERRM, lcLocatie);
|
||||
raise_application_error(-20000, SQLERRM);
|
||||
END;
|
||||
DBMS_LOCK.SLEEP(1);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
p_result := 0;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
p_result := -1;
|
||||
END EXECUTESCRIPTOS;
|
||||
DBMS_DATAPUMP.DETACH(h1);
|
||||
|
||||
end NewSchema;
|
||||
/
|
||||
|
||||
PROMPT [10/11] Creating SYS.NEWSCHEMA procedure...
|
||||
CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMA(
|
||||
p_schema_name IN VARCHAR2,
|
||||
p_password IN VARCHAR2,
|
||||
p_result OUT NUMBER
|
||||
) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'CREATE USER ' || p_schema_name ||
|
||||
' IDENTIFIED BY ' || p_password ||
|
||||
' DEFAULT TABLESPACE ROA' ||
|
||||
' TEMPORARY TABLESPACE TEMP' ||
|
||||
' QUOTA UNLIMITED ON ROA';
|
||||
|
||||
EXECUTE IMMEDIATE 'GRANT CONNECT, RESOURCE TO ' || p_schema_name;
|
||||
EXECUTE IMMEDIATE 'GRANT CREATE SESSION TO ' || p_schema_name;
|
||||
EXECUTE IMMEDIATE 'GRANT CREATE TABLE TO ' || p_schema_name;
|
||||
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.NEWSCHEMAJOB(
|
||||
p_schema_name IN VARCHAR2,
|
||||
p_password IN VARCHAR2
|
||||
) IS
|
||||
v_job_name VARCHAR2(100);
|
||||
BEGIN
|
||||
v_job_name := 'NEWSCHEMA_' || p_schema_name;
|
||||
|
||||
DBMS_SCHEDULER.CREATE_JOB(
|
||||
job_name => v_job_name,
|
||||
CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMAJOB(tcSchema varchar2,
|
||||
tnLuna number,
|
||||
tnAn number) as
|
||||
lcJobName varchar2(500);
|
||||
begin
|
||||
lcJobName := 'NEWSCHEMA_' || UPPER(tcSchema);
|
||||
dbms_scheduler.create_job(job_name => lcJobName,
|
||||
job_type => 'STORED_PROCEDURE',
|
||||
job_action => 'SYS.NEWSCHEMA',
|
||||
job_action => 'NEWSCHEMA',
|
||||
number_of_arguments => 3,
|
||||
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;
|
||||
enabled => false);
|
||||
dbms_scheduler.set_job_argument_value(lcJobName, 1, tcSchema);
|
||||
dbms_scheduler.set_job_argument_value(lcJobName, 2, to_char(tnLuna));
|
||||
dbms_scheduler.set_job_argument_value(lcJobName, 3, to_char(tnAn));
|
||||
dbms_scheduler.enable(lcJobName);
|
||||
end NEWSCHEMAJOB;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE SYS.UPDATESQLPLUS IS
|
||||
v_result NUMBER;
|
||||
BEGIN
|
||||
-- Path may need to be adjusted for your Windows installation
|
||||
EXECUTESCRIPTOS('D:\ROMFAST\UPDATE\UPDATE_SQLPLUS.BAT', '', 'N', v_result);
|
||||
END UPDATESQLPLUS;
|
||||
CREATE OR REPLACE PROCEDURE SYS.UpdateSQLPLUS(tcSqlPlusPath in varchar2,
|
||||
tcScriptPath in varchar2) as
|
||||
lcJobName varchar2(500);
|
||||
begin
|
||||
lcJobName := 'updateschema_' || to_char(sysdate, 'YYYYMMDDHH24MISS');
|
||||
dbms_scheduler.create_job(lcJobName,
|
||||
job_action => tcSqlPlusPath,
|
||||
number_of_arguments => 2,
|
||||
job_type => 'executable',
|
||||
enabled => false);
|
||||
dbms_scheduler.set_job_argument_value(lcJobName, 1, '/nolog');
|
||||
dbms_scheduler.set_job_argument_value(lcJobName, 2, '@' || tcScriptPath);
|
||||
dbms_scheduler.enable(lcJobName);
|
||||
end;
|
||||
/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- SECTION 7: UTL_MAIL
|
||||
-- ============================================================================
|
||||
-- UTL_MAIL nu se instaleaza implicit in Oracle 21c. Fara el raman INVALID:
|
||||
-- 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
|
||||
-- ============================================================================
|
||||
|
||||
@@ -95,6 +95,7 @@ DECLARE
|
||||
)
|
||||
ORDER BY username;
|
||||
v_count NUMBER := 0;
|
||||
v_failed NUMBER := 0;
|
||||
BEGIN
|
||||
FOR r IN c_users LOOP
|
||||
BEGIN
|
||||
@@ -107,10 +108,30 @@ BEGIN
|
||||
v_count := v_count + 1;
|
||||
EXCEPTION
|
||||
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 LOOP;
|
||||
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;
|
||||
/
|
||||
|
||||
@@ -137,8 +158,18 @@ BEGIN
|
||||
END;
|
||||
|
||||
-- Now drop the user
|
||||
BEGIN
|
||||
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
|
||||
DBMS_OUTPUT.PUT_LINE(' User CONTAFIN_ORACLE does not exist.');
|
||||
END IF;
|
||||
@@ -170,7 +201,7 @@ DECLARE
|
||||
'PACK_UTILS_FILE', 'PACK_ROARTVAI', 'RTVAI_AGENTI', 'RTVAI_ISTORIC',
|
||||
'FF_SUME', 'FF_PERSINTRET', 'VANZARI_DETALII_TAB', 'PIVOT_TABLE',
|
||||
'PIVOT_ROW', 'TABINCHIDERETVA', 'TABELAVALORITAGURI',
|
||||
'RANDINCHIDERETVA', 'SERVER_INFO'
|
||||
'RANDINCHIDERETVA', 'SERVER_INFO', 'EXECUTESCRIPTOS'
|
||||
)
|
||||
OR synonym_name LIKE 'SYN_%');
|
||||
v_count NUMBER := 0;
|
||||
@@ -344,10 +375,100 @@ PROMPT
|
||||
PROMPT Tablespace ROA:
|
||||
SELECT tablespace_name, status FROM dba_tablespaces WHERE tablespace_name = 'ROA';
|
||||
|
||||
PROMPT
|
||||
PROMPT ============================================================
|
||||
PROMPT ROA UNINSTALL COMPLETE
|
||||
PROMPT ============================================================
|
||||
PROMPT
|
||||
PROMPT Database is now clean. You can re-run the setup scripts.
|
||||
PROMPT
|
||||
-- ============================================================================
|
||||
-- VERDICT: verificare autoritara, cu cod de iesire
|
||||
-- ============================================================================
|
||||
-- Toate sectiunile de mai sus prind exceptiile in WHEN OTHERS si doar scriu in
|
||||
-- DBMS_OUTPUT, ca sa nu opreasca dezinstalarea la primul obstacol. Consecinta:
|
||||
-- scriptul se termina "cu succes" chiar daca un user a supravietuit, iar
|
||||
-- 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
|
||||
|
||||
459
proxmox/lxc108-oracle/scripts/build-client-kit.ps1
Normal file
459
proxmox/lxc108-oracle/scripts/build-client-kit.ps1
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
### Full Installation Test
|
||||
|
||||
Reference in New Issue
Block a user