Virtualenv: - alternativas reubicables

Creado en 10 feb. 2020  ·  43Comentarios  ·  Fuente: pypa/virtualenv

Usé la bandera --relocatable. La nueva versión 20.0 no tiene esta bandera. ¿Cómo creo ahora entornos reubicables?

question

Comentario más útil

Usamos --relocatable para agrupar un venv en un rpm. virtualenv se crea en $ DESTDIR y finalmente se mueve en /opt/company .

Todos 43 comentarios

La bandera reubicable siempre ha sido experimental y nunca funcionó realmente; ya no lo admitimos y la función se ha eliminado por completo (de ahí la versión principal). Explique su caso de uso y podríamos sugerirle un enfoque alternativo.

CMD export branch && cd /build_dir && \
 apt-get update -y && apt-get upgrade -y && \
 pip3 install virtualenv && \
 virtualenv --always-copy --python=python3 env && \
 git clone http://user:pass@gitlab/dev/repo.git && \
 cd /build_dir/veil-repo/code/veil-common && \
 git checkout $branch && \
 python3 install.py -p /build_dir/veil-repo/code/cli-app/ -v /build_dir/env && \
 python3 install.py -p /build_dir/veil-repo/code/controller/ -v /build_dir/env && \
 python3 install.py -p /build_dir/veil-repo/code/node/ -v /build_dir/env && \
 cd /build_dir/ && \
 ./env/bin/pip3 install -r requirements.txt && \
 virtualenv --relocatable env

Este es un extracto de Dockerfile. ¿El código funcionará correctamente si elimino el indicador --relocatable? Es decir, necesito crear mi propio entorno aislado, que puedo copiar de cualquier forma.

Dentro de una ventana acoplable, diría que el 90% lo haría. Pero para asegurarse de que tendría que ponerse en contacto con quién mantiene ese código de la ventana acoplable, podría haber diferencias sutiles de cómo manejamos los reubicables.

Usamos esta característica a veces porque nuestro sistema CI crea virtualenvs en directorios con nombres largos. El nombre sería lo suficientemente largo como para que #! sea ​​demasiado largo y no podamos ejecutar los scripts en el env.

@ Nitori- para esos casos se recomienda usar el formato python -m para invocar las herramientas en general 🤔

Eso es justo. Aunque muchos paquetes de Python se comportan mal y no se permiten invocarlos así.

@ Nitori- incluso si ese es el caso, siempre puede forzar la invocación invocando los ejecutables a través del intérprete de Python dentro de la carpeta binaria; p.ej

{venv}/bin/python {venv}/bin/bad-bad-tool

donde {venv} puede ser arbitrariamente largo 👍

En mi empresa usamos la bandera --relocatable en nuestras canalizaciones para ayudarnos a reutilizar un virtualenv y ahorrar tiempo: usamos GitLab, construimos el virtualenv en un paso inicial, lo guardamos como un artefacto y luego lo reutilizamos para ejecutar un montón de pruebas paralelas.

Teníamos la intención de anclar la versión de virtualenv, pero debido a un error, terminamos sacando la última, por lo que nuestras tuberías se rompieron esta mañana. Arreglamos ese error para que esté anclado y todo se esté ejecutando ahora, y encontraremos una forma de evitar la eliminación de la bandera. Pero, pensé que anotaría aquí para transmitir mi experiencia a pesar de que el problema está cerrado y no espero que la bandera sea compatible en el futuro.

Con el nuevo sembrador de datos de la aplicación, la creación de un virtualenv lleva poco menos de 100 ms, este enfoque es el preferido en su caso de uso.

Usamos --relocatable para agrupar un venv en un rpm. virtualenv se crea en $ DESTDIR y finalmente se mueve en /opt/company .

Este es mi caso.

Entonces, ¿ayudaría poder pasar el objetivo final por adelantado para las rutas generadas?

@gaborbernat ¡sí!

@gaborbernat aún, el virtualenv debe poder usarse durante la fase de construcción, antes de la implementación en la ubicación final.

No estoy seguro de cuál es una buena solución aquí 🤔 Estoy abierto a propuestas.

@gaborbernat para tal caso, el comportamiento estándar es distinguir builddir y prefix.

virtualenv tiene un argumento DEST_DIR que puede ser engañoso en este caso. DEST_DIR es la ubicación real de venv, que es efectivamente un prefijo (como / usr, / usr / local, etc.). Entonces, tal vez, documentar virtualenv LOCATION debería aclarar esto.

Luego puede agregar una opción --destdir o --root que por defecto es / . De esta manera, virtualenv puede funcionar aislado en destdir (algo así como un chroot). No sé cómo python, pip y otros scripts tendrán que hacer frente a esto.

