Alternative Pfade für Module

Probleme bei der Installation?
Antworten
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

Moin, moin!

Ich würde gerne für die "top-level destination folders", wie "/bin und /sbin" alternative Pfade verwenden, um nicht mit aus den System-Repos per apt, rpm und Co. installierten Dateien in Konflikt zu geraten. Nach eingehendem Studium der pip - Doku meinte ich den passenden Parameter gefunden zu haben:

https://pip.pypa.io/en/stable/reference ... ion-prefix :
--prefix <dir>
Installation prefix where lib, bin and other top-level folders are placed
Das klappt auch eigentlich soweit:

Code: Alles auswählen

~ # python3.6.3 -m pip install -v --prefix=/opt Sphinx
...
Installing collected packages: pytz, babel, MarkupSafe, Jinja2, imagesize, snowballstemmer, sphinxcontrib-websupport, alabaster, docutils, idna, urllib3, chardet, certifi, requests, Sphinx
  Creating /opt/bin
  changing mode of /opt/bin/pybabel to 755
  changing mode of /opt/bin/chardetect to 755
  changing mode of /opt/bin/sphinx-apidoc to 755
  changing mode of /opt/bin/sphinx-autogen to 755
  changing mode of /opt/bin/sphinx-build to 755
  changing mode of /opt/bin/sphinx-quickstart to 755
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Sphinx-1.6.5 alabaster-0.7.10 babel-2.5.1 certifi-2017.11.5 chardet-3.0.4 docutils-0.14 idna-2.6 imagesize-0.7.1 pytz-2017.3 requests-2.18.4 snowballstemmer-1.2.1 sphinxcontrib-websupport-1.0.1 urllib3-1.22
Cleaning up...
~ #
Allerdings tauchen diese dann auch in der Ausgabe von "pip freeze" nicht mehr auf:

Code: Alles auswählen

~ # python3.6.3 -m pip freeze
decorator==4.1.2
ipython==6.2.1
ipython-genutils==0.2.0
jedi==0.11.0
parso==0.1.0
pbr==3.1.1
pexpect==4.3.0
pickleshare==0.7.4
prompt-toolkit==1.0.15
ptyprocess==0.5.2
Pygments==2.2.0
simplegeneric==0.8.1
six==1.11.0
stevedore==1.27.1
traitlets==4.3.2
virtualenv==15.1.0
virtualenv-clone==0.2.6
virtualenvwrapper==4.8.2
wcwidth==0.1.7
~ #
Und einfach importieren lassen sie sich ebenfalls nicht:

Code: Alles auswählen

