Python-fejl i OpenVPN 3: ret værktøjet, ikke systemets Python
En traceback angiver den fortolker, der kørte en frontend, ikke den tjeneste, der ejer tunnelen. Sammenlign de to, før du omdirigerer noget systembredt.
En traceback vises, når en VPN-administrationskommando starter, og den første indskydelse er at installere en anden Python eller pege systemets standard et andet sted hen. Den indskydelse blander to runtime-miljøer, der ikke har noget med hinanden at gøre. Det ene tilhører styresystemet og dets pakkede værktøjer; det andet tilhører det projekt, du er ved at bygge. At ændre det første for at tilfredsstille det andet er måden, hvorpå en fungerende computer mister sin pakkehåndtering.
Den sammenligning, der er værd at lave, er mellem den komponent, der faktisk fejlede, og det runtime, du har ret til at ændre. De er næsten aldrig det samme objekt.
To Python-spørgsmål, der ligner ét
Det første spørgsmål er: hvilken fortolker kørte det program, der udskrev tracebacken? Det andet er: hvilken fortolker bør mit projekt bruge? De ser identiske ud i en terminal, fordi begge besvares ved at skrive python3, og de har forskellige ejere, forskellige opgraderingsveje og forskellige skadeområder.
Et systemværktøj er bundet til den fortolker, som dets distribution blev leveret med, sammen med de kompilerede moduler, der er bygget mod den fortolkers ABI. Et projekt er bundet til det miljø, du opretter til det. Flytning af systemets standard ændrer det første for alle værktøjer på maskinen på én gang; oprettelse af et miljø ændrer det andet for én mappe.
Kun én af de handlinger kan rulles tilbage på et minut. Det er ikke den første.
Hvilken komponent frembragte fejlen
Læs den første linje i tracebacken og den kørbare fil, der frembragte den, før du læser noget andet. Frontenden på kommandolinjen, den privilegerede tjeneste og API-bindingerne er separate dele, og kun nogle af dem er overhovedet Python.
command -v openvpn3
head -n 1 "$(command -v openvpn3)"
dpkg -S "$(command -v openvpn3)" 2>/dev/null
systemctl status openvpn3-service-client --no-pager
Den første linje i et script angiver den fortolker, det vil bruge, og det er den fortolker, tracebacken kom fra. Pakkeforespørgslen fortæller, hvem der ejer filen, hvilket afgør, hvem der må ændre den. Tjenestens status besvarer et helt andet spørgsmål: om den privilegerede backend, der faktisk etablerer sessioner, kører.
En modulimportfejl, en afvisning af D-Bus-aktivering og en afvist legitimationsoplysning er tre forskellige stadier. En importfejl opstår, før nogen session findes, så ingen VPN-konfiguration kan rette den, og en fungerende tjeneste retter den heller ikke. At sortere meddelelsen i et af de tre stadier er det egentlige første skridt.
Hvad et projektmiljø kan og ikke kan rette
Et projektmiljø løser et projektproblem: de præcise biblioteksversioner, som én applikation skal bruge, isoleret fra alt andet. Det er virkelig nyttigt, og det er det rigtige værktøj, når det fejlende program er et script, du selv ejer.
uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'
Den anden kommando viser, hvilken kopi af bindingerne en given fortolker kan se, hvilket er den hurtigste måde at skelne en manglende pakke fra en tilsløret. Kør den med den fortolker, det fejlende script bruger, ikke med en anden, der tilfældigvis virker.
Det, et projektmiljø ikke kan, er at reparere en frontend, der er pakket af distributionen. Det programs afhængigheder blev bygget til den fortolker, pakkehåndteringen valgte, og at køre det inde i dit projekts miljø fejler enten eller giver en blanding, som ingen understøtter. At injicere stier i det med en miljøvariabel er den samme fejl med ekstra trin: du har ændret, hvad værktøjet indlæser, uden at ændre, hvad det blev testet imod. Den handel ligner en rettelse præcis så længe, som det tager at ramme den næste import.
Hvorfor det er en fælde at pege systemfortolkeren om
Det er tillokkende at ændre standardfortolkeren, fordi det ser ud til at rette tracebacken med én kommando. Det bryder også den antagelse, som hvert pakket Python-værktøj på værten er bygget på, og fejlene dukker op senere og på ikke-relaterede steder.
Mekanismerne til alternativvalg blev designet til at skifte mellem ækvivalente implementeringer, ikke til at installere et nyere sprog under ældre kompilerede moduler. Kompilerede udvidelser bygges til en bestemt ABI, så et modul, der blev importeret i går, kan fejle med at indlæse i dag, uden at en enkelt pakke er fjernet.
Der er også en navnefælde i det råd, folk finder. Kommandoen python uden version har ikke én universel betydning på tværs af distributioner og miljøer, og at behandle den som et fast synonym for en bestemt hovedversion giver rettelser, der kun virker på den maskine, hvor de blev skrevet. Læs politikken for det system, du har foran dig, i stedet for den i blogindlægget.
Særskilte accepttests
Der skal være to tests til sidst, og at bestå den ene siger intet om den anden. Den første er, at den understøttede klientkommando virker med den fortolker, den blev pakket til. Den anden er, at den privilegerede tjeneste etablerer en session, og at tunnelen bærer trafik.
openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0
Hold en uafhængig vej ind på maskinen, mens du arbejder, især hvis VPN'en bærer din eneste administrative adgang. En ændring af en systemfortolker er netop den slags redigering, der kan fjerne den adgang midtvejs.
Hvis fejlen er et manglende modul til et systemværktøj, er rettelsen en pakkehandling gennem den understøttede arbejdsgang. Hvis fejlen er en versionskonflikt i dit eget projekt, er rettelsen et miljø. Valget mellem de to er hele beslutningen, og den afgøres af, hvilket program der udskrev tracebacken.