Virtualenv: - alternativas relocáveis

Criado em 10 fev. 2020  ·  43Comentários  ·  Fonte: pypa/virtualenv

Usei o sinalizador --relocatable. A nova versão 20.0 não possui este sinalizador. Como faço para criar ambientes relocáveis?

question

Comentários muito úteis

Usamos --relocatable para agrupar um venv em um rpm. virtualenv é criado em $ DESTDIR e finalmente movido em /opt/company .

Todos 43 comentários

O sinalizador de realocação sempre foi experimental e nunca realmente funcionou; não oferecemos mais suporte a ele e o recurso foi totalmente descartado (daí o lançamento principal). Explique seu caso de uso e poderemos sugerir uma abordagem alternativa.

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 é um trecho do Dockerfile. O código funcionará corretamente se eu remover o sinalizador --relocatable? Ou seja, preciso criar meu próprio ambiente isolado, que posso copiar de qualquer forma.

Dentro de um docker, eu diria que 90% sim. Mas, para ter certeza de que você teria que entrar em contato com quem mantém esse código do docker, pode realmente haver diferenças sutis de como tratamos os relocáveis.

Às vezes usamos esse recurso porque nosso sistema de CI criaria virtualenvs em diretórios com nomes longos. O nome seria longo o suficiente para que #! ficasse muito longo e não podemos executar os scripts no env.

@ Nitori- para esses casos, é recomendado usar o formato python -m para invocar as ferramentas em geral 🤔

Isso é justo. Embora muitos pacotes Python se comportem mal e não permitam que sejam invocados dessa forma.

@ Nitori- mesmo que seja o caso, você sempre pode forçar a invocação invocando os executáveis ​​por meio do interpretador python dentro da pasta binária; por exemplo

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

onde {venv} pode ser arbitrariamente longo 👍

Na minha empresa, usamos a sinalização --relocatable em nossos pipelines para nos ajudar a reutilizar um virtualenv e economizar tempo - usamos o GitLab, construímos o virtualenv em uma etapa inicial, salvamos como um artefato e, em seguida, o reutilizamos para executar um monte de testes paralelos.

Pretendíamos fixar a versão do virtualenv, mas devido a um bug, acabamos puxando a última, então nossos pipelines quebraram esta manhã. Corrigimos esse bug para que ele seja fixado e tudo esteja funcionando agora, e encontraremos uma maneira de contornar a sinalização que está sendo removida. Mas, pensei em anotar aqui para transmitir minha experiência, embora o problema esteja encerrado e eu não espere que a bandeira seja apoiada no futuro.

Com o novo semeador de dados de aplicativo, a criação de um virtualenv leva pouco menos de 100 ms, essa abordagem é preferida em seu caso de uso.

Usamos --relocatable para agrupar um venv em um rpm. virtualenv é criado em $ DESTDIR e finalmente movido em /opt/company .

Este é o meu caso.

Então, seria útil ser capaz de passar o alvo final antecipadamente para os caminhos gerados?

@gaborbernat sim!

@gaborbernat ainda, o virtualenv deve ser utilizável durante a fase de construção, antes da implantação no local final.

Não tenho certeza qual é uma boa solução aqui 🤔 Estou aberto a propostas.

@gaborbernat para esse caso, o comportamento padrão é distinguir builddir e prefixo.

virtualenv tem um argumento DEST_DIR que pode ser enganoso neste caso. DEST_DIR é a localização real do venv, que é efetivamente um prefixo (assim como / usr, / usr / local etc.) Então, talvez, documentar virtualenv LOCATION torne isso mais claro.

Então você pode adicionar uma opção --destdir ou --root cujo padrão é / . Desta forma, o virtualenv pode funcionar isolado em destdir (algo como um chroot). Não sei como python, pip e outros scripts terão que lidar com isso.

AFAIK, o problema é que todos os scripts de console gerados codificam o caminho durante a criação para o shebang. Não há uma maneira padrão de fazer esses scripts de console gerados com shebangs funcionarem durante a construção e durante a execução após a implantação. Isso é, a menos que, após a construção, alguém conserte as coisas. Mas agora isso está fora do escopo da criação do ambiente virtual, portanto, fora do nosso controle.

@gaborbernat, você quer dizer que devemos implementar isso nas

