Como posso instalar e executar pacotes conflitantes no Debian / Ubuntu?

1

Eu gostaria de instalar python3.7 e idle-python3.7 na minha caixa stable Debian, mas eles são de sid e exigem versões mais recentes de libc , o que exigiria atualizações de cargas e cargas de pacotes principais para versões instáveis se eu fizer da maneira normal . Além disso, envolveria a atualização ou a remoção de vários pacotes que, por alguma razão, especificam exatamente python3.5 como uma das dependências deles. Eu não quero fazer isso.

Eu também não consigo compilar python3.7 por algum motivo; quando tento, os testes falham. Os mantenedores do Debian conseguiram compilar para minha arquitetura, então eu quero usar a versão deles.

Como posso instalar esses pacotes conflitantes?

    
por wizzwizz4 25.07.2018 / 13:53

2 respostas

1

Eles estão disponíveis no link

Você deve ser capaz de fazer o backport do teste para o link estável     

por 25.07.2018 / 15:45
1

Aviso: isso é um hack. Como tal, não faço promessas quanto à sua confiabilidade. É menos provável que lixem seu sistema do que a alternativa , embora.

Para fazer isso, estaremos instalando uma nova cópia do Debian dentro do seu sistema de arquivos, chroot ing para instalar alguns pacotes, então criando um tipo de sistema híbrido dentro de um namespace separado para rodar o programa. O acesso à raiz é necessário para algumas das etapas e deve ser opcional para outras pessoas (mas ainda não resolvi isso). Você precisará de um shell, debootstrap , chroot e gcc (o último porque precisamos de uma ferramenta personalizada).

Instalando uma instância mínima do Debian

Para fazer isso, precisaremos de um programa chamado debootstrap . Este programa, como o nome sugere, permite inicializar uma instalação Debian. Você pode instalá-lo com:

sudo apt-get install debootstrap

Agora que isso é feito, podemos chegar à instalação real.

  1. Primeiro, verifique em qual versão do Debian seus pacotes desejados estão.
    Os meus estão em sid no momento da escrita.
  2. Agora determine onde você gostaria de armazenar esta imagem Debian.
    Eu sou chato e espero precisar fazer isso mais de uma vez, então eu chamei o meu chroot.0 e coloquei diretamente no meu CWD (que também é ~ ).
  3. Execute este comando:

    sudo debootstrap --variant=minbase sid chroot.0
    

    substituindo sid pela versão desejada do Debian e chroot.0 pelo caminho para o diretório que você gostaria de usar.

    Você também pode usar o uso --variant=fakeroot e possivelmente evitar usar sudo aqui, mas isso instalará muitos pacotes extras (a menos que você possa combinar --variant s) e poderá invalidar o restante da resposta para problemas de permissões.

Enquanto isso estiver em execução, você pode ler a próxima seção desta resposta.

Instalando os pacotes

Essa é a parte fácil. Uma vez que o sistema está instalado, você pode chroot para instalar os pacotes que você deseja.

  1. chroot na instância mínima do Debian:

    sudo chroot chroot.0
    

    (novamente substituindo o chroot.0 pelo caminho que você usou).

  2. Agora você deve estar em um shell de root, onde você pode instalar os pacotes que deseja:

    apt install idle-python3.7 python3.7
    
  3. Deixe o chroot executando exit .

Agora, nós poderíamos executar os pacotes do chroot . Mas então eles estariam rodando como root e isolados do seu diretório pessoal, a menos que você se esforçasse para criar um novo usuário dentro do chroot e configurar um ponto de montagem encadernado para o seu diretório pessoal ... e em Nesse ponto, começa a ser como configurar todo um novo sistema. Em vez disso, vamos começar a criar ferramentas.

Crie uma ferramenta

Salve isso em algum lugar:

#include <stdio.h>
#include <string.h>
#include <sys/mount.h>
#include <linux/limits.h>

int main(int argc, char **argv) {
    if (argc < 3) {
        printf(
"This is a single-use, disposable program that binds specified directories from\n"
"a chroot's root to the current root.\n"
"\n"
"Argument #1 should be the path to the chroot directory, sans trailing /.\n"
"Subsequent arguments should be paths relative to the root, with preceeding /.\n"
        );
        return 2;
    }
    for (int i = 2; i < argc; i += 1) {
        char source[PATH_MAX];  /* Not really MAX, but quite big. */
        strcpy(&source, argv[1]);
        strcat(&source, argv[i]);
        if (mount(&source, argv[i],
                  NULL, MS_BIND,
                  NULL) == -1) {
            return 1;
        }
    }
    return 0;
}

e compile com gcc :

gcc bindfromchroot.c -o bindfromchroot

Eu chamei de bindfromchroot porque é isso que faz. A razão pela qual não podemos usar apenas mount --bind é que pelo menos duas chamadas para mount são necessárias; um deles irá sombrear mount e outro irá sombrear suas bibliotecas - ambos irão parar mount rodando em um tempo subseqüente e nos deixar com um namespace quebrado que teremos que exit de.

Agora que toda a nossa configuração está concluída, podemos executar alguns comandos que provavelmente devem ser colocados em um script de shell.

Crie o namespace e execute o programa

  1. Execute sudo unshare -m su YOUR_USERNAME ou sudo unshare -m su $(id -un) para lançar um shell em um namespace separado como você (ou o usuário atual). Esse "namespace separado" é importante; isso significa que quando montamos partes de nossa instância mínima do Debian sobre o host Debian, as mudanças só se aplicam ao nosso novo shell e seus processos filhos (em oposição a cada processo). Pode ser uma boa ideia anexar -c /bin/sh ao comando, porque bash exibe mensagens de aviso irritantes sobre as coisas que estão ficando catastroficamente incorretas depois de executarmos a próxima etapa.
  2. Execute a ferramenta que você compilou anteriormente. Ele requer sudo e realmente não informa sobre erros salvos via echo $? , mas faz o trabalho. Quanto do Debian você precisa se ligar depende do programa, mas eu sugiro strongmente que seja o mais específico possível e não de ligação sobre /etc , /dev ou /boot . Para fazer o Python 3.7 funcionar na minha máquina, eu corri:

    sudo ./bindfromchroot chroot.0 /usr /lib
    
  3. Teste o programa que você deseja executar, por exemplo %código%. Se não funcionar, verifique as mensagens de erro, calcule o que está faltando, idle-python3.7 e tente novamente na etapa 1.

Escrevendo um script de shell para executar seu programa automaticamente

Eu consegui um one-liner para isso. Modifique conforme apropriado:

sudo unshare -m su wizzwizz4 -c sh -c 'sudo -S ./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

Se você deseja que isso preserve as variáveis de ambiente, use esta versão:

sudo -E unshare -m su wizzwizz4 -mc sh -c 'sudo -ES ./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

Você pode alterar o exit para sudo -ES para executar o programa definido na variável de ambiente sudo -EA , que pode ser um prompt gráfico (como o fornecido com SUDO_ASKPASS ), se desejar.

    
por 25.07.2018 / 13:53