خطای 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 تنها دسترسی مدیریتی شما را حمل میکند. تغییر در مفسر سیستم دقیقاً همان نوع ویرایشی است که میتواند آن دسترسی را در میانه راه از میان بردارد.
اگر خرابی یک ماژول گمشده برای ابزار سیستمی باشد، اصلاح یک عملیات بسته از طریق جریان کاری پشتیبانیشده است. اگر خرابی تعارض نسخه در پروژه خودتان باشد، اصلاح یک محیط است. انتخاب میان این دو تمام تصمیم است، و آن را این تعیین میکند که کدام برنامه ردیابی را چاپ کرده است.