AFAIK, el problema es que todos los scripts de consola generados codifican la ruta durante la creación del shebang. No existe una forma estándar de hacer que estos scripts de consola generados con shebangs funcionen durante la compilación y durante la ejecución después de la implementación. Eso es a menos que después de la construcción alguien arregle los shebangs. Pero eso ahora está fuera del alcance de la creación de entornos virtuales, por lo que está fuera de nuestro control.

@gaborbernat, ¿ quieres decir que deberíamos implementar esto en las herramientas de configuración? ¿Qué shebang se puede usar tanto aislado en el momento de la construcción como en la ubicación de destino durante el tiempo de ejecución?

Estoy pensando en escribir un script virtualenv-relocate que edite shebangs en un virtualenv existente, haciéndolo utilizable en su nueva ubicación. Algo como :

$ virtualenv-relocate /build/dir/venv /opt/company/app/venv
Rewriting shebang of bin/pip.
Rewriting shebang of bin/pip3.5.
...
$

Tampoco creo que setuptools sea un buen lugar para esto. Es una característica que debería ser parte del sistema de construcción que se construye en la ubicación A pero luego se implementa en la ubicación B.

Bueno, el proyecto C permite construir aislado simplemente editando PATH y LD_LIBRARY_PATH. No importa qué sistema de compilación utilice.

No estoy familiarizado con cómo C logra esto, tal vez alguien pueda explicarlo, ¿vincularlo? Lo que ha estado sucediendo antes está aquí https://github.com/pypa/virtualenv/blob/legacy/virtualenv.py#L1880 -L1894; Básicamente, hemos estado tratando de hacer que algunas rutas sean relativas: scripts y archivos pth / egg.

Mi repositorio también está usando --relocatable y estoy usando un script (después de que se creó el entorno virtual reubicable) para copiar bibliotecas adicionales al virtualenv. Con esto, fue posible crear virtualenv que es completamente reubicable. Por ejemplo, usamos esto en Windows y agregamos virtualenv a nuestro instalador. Después de la instalación, los programas de python3 funcionan bien con el virtualenv empaquetado.

El mismo caso de uso también funciona en mac y linux para nosotros ...

@ Gagi2k lo que haces allí ya mostró la fragilidad de la implementación actual reubicable; Necesitaba hacer algunos scripts adicionales después de que se creó el env para hacerlo completamente reubicable. El problema es cómo hacer que un paquete sea completamente reubicable depende en gran medida del entorno de destino. Entonces, la idea aquí es que virtualenv se da por vencido en tratar de hacer que sus entornos sean completamente reubicables (ya que no puede tener éxito en muchos casos) ... y en cambio delega el trabajo por completo en las personas que escriben estos scripts personalizados, que logran esto; scripts que tienen el conocimiento del entorno de destino, así que sepa exactamente qué y cuántos cambios se necesitan para hacer algo reubicable.

Cierto, justo punto.

Mi problema es más o menos que ahora necesito recrear la funcionalidad que proporcionaste antes y probarla en todas las plataformas + varias distribuciones para hacer exactamente lo mismo que la función anterior.

Creo que intentaré seguir con una versión anterior de virtualenv por ahora hasta que yo o alguien más tenga tiempo para implementar esto.

@ Gagi2k vea mi comentario anterior sobre una idea de proyecto virtualenv-relocate . Estaré feliz de cooperar en esto con otros. https://github.com/spotify/dh-virtualenv/ puede ser un buen punto de partida.

@bersace thx, ya copié el código antiguo ahora y creé un script de Python independiente a partir de él. Creo que lo usaré por ahora como una solución inmediata, pero estoy feliz de cambiar a otra cosa en el futuro o contribuir con los scripts que tengo.

@ Gagi2k, ¿te importaría compartirlo?

@bersace Todavía se está trabajando: https://codereview.qt-project.org/c/qt/qtivi/+/290859

Toda la actualización de virtualenv 20 causa más problemas de los anticipados. Reutilizar la funcionalidad anterior para hacer que los scripts sean reubicables no es un gran problema, pero debido a que ahora está basado en venv y con ese pyvenv.cfg se vuelve mucho más complicado. Por ejemplo, en Windows, el antiguo virtualenv copió muchos archivos base py a/ lib / python(o lo enlazó simbólicamente). Ahora no se copian en absoluto, pero pyvenv solo apunta a la ubicación original. Una vez que se actualiza la ubicación original, su virtualenv debe manejarla y debe esperar que todo lo necesario aún esté en su lugar. El problema aún mayor es https://bugs.python.org/issue39469 , lo que hace que sea difícil pasarlo a una ubicación relativa donde se configura todo para que el virtualenv se pueda reubicar ...

Por ahora, no creo que se pueda hacer (sin que pyvenv.cfg lo admita).

@gaborbernat Podría estar haciendo un mal uso de virtualenv para lo que se pretendía originalmente, pero ¿cuál es la forma oficial de proporcionar su propia copia de python3 con su aplicación, ya que desea permitir que la gente la extienda usando pip?

