Traceback xuất hiện khi một lệnh quản lý VPN khởi chạy, và phản xạ đầu tiên là chạy đi cài một Python khác hoặc trỏ giá trị mặc định của hệ thống sang nơi khác. Phản xạ đó trộn hai runtime không liên quan gì đến nhau. Một cái thuộc về hệ điều hành và các công cụ đã đóng gói của nó; cái kia thuộc về bất kỳ dự án nào bạn đang xây. Thay đổi cái đầu để thỏa mãn cái sau chính là cách một desktop đang chạy mất đi trình quản lý gói của nó.

Phép so sánh đáng làm là giữa thành phần thực sự hỏng và runtime mà bạn có quyền thay đổi. Chúng gần như không bao giờ là cùng một đối tượng.

Hai câu hỏi về Python trông như một

Câu hỏi thứ nhất: trình thông dịch nào đã chạy chương trình đã in ra traceback? Câu thứ hai: dự án của tôi nên dùng trình thông dịch nào? Trong terminal chúng trông giống hệt nhau, vì cả hai đều được trả lời bằng cách gõ python3, và chúng có chủ sở hữu khác nhau, đường nâng cấp khác nhau và bán kính ảnh hưởng khác nhau.

Một công cụ hệ thống bị ràng buộc vào trình thông dịch mà bản phân phối đã gửi kèm, cùng với các mô-đun đã biên dịch được dựng cho ABI của trình thông dịch đó. Một dự án bị ràng buộc vào bất kỳ môi trường nào bạn tạo cho nó. Dịch chuyển mặc định của hệ thống thay đổi cái đầu cho mọi công cụ trên máy cùng lúc; tạo một môi trường thay đổi cái sau cho một thư mục duy nhất.

Chỉ một trong những hành động đó là có thể hoàn tác trong một phút. Đó không phải là cái đầu.

Thành phần nào đã tạo ra lỗi

Đọc dòng đầu tiên của traceback và tệp thực thi đã tạo ra nó trước khi đọc bất cứ điều gì khác. Frontend dòng lệnh, dịch vụ đặc quyền và các liên kết API là những mảnh riêng biệt, và chỉ một số trong đó là 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òng đầu tiên của một script nêu tên trình thông dịch mà nó sẽ dùng, và traceback đến từ chính trình thông dịch đó. Truy vấn gói cho bạn biết ai sở hữu tệp, điều này quyết định ai được phép thay đổi nó. Trạng thái dịch vụ trả lời một câu hỏi hoàn toàn khác: liệu backend đặc quyền thực sự mở các phiên có đang chạy hay không.

Lỗi nhập mô-đun, một lần từ chối kích hoạt D-Bus và một thông tin xác thực bị từ chối là ba giai đoạn khác nhau. Lỗi nhập xảy ra trước khi bất kỳ phiên nào tồn tại, nên không lượng cấu hình VPN nào sửa được nó, và một dịch vụ đang chạy cũng không sửa được. Việc xếp thông báo vào một trong ba giai đoạn đó chính là bước đầu tiên thực sự.

Môi trường dự án có thể và không thể sửa gì

Một môi trường dự án giải quyết một vấn đề của dự án: đúng các phiên bản thư viện mà một ứng dụng cần, tách biệt khỏi mọi thứ khác. Điều đó thực sự hữu ích, và đó là công cụ đúng khi chương trình hỏng là script của chính bạn.

uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'

Lệnh thứ hai cho thấy một trình thông dịch nhất định nhìn thấy bản sao nào của các liên kết, và đó là cách nhanh nhất để phân biệt một gói bị thiếu với một gói bị che khuất. Hãy chạy nó bằng trình thông dịch mà script hỏng dùng, không phải bằng một trình khác tình cờ chạy được.

Điều một môi trường dự án không thể làm là sửa một frontend do bản phân phối đóng gói. Các phụ thuộc của chương trình đó được dựng cho trình thông dịch mà trình quản lý gói đã chọn, và chạy nó bên trong môi trường dự án của bạn hoặc thất bại hoặc tạo ra một hỗn hợp không ai hỗ trợ. Tiêm đường dẫn vào nó bằng một biến môi trường là cùng một sai lầm với thêm các bước: bạn đã thay đổi thứ công cụ tải vào mà không thay đổi thứ nó được kiểm thử. Sự đánh đổi đó trông giống một bản sửa chữa đúng bằng khoảng thời gian cho đến lần nhập tiếp theo.

Vì sao chuyển hướng trình thông dịch hệ thống là một cái bẫy

Thay đổi trình thông dịch mặc định rất hấp dẫn vì nó có vẻ sửa traceback bằng một lệnh duy nhất. Nó cũng phá vỡ giả định mà mọi công cụ Python đã đóng gói trên máy chủ được dựng trên, và các lỗi xuất hiện muộn hơn và ở những nơi không liên quan.

Các cơ chế chọn thay thế được thiết kế để chuyển đổi giữa các cách triển khai tương đương, không phải để cài một ngôn ngữ mới hơn bên dưới các mô-đun đã biên dịch cũ hơn. Các tiện ích mở rộng đã biên dịch được dựng cho một ABI cụ thể, nên một mô-đun nhập được hôm qua có thể không tải được hôm nay mà không có gói nào bị gỡ bỏ.

Cũng có một cái bẫy về tên trong những lời khuyên người ta tìm thấy. Lệnh python không có phiên bản không có một ý nghĩa phổ quát duy nhất giữa các bản phân phối và môi trường, và coi nó là từ đồng nghĩa cố định của một phiên bản chính cụ thể sẽ tạo ra những bản sửa chỉ chạy trên máy nơi chúng được viết. Hãy đọc chính sách của hệ thống trước mắt bạn, không phải chính sách trong bài blog.

Những bài kiểm tra chấp nhận riêng biệt

Ở cuối nên có hai bài kiểm tra, và việc vượt qua một bài không nói lên điều gì về bài kia. Bài thứ nhất là lệnh máy khách được hỗ trợ chạy với trình thông dịch mà nó được đóng gói cho. Bài thứ hai là dịch vụ đặc quyền thiết lập một phiên và tunnel mang lưu lượng.

openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0

Hãy giữ một đường vào máy độc lập trong khi làm việc, đặc biệt nếu VPN mang theo quyền truy cập quản trị duy nhất của bạn. Một thay đổi đối với trình thông dịch hệ thống chính là kiểu chỉnh sửa có thể lấy đi quyền truy cập đó giữa chừng.

Nếu lỗi là một mô-đun bị thiếu cho một công cụ hệ thống, bản sửa là một thao tác gói thông qua quy trình được hỗ trợ. Nếu lỗi là một xung đột phiên bản trong dự án của chính bạn, bản sửa là một môi trường. Chọn giữa hai điều đó là toàn bộ quyết định, và nó được quyết định bởi chương trình nào đã in ra traceback.

Bài viết liên quan