Eroare Python în OpenVPN 3: repară instrumentul, nu Python-ul sistemului
Un traceback numește interpretorul care a rulat un frontend, nu serviciul care deține tunelul. Compară cele două înainte de a redirecta ceva la nivel de sistem.
Un traceback apare când pornește o comandă de administrare a VPN-ului, iar primul instinct fuge spre instalarea altui Python sau spre îndreptarea valorii implicite a sistemului în altă parte. Acel instinct amestecă două runtime-uri care nu au nimic de-a face unul cu altul. Unul aparține sistemului de operare și instrumentelor sale împachetate; celălalt aparține oricărui proiect pe care îl construiești. A-l schimba pe primul pentru a-l satisface pe al doilea este felul în care un desktop funcțional își pierde managerul de pachete.
Comparația care merită făcută este între componenta care a eșuat de fapt și runtime-ul pe care ai dreptul să îl schimbi. Aproape niciodată nu sunt același obiect.
Două întrebări despre Python care par una singură
Prima întrebare este: ce interpretor a rulat programul care a tipărit traceback-ul? A doua este: ce interpretor ar trebui să folosească proiectul meu? Într-un terminal par identice, pentru că la ambele se răspunde tastând python3, și au proprietari diferiți, căi de actualizare diferite și raze de impact diferite.
Un instrument de sistem este legat de interpretorul cu care a fost livrat de distribuție, împreună cu modulele compilate construite pentru ABI-ul acelui interpretor. Un proiect este legat de orice mediu pe care îl creezi pentru el. Mutarea valorii implicite a sistemului îl schimbă pe primul pentru fiecare instrument de pe mașină deodată; crearea unui mediu îl schimbă pe al doilea pentru un singur director.
Doar una dintre aceste acțiuni este reversibilă într-un minut. Nu este prima.
Ce componentă a produs eroarea
Citește prima linie a traceback-ului și executabilul care l-a produs înainte de a citi orice altceva. Frontend-ul din linia de comandă, serviciul privilegiat și legăturile API sunt piese separate, și doar unele dintre ele sunt Python.
command -v openvpn3
head -n 1 "$(command -v openvpn3)"
dpkg -S "$(command -v openvpn3)" 2>/dev/null
systemctl status openvpn3-service-client --no-pagerPrima linie a unui script numește interpretorul pe care îl va folosi, și din acel interpretor a venit traceback-ul. Interogarea pachetului îți spune cui aparține fișierul, ceea ce decide cine are voie să îl modifice. Starea serviciului răspunde la o cu totul altă întrebare: dacă rulează backend-ul privilegiat care chiar deschide sesiuni.
O eroare de import a unui modul, o refuzare a activării D-Bus și o acreditare respinsă sunt trei etape diferite. O eroare de import are loc înainte să existe vreo sesiune, așa că nicio cantitate de configurare VPN nu o repară, iar un serviciu funcțional nici el nu o repară. Încadrarea mesajului într-una dintre aceste trei etape este adevăratul prim pas.
Ce poate și ce nu poate repara un mediu de proiect
Un mediu de proiect rezolvă o problemă de proiect: versiunile exacte ale bibliotecilor de care are nevoie o aplicație, izolate de tot restul. Este cu adevărat util și este instrumentul potrivit când programul care eșuează este un script al tău.
uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'A doua comandă arată ce copie a legăturilor vede un anumit interpretor, iar aceasta este cea mai rapidă cale de a distinge un pachet lipsă de un pachet umbrit. Ruleaz-o cu interpretorul folosit de scriptul care eșuează, nu cu altul care funcționează din întâmplare.
Ce nu poate face un mediu de proiect este să repare un frontend împachetat de distribuție. Dependențele acelui program au fost construite pentru interpretorul ales de managerul de pachete, iar rularea lui în mediul proiectului tău fie eșuează, fie produce un amestec pe care nimeni nu îl susține. Injectarea de căi în el cu o variabilă de mediu este aceeași greșeală cu pași în plus: ai schimbat ce încarcă instrumentul fără a schimba față de ce a fost testat. Acea schimbare arată ca o reparație exact atât timp cât durează până la următorul import.
De ce redirecționarea interpretorului de sistem este o capcană
Schimbarea interpretorului implicit este atrăgătoare pentru că pare să repare traceback-ul cu o singură comandă. Ea încalcă și presupunerea pe care a fost construit fiecare instrument Python împachetat de pe gazdă, iar eșecurile apar mai târziu și în locuri nelegate.
Mecanismele de selecție a alternativelor au fost concepute pentru a comuta între implementări echivalente, nu pentru a instala un limbaj mai nou sub module compilate mai vechi. Extensiile compilate sunt construite pentru un ABI anume, așa că un modul care se importa ieri poate azi să nu se mai încarce fără ca vreun pachet să fi fost eliminat.
Există și o capcană de denumire în sfaturile pe care le găsesc oamenii. Comanda python fără versiune nu are un sens universal între distribuții și medii, iar tratarea ei ca sinonim fix pentru o anumită versiune majoră produce reparații care funcționează doar pe mașina unde au fost scrise. Citește politica sistemului din fața ta, nu pe cea din articolul de blog.
Teste de acceptare separate
La final se cuvin două teste, iar trecerea unuia nu spune nimic despre celălalt. Primul este că comanda de client suportată funcționează cu interpretorul pentru care a fost împachetată. Al doilea este că serviciul privilegiat deschide o sesiune și tunelul transportă trafic.
openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0Păstrează o cale independentă către mașină în timp ce lucrezi, mai ales dacă VPN-ul transportă singurul tău acces administrativ. O modificare a unui interpretor de sistem este exact genul de editare care poate lua acel acces la jumătatea drumului.
Dacă eșecul este un modul lipsă pentru un instrument de sistem, corecția este o operație de pachet prin fluxul de lucru suportat. Dacă eșecul este un conflict de versiuni în propriul tău proiect, corecția este un mediu. Alegerea între cele două este întreaga decizie, și ea este decisă de ce program a tipărit traceback-ul.