~ # python3.6.3
Python 3.6.3 (default, Nov  6 2017, 20:15:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sphinx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'sphinx'
>>>
Ist ja auch klar: Die landen unter /opt/lib/python3.6/site-packages und sind damit nicht Teil des PYTHONPATH .
Einfach so den PYTHONPATH ergänzen geht aber auch nicht, da wir Python2 und Python3 parallel betreiben.

Wie erreiche ich, das NUR solche Dateien die normal unter /bin oder /sbin landen würden in einer alternativen Prefixstruktur (/opt(/sbin, /bin)) landen, der Rest jedoch im normalen site-packages ?
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Art das zu loesen besteht normalerweise darin, virtualenvs zu verwenden. Diese lassen dir die Entscheidung offen, ob du system-packete (site-packages in der Python-Lingo) zur Verfuegung haben moechtest. Der Rest der Module die du installierst wird dann in das venv installiert. Da dort auch ein Python-Interpreter liegt, den du direkt aufrufen kannst, ohne das venv aktivieren zu muessen, sowie auch pip, so das die Installation direkt in das venv erfolgt, ist das eine sowohl bequeme als auch leistungsstarke Loesung.
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

__deets__ hat geschrieben:Die Art das zu loesen besteht normalerweise darin, virtualenvs zu verwenden.
Ich vergaß das zu schreiben: Ich kenne natürlich die Möglichkeit virtualenvs zu verwenden und kenne mich damit auch gut aus.
Allerdings fällt diese Methode meiner Meinung nach heraus, da man den Scope unterscheiden muss:

Hat man ein klar abgegrenztes Applikations- oder Projekt-Verzeichnis irgendwo, wie bei einem Django-Hosting oder einer anderen, "Serverdienst-artigen", abgegrenzten Applikation oder auch eine derart klar strukturierte Entwicklungslandschaft über X Workstations hinweg, dann gebe ich Dir vollkommen Recht: Da gehören virtualEnvs mit requirement.txt files hin und nichts anderes!
In diesen "Projekten" (nenne ich es jetzt mal) hat man aber naturgemäß auch verschiedene Anforderungen. Um exemplarisch beim Django-Hosting zu bleiben: Django ist dann zwar der als Modul vorliegende Kern des hostings und hat weitestgehend immer dieselben requirements, aus den individuellen Projektbedingungen heraus (Erweiterungen, eigener Code, etc.) gibt es jedoch unzählige Kombinationsmöglichkeiten für jedes einzelne Projekt, bei dem man sich, wenn man keine vEnvs verwendet, schnell in die Quere kommt.
Hierbei organisiert man das ja dann in der Regel so, das es beliebig viele Projekte auf einem Host gibt, jedes "Projekt" sein eigenes vEnv bekommt und man darin, ohne die anderen zu "stören", machen kann was man will.

Wir schreiben uns jedoch mit Python hauptsächlich unsere eigenen Scripte für z.B. DevOps-Operationen. Wir schreiben uns keine eigenen in "Projekte" unterteilbare, abgegrenzten "Code-Inseln", für die es dann gilt pro Host beliebig viele Instanzen zu generieren, sondern diese Tools stehen dann pro Host nur einmal (z.B. unter /usr/local/bin) als commandline tool zur Verfügung.
Bei diesem Ansatz stehen dann ganz andere Dinge als im zuvor beschriebenen Anwendungsfall im Vordergrund, z.B.:
  • Man will garkeine unterschiedlichen Versionsstände ermöglichen; stattdessen sollen sich alle schon bei der Entwicklung an bereitgestellte, festgelegte und freigegebene Versionen bestimmter Module halten (Compliance).
  • Bei einer Infrastruktur von über 1.400 Hosts (Tendenz schnell steigend) braucht man ein System, mit dem man diese Landschaft einheitlich orchestrieren und verwalten kann. Wir sind da nicht die einzige Landschaft die hierzu auf die distributionsübliche Paketverwaltung in Kombination mit Tools wie Ansible, Puppet oder Chef setzt.
  • Für die im vorigen Punkt genannten Pakete ist die Distributionslogik, -technik, -workflow und -infrastruktur bereits vorhanden. Daher macht es nicht immer automatisch den meisten Sinn für jede Technologie auf die in Entwicklerkreisen jeweils übliche Methode zu setzen, da man so schnell in einem Wartungsalptraum landet: Statt für Perl pakete CPAN, für PHP Pear und Python pip/pypi und vEnvs zu verwenden und jeweils ein eigenes Verwaltungsframework zu betreuen, kann es aus Wartungs-, Compliance- und Aufwandsgründen durchaus Sinn machen auf, aus Host-sicht, "globale" Alternativen wie die Paketverwaltung der Distribution zu setzen. Auch das sehen wir sicher nicht als einzige Anwender so; schließlich dürfte es sonst, außer die Python-Interpreter, Setuptools, virtualenv und PIP in den Distributionen erst garkeine Pakete für andere Module geben; tut es aber ;)
  • Würde jedes Script, welches wir so verwenden, seine eigene vEnv verwenden, ist das sehr schnell eher kontraproduktiv, da es sich komplementär zum Sinn und Zweck hinter vEnvs verhält: vEnvs sind dazu da,
    • Auf shared Hosts einen Versionskonflikt von Projekten zu vermeiden
    • Nicht-Administrativen Usern die freie Verwaltung des zur Verfügung stehenden Modulumfanges zu ermöglichen
    Und so die projektorientierte Verwaltbarkeit verschiedener Umgebungen zu ermöglichen und zu vereinfachen.
    In unserem Fall würde das aber bedeuten, das
    • es unübersichtlicher wird als beim aktuellen Ansatz das die Entwickler sich an die vorgegebenen Versionen halten müssen, da es auf einmal unzählige Modul-Pools zu verwalten gilt
    • wir uns nicht mehr, ohne zuvor PYTHONPATH Variablen anpassen zu müssen, einfach auf jedes Python Script stürzen und ausführen können
    • wir nicht mehr auf bewährte Tools zur Orchestrierung der Infrastruktur zurückgreifen können und eine Ausnahme Lösung neu schaffen müssen
    • es unübersichtlicher wird in der Frage "welche Versionen und Module sind in unserer Infrastruktur eigentlich im Einsatz?"
