sync SVN r18148
This commit is contained in:
341
docs/handoff_update_romfast.md
Normal file
341
docs/handoff_update_romfast.md
Normal file
@@ -0,0 +1,341 @@
|
||||
# Handoff: actualizare blocata pe ROMFAST 10.0.20.36 (16.09.2026, seara)
|
||||
|
||||
Stare, nu concluzie finala. Nimic modificat pe productie: exclusiv `SELECT`-uri.
|
||||
|
||||
## Ce e DOVEDIT
|
||||
|
||||
1. **Nu e problema de certificat.** `ORA-29024` vine de pe ramura a doua a lui
|
||||
`CONTAFIN_ORACLE.PACK_UTILS.URL2Clob`. Cod instalat, citit din `all_source`:
|
||||
- linia 285: `IF lcPowerShellDownload = '1' THEN` -> ramura 1 (curl extern);
|
||||
- linia 291: `llDownloaded := DownloadFileOS(tcURL, lcDir, lcFileName);` cu `lcDir := 'DMPDIR'`;
|
||||
- linia 293-301: daca a mers, citeste si `RETURN`;
|
||||
- linia 305: `l_clob := HTTPURITYPE.createuri(tcURL).getclob();` <- ramura 2, cade aici;
|
||||
- linia 307-313: `WHEN OTHERS` -> cleanup -> `RAISE`.
|
||||
Stiva reala (`PACK_UTILS` 313 si 305) se potriveste exact. Deci ORA-29024 = ramura 1 nu a produs fisierul.
|
||||
|
||||
2. **Ramura 1 E activata pe ROMFAST.** `CONTAFIN_ORACLE.SERVER_INFO`:
|
||||
`POWERSHELLDOWNLOAD = 1`, `POWERSHELLTIMEOUT = 30`,
|
||||
`POWERSHELLPATH = C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe`,
|
||||
`ROAUPDATEPATH = D:\ROAUPDATE`. **Nu exista rand `CURLPATH`**, dar codul are fallback pe
|
||||
`C:\Windows\System32\curl.exe` (`PACK_UTILS` body 690-692), deci absenta lui nu e fatala.
|
||||
|
||||
3. **Esecul dureaza exact cat timeout-ul.** `all_scheduler_job_run_details`, `UPDATEROA_JOB`:
|
||||
- 21:17:51 SUCCEEDED (error# 0)
|
||||
- 22:10:36 FAILED, error# 29273 — pornire 22:10:05 => **31 secunde**
|
||||
- 22:27:42 FAILED, error# 29273 — pornire 22:27:12 => **30 secunde**
|
||||
`POWERSHELLTIMEOUT = 30`. Bucla de polling (`PACK_UTILS` body 709-713) a mers pana la capat si
|
||||
`PACK_UTILS_FILE.FileExists` a intors fals. Fisierul **nu a aparut niciodata**, nu a aparut tarziu.
|
||||
|
||||
4. **Corelatia temporala cu patch-ul de azi.** `all_objects`, owner `CONTAFIN_ORACLE`:
|
||||
`PACK_UTILS` (spec+body), `PACK_UTILS_FILE` (spec+body) `last_ddl_time = 16.09 21:17:51`;
|
||||
`PACK_UPDATE` (spec+body) `21:17:52`. Toate VALID.
|
||||
Rularea de la 21:17:30-21:20:14 e cea care a **instalat** noul cod; descarcarea din ea s-a facut
|
||||
inainte de recompilare, deci **cu codul vechi**. Toate rularile de DUPA recompilare (22:10, 22:27)
|
||||
au esuat. => **noul `PACK_UTILS` nu a descarcat niciodata nimic cu succes pe ROMFAST.**
|
||||
|
||||
5. **Serverul de update raspunde.** Masurat de pe statia de lucru, 16.09.2026:
|
||||
`https://roa.romfast.ro/contafinupdate/roaupdate/` -> HTTP 200 in 0.127s.
|
||||
`http://10.0.20.122/` -> 404 in 0.0016s de la `Microsoft-HTTPAPI/2.0` (normal, situl real e pe
|
||||
portul 81 cu ruta `/contafinupdate/...`; 404 de la `http.sys` NU inseamna server picat).
|
||||
|
||||
6. **Versiuni** (`SERVER_INFO.VERSIUNE_*`): majoritatea schemelor la `202609150001` (15.09);
|
||||
`CONTAFIN_ORACLE` la `202609160003`, `ROMFAST` la `202609160005`. Actualizarea de azi a inceput si
|
||||
s-a oprit pe drum.
|
||||
|
||||
7. **`UPD_LOG` se goleste la fiecare rulare** (`last_ddl_time` 22:27:02 pe tabela si indecsi).
|
||||
Singurul rand ramas: `16.09 22:34:38 ACTUALIZARE INCHEIATA MANUAL`. Nu e sursa de istoric.
|
||||
|
||||
8. **`sys.ExecuteScriptOS`** (`all_source`, owner SYS, `last_ddl_time` 05.02.2026, deci **neatins azi**)
|
||||
creeaza un job `exec_ps_<8hex>` de tip `executable` cu argumentele
|
||||
`-ExecutionPolicy Bypass -File <script>` si il `ENABLE`-aza. Joburile sunt SYS-owned, deci
|
||||
`CONTAFIN_ORACLE` **nu le vede** in `all_scheduler_job_run_details` (interogat: zero randuri
|
||||
`EXEC_PS%`). Aici e gaura de vizibilitate.
|
||||
|
||||
## Ce NU e dovedit (ipoteze deschise, in ordinea probabilitatii)
|
||||
|
||||
- **A. Patch-ul de azi a rupt ramura 1.** Cel mai probabil, pe baza punctului 4. Ce s-a schimbat azi
|
||||
(antet `PACK_UTILS` body linia 4): „DownloadFileOS descarca in .part si redenumeste la final, nume
|
||||
unic de script ps". Scriptul generat (body 694-699):
|
||||
`& "<curl>" -k -o "<dest>.part" "<url>"` + `if ($LASTEXITCODE -eq 0) { Move-Item ... } else { Remove-Item ... }`.
|
||||
Scris cu `pack_utils_file.clob2fileX` (701), citit cu `File2ClobX` (295) — ambele functii noi.
|
||||
**Nedeterminat care linie anume pica.** Nu am comparat inca versiunea instalata cu cea anterioara.
|
||||
- **B. PowerShell/curl nu ruleaza deloc pe server** (drepturi pe jobul extern, `C:\DMPDIR` nescriibil,
|
||||
curl absent). Ar da acelasi simptom si ar fi independent de patch — dar atunci ar fi picat si
|
||||
inainte de 21:17, ceea ce contrazice punctul 3. Slaba, dar nu exclusa.
|
||||
- **C. Legatura cu incidentul conpress de azi.** Capatul departat al db link-ului `DBL_ROMFAST2` este
|
||||
chiar 10.0.20.36; la conpress s-a omorat sesiunea de pe partea apropiata (ROA_CENTRAL) fara sa se
|
||||
priveasca vreodata partea departata. **Neverificata.**
|
||||
|
||||
## Urmatorul pas care departajeaza (nerulat)
|
||||
|
||||
Pe serverul 10.0.20.36, in afara Oracle: ruleaza manual scriptul pe care il genereaza codul si vezi
|
||||
codul de iesire al lui `curl.exe` — el e singura informatie pe care lantul o pierde complet
|
||||
(`$LASTEXITCODE` decide doar redenumirea, valoarea nu se logheaza nicaieri). Si verifica ce ramane in
|
||||
`C:\DMPDIR` dupa o rulare esuata: daca ramane un `.part`, curl a mers si a picat `Move-Item`; daca nu
|
||||
ramane nimic, curl a esuat sau PowerShell n-a pornit.
|
||||
Alternativ, din Oracle ca SYS: `dba_scheduler_job_run_details` pentru joburile `EXEC_PS%` — acolo
|
||||
sunt esecurile jobului extern, invizibile din `CONTAFIN_ORACLE`.
|
||||
|
||||
## Stare periculoasa / de curatat
|
||||
|
||||
- **Tunelul Bitvise e RIDICAT** — proces `stnlc`, profil `D:\vm303-profile\romfast.tlp`,
|
||||
forwardari active pe `127.0.0.1:1521` (ROMFAST, `SID=ROA`), 1522, 1523 si altele.
|
||||
**De inchis** cand nu mai e nevoie:
|
||||
`Stop-Process -Id (Get-NetTCPConnection -LocalPort 1521 -State Listen).OwningProcess`.
|
||||
- Nimic modificat pe productie. Doar `SELECT`-uri. Niciun script relansat, niciun job atins.
|
||||
- `SERVER_INFO` contine parole (`PASSWORD_SYS`, `PASSWORD_CONTAFIN_ORACLE` base64+gzip,
|
||||
`EMAIL_PASSWORD` in clar). **Nu le pune in niciun raport, doc sau commit.**
|
||||
- Modificare necomisa in alt repo: `COMUN/docs/depanare-server-update-roa.md`, +60 linii
|
||||
(doua sectiuni noi, doar insertii). Neverificata linie cu linie de Marius.
|
||||
- Lane opencode `src` inca rula la scrierea acestui fisier; livrabilul lui ar fi
|
||||
`docs/raport_src.md` (diff conceptual intre versiunea de azi a lui PACK_UTILS si cea anterioara).
|
||||
|
||||
## Cum se reia conexiunea
|
||||
|
||||
```
|
||||
"C:\Program Files (x86)\Bitvise SSH Client\stnlc.exe" "-profile=D:/vm303-profile/romfast.tlp"
|
||||
D:\ROA\instantclient_19_18\sqlplus.exe -S -L "CONTAFIN_ORACLE/<parola>@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SID=ROA)))" "@script.sql"
|
||||
```
|
||||
Din Git Bash, calea profilului se da cu **bare oblice** — backslash-urile sunt inghitite si dau
|
||||
„CreateFile(): Windows error 2". Parola se cere de la Marius, nu se ghiceste
|
||||
(`FAILED_LOGIN_ATTEMPTS` poate bloca schema in productie).
|
||||
|
||||
---
|
||||
|
||||
## COMPLETARE (dupa lane-ul `src` + `dba_scheduler_job_run_details`)
|
||||
|
||||
`CONTAFIN_ORACLE` **are** drept pe vederile DBA. Joburile externe PowerShell sunt vizibile si
|
||||
schimba diagnosticul:
|
||||
|
||||
```
|
||||
EXEC_PS_40900C5A SUCCEEDED 16.09 22:27:13 error# 0
|
||||
UPDATEROA_JOB FAILED 16.09 22:27:42 error# 29273
|
||||
EXEC_PS_804FF579 SUCCEEDED 16.09 22:10:06 error# 0
|
||||
UPDATEROA_JOB FAILED 16.09 22:10:36 error# 29273
|
||||
EXEC_PS_B5715BCA / BF32458E / A31FD48B / 6FC1191C / 8E28DF1C / 15128026 SUCCEEDED 16.09 21:17:31-38
|
||||
UPDATEROA_JOB SUCCEEDED 16.09 21:17:51
|
||||
EXEC_PS_* x7 SUCCEEDED 16.09 04:00:01-08 (rularea automata, cod vechi)
|
||||
```
|
||||
|
||||
**Ce dovedeste asta:**
|
||||
|
||||
1. **PowerShell PORNESTE si iese cu cod 0.** Ipoteza B din handoff (job extern neconfigurat, lipsa
|
||||
drepturi, `curl` absent) e **INFIRMATA**. `sys.ExecuteScriptOS` functioneaza pe ROMFAST.
|
||||
2. **Esecul e INAUNTRUL scriptului `.ps1`.** Jobul e `job_type=>'executable'` pe `powershell.exe`;
|
||||
`SUCCEEDED` inseamna doar ca `powershell.exe` a iesit cu 0. Scriptul iese cu 0 **si pe ramura de
|
||||
esec**, fiindca `else { Remove-Item ... }` (PACK_UTILS body 698-699) nu propaga nimic.
|
||||
Deci: ori `curl` a esuat si `.part` a fost sters, ori `curl` a mers si `Move-Item` a picat.
|
||||
**Ambele sunt inghitite tacit.**
|
||||
3. **Sub codul vechi mergea, sub cel nou nu.** La 04:00 (automat) au rulat 7 joburi PS, toate
|
||||
reusite, si actualizarea a mers; la 21:17 sase joburi PS reusite, `UPDATEROA_JOB` SUCCEEDED —
|
||||
toate **inainte** de recompilarea de la 21:17:51. Dupa recompilare: la 22:10 si 22:27 ruleaza
|
||||
**exact un singur** job PS, apoi esec la 30 de secunde. Adica **prima descarcare** sub noul cod
|
||||
pica, si lantul se opreste acolo.
|
||||
|
||||
**Diferentele reale introduse azi** (lane `src`, comparatie `co_2026_09_16_02` vs
|
||||
`co_2026_01_14_01_PACK_UTILS.sql`):
|
||||
- numele scriptului `.ps1`: fix `download_file.ps1` -> unic `download_<timestamp>.ps1`;
|
||||
- se sterge fisierul destinatie INAINTE de descarcare (body 685) — nou;
|
||||
- se descarca in `<dest>.part` si se muta cu `Move-Item -Force` — nou;
|
||||
- `.ps1` se sterge la final (body 719) — nou;
|
||||
- in `PACK_UTILS_FILE`, `FileDelete` a devenit best-effort (`when others then null`), deci nu mai
|
||||
ridica ORA-29283/29291 care inainte semnalau problema.
|
||||
- **Gardele si preconditiile sunt NESCHIMBATE** — deci nu s-a pierdut nicio configurare.
|
||||
|
||||
**Suspectul principal ramas:** scriptul `.ps1` nou. Doua variante, nedepartajate:
|
||||
(a) `curl.exe -k -o "<dest>.part"` esueaza (dar mergea la 21:17 cu aceeasi retea si acelasi URL);
|
||||
(b) `Move-Item -Force` din `.part` in destinatie pica — si e exact pasul care NU exista inainte.
|
||||
Varianta (b) explica de ce simptomul a aparut fix la prima rulare de dupa recompilare.
|
||||
A treia varianta, de exclus: `clob2fileX` (functie noua) scrie `.ps1`-ul incomplet/gol — powershell
|
||||
ar rula un fisier gol si ar iesi tot cu 0, exact ce se vede.
|
||||
|
||||
**Cum se departajeaza, pe OS, pe 10.0.20.36, in `C:\DMPDIR`:**
|
||||
- raman fisiere `url2clob_*.tmp.part` -> `curl` a mers, `Move-Item` a picat -> varianta (b);
|
||||
- nu ramane nimic -> `curl` a esuat -> varianta (a);
|
||||
- raman `download_*.ps1` -> scriptul nu a fost sters, deci bucla nu a ajuns la capat;
|
||||
- deschide un `download_*.ps1` ramas si vezi daca are continut -> departajeaza `clob2fileX`.
|
||||
Rularea manuala a aceluiasi `.ps1` din consola, pe server, arata direct codul de iesire al lui `curl`.
|
||||
|
||||
---
|
||||
|
||||
## COMPLETARE 2: dovada de pe disc (`\10.0.20.36\c\DMPDIR`)
|
||||
|
||||
`roadigi.romfast.ro` ESTE 10.0.20.36; share-ul `\10.0.20.36\c\` e accesibil direct de pe statie.
|
||||
|
||||
Continut relevant:
|
||||
```
|
||||
url2clob_20260916222712422000000.tmp.part 10863 octeti
|
||||
CreationTime = LastWriteTime = 16.09 22:27:12.990
|
||||
```
|
||||
- Numele contine timestamp-ul generat de PL/SQL: **22:27:12.422**.
|
||||
- `EXEC_PS_40900C5A` (jobul PowerShell) s-a incheiat SUCCEEDED la **22:27:13**.
|
||||
- `UPDATEROA_JOB` a esuat la 22:27:42 (30s = `POWERSHELLTIMEOUT`).
|
||||
- Continutul `.part` este `roa_app.xml` **complet si valid** (`<?xml ... Windows-1252?><VFPData>` ...
|
||||
`</VFPData>`), lista de programe de la ROAACNPRO la ROAVIN.
|
||||
- **Niciun `download_*.ps1` ramas** in DMPDIR (stergerea de la body 719 a functionat).
|
||||
|
||||
**Ce e DOVEDIT acum:**
|
||||
1. `curl.exe` a mers perfect: a descarcat tot fisierul, in ~0.5 secunde, in locatia corecta.
|
||||
Ipoteza (a) — „curl esueaza" — e **INFIRMATA**.
|
||||
2. Redenumirea `.part` -> destinatie **nu s-a facut**. Nici `Remove-Item` de pe ramura `else` nu
|
||||
s-a facut, altfel fisierul ar fi disparut.
|
||||
3. PowerShell a iesit imediat dupa `curl` (22:27:12.990 -> job incheiat 22:27:13), cu cod 0.
|
||||
4. NTFS pe `C:\DMPDIR`: `Authenticated Users:(M)` — **Modify, deci si drept de stergere**.
|
||||
Ipoteza „lipsa drept de delete/rename" e **INFIRMATA**.
|
||||
|
||||
**Intrebarea ramasa, singura, nedepartajata:** de ce nu s-a executat linia a doua a scriptului.
|
||||
Doua variante, ambele compatibile cu toate dovezile de mai sus:
|
||||
- **(b) `Move-Item` a rulat si a esuat** ca eroare ne-terminanta -> scrisa pe stderr, ignorata,
|
||||
PowerShell iese 0. Motivul esecului ramane nestiut (jobul extern nu captureaza stderr).
|
||||
- **(c) fisierul `.ps1` a fost scris trunchiat la primul CRLF**, deci PowerShell a executat doar
|
||||
linia cu `curl` si a iesit. Scrierea se face cu `PACK_UTILS_FILE.Clob2FileX`
|
||||
(`dbms_xslprocessor.clob2file(clob, dir, file, csid => 0)`), iar scriptul de azi este **primul
|
||||
script cu mai mult de o linie** — inainte era o singura comanda `curl` direct in destinatie, deci
|
||||
o trunchiere la primul CRLF ar fi fost invizibila. Asta explica de ce simptomul apare exact la
|
||||
prima rulare de dupa patch.
|
||||
|
||||
**Testul minim care departajeaza (cere o scriere, NU s-a facut):** pe o instanta de test, apeleaza
|
||||
`PACK_UTILS_FILE.Clob2FileX` cu un clob de doua linii separate prin `chr(13)||chr(10)` si uita-te la
|
||||
fisierul rezultat: daca are o singura linie -> varianta (c), si reparatia e in felul in care se scrie
|
||||
`.ps1`-ul, nu in `curl`. Daca are doua linii -> varianta (b), si atunci trebuie capturat stderr-ul
|
||||
scriptului ca sa se vada de ce pica `Move-Item`.
|
||||
|
||||
**Fisierul `.part` de la 22:27 e singura proba fizica ramasa — nu-l stergeti si nu-l redenumiti
|
||||
pana nu se decide testul.** Cel de la rularea 22:10 nu mai exista (nu se stie cine l-a sters).
|
||||
|
||||
---
|
||||
|
||||
## CAUZA RADACINA — DEMONSTRATA prin reproducere pe ROMFAST (16.09.2026, 23:07)
|
||||
|
||||
Marius a aprobat rularea directa pe productie. Probele au fost rulate prin
|
||||
`PACK_UTILS_FILE.Clob2FileX` + `sys.ExecuteScriptOS`, adica prin exact acelasi mecanism si sub
|
||||
exact acelasi cont ca lantul real. Toate fisierele de proba au fost sterse dupa (vezi „Curatenie").
|
||||
|
||||
### Proba 1 — `Clob2FileX` scrie corect (varianta (c) INFIRMATA)
|
||||
Clob de doua linii separate prin `chr(13)||chr(10)` -> fisier de 248 octeti, **ambele linii intacte**,
|
||||
`\r \n` pastrat, fara BOM, fara trunchiere (`od -c`). Scrierea `.ps1`-ului nu e problema.
|
||||
|
||||
### Proba 2 — `Move-Item` functioneaza sub contul jobului (varianta (b) INFIRMATA)
|
||||
Script rulat prin `ExecuteScriptOS`: creeaza un fisier in `C:\DMPDIR`, il muta, il sterge.
|
||||
Rezultat in log: `MOVE OK`, `DEL OK`. Si `cwd=C:\`. Deci nici drepturile, nici `Move-Item` nu pica.
|
||||
(NTFS pe `C:\DMPDIR`: `Authenticated Users:(M)`.)
|
||||
|
||||
### Proba 3 — reproducerea scriptului real
|
||||
Script identic cu cel generat de `DownloadFileOS`, pe URL-ul real
|
||||
`https://roa.romfast.ro/contafinupdate/default.aspx/updroa/download/1/roa_app.xml`
|
||||
(`optiuni.UPD_URL_APP` + `sys.auth_detalii.detalii = 1`):
|
||||
```
|
||||
lastexit=
|
||||
part_ramas=False dest_creat=False
|
||||
erori=1
|
||||
Cannot find path 'C:\DMPDIR\claude_repro.tmp.part' because it does not exist.
|
||||
```
|
||||
`$LASTEXITCODE` **gol**; `Remove-Item` a picat pentru ca fisierul inca nu exista. Fisierul `.part`
|
||||
a aparut DUPA ce scriptul se terminase.
|
||||
|
||||
### Proba 4 — mecanismul, cu ceas
|
||||
```
|
||||
t0=23:07:08.671
|
||||
t1=23:07:08.707 ec=[] exists=False <- la 36 de milisecunde dupa lansarea curl
|
||||
t2=23:07:13.735 exists=True <- dupa Start-Sleep 5
|
||||
proc_curl=0
|
||||
```
|
||||
|
||||
### Verdict
|
||||
**Sub jobul extern DBMS_SCHEDULER (proces fara consola), operatorul `&` din PowerShell nu asteapta
|
||||
procesul nativ.** Scriptul trece la linia urmatoare in ~36 ms, `$LASTEXITCODE` nu e niciodata setat
|
||||
(deci `$null -eq 0` = False), se executa ramura `else` pe un fisier inca inexistent, iar cand `curl`
|
||||
termina in fundal lasa `<destinatie>.part` pe disc **pentru totdeauna**. Fisierul destinatie nu apare
|
||||
niciodata -> bucla de polling din `DownloadFileOS` expira dupa `POWERSHELLTIMEOUT` (30s) ->
|
||||
`llDownloaded = FALSE` -> `URL2Clob` cade pe `HTTPURITYPE` (body 305) -> pe `https` fara wallet ->
|
||||
**ORA-29273 / ORA-29024**.
|
||||
|
||||
**De ce mergea inainte:** codul vechi scria cu `curl -o` DIRECT in fisierul destinatie. Nu exista
|
||||
pas de redenumire, deci nu depindea de terminarea lui `curl`: bucla de polling din Oracle astepta
|
||||
oricum aparitia fisierului, iar asincronia era inofensiva. Patch-ul de azi a introdus un pas
|
||||
(`Move-Item`) care presupune ca `curl` s-a terminat — presupunere falsa in acest mediu.
|
||||
Asta explica exact de ce simptomul apare la prima rulare de dupa recompilarea de la 21:17:51.
|
||||
|
||||
### Directia de reparatie (NEAPLICATA, nediscutata inca)
|
||||
Scriptul trebuie sa astepte explicit procesul, nu sa se bazeze pe `&` si pe `$LASTEXITCODE`. Varianta
|
||||
minima, in `PACK_UTILS.DownloadFileOS` body ~694-699, inlocuind linia cu `&`:
|
||||
```powershell
|
||||
$p = Start-Process -FilePath "<curl>" -ArgumentList '-k','-o','<dest>.part','<url>' -Wait -PassThru -NoNewWindow
|
||||
if ($p.ExitCode -eq 0) { Move-Item ... } else { Remove-Item ... }
|
||||
```
|
||||
Alternativ, `& "<curl>" ... | Out-Null` forteaza consumarea iesirii, deci asteptarea — dar `Start-Process
|
||||
-Wait -PassThru` e explicit si nu depinde de un efect secundar al pipeline-ului.
|
||||
**Ambele variante trebuie probate prin acelasi mecanism (`ExecuteScriptOS`) inainte de a fi propuse
|
||||
pentru commit** — mediul jobului extern e exact ce a invalidat presupunerea initiala.
|
||||
|
||||
### Curatenie
|
||||
Toate fisierele de proba sterse din `C:\DMPDIR` (`test_clob2file_claude.txt`, `diag_claude.*`,
|
||||
`repro_claude.*`, `claude_repro.*`, `async_claude.*`). A ramas **doar** proba originala
|
||||
`url2clob_20260916222712422000000.tmp.part` (10863 octeti, 22:27) — nu o stergeti, e dovada fizica
|
||||
a incidentului.
|
||||
Nu s-a modificat niciun pachet, niciun job, nicio optiune. Singurele scrieri pe productie au fost
|
||||
fisiere temporare in `C:\DMPDIR`, toate sterse.
|
||||
|
||||
---
|
||||
|
||||
## INCHEIERE BLOC (16.09.2026, ~23:40)
|
||||
|
||||
### Livrat si comis
|
||||
| ce | unde | revizie |
|
||||
|---|---|---|
|
||||
| `co_2026_09_16_06_COMUN_PACK_UTILS.sql` | `^/DATABASE/Branches/RB-1.00` | r18146 (comis de Marius), r18148 (scoaterea lui `&`) |
|
||||
| `docs/depanare-server-update-roa.md` | `^/COMUN/Trunk` | r18147 |
|
||||
|
||||
### Aplicat pe servere
|
||||
- **ROMFAST 10.0.20.36**: aplicat 23:19:32, `PACK_UTILS` VALID, `VERSIUNE_CONTAFIN_ORACLE =
|
||||
202609160006`. `PACK_UPDATE.UpdateROA` rulat de Marius 23:21:50-23:24:19, `UPDATEROA_JOB`
|
||||
SUCCEEDED, sase joburi `EXEC_PS_*` reusite, `UPD_LOG` fara randuri `ERR`, 65 de scheme pe
|
||||
`20260916`. `URL2Clob` intoarce documentul complet in ~2s.
|
||||
- **ROA_CENTRAL 10.0.20.122**: aplicat de Marius. A afisat `SP2-0317: expected symbol name is
|
||||
missing` — cauza: un `&` la sfarsit de rand intr-un COMENTARIU (linia 756), citit de sqlplus ca
|
||||
variabila de substitutie fara nume. Efect strict cosmetic: pachetul s-a compilat
|
||||
(„Package body created"), codul e intact. Reparat in r18148 prin reformularea comentariilor.
|
||||
**NU e BOM** — fisierul are 0 octeti non-ASCII, verificat la scriere si la commit.
|
||||
**Nu s-a verificat independent** starea de pe ROA_CENTRAL (nu s-a deschis tunel acolo).
|
||||
|
||||
### Capcana de retinut
|
||||
La aplicarea unui script prin sqlplus, **nu filtra iesirea** — asa am ratat acelasi `SP2-0317` pe
|
||||
ROMFAST. Un `&` la sfarsit de rand, chiar si in comentariu, produce eroarea; `&` urmat de virgula
|
||||
sau spatiu e tolerat.
|
||||
|
||||
### Ramas deschis
|
||||
- **Tunelul Bitvise catre ROMFAST e inca RIDICAT** (`stnlc`, profil `D:\vm303-profile\romfast.tlp`,
|
||||
porturi 1521/1522/1523). De inchis:
|
||||
`Stop-Process -Id (Get-NetTCPConnection -LocalPort 1521 -State Listen).OwningProcess`.
|
||||
- `C:\DMPDIR\url2clob_20260916222712422000000.tmp.part` — proba fizica a incidentului, pastrata
|
||||
intentionat. Acum ca e documentata, poate fi stearsa.
|
||||
- **Necomise, intentionat** (documente de lucru): `docs/handoff_update_romfast.md`,
|
||||
`docs/raport_src.md`, `docs/raport_doc.md`.
|
||||
- **Intrebare deschisa, neinrudita cu reparatia asta**: capatul departat al db link-ului
|
||||
`DBL_ROMFAST2` este chiar 10.0.20.36; la incidentul conpress s-a omorat sesiunea de pe partea
|
||||
apropiata (ROA_CENTRAL) fara sa se priveasca partea departata. Cele doua incidente pot avea
|
||||
radacini diferite — reparatia de azi NU il explica pe cel de la conpress.
|
||||
- Restul serverelor de client: scriptul ajunge la ele prin fluxul normal de actualizare.
|
||||
|
||||
### Stare periculoasa
|
||||
Niciuna. Pe productie nu a ramas nimic in lucru: niciun job atins, nicio tranzactie deschisa, toate
|
||||
fisierele de proba sterse din `C:\DMPDIR`.
|
||||
|
||||
---
|
||||
|
||||
## ACTUALIZARE FINALA (23:45)
|
||||
|
||||
**Tunelul Bitvise catre ROMFAST este INCHIS.** Anuleaza randul „Tunelul ... e inca RIDICAT" din
|
||||
sectiunea „Ramas deschis" de mai sus: procesul `stnlc` a fost oprit, iar porturile 1521/1522/1523
|
||||
nu mai asculta (verificat cu `Get-NetTCPConnection`). Nu mai exista acces deschis la productie din
|
||||
aceasta sesiune.
|
||||
|
||||
Reluarea conexiunii, cand va fi nevoie:
|
||||
```
|
||||
"C:\Program Files (x86)\Bitvise SSH Client\stnlc.exe" "-profile=D:/vm303-profile/romfast.tlp"
|
||||
```
|
||||
Din Git Bash calea profilului se da cu bare oblice — backslash-urile sunt inghitite si dau
|
||||
„CreateFile(): Windows error 2".
|
||||
|
||||
Restul sectiunii „Ramas deschis" ramane valabil: proba `.part` din `C:\DMPDIR`, documentele de lucru
|
||||
necomise, si intrebarea deschisa despre db link-ul `DBL_ROMFAST2`.
|
||||
9
docs/raport_doc.md
Normal file
9
docs/raport_doc.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# raport doc
|
||||
|
||||
1. Facut: `COMUN\docs\depanare-server-update-roa.md` - adaugate 2 sectiuni la final (doar insertii, 60 linii; nimic sters/modificat):
|
||||
- „Anatomia fallback-ului PACK_UTILS: de ce ORA-29024 nu inseamna certificat" (linia 181).
|
||||
- „Incident 16.09.2026 (2): ROMFAST 10.0.20.36, acelasi simptom" (linia 221, se termina la 239).
|
||||
2. Verificari: octeti non-ASCII = 0 (scris strict ASCII); CR = 0 (LF pastrat, ca fisierul original); `git diff --stat` = 60 insertions, 0 deletions; liniile 118-160 neat inse.
|
||||
3. Corectii de linii in PACK_UTILS fata de sarcina: niciuna - 347/298, 353/304, 367/318 corespund exact. O corectie de continut: „codul de iesire nu e capturat" e prea tare - in co_2026_09_16_02 `$LASTEXITCODE` (linia 758) decide redenumirea `.part`, dar valoarea nu se logheaza; am scris exact asa.
|
||||
4. Nefacut/blocat: nimic. Fara commit, fara write-back, fara Oracle.
|
||||
5. Stare periculoasa: niciuna.
|
||||
350
docs/raport_src.md
Normal file
350
docs/raport_src.md
Normal file
@@ -0,0 +1,350 @@
|
||||
# Raport lane src — de ce cade ramura 1 (curl/PowerShell) pe ROMFAST 10.0.20.36
|
||||
|
||||
READ ONLY. Nu s-a rulat nimic pe Oracle, nu s-a modificat niciun fisier de cod.
|
||||
Comanda ceruta pentru teste: niciuna (nu e caz de test). Dovezi = citate din scripturi.
|
||||
|
||||
## Fisiere de referinta (aliasuri folosite mai jos)
|
||||
|
||||
- **PU** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\co_2026_09_16_02_COMUN_PACK_UTILS.sql` (azi)
|
||||
- **PU_old** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\01\co_2026_01_14_01_PACK_UTILS.sql` (versiunea anterioara)
|
||||
- **PUF** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\co_2026_09_16_01_COMUN_PACK_UTILS_FILE.sql` (azi)
|
||||
- **PUPD** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\09\co_2026_09_16_03_COMUN_PACK_UPDATE.sql` (azi)
|
||||
- **ESO** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2025\09\sys_2025_09_24_03_EXECUTESCRIPTOS.sql`
|
||||
- **SRV** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2025\09\co_2025_09_24_02_COMUN_SERVER_INFO.sql`
|
||||
- **UPD25** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2025\10\co_2025_10_05_01_COMUN_UPDATE.sql`
|
||||
- **DMP** = `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\co_2026_08_20_01_DIAG_SPATIU_PACK.sql`
|
||||
|
||||
---
|
||||
|
||||
## 1. `DownloadFileOS` integral + preconditiile de pe serverul Oracle
|
||||
|
||||
### 1.1 Codul (PU:681-786)
|
||||
|
||||
```plsql
|
||||
681: function DownloadFileOS(tcURL in varchar2,
|
||||
682: tcProgramUPDDirectory in varchar2,
|
||||
683: tcFileName in varchar2) return boolean as
|
||||
684: lcScript clob;
|
||||
685: lcDir varchar2(20) := 'DMPDIR';
|
||||
686: lcFileName varchar2(60) := 'download_' ||
|
||||
687: to_char(systimestamp, 'YYYYMMDDHH24MISSFF') ||
|
||||
688: '.ps1';
|
||||
689: lcPowerShellPath server_info.value%type;
|
||||
690: lcCURLPath server_info.value%type;
|
||||
691: lcDMPDIR varchar2(1000);
|
||||
692: lcScriptFilePath varchar2(1000);
|
||||
693: llReturn boolean := False;
|
||||
694: tcDestination varchar2(1000) := PACK_UTILS_FILE.DirectoryPath(tcProgramUPDDirectory) ||
|
||||
695: tcFileName;
|
||||
696: lcTimeOut varchar2(5) := '60';
|
||||
697: lnTimeOut number(5) := 60;
|
||||
698: begin
|
||||
699: BEGIN
|
||||
700: select value
|
||||
701: into lcPowerShellPath
|
||||
702: from SERVER_INFO
|
||||
703: WHERE UPPER(name) = 'POWERSHELLPATH';
|
||||
704:
|
||||
705: EXCEPTION
|
||||
706: WHEN NO_DATA_FOUND THEN
|
||||
707: NULL;
|
||||
708: END;
|
||||
709:
|
||||
710: BEGIN
|
||||
711: select value
|
||||
712: into lcTimeOut
|
||||
713: from SERVER_INFO
|
||||
714: WHERE UPPER(name) = 'POWERSHELLTIMEOUT';
|
||||
715:
|
||||
716: EXCEPTION
|
||||
717: WHEN NO_DATA_FOUND THEN
|
||||
718: NULL;
|
||||
719: END;
|
||||
720: lnTimeOut := GREATEST(TO_NUMBER(lcTimeOut), 5);
|
||||
721:
|
||||
722:
|
||||
723: BEGIN
|
||||
724: select value
|
||||
725: into lcCURLPath
|
||||
726: from SERVER_INFO
|
||||
727: WHERE UPPER(name) = 'CURLPATH';
|
||||
728:
|
||||
729: EXCEPTION
|
||||
730: WHEN NO_DATA_FOUND THEN
|
||||
731: NULL;
|
||||
732: END;
|
||||
733:
|
||||
734: lcDMPDIR := PACK_UTILS_FILE.DirectoryPath(lcDir);
|
||||
735:
|
||||
736: if lcDMPDIR is not null then
|
||||
737: lcScriptFilePath := lcDMPDIR || lcFileName;
|
||||
738: END if;
|
||||
739:
|
||||
740: -- Nu se continua daca nu exista calea catre POWERSHELL
|
||||
741: if lcPowerShellPath is null or lcScriptFilePath is null then
|
||||
742: goto sfarsit;
|
||||
743: end if;
|
||||
744:
|
||||
745: -- Sterg scriptul ps anterior si fisierul destinatie ramas de la o rulare anterioara
|
||||
746: pack_utils_file.filedelete(lcDir, lcFileName);
|
||||
747: pack_utils_file.filedelete(tcProgramUPDDirectory, tcFileName);
|
||||
748:
|
||||
749: -- Creez pe disk scriptul ps pentru download
|
||||
750: -- Descarc in <fisier>.part si redenumesc la final, ca fisierul destinatie
|
||||
751: -- sa apara doar complet si eliberat de curl (altfel citirea lui da ORA-29283/ORA-29291)
|
||||
752: if lcCURLPath is null then
|
||||
753: lcCURLPath := 'C:\Windows\System32\curl.exe';
|
||||
754: end if;
|
||||
755:
|
||||
756: lcScript := '& "' || lcCURLPath || '" -k -o "' || tcDestination ||
|
||||
757: '.part" "' || tcURL || '"' || chr(13) || chr(10) ||
|
||||
758: 'if ($LASTEXITCODE -eq 0) { Move-Item -Force -LiteralPath "' ||
|
||||
759: tcDestination || '.part" -Destination "' || tcDestination ||
|
||||
760: '" } else { Remove-Item -Force -ErrorAction SilentlyContinue -LiteralPath "' ||
|
||||
761: tcDestination || '.part" }';
|
||||
762:
|
||||
763: pack_utils_file.clob2fileX(lcScript, lcDir, lcFileName);
|
||||
764:
|
||||
765: -- Execut scriptul ps
|
||||
766: sys.ExecuteScriptOS(lcPowerShellPath, lcScriptFilePath);
|
||||
767:
|
||||
768: llReturn := True;
|
||||
769:
|
||||
770: -- Astept maxim 10 minute sa se descarce fisierul
|
||||
771: for lnSleep in 1 .. lnTimeOut loop
|
||||
772: exit when PACK_UTILS_FILE.FileExists(tcProgramUPDDirectory,
|
||||
773: tcFileName);
|
||||
774: sys.dbms_lock.sleep(1);
|
||||
775: end loop;
|
||||
776:
|
||||
777: llReturn := PACK_UTILS_FILE.FileExists(tcProgramUPDDirectory,
|
||||
778: tcFileName);
|
||||
779:
|
||||
780: -- Sterg scriptul ps (are nume unic, altfel se aduna in DMPDIR)
|
||||
781: pack_utils_file.filedelete(lcDir, lcFileName);
|
||||
782:
|
||||
783: <<sfarsit>>
|
||||
784:
|
||||
785: return llReturn;
|
||||
786: end DownloadFileOS;
|
||||
```
|
||||
|
||||
Intrarea in functie, dar si toata `URL2Clob` (contractul apelantului), se citeste la PU:333-376; ramura 1 se deschide doar la PU:347 (`IF lcPowerShellDownload = '1' THEN`), citirea fiind PU:341-344.
|
||||
|
||||
### 1.2 Fiecare preconditie care trebuie indeplinita PE SERVERUL ORACLE
|
||||
|
||||
| # | Preconditie | Unde se citeste/consuma | Valoare asteptata | Daca nu e indeplinita |
|
||||
|---|---|---|---|---|
|
||||
| P1 | `SERVER_INFO(NAME='POWERSHELLDOWNLOAD')` | PU:341-347 | `VALUE = '1'` exact | ramura 1 nu se intra deloc → direct `HTTPURITYPE` (PU:367) → ORA-29273/29024. Daca randul lipseste: `NO_DATA_FOUND` neprins, alta eroare. |
|
||||
| P2 | `SERVER_INFO(NAME='POWERSHELLPATH')` | PU:700-703, garda PU:741 | non-NULL, ex. `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe` (SRV:7) | `goto sfarsit` (PU:741-743) → `return FALSE`, FARA nicio urma |
|
||||
| P3 | directorul Oracle `DMPDIR` exista (si, mai jos, e scriibil) | `DirectoryPath('DMPDIR')` PUF:327-343 → PU:734-738 | rand in `all_directories` | `lcScriptFilePath` ramane NULL → `goto sfarsit` (PU:741) → `FALSE`, fara urma. Scriptul `.ps1` nu se poate scrie (PUF `CLOB2FILEX` → `dbms_xslprocessor.clob2file`) → exceptie |
|
||||
| P4 | directorul de destinatie `tcProgramUPDDirectory` (ex. `UPD_ROACONT`, `DMPDIR`) exista | `DirectoryPath(...)` PUF:327-343 → PU:694 | rand in `all_directories` | `DirectoryPath` intoarce NULL → `tcDestination = NULL||tcFileName = tcFileName` (doar numele, fara cale, PU:694) → curl scrie in CWD-ul jobului; `FileExists` pe un director inexistent ridica ORA-29280 (PUF:169 `utl_file.fgetattr`) |
|
||||
| P5 | `sys.ExecuteScriptOS` exista si e executabil din `CONTAFIN_ORACLE` | PU:766, definit in ESO:1-21 | procedura in schema SYS + grant | `ORACLE` nu-l vede / PLS-00201 sau ORA-06550; `ESO:16` in varianta curenta NU mai contine grant-ul (vezi 1.4) |
|
||||
| P6 | contul OS al jobului extern | DBMS_SCHEDULER job `job_type=>'executable'` (ESO:7-13) | contul de rulare al serviciului OracleJobScheduler are drept de executare `powershell.exe`, citire `.ps1`, scriere in DMPDIR si in directorul destinatie, executare `curl.exe`, acces retea+TLS catre `https://roa.romfast.ro` | jobul extern nu porneste / porneste si nu are drepturi → `.ps1` scris pe disc dar fara efect. **Punctul cel mai probabil de esec pe o instanta neconfigurata.** |
|
||||
| P7 | `SERVER_INFO(NAME='POWERSHELLTIMEOUT')` | PU:710-720, folosit PU:771 | numeric, ex. `'30'` (SRV:11) sau lipsa → default `'60'` (PU:696) | daca randul EXISTA dar e gol/NULL: `GREATEST(TO_NUMBER(NULL),5)=NULL` → `for lnSleep in 1..NULL` = 0 iteratii → verificarea de existenta se face imediat → `FALSE` (fals negativ), desi descarcarea ar fi reusit in cateva secunde |
|
||||
| P8 | `SERVER_INFO(NAME='CURLPATH')` (optional) | PU:723-727, folosit PU:752-754 | cale valida la `curl.exe` | NU e preconditie: daca lipseste, codul cade pe `C:\Windows\System32\curl.exe` (PU:753). Daca acel fisier nu exista pe OS, scriptul PowerShell da eroare → fara fisier |
|
||||
|
||||
**Criteriul de succes este exclusiv existenta fisierului** (PU:777-778). Codul de iesire al `curl.exe` este folosit doar in interiorul scriptului `.ps1` ca sa decida redenumirea (PU:758) — Oracle nu il vede niciodata. Preconditiile P6/P7/P8 sunt OS, deci SQL nu le poate confirma direct.
|
||||
|
||||
### 1.3 Unde scrie `.part` si unde il muta
|
||||
|
||||
- `tcDestination` = `DirectoryPath(tcProgramUPDDirectory) || tcFileName` (PU:694-695) — calea FIZICA a directorului Oracle.
|
||||
- curl scrie in `<tcDestination>.part` (`-o`, PU:756-757), apoi `Move-Item -Force` in `<tcDestination>` doar daca `$LASTEXITCODE -eq 0`; altfel `Remove-Item` pe `.part` (PU:758-761).
|
||||
- Daca directorul nu exista (P4) → `tcDestination` fara cale → fisierul ajunge in directorul curent al procesului jobului.
|
||||
- Daca directorul nu e scriibil pentru contul OS (P6): curl da eroare → nu apare `.part` si nu apare nici destinatia → `FALSE`. Pe vechiul cod (fara `.part`) eroarea se manifesta la CITIRE (ORA-29283/29291), pe cel nou se manifesta ca „fisier lipsa“ (vezi sectiunea 3).
|
||||
|
||||
### 1.4 `sys.ExecuteScriptOS` — ce e exact si ce cere
|
||||
|
||||
Definitie (ESO:1-21):
|
||||
|
||||
```plsql
|
||||
1: create or replace procedure ExecuteScriptOS(tcPowerShellPath in varchar2,
|
||||
2: tcScriptPath in varchar2) as
|
||||
3: lcJobName varchar2(500);
|
||||
4: begin
|
||||
5: lcJobName := 'exec_ps_' || SUBSTR(SYS_GUID(), 1, 8);
|
||||
6: DBMS_SCHEDULER.CREATE_JOB(
|
||||
7: job_name => lcJobName,
|
||||
8: job_action => tcPowerShellPath,
|
||||
9: number_of_arguments => 4,
|
||||
10: job_type => 'executable',
|
||||
11: enabled => FALSE
|
||||
12: );
|
||||
13: DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 1, '-ExecutionPolicy');
|
||||
14: DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 2, 'Bypass');
|
||||
15: DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 3, '-File');
|
||||
16: DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 4, tcScriptPath);
|
||||
17: DBMS_SCHEDULER.ENABLE(lcJobName);
|
||||
18: end ExecuteScriptOS;
|
||||
```
|
||||
|
||||
- **Nu** e Java stored proc, **nu** e DBMS_SCHEDULER „program“ cu credential, **nu** e extproc: e un **DBMS_SCHEDULER external executable job** (`job_type => 'executable'`, ESO:10). Comanda lansata pe OS: `<tcPowerShellPath> -ExecutionPolicy Bypass -File <tcScriptPath>` (ESO:13-16).
|
||||
- Proprietar: **SYS** — fisierul e `sys_*`, iar `UpdateVersiune('sys_2025_09_24_03_EXECUTESCRIPTOS','','SYS')` (ESO:24); apelul e calificat `sys.ExecuteScriptOS` (PU:766). S-a schimbat de la 1 argument (2023/05 si 2024/02) la 4 argumente (`-ExecutionPolicy Bypass -File`) in `sys_2025_09_24_03`.
|
||||
- Componente/privilegii cerute:
|
||||
- `EXECUTE` pe `SYS.ExecuteScriptOS` pentru `CONTAFIN_ORACLE`. In ESO:24 (versiunea din 16.09.2026) **nu mai exista linia de grant** — trimite la `grant execute on EXECUTESCRIPTOS to CONTAFIN_ORACLE` din scriptul de instalare `ALTELE\Creare_server_scripturi\sys_2024_02_22_01_COMUN.sql:16`. Daca procedura a fost recreata de ESO (fara grant), grant-ul mai vechi **se pastreaza** (CREATE OR REPLACE nu-l pierde), dar pe o instanta curata trebuie rulat scriptul de instalare. **Neverificat pe ROMFAST.**
|
||||
- Componenta `DBMS_SCHEDULER` si `CREATE JOB` — se executa in SYS (droits de definer), deci nu cere `CREATE EXTERNAL JOB` in `CONTAFIN_ORACLE`.
|
||||
- **Contul OS al jobului extern** — conditionarea reala: procesul `OracleJobScheduler<SID>` (Windows) ruleaza ca un cont de serviciu; acel cont trebuie sa poata executa `powershell.exe`, sa citeasca `.ps1`-ul din DMPDIR, sa scrie in DMPDIR si in directorul destinatie, sa execute `curl.exe` si sa iasa in retea pe `https://roa.romfast.ro`. Fara aceste drepturi, jobul ruleaza si esueaza fara ca Oracle sa vada ceva (codul de iesire nu e citit).
|
||||
- Nu s-a gasit niciun script in `SCRIPTURI_CLAR` / `ALTELE` care sa acorde `CREATE ANY DIRECTORY` sau `READ,WRITE ON DIRECTORY DMPDIR` (grep pe tot `D:\ROA\DATABASE`): DMPDIR vine din instalare — `create or replace directory DMPDIR as 'C:\DMPDIR'` (`ALTELE\Creare_server_scripturi\sys_2012_06_21_01_FIRMA.sql:119`) si `grant all on directory DMPDIR to CONTAFIN_ORACLE` (`SCRIPTURI_CLAR\2013\01\sys_2013_01_23_02.sql:8`). Atentie: in `SCRIPTURI_CLAR\2012\06\sys_2012_06_21_01_FIRMA.sql:388` linia de grant este **comentata** (`rem grant all on directory DMPDIR to CONTAFIN_ORACLE;`) — pe instantele instalate din acel script, grant-ul poate lipsi. **Neverificat pe ROMFAST.**
|
||||
- Jobul NU are `auto_drop` (ESO:6-12) → dupa rulare ramane in `DBA_SCHEDULER_JOBS` ca job one-time, cu nume unic `exec_ps_<8 hex>`. Util pentru a dovedi daca jobul a fost lansat vreodata.
|
||||
|
||||
### 1.5 Normalizarea directorului — de unde vine `lcDir`
|
||||
|
||||
`lcDir` este **hardcodat** `'DMPDIR'` in ambele locuri (PU:336 in URL2Clob, PU:685 in DownloadFileOS); nu vine nici din parametru, nici din `SERVER_INFO`. `PACK_UTILS_FILE.DirectoryPath` (PUF:327-343) il rezolva la calea fizica prin `select DIRECTORY_PATH into lcPath from all_directories where directory_name = UPPER(tcDirectoryName)` si adauga bara (PUF:336). Deci:
|
||||
|
||||
- numele `DMPDIR` este un **obiect Oracle DIRECTORY**, nu o cale;
|
||||
- drepturile semnificative sunt pe obiectul DIRECTORY: `READ` (pentru `FGETATTR`/`FREMOVE`/`READ2CLOB`) si `WRITE` (pentru `CLOBFILE2FILE`/`FREMOVE`) — PUF:169, PUF:185, PUF:302, PUF:321.
|
||||
|
||||
---
|
||||
|
||||
## 2. Ce se logheaza la esecul ramurii 1
|
||||
|
||||
**Raspuns explicit: in ramura 1 nu se logheaza absolut nimic.** `DownloadFileOS` nu are `UPD_LOG`, nu are `DBMS_OUTPUT`, nu are `RAISE`; singurul rezultat al esecului este `return FALSE` (PU:693, PU:777-785). Nu exista nici macar urma ca a fost incercata.
|
||||
|
||||
Traseul erorii, in continuare:
|
||||
|
||||
1. `URL2Clob` cade pe `HTTPURITYPE.createuri(tcURL).getclob()` (PU:367) → ORA-29273 (peste `https` fara wallet → ORA-29024).
|
||||
2. Handler-ul `URL2Clob` (PU:369-375) sterge doar fisierul temporar si face `RAISE`; **nu logheaza**.
|
||||
3. `UPDLOG` nu este apelat pe acest drum inainte de `URL2Clob` — singurul `UPDLOG` din pasul listelor este DUPĂ ambele descarcari, la PUPD:427, deci nu se executa niciodata daca `URL2Clob` a aruncat.
|
||||
|
||||
Locul exact al apelului (PUPD:416-427):
|
||||
|
||||
```plsql
|
||||
418: lcListaPrograme := PACK_UTILS.URL2Clob(lcURLAppXml);
|
||||
...
|
||||
423: lcListaRoastart := PACK_UTILS.URL2Clob(lcURLRoastartXml);
|
||||
...
|
||||
427: UPDLOG(lcText, ldDataOraS);
|
||||
```
|
||||
|
||||
Apelurile 418/423 sunt in corpul procedurii `UpdateApp` (inceput la PUPD:309), **in afara** blocului `begin/exception` de la PUPD:434-520 (care prinde doar bucla de scanare a programelor, PUPD:514-519). `UpdateApp` este `pragma autonomous_transaction` (PUPD:310) si nu are handler propriu → exceptia iese din `UpdateApp`, iar `UpdateROA` **nu are nici el handler** (apel la PUPD:275; `UpdateROA` se termina la PUPD:303) → nu se ajunge nici la `EmailLog` de la PUPD:300-302.
|
||||
|
||||
**Unde s-ar fi putut loga:**
|
||||
- PUPD:427 (primul `UPDLOG`) — dar e dupa `URL2Clob`;
|
||||
- un `begin/exception` in jurul lui PUPD:418/423 (modelul exista la buletinul informativ, PUPD:729-737, care logheaza `'ERR: ' || lcURL... || sqlcode || sqlerrm`);
|
||||
- in `DownloadFileOS` sau in handler-ul `URL2Clob` (PU:369-375).
|
||||
|
||||
**Ce urme ramane totusi:**
|
||||
- `UPD_ISTORIC.STARE` = `UPDATE_STARE_APLICATII`, scris la PUPD:274 inainte de `UpdateApp` (`UpdateIstoric`, PUPD:2408-2436) → stare lasata „blocat la aplicatii“.
|
||||
- Un rand de eroare in jobul DBMS_SCHEDULER `UPDATEROA_JOB` (creat la PUPD:178-186, `job_action => 'PACK_UPDATE.UpdateROA'`) — deci `DBA_SCHEDULER_JOB_LOG` / `_RUN_DETAILS.ADDITIONAL_INFO`, nu `UPD_LOG`.
|
||||
- **Diferenta importanta de diagnostic:** daca esecul e pe buletinul informativ (PUPD:730), `UPD_LOG` **contine** un rand `'ERR: <url> ORA-29273 ... ORA-29024'` (PUPD:732-736). Daca `UPD_LOG` nu are niciun rand `ERR:` pentru rularea respectiva, esecul e la PUPD:418 sau 423.
|
||||
|
||||
---
|
||||
|
||||
## 3. Ce a schimbat scriptul de azi fata de versiunea anterioara
|
||||
|
||||
Versiunea precedenta a lui PACK_UTILS: **PU_old** (`co_2026_01_14_01_PACK_UTILS.sql`, 14.01.2026). Urmatoarea in istoricul de fisiere: `2025/09/co_2025_09_24_01_COMUN_PACK_UTILS.sql` (introduce DownloadFileOS + POWERSHELLDOWNLOAD).
|
||||
|
||||
### 3.1 Diff conceptual (numai `DownloadFileOS`)
|
||||
|
||||
| Element | PU_old | PU (azi) |
|
||||
|---|---|---|
|
||||
| numele scriptului `.ps1` | `varchar2(30) := 'download_file.ps1'` (PU_old:680) — FIX | `varchar2(60) := 'download_' || to_char(systimestamp,'YYYYMMDDHH24MISSFF') || '.ps1'` (PU:686-688) — unic |
|
||||
| sterge fisierul destinatie inainte | nu | `pack_utils_file.filedelete(tcProgramUPDDirectory, tcFileName)` (PU:747) |
|
||||
| scrie in | direct `<dest>` (PU_old:743-747) | `<dest>.part`, apoi `Move-Item -Force` (PU:756-761) |
|
||||
| rezultat partial | fisier partial vizibil (de aceea bug-ul ORA-29283/29291, PU:750-751) | fisierul final apare doar dupa `Move-Item` reusit |
|
||||
| sterge `.ps1` la final | nu | `pack_utils_file.filedelete(lcDir, lcFileName)` (PU:781) |
|
||||
| preconditii de intrare | identice (POWERSHELLDOWNLOAD / POWERSSHELLPATH / DMPDIR / CURLPATH / TIMEOUT) | identice, neschimbate |
|
||||
| `URL2Clob` / `URL2Blob` | — | neschimbate logic (se schimba doar diacriticele din comentarii) |
|
||||
|
||||
### 3.2 Verdict: **NU** — modificarea de azi nu a „rupt“ ramura 1 prin preconditii
|
||||
|
||||
Cu citat: garda de intrare din `URL2Clob` este neschimbata (`IF lcPowerShellDownload = '1' THEN` PU:347, identic PU_old:292), garda de iesire din `DownloadFileOS` este neschimbata (`if lcPowerShellPath is null or lcScriptFilePath is null then goto sfarsit;` PU:741-743, identic PU_old:733-735), aceleasi nume de `SERVER_INFO` (PU:703/714/727 vs PU_old:695/706/719) si acelasi `lcDir := 'DMPDIR'` (PU:685 vs PU_old:679). **Niciun director nou, nicio preconditie in minus.**
|
||||
|
||||
### 3.3 Ce s-a schimbat, totusi, in comportamentul de esec (relevant pentru simptom)
|
||||
|
||||
Modificarea poate fi **neverificat** cauza incidentului, dar nu prin preconditii, ci prin **felul in care se manifesta un esec deja existent**:
|
||||
|
||||
- Inainte: curl scria direct in `<dest>`; daca fisierul era tinut deschis de alt proces, citirea dadea **ORA-29283/ORA-29291** (exact motivul notat in comentariul de azi, PU:750-751).
|
||||
- Acum: curl scrie in `<dest>.part`, iar `<dest>` apare **doar daca `Move-Item` reuseste** (PU:758). Un `Move-Item` care esueaza (fisier destinatie blocat, drepturi, antivirus) este **inghitit tacit** — scriptul nu scrie nimic in log, iar Oracle testeaza doar existenta fisierului (PU:777-778) → `FALSE` → fallback `HTTPURITYPE` → **ORA-29273/ORA-29024**.
|
||||
- Deci: daca pe ROMFAST conditia de baza era deja marginala, eroarea raportata acum **se schimba** din ORA-29291 in ORA-29024, fara ca vreo preconditie sa fi fost scoasa.
|
||||
- A doua schimbare de azi, in `PACK_UTILS_FILE` (**PUF**), merge in acelasi sens: `FileDelete` a devenit best-effort (`when others then null`, PUF:187-192), deci nu mai poate masca eroarea originala cu ORA-29291. Nici aceasta nu introduce preconditii.
|
||||
|
||||
Concluzie punct 3: **NU** (nu a rupt-o prin preconditii) + **neverificat** daca a contribuit la simptomul de azi (ar cere dovezi OS: exista `.part` sau `.ps1` ramase in DMPDIR?).
|
||||
|
||||
---
|
||||
|
||||
## 4. Interogari read-only de rulat pe ROMFAST (scrise, NU rulate)
|
||||
|
||||
Toate sunt `SELECT`. Pentru Oracle 10.2 compatibil (fara `FETCH FIRST`).
|
||||
|
||||
**Q1 — configurarea, cheia de departajare a ipotezelor.**
|
||||
```sql
|
||||
SELECT name, value FROM SERVER_INFO
|
||||
WHERE UPPER(name) IN ('POWERSHELLDOWNLOAD','POWERSHELLPATH','POWERSHELLTIMEOUT',
|
||||
'CURLPATH','DMPDIR','ROAUPDATEPATH','UPDATEPREREQ')
|
||||
ORDER BY name;
|
||||
```
|
||||
- `POWERSHELLDOWNLOAD` ∈ {`'0'`, `''`, NULL} → **confirma** ca ramura 1 nu se intra (cauza = P1) si ca ORA-29024 e garantat; `='1'` → **infirma**, ramura 1 se incearca.
|
||||
- `POWERSHELLPATH` NULL/`''` → **confirma** ca `DownloadFileOS` iese imediat cu `FALSE` (P2) — suspectul principal; non-NULL → infirma.
|
||||
- `POWERSHELLTIMEOUT` prezent dar gol → **confirma** falsul negativ din P7; absent → default 60s (ok).
|
||||
- `UPDATEPREREQ='1'` → explica de ce DMPDIR/update dirs **nu** mai sunt re-verificate la fiecare update.
|
||||
|
||||
**Q2 — directorul Oracle (P3/P4).**
|
||||
```sql
|
||||
SELECT directory_name, directory_path FROM all_directories
|
||||
WHERE directory_name = 'DMPDIR' OR directory_name LIKE 'UPD_%' ORDER BY 1;
|
||||
```
|
||||
Lipsa lui `DMPDIR` → **confirma** ca ramura 1 e imposibila (`lcScriptFilePath` NULL); lipsa unui `UPD_<PROGRAM>` → alta eroare (ORA-29280), nu ORA-29024.
|
||||
|
||||
**Q3 — drepturile pe DMPDIR si pe SYS.ExecuteScriptOS (P5).**
|
||||
```sql
|
||||
SELECT grantee, privilege FROM all_tab_privs
|
||||
WHERE table_name = 'DMPDIR' AND privilege IN ('READ','WRITE') ORDER BY 1;
|
||||
SELECT owner, object_name, status FROM all_objects
|
||||
WHERE object_name = 'EXECUTESCRIPTOS' AND object_type = 'PROCEDURE';
|
||||
SELECT grantee FROM all_tab_privs
|
||||
WHERE table_name = 'EXECUTESCRIPTOS' AND privilege = 'EXECUTE';
|
||||
```
|
||||
Lipsa `READ`/`WRITE` pentru `CONTAFIN_ORACLE`/`PUBLIC` → confirma ca fisierul nu se poate scrie/citi; `STATUS='INVALID'` sau lipsa grant → confirma P5.
|
||||
|
||||
**Q4 — urma din UPD_LOG / UPD_ISTORIC (punctul 2).**
|
||||
```sql
|
||||
SELECT secventa, TO_CHAR(dataora,'DD.MM.YYYY HH24:MI:SS') d, SUBSTR(explizatie,1,300) t
|
||||
FROM UPD_LOG WHERE dataora > SYSDATE - 7 ORDER BY secventa;
|
||||
SELECT TO_CHAR(dataora_start,'DD.MM.YYYY HH24:MI:SS') s, stare, id_util
|
||||
FROM UPD_ISTORIC WHERE dataora_start > SYSDATE - 7 ORDER BY dataora_start;
|
||||
```
|
||||
Prezenta unui rand `ERR:` cu `ORA-29273`/`ORA-29024` → esecul e pe buletinul informativ (PUPD:730). **Absenta** oricarui `ERR:` + `STARE` = starea „aplicatii“ → confirma esecul la PUPD:418/423 (nelogat).
|
||||
|
||||
**Q5 — joburile externe si jobul de update (P6) — dovedeste daca PowerShell a fost lansat vreodata.**
|
||||
```sql
|
||||
SELECT job_name, TO_CHAR(log_date,'DD.MM.YYYY HH24:MI:SS') d, status, error#, SUBSTR(additional_info,1,500) info
|
||||
FROM (SELECT * FROM dba_scheduler_job_log ORDER BY log_date DESC)
|
||||
WHERE (job_name LIKE 'exec_ps_%' OR job_name = 'UPDATEROA_JOB') AND ROWNUM <= 50;
|
||||
SELECT job_name, enabled, state, TO_CHAR(last_start_date,'DD.MM.YYYY HH24:MI:SS') last_start
|
||||
FROM dba_scheduler_jobs WHERE job_name LIKE 'exec_ps_%' OR job_name = 'UPDATEROA_JOB';
|
||||
```
|
||||
Existenta joburilor `exec_ps_*` cu `status='SUCCEEDED'` → PowerShell a rulat cel putin o data (**infirma** „instanta neconfigurata“); zero joburi `exec_ps_*` → **confirma** ca `sys.ExecuteScriptOS` nu s-a executat niciodata; `UPDATEROA_JOB` esuat cu ORA-29273/29024 in `additional_info` → confirma locul erorii.
|
||||
|
||||
**Q6 — URL-urile reale (ca sa nu banuim degeaba https-ul).**
|
||||
```sql
|
||||
SELECT varname, varvalue FROM OPTIUNI WHERE varname LIKE 'UPD_URL%';
|
||||
SELECT TO_NUMBER(detalii) customerid FROM SYS.AUTH_DETALII;
|
||||
```
|
||||
`UPD_URL_APP` fara `https://` sau NULL → s-ar lua default-ul http (PUPD:379/381), unde `HTTPURITYPE` ar putea functiona — deci **infirma** ipoteza „https fara wallet“ si muta cauza in alta parte. `https://roa.romfast.ro` → **confirma** ca esecul ramurii 1 duce obligatoriu in ORA-29024.
|
||||
|
||||
**Q7 — identitatea instantei (sa nu raportam de pe alt server).**
|
||||
```sql
|
||||
SELECT SYS_CONTEXT('USERENV','SERVER_HOST') host, SYS_CONTEXT('USERENV','DB_NAME') db,
|
||||
SYS_CONTEXT('USERENV','INSTANCE_NAME') inst FROM dual;
|
||||
```
|
||||
|
||||
### Verificari OS (NU se pot face prin SQL — marcat neverificat pana se fac)
|
||||
|
||||
In directorul fizic al `DMPDIR` (Q2/Q1), pe ROMFAST:
|
||||
- exista fisiere `url2clob_*.tmp.part` sau `url2app_*.part` rămase → curl **a scris**, dar `Move-Item` a esuat (blocare/drepturi) → confirma scenariul din 3.3;
|
||||
- exista fisiere `download_*.ps1` acumulate → scriptul se scrie, dar jobul extern nu ruleaza/vrea sa-l ruleze → confirma P5/P6;
|
||||
- nu exista nici `.part`, nici `.ps1` → `DownloadFileOS` nu a ajuns la scriere deloc → confirma P1/P2/P3;
|
||||
- `C:\Windows\System32\curl.exe` exista si depinde daca `CURLPATH` e setat (PU:752-754).
|
||||
- in `DBA_SCHEDULER_JOB_RUN_DETAILS.ADDITIONAL_INFO` se vede codul de iesire OS al jobului extern PowerShell (singurul loc unde ajunge `$LASTEXITCODE`-ul real al scenariului).
|
||||
|
||||
---
|
||||
|
||||
## 5. Nefacut / deschis
|
||||
|
||||
- Nu s-a rulat nicio interogare si nicio comanda pe ROMFAST/10.0.20.36 (interzis de sarcina): **cine a produs incidentul de azi ramane neverificat pana la Q1-Q7 + verificarile OS.**
|
||||
- Nu am putut confirma daca `POWERSHELLPATH` / `CURLPATH` / grant-urile pe `DMPDIR` sunt configurate pe ROMFAST — nu apar in niciun script de migrare (verificat prin grep pe `D:\ROA\DATABASE`), deci sunt setari de instalare/OS.
|
||||
- Nu s-a facut write-back, nu s-a modificat niciun fisier (in afara de acest raport), nu s-a pornit niciun proces.
|
||||
- Stare periculoasa: **niciuna**.
|
||||
|
||||
GATA src
|
||||
Reference in New Issue
Block a user