Traceback ჩნდება მაშინ, როცა VPN-ის მართვის ბრძანება იწყება და პირველი ინსტინქტი სხვა Python-ის დაყენებისკენ ან სისტემური ნაგულისხმევის სხვაგან გადამისამართებისკენ მიდის. ეს ინსტინქტი ურევს ორ გარემოს, რომლებსაც ერთმანეთთან არაფერი აკავშირებს. ერთი ეკუთვნის ოპერაციულ სისტემას და მის პაკეტირებულ ხელსაწყოებს; მეორე ეკუთვნის ნებისმიერ პროექტს, რომელსაც აშენებ. პირველის შეცვლა მეორის დასაკმაყოფილებლად ის გზაა, რომლითაც მომუშავე დესკტოპი პაკეტების მენეჯერს კარგავს.

შედარება, რომლის გაკეთებაც ღირს, არის იმ კომპონენტსა და იმ გარემოს შორის, რომლის შეცვლის უფლებაც გაქვს. ისინი თითქმის არასოდეს არის ერთი და იგივე ობიექტი.

ორი Python-ური კითხვა, რომლებიც ერთს ჰგავს

პირველი კითხვაა: რომელმა ინტერპრეტატორმა გაუშვა პროგრამა, რომელმაც Traceback დაბეჭდა? მეორეა: რომელი ინტერპრეტატორი უნდა გამოიყენოს ჩემმა პროექტმა? ტერმინალში ისინი ერთნაირად გამოიყურება, რადგან ორივეს პასუხი python3-ის აკრეფაა, თუმცა მათ განსხვავებული მფლობელები, განახლების გზები და ზემოქმედების რადიუსი აქვთ.

სისტემური ხელსაწყო მიბმულია ინტერპრეტატორზე, რომლითაც დისტრიბუტივმა გამოუშვა, და ამ ინტერპრეტატორის ABI-ზე აგებულ კომპილირებულ მოდულებზე. პროექტი მიბმულია ნებისმიერ გარემოზე, რომელსაც მისთვის შექმნი. სისტემური ნაგულისხმევის გადაადგილება პირველს ცვლის მანქანის ყველა ხელსაწყოსთვის ერთდროულად; გარემოს შექმნა მეორეს ცვლის მხოლოდ ერთი დირექტორიისთვის.

ამ ქმედებებიდან მხოლოდ ერთი შეიძლება ერთ წუთში გაუქმდეს. ეს პირველი არ არის.

რომელმა კომპონენტმა წარმოშვა შეცდომა

სანამ სხვა რამეს წაიკითხავ, წაიკითხე Traceback-ის პირველი ხაზი და შესრულებადი ფაილი, რომელმაც ის წარმოშვა. ბრძანების ხაზის ფრონტენდი, პრივილეგირებული სერვისი და 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

სკრიპტის პირველი ხაზი ასახელებს ინტერპრეტატორს, რომელსაც გამოიყენებს და სწორედ ის არის Traceback-ის წყარო. პაკეტის შეკითხვა გეუბნება, ვის ეკუთვნის ფაილი, რაც წყვეტს, ვის აქვს მისი შეცვლის უფლება. სერვისის სტატუსი სულ სხვა კითხვას პასუხობს: მუშაობს თუ არა პრივილეგირებული ბექენდი, რომელიც სინამდვილეში ხსნის სესიებს.

მოდულის იმპორტის შეცდომა, D-Bus-ის აქტივაციის უარყოფა და უარყოფილი სერტიფიკატი სამი განსხვავებული ეტაპია. იმპორტის შეცდომა ხდება მანამ, სანამ რომელიმე სესია არსებობს, ამიტომ VPN-ის კონფიგურაციის არც ერთი რაოდენობა ვერ გამოასწორებს და მომუშავე სერვისიც ვერ გამოასწორებს. შეტყობინების ამ სამი ეტაპიდან ერთში მოთავსება სწორედ პირველი ნაბიჯია.

რისი გაკეთება შეუძლია და არ შეუძლია პროექტის გარემოს

პროექტის გარემო წყვეტს პროექტის პრობლემას: ზუსტ ბიბლიოთეკის ვერსიებს, რომლებიც ერთ აპლიკაციას სჭირდება, დანარჩენისგან იზოლირებულს. ეს მართლაც სასარგებლოა და სწორი ხელსაწყოა, როცა წარუმატებელი პროგრამა შენი სკრიპტია.

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