Estou pensando em escrever um script virtualenv-relocate que edite shebangs em um virtualenv existente, tornando-o utilizável em seu novo local. Algo como :

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

Também não acho que o setuptools seja um bom lugar para isso. É um recurso que deve fazer parte do sistema de construção que é construído no local A, mas depois implementado no local B.

Bem, o projeto C permite construir de forma isolada simplesmente editando PATH e LD_LIBRARY_PATH. Não importa o sistema de compilação que você usa.

Não estou familiarizado com como C consegue isso, talvez alguém possa explicar, fazer um link para isso? O que aconteceu antes está aqui https://github.com/pypa/virtualenv/blob/legacy/virtualenv.py#L1880 -L1894; basicamente tentamos tornar alguns caminhos relativos: a saber, scripts e arquivos pth / egg.

Meu repositório também está usando --relocatable e estou usando um script (depois que o env virtual relocável foi criado) para copiar bibliotecas adicionais para o virtualenv. Com isso, foi possível criar um virtualenv totalmente realocável. Por exemplo, usamos isso no Windows e adicionamos o virtualenv ao nosso instalador. Após a instalação, os programas python3 estão funcionando bem com o virtualenv empacotado.

O mesmo caso de uso também funciona em mac e linux para nós ....

@ Gagi2k o que você faz lá já mostrou a fragilidade da implementação realocável atual; você precisava fazer alguns scripts adicionais depois que o env foi criado para torná-lo totalmente relocável. O problema é como você pode tornar um pacote totalmente relocável depende muito do seu ambiente de destino. Portanto, a ideia aqui é que o próprio virtualenv desista de tentar tornar seus ambientes totalmente realocáveis ​​(já que não pode ter sucesso em muitos casos) ... e, em vez disso, delega o trabalho inteiramente às pessoas que escrevem esses scripts personalizados, que fazem isso; scripts que têm o conhecimento do ambiente de destino, portanto, saibam exatamente quais e quantas mudanças são necessárias para tornar algo relocável.

Verdade, ponto justo.

Meu problema é mais ou menos que agora preciso recriar a funcionalidade fornecida antes e testá-la em todas as plataformas + várias distros para fazer exatamente o mesmo que a função antiga.

Acho que vou tentar ficar com uma versão mais antiga do virtualenv por enquanto, até que eu ou outra pessoa tenha tempo para implementá-la.

@ Gagi2k veja meu comentário acima sobre uma ideia de projeto virtualenv-relocate . Terei todo o gosto em cooperar com outro. https://github.com/spotify/dh-virtualenv/ pode ser um bom ponto de partida.

@bersace thx, eu já copiei o código antigo agora e criei um script python autônomo a partir dele. Acho que vou usar isso por agora como uma solução drop-in, mas estou feliz em mudar para outra coisa no futuro ou contribuir com os scripts que tenho.

@ Gagi2k , você se importaria em compartilhá-lo?

@bersace Ainda está em andamento: https://codereview.qt-project.org/c/qt/qtivi/+/290859

Toda a atualização do virtualenv 20 causa muito mais problemas do que o previsto. Reutilizar a funcionalidade antiga para tornar os scripts realocáveis ​​não é um grande negócio, mas como agora é baseada no venv e com esse pyvenv.cfg, fica muito mais complicado. Por exemplo, no Windows, o antigo virtualenv copiava muitos arquivos base py para/ lib / python(ou linkado). Agora, eles não são copiados, mas o pyvenv apenas aponta para o local original. Depois que o local original é atualizado, seu virtualenv precisa lidar com isso e você precisa esperar que tudo o que é necessário ainda esteja no lugar. O problema ainda maior é https://bugs.python.org/issue39469 , o que torna difícil passar um local relativo onde você configurou tudo para tornar o virtualenv realocável ...

Por enquanto, eu não acho que isso possa ser feito (sem o suporte do pyvenv.cfg).

@gaborbernat Posso estar incorretamente para o que foi originalmente planejado, mas qual é a maneira oficial de fornecer sua própria cópia python3 com seu aplicativo, já que você deseja permitir que as pessoas o estendam usando pip?

@ Gagi2k Tenho certeza de que estou faltando alguma coisa aqui; mas você não poderia simplesmente alterar pyenv.cfg hone como parte da fase de instalação em uma determinada máquina?

