Files
roafacturare/docs/handoff_update_romfast.md
2026-09-16 23:35:55 +03:00

20 KiB

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 &:

$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.