In diesem Anwendungsfall finde ich daher, das es eher zur Unübersichtlichkeit trotz deutlich erhöhtem Wartungsaufwand als zur Vereinfachung beiträgt virtualenv's zu verwenden.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Judge: mir erscheinen Deine Überlegungen etwas überkomplex. Legt euch doch zwei venvs an, eines für Python 2 und eines für Python 3. In die Skripte fügt ihr dann als erstes eine Shebang-Zeile mit dem Pfad zu dem jeweils gültigen Python-Interpreter ein und markiert die Dateien als ausführbar.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Deine Ausfuehrungen sind faktisch richtig, die gezogenen Schluesse sind nur falsch ;) Nur weil du venvs praedominant in bestimmten Szenarien kennst, sind sie darauf nicht beschraenkt.

Es gibt nur so viele Moeglichkeiten, einen Python-Interpreter Pakete unterzuschieben. PYTHONPATH ist eine davon, andere sind .pth-Files, der site-Mechanismus etc.

venv macht sich diese zu nutze, um euch genau das zu liefern, was ihr braucht: eine auf dem system-python basierende, aber ggf. nicht von zusaetzlich ueber das Paketmanagement installierte 3rd-party-Pakete 'verschmutzte' Python-Distribution, bei der ihr nach Bedarf zB auch noch weiter Pakete dazuschiessen koennt. Das ist erstmal einfach die Laufzeitrealitaet. Und es gibt auch keinerlei technischen Grund, ein solches venv nicht als DEB oder was auch immer du nutzen moechtest zu distributieren.

Die Mechanismen zur Anlage und Pflege dieses venvs kommen lediglich zur *Entwicklungszeit* zum tragen. Genauso wie du da auch mit C++ compilern, build-systemen und vielen anderen build-dependencies umgehen musst, die aber zur Laufzeit keine Rolle spielen.

Insofern - doch, venvs sind die Loesung. Frickeln ueber die oben angesprochenen Mechanismen koennt ihr das bei fortgesetztem Unglauben natuerlich auch selbst, aber dann eben mit Konsequenzen fuer die Bequemlichkeit, die du ja selbst schon bemerkt hast.
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

kbr hat geschrieben:@Judge: mir erscheinen Deine Überlegungen etwas überkomplex. Legt euch doch zwei venvs an, eines für Python 2 und eines für Python 3. In die Skripte fügt ihr dann als erstes eine Shebang-Zeile mit dem Pfad zu dem jeweils gültigen Python-Interpreter ein und markiert die Dateien als ausführbar.
Es sind eigentlich ganz normale Überlegungen von Admins, die größere IT Landschaften zu verwalten haben. Da ist die Lösung nunmal ab und an etwas komplexer als in Buden, die dem knacken der 100 - Systeme - Marke entgegenfiebern ;) Dafür hat man dann später weniger Probleme.

Ich habe Deinen Vorschlag eben mal ausprobiert. Ehrlich gesagt habe ich damit gerechnet das das nicht klappt; tut es aber, und ich stehe hier gerade mit dem fragendsten Gesicht aller Zeiten. Wieso tut es das?? :wink:
Ich meine: Es handelt sich bei den beiden Interpreterdateien (/usr/bin/python3.6 und das der virtualenv in /root/py36venv/bin/python3.6) um binäridentische Kopien einer ELF binary; kein wrapper Script o.ä., welches eine Chance hätte irgendwelche Environment Variablen wie PYTHONPATH umzusetzen oder so - Kannst Du mir einen Hinweis auf das passende Buzzword zum Suchen oder eine Doku geben in der das erklärt wird?

Ich kannte das in der Tat nur so, das man mit "source .... /activate" zunächst alle Umgebungsbedingungen herstellen muss, um mit der venv zu arbeiten. Wenn das SO funktioniert, ist das echt schon fast die Musterlösung für mein Szenario! Vielen Dank schonmal dafür!
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

das liegt daran, das der Python-Interpreter nach "../lib/pythonXX" schaut, also relativ zu sich selbst. Und darin wiederum nach bestimmten Dateien, die seine Laufzeitumgebung bestimmen. Eben das macht sich venv zu nutze.

Uebrigens habe ich das mit dem direkt aufrufbaren Interpreter auch schon erwaehnt ;)
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

__deets__ hat geschrieben:Uebrigens habe ich das mit dem direkt aufrufbaren Interpreter auch schon erwaehnt ;)
Lieber __deets__, ich wollte Dir sicherlich nicht Deine Lorbeeren streitig machen; ich habe das nur nicht so verstanden als Du es geschrieben hattest. Sorry dafür! ;)

Vielen Dank an Euch beide! Mit dem Gedanken spiele ich jetzt erstmal herum!
Antworten