მეორე ბრძანება გვიჩვენებს, მოცემული ინტერპრეტატორი მიბმების რომელ ასლს ხედავს, რაც ყველაზე სწრაფი გზაა დაკარგული პაკეტის დაჩრდილულისგან გასარჩევად. გაუშვი იმ ინტერპრეტატორით, რომელსაც წარუმატებელი სკრიპტი იყენებს და არა სხვა ინტერპრეტატორით, რომელიც შემთხვევით მუშაობს.

რისი გაკეთებაც პროექტის გარემოს არ შეუძლია, დისტრიბუტივის მიერ პაკეტირებული ფრონტენდის შეკეთებაა. ამ პროგრამის დამოკიდებულებები აგებულია იმ ინტერპრეტატორზე, რომელიც პაკეტების მენეჯერმა აირჩია, და პროექტის გარემოში მისი გაშვება ან ვერ ხერხდება, ან ქმნის ნარევს, რომელსაც არავინ მხარს უჭერს. გზების ჩასმა მასში გარემოს ცვლადით იგივე შეცდომაა დამატებითი ნაბიჯებით: შეცვალე ის, რასაც ხელსაწყო იტვირთავს და არა ის, რაზეც გამოიცადა. ეს გაცვლა გამოსწორებას ჰგავს ზუსტად იმდენ ხანს, რამდენიც შემდეგ იმპორტამდე მისვლას სჭირდება.

რატომ არის სისტემური ინტერპრეტატორის გადამისამართება ხაფანგი

ნაგულისხმევი ინტერპრეტატორის შეცვლა მიმზიდველია, რადგან ჩანს, თითქოს ერთი ბრძანებით ასწორებს Traceback-ს. ის ასევე არღვევს იმ ვარაუდს, რომელზეც ჰოსტის ყველა პაკეტირებული Python ხელსაწყო აგებულია, და მარცხები მოგვიანებით, დაუკავშირებელ ადგილებში ჩნდება.

ალტერნატივის შერჩევის მექანიზმები შექმნილია ეკვივალენტურ იმპლემენტაციებს შორის გადასართავად და არა უფრო ძველი კომპილირებული მოდულების ქვეშ უფრო ახალი ენის ჩასაყენებლად. კომპილირებული გაფართოებები აგებულია კონკრეტულ ABI-ზე, ამიტომ მოდული, რომელიც გუშინ იმპორტირდა, დღეს შეიძლება ვერ ჩაიტვირთოს არც ერთი პაკეტის წაშლის გარეშე.

არსებობს დასახელების ხაფანგიც იმ რჩევებში, რომლებსაც ხალხი პოულობს. ვერსიის გარეშე python ბრძანებას არ აქვს ერთი უნივერსალური მნიშვნელობა დისტრიბუტივებსა და გარემოებს შორის და მისი, როგორც კონკრეტული ძირითადი ვერსიის ფიქსირებული სინონიმის, განხილვა წარმოქმნის გამოსწორებებს, რომლებიც მხოლოდ იმ მანქანაზე მუშაობს, სადაც დაიწერა. წაიკითხე შენს წინ არსებული სისტემის პოლიტიკა და არა ბლოგის პოსტში არსებული.

ცალკე მისაღები ტესტები

ბოლოში ორი ტესტი უნდა იყოს და ერთის გავლა მეორეზე არაფერს ამბობს. პირველი ის არის, რომ მხარდაჭერილი კლიენტის ბრძანება მუშაობს იმ ინტერპრეტატორთან, რომლისთვისაც იყო პაკეტირებული. მეორე ის არის, რომ პრივილეგირებული სერვისი ხსნის სესიას და გვირაბი ტრაფიკს ატარებს.

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

სამუშაოს დროს შეინარჩუნე მანქანაში შესვლის დამოუკიდებელი გზა, მით უმეტეს თუ VPN შენი ერთადერთი ადმინისტრაციული წვდომის მატარებელია. სისტემური ინტერპრეტატორის ცვლილება სწორედ ისეთი რედაქტირებაა, რომელსაც ეს წვდომა შუაში შეუძლია წაართვას.

თუ მარცხი სისტემური ხელსაწყოსთვის მოდულის უქონლობაა, გამოსწორება პაკეტის ოპერაციაა მხარდაჭერილი სამუშაო პროცესით. თუ მარცხი საკუთარ პროექტში ვერსიების კონფლიქტია, გამოსწორება გარემოა. ამ ორს შორის არჩევა მთელი გადაწყვეტილებაა და ის განისაზღვრება იმით, რომელმა პროგრამამ დაბეჭდა Traceback.

დაკავშირებული სტატიები