خطأ Python في OpenVPN 3: أصلح الأداة، لا Python النظام
يذكر التتبّع المفسّر الذي شغّل الواجهة، لا الخدمة التي تملك النفق. قارن بينهما قبل أن تعيد توجيه أي شيء على مستوى النظام.
يظهر التتبّع عند بدء أمر إدارة VPN، فتكون أول ردة فعل هي تثبيت نسخة Python أخرى أو توجيه الافتراضي في النظام إلى مكان آخر. تنم هذه الرّدة عن خلط بين بيئتي تشغيل لا علاقة لإحداهما بالأخرى. إحداهما تنتمي إلى نظام التشغيل وأدواته المحزومة؛ والأخرى تنتمي إلى أي مشروع تبنيه. وتغيير الأولى لإرضاء الثانية هو الطريق الذي يفقد به حاسوب مكتبي يعمل مدير الحزم فيه.
المقارنة التي تستحق أن تُجرى هي بين المكوّن الذي فشل فعلاً وبيئة التشغيل التي يحق لك تغييرها. وهما ليسا الشيء نفسه إلا نادراً.
سؤالان عن Python يبدوان سؤالاً واحداً
السؤال الأول هو: أي مفسّر شغّل البرنامج الذي طبع التتبّع؟ والسؤال الثاني هو: أي مفسّر ينبغي أن يستخدمه مشروعي؟ يبدوان متطابقين في الطرفية لأن الإجابة عن كليهما تكون بكتابة python3، ولهما مالك مختلف ومسار ترقية مختلف ونطاق تأثير مختلف.
أداة النظام مرتبطة بالمفسّر الذي شُحن مع توزيعتها، وبالوحدات المترجمة التي بُنيت مقابل واجهة ABI لذلك المفسّر. أما المشروع فيرتبط بأي بيئة تنشئها له. نقل الافتراضي في النظام يغيّر الأول لكل أداة على الجهاز دفعة واحدة؛ وإنشاء بيئة يغيّر الثاني لمجلد واحد.
واحدة فقط من تلك الإجراءات قابلة للعكس في دقيقة واحدة. وهي ليست الأولى.
أي مكوّن أنتج الخطأ
اقرأ السطر الأول من التتبّع والملف التنفيذي الذي أنتجه قبل أن تقرأ أي شيء آخر. واجهة سطر الأوامر والخدمة ذات الامتيازات وروابط API قطع منفصلة، وليست كلها 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
يسمّي السطر الأول من السكربت المفسّر الذي سيستخدمه، وهو المفسّر الذي جاء منه التتبّع. ويخبرك استعلام الحزمة بمن يملك الملف، وهذا ما يحدّد من يحق له تغييره. أما حالة الخدمة فتجيب عن سؤال مختلف تماماً: هل الخلفية ذات الامتيازات التي تنشئ الجلسات فعلاً تعمل.
رفض تنشيط D-Bus وخطأ استيراد وحدة، وبيانات اعتماد مرفوضة ثلاث مراحل مختلفة. يحدث خطأ الاستيراد قبل وجود أي جلسة، فلا مقدار من ضبط VPN يصلحه، ولن تصلحه خدمة تعمل. وتصنيف الرسالة في واحدة من تلك المراحل الثلاث هو الخطوة الأولى الحقيقية.
ما يمكن لبيئة المشروع إصلاحه وما لا يمكن
تحل بيئة المشروع مشكلة مشروع: إصدارات المكتبات الدقيقة التي يحتاجها تطبيق واحد، معزولة عن كل شيء آخر. هذا مفيد حقاً، وهو الأداة الصحيحة حين يكون البرنامج الفاشل سكربتاً تملكه.
uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'
يعرض الأمر الثاني أي نسخة من الروابط يستطيع مفسّر معيّن رؤيتها، وهي أسرع طريقة للتمييز بين حزمة مفقودة وحزمة محجوبة. شغّله بالمفسّر الذي يستخدمه السكربت الفاشل، لا بمفسّر آخر يعمل بمحض الصدفة.
ما لا تستطيع بيئة المشروع فعله هو إصلاح واجهة محزومة من التوزيعة. فقد بُنيت تبعيات ذلك البرنامج للمفسّر الذي اختاره مدير الحزم، وتشغيله داخل بيئة مشروعك إما يفشل وإما ينتج خليطاً لا يدعمه أحد. وحقن مسارات فيه بمتغيّر بيئة هو الخطأ نفسه بخطوات إضافية: غيّرت ما تحمّله الأداة دون تغيير ما اختُبرت مقابله. وتبدو هذه المقايضة كإصلاح لمدة تساوي بالضبط الوقت اللازم للوصول إلى الاستيراد التالي.
لماذا يُعدّ إعادة توجيه مفسّر النظام فخاً
تغيير المفسّر الافتراضي جاذب لأنه يبدو وكأنه يصلح التتبّع بأمر واحد. وهو أيضاً يكسر الافتراض الذي بُنيت عليه كل أداة Python محزومة على المضيف، وتظهر الأعطال لاحقاً وفي أماكن لا علاقة لها.
صُمّمت آليات اختيار البدائل للتبديل بين تطبيقات متكافئة، لا لتثبيت لغة أحدث تحت وحدات مترجمة أقدم. فالامتدادات المترجمة تُبنى لواجهة ABI محددة، لذا قد تفشل وحدة استُوردت أمس في التحميل اليوم دون إزالة أي حزمة.
هناك أيضاً فخّ تسمية في النصيحة التي يعثر عليها الناس. فلا معنى واحداً شاملاً لأمر python غير المرقّم عبر التوزيعات والبيئات، والتعامل معه كمرادف ثابت لإصدار رئيسي معيّن ينتج إصلاحات تعمل فقط على الجهاز الذي كُتبت عليه. اقرأ سياسة النظام الذي أمامك لا سياسة التدوينة.
اختبارا قبول منفصلان
يجب أن يكون اختباران في النهاية، ونجاح أحدهما لا يقول شيئاً عن الآخر. الأول أن أمر العميل المدعوم يعمل بالمفسّر الذي حُزم له. والثاني أن الخدمة ذات الامتيازات تنشئ جلسة وأن النفق يحمل حركة المرور.
openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0
احتفظ بطريق مستقل إلى الجهاز أثناء عملك، خصوصاً إذا كان VPN يحمل وصولك الإداري الوحيد. فتغيير مفسّر النظام هو بالضبط نوع التعديل الذي قد يزيل ذلك الوصول في منتصف الطريق.
إذا كان العطل وحدة مفقودة لأداة نظام، فالتصحيح عملية حزمة عبر سير العمل المدعوم. وإذا كان العطل تعارض إصدارات في مشروعك، فالتصحيح بيئة. والاختيار بين هذين هو القرار كله، ويحدّده البرنامج الذي طبع التتبّع.