Bibliotecas conflitantes de pacotes RPM

2

Qual é a prática recomendada para o empacotamento RPM, algo que fornece uma biblioteca que, no nome, cria uma sombra na biblioteca do sistema?

Antecedentes: Para um sistema Linux suportado por RPM, estou empacotando um aplicativo "autocontido" foo que deseja viver sob / opt e fornecer tantas de suas próprias dependências quanto possível, para não depender das versões instaladas em o sistema principal. ( foo usa LD_LIBRARY_PATH para evitar bibliotecas do sistema.)

Infelizmente, uma das dependências foo é uma biblioteca grunk , cuja versão é exatamente igual à libgrunk.so necessária para o sistema principal. A geração automática de Provides: do RPM identifica então dois RPMs como provedores desta biblioteca. (Isso não é realmente verdade - apenas o pacote do sistema disponibiliza a biblioteca para qualquer programa, enquanto o pacote foo o disponibiliza apenas para foo .)

Isso confunde a resolução automática de dependência, às vezes. Por exemplo, yum pode instalar o pacote errado ou apenas um pacote quando dois são necessários.

Exemplo:

grunk-libs-1.2-3.$arch.rpm              # System Library
  Files:
    %{_libdir}/libgrunk.so.1
    %{_libdir}/libgrunk.so.1.2
  Provides:
    libgrunk.so.1()(%{_arch})

foo-x.y.z-r.$arch.rpm                   # App
   Files:
     /opt/foo
     /opt/foo/bin/...
   Requires:
     libgrunk.so.1()(%{_arch})          # foo needs grunk, but wants its own instance

foo-grunklibs-1.2-1.$arch.rpm           # App Dependency
  Files:
    /opt/foo/libs/libgrunk.so.1
    /opt/foo/libs/libgrunk.so.1.2
  Provides:
    libgrunk.so.1()(%{_arch})           # <-- same as from system "grunk-libs"

Eu desativei o AutoReqProv por enquanto, mas quero aproveitar os recursos automáticos e a geração de dependências do RPM. Eu quero que o RPM saiba que foo.rpm requer foo-grunklibs.rpm em virtude do último libgrunk.so.1 , mas também sabe que a mesma biblioteca do sistema principal rpm não será suficiente.

Acho que estou nos limites do uso convencional. Existe uma técnica de embalagem que eu possa usar aqui para resolver isso?

    
por pilcrow 21.03.2014 / 14:42

1 resposta

0

Depois de considerar isso por um tempo, acho que a abordagem mais correta é usar "namespaces" de recursos virtuais de RPM. Por exemplo:

Provides:  resource               # 'resource' is available to the whole system
Provides:  namespace(resource)    # 'resource' is specifically available only to "namespace"

Os RPMs ficam assim:

grunk-libs.rpm
  Provides:  libgrunk.so.1()(%{_arch})       # System library.  unchanged

foo.rpm
  Requires:  /bin/sh
  Requires:  libc.so.6()(%{_arch})
  Requires:  foo(libgrunk.so.1()(%{_arch}))  # Note special foo(...) namespace

foo-grunklibs.rpm
  Provides:  foo(libgrunk.so.1()(%{_arch}))  # Note special foo(...) namespace

Dessa forma, a dependência foo na compilação especial de libgrunk não pode ser satisfeita pelo grunk-libs RPM comum, mas deve ser satisfeita pela compilação específica dessa biblioteca.

Minha prova de conceito é assim:

Name:     foo
...
Source99: find-namespaced-requires     # Here's the magic

%define    _use_internal_dependency_generator 0
%define    __find_requires %{SOURCE99} foo /bin/sh glibc

Onde o script find-namespaced-requires envolve o RPM padrão % {_ rpmconfigdir} / find-requires e filtra sua saída. Seu primeiro argumento é o namespace ( "foo(...)" ) a ser usado, e os argumentos subseqüentes são dependências ou RPMs que fornecem dependências que devem não ser namespaced. Neste exemplo, eu quero que foo exija o / bin / sh do sistema principal e também o libc, libdl, libm, etc. comuns de glibc , mas todas as outras dependências devem ser consideradas específicas de foo .

Isso poderia ser um pouco mais limpo e mais genérico, finalizando a maioria dos itens acima em um RPM de tempo de compilação e dizendo algo como:

Name:          foo
BuildRequires: special-deps-macros

%define _namespace            foo      # defaults to %{name} ?
%define _generic_dependencies ...      # defaults to /bin/sh glibc libselinux ?
    
por 25.03.2014 / 20:52