@ Gagi2k Estoy seguro de que me falta algo aquí; pero ¿no podría simplemente alterar el pyenv.cfg hone como parte de la fase de instalación en una máquina determinada?

@gaborbernat Podría estar haciendo un mal uso de virtualenv para lo que se pretendía originalmente, pero ¿cuál es la forma oficial de proporcionar su propia copia de python3 con su aplicación, ya que desea permitir que la gente la extienda usando pip?

Los entornos virtuales fueron diseñados para ser siempre una referencia a algún intérprete de Python en una máquina. La suposición básica es que tiene un entorno de Python completamente funcional en la máquina, y solo desea tener múltiples site-packages separados para él. Puedo ver algún valor en hacer que el enlace no sea completamente explícito (como ahora con la ruta completamente explícita), pero si va por esa ruta, ¿por qué no ir hasta el final y usar PyInstaller o pex para empaquetar su código con el ejecutable de Python por adelantado, sin referencias fáciles de romper?

@gaborbernat Seguro, eso funcionaría, el mayor problema es que la mayoría de los usuarios están acostumbrados a poder simplemente cambiar el nombre de la carpeta después de la instalación y sigue funcionando ...
Pero acabo de descubrir que configurar PYTHONHOME también funciona, al menos en Windows lo hice funcionar sin referencia a la instalación original.

pex parece interesante y lo miraré más de cerca, gracias por la pista.

@gaborbernat todavía, ¿cómo construir un virtualenv en un builddir y enviarlo en un .deb o .rpm?

@gaborbernat Seguro, eso funcionaría, el mayor problema es que la mayoría de los usuarios están acostumbrados a poder simplemente cambiar el nombre de la carpeta después de la instalación y sigue funcionando ...

No estoy seguro de por qué esperan esto. Este nunca fue el caso; incluso con la bandera reubicable, era cierto en un subconjunto de los posibles casos. De ahí por qué se eliminó con v20.

@gaborbernat todavía, ¿cómo construir un virtualenv en un builddir y enviarlo en un .deb o .rpm?

@bersace esto depende de gran parte de su caso de uso. ¿Deb / rpm garantiza que Python estará disponible en la misma ubicación en la máquina de destino? Si es así, simplemente arregle las rutas de shebang durante la instalación 👍

@gaborbernat dependiendo del sistema python es suficiente para garantizar que python esté en una ubicación específica.

Modificar archivos instalados en postinst es una muy mala idea. Esto requiere excluir todos los scripts del reino dpkg, por lo que dpkg no los tocará en la actualización. Eso no es aceptable.

AFIAK, la mejor solución sería un virtualenv-change-prefix que edite todos los shebangs para eliminar destdir , que se ejecutará antes de archivar el paquete final.

@bersace y ¿en qué establecerías los shebangs?

@gaborbernat la ubicación de destino absoluta. por ejemplo, #!/opt/company/app/venv/bin/python .

Eso implicaría ahora que la implementación de ese paquete en un nuevo refroot que no sea / ahora no es compatible, ¿no?

@gaborbernat sí, por diseño. Los usuarios no deben mover los archivos administrados por dpkg / rpm.

Esto es algo diferente de relocatable . El propósito no es hacer que venv sea relativo , sino distinguir builddir (debian / build / ... o% builddir) y rundir (/).

Cerrando esto porque no hay ningún elemento procesable de nuestro lado. Recomiendo continuar la discusión aquí, o sobre posibles proyectos que intenten abordar esto además de virtualenv.

En realidad, una alternativa es algo de dependencias de proveedores, sin versionarlas.

En mi caso, tengo que comprimir un paquete de Python con las dependencias necesarias y pasarlo como un 'archivo' a Spark en Yarn para que mi programa se ejecute en un clúster Spark distribuido. Aunque Anaconda puede finalizar esta operación, el software empresarial no se puede utilizar en mi empresa. relocatable puede resolver este problema en el pasado, pero ahora desapareció.

En mi caso, tengo que comprimir un paquete de Python con las dependencias necesarias y pasarlo como un 'archivo' a Spark en Yarn para que mi programa se ejecute en un clúster Spark distribuido. Aunque Anaconda puede finalizar esta operación, el software empresarial no se puede utilizar en mi empresa. relocatable puede resolver este problema en el pasado, pero ahora desapareció.

Hola @jackhhh , ¿encontraste una solución para el caso de uso existente?
Nos encontramos con el mismo problema.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

npinto picture npinto  ·  4Comentarios

oconnor663 picture oconnor663  ·  3Comentarios

earthgecko picture earthgecko  ·  4Comentarios

erbatyr picture erbatyr  ·  5Comentarios

mnm678 picture mnm678  ·  7Comentarios