@gaborbernat Posso estar incorretamente para o que foi originalmente planejado, mas qual é a maneira oficial de fornecer sua própria cópia python3 com seu aplicativo, já que você deseja permitir que as pessoas o estendam usando pip?

ambientes virtuais foram projetados para ser sempre uma referência a algum interpretador python em uma máquina. A suposição básica é que você tem um ambiente python totalmente funcional na máquina e deseja apenas ter vários site-packages separados para ele. Eu posso ver algum valor em tornar o link não totalmente explícito (como está agora com o caminho totalmente explícito), mas se você está indo por esse caminho, por que não ir até o fim e usar PyInstaller ou pex para empacotar seu código com o executável python inicial, sem nenhuma referência fácil de quebrar?

@gaborbernat Claro, isso funcionaria, o maior problema é que a maioria dos usuários costuma ser capaz de simplesmente renomear a pasta após a instalação e ela continua funcionando ...
Mas acabei de descobrir que definir PYTHONHOME também funciona, pelo menos no Windows, ele funciona sem referência à instalação original.

pex parece interessante e vou olhar mais de perto, obrigado pela dica.

@gaborbernat ainda, como construir um virtualenv em um builddir e enviá-lo em um .deb ou .rpm?

@gaborbernat Claro, isso funcionaria, o maior problema é que a maioria dos usuários costuma ser capaz de simplesmente renomear a pasta após a instalação e ela continua funcionando ...

Não sei por que eles esperam isso. Isso nunca foi o caso; mesmo com o sinalizador relocável, era verdadeiro em um subconjunto dos casos possíveis. Daí porque ele foi cortado com v20.

@gaborbernat ainda, como construir um virtualenv em um builddir e enviá-lo em um .deb ou .rpm?

@bersace isso depende muito do seu caso de uso. O deb / rpm garante que o python estará disponível no mesmo local na máquina de destino? Se sim, apenas conserte os caminhos do shebang durante a instalação 👍

@gaborbernat dependendo do sistema python é suficiente para garantir que o python esteja em um local específico.

Modificar os arquivos instalados no postinst é uma ideia muito ruim. Isso requer a exclusão de todos os scripts do reino do dpkg, portanto, o dpkg não os afetará na atualização. Isso não é aceitável.

AFIAK, a melhor solução seria um virtualenv-change-prefix que edite todas as coisas para remover destdir , a ser executado antes de arquivar o pacote final.

@bersace e como você definiria os shebangs?

@gaborbernat o local de destino absoluto. por exemplo, #!/opt/company/app/venv/bin/python .

Isso implicaria que implantar esse pacote em um novo refroot diferente de / agora não é suportado, não?

@gaborbernat sim, por design. Os arquivos gerenciados por dpkg / rpm não devem ser movidos pelos usuários.

Isso é um pouco diferente de relocatable . O propósito não é tornar o venv relativo , mas distinguir builddir (debian / build / ... ou% builddir) e rundir (/).

Fechando isso porque não há nenhum item acionável do nosso lado. Eu recomendo continuar a discussão aqui, ou em projetos potenciais que tentam lidar com isso no topo do virtualenv.

Na verdade, uma alternativa é algumas dependências do fornecedor, sem versioná-las.

No meu caso, tenho que compactar um pacote Python com as dependências necessárias e passá-lo como um 'arquivo' para o Spark on Yarn para dar suporte à execução do meu programa em um cluster Spark distribuído. Embora esta operação possa ser concluída pelo Anaconda, o software corporativo não pode ser usado na minha empresa. relocatable pode resolver esse problema no passado, mas agora ele desapareceu.

No meu caso, tenho que compactar um pacote Python com as dependências necessárias e passá-lo como um 'arquivo' para o Spark on Yarn para dar suporte à execução do meu programa em um cluster Spark distribuído. Embora esta operação possa ser concluída pelo Anaconda, o software corporativo não pode ser usado na minha empresa. relocatable pode resolver esse problema no passado, mas agora ele desapareceu.

Olá @jackhhh , você encontrou uma solução alternativa para o caso de uso existente?
Estamos enfrentando o mesmo problema.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

zbuc picture zbuc  ·  5Comentários

mitchhentges picture mitchhentges  ·  3Comentários

asottile picture asottile  ·  6Comentários

oconnor663 picture oconnor663  ·  3Comentários

erbatyr picture erbatyr  ·  5Comentários