Substituindo um link simbólico por um diretório ou um diretório por qualquer tipo de arquivo

Devido a uma limitação conhecida do RPM, não é possível substituir um diretório por qualquer tipo de arquivo ou link simbólico, nem é possível substituir um link simbólico para um diretório por um diretório sem RPM produzindo erros de conflito de arquivo ao tentar instalar o pacote. Para obter mais informações sobre os problemas envolvidos, consulte bug 447156 e bug 646523.

Tente evitar o problema em primeiro lugar

Embora obviamente não seja possível prever todos os casos em que possa surgir a necessidade, quando a necessidade é previsível, como com bibliotecas agrupadas, é melhor usar um link simbólico desde o início, pois o alvo do link simbólico pode ser alterado mais facilmente . Por exemplo, se você tem uma biblioteca libfoo dentro da estrutura de diretório do pacote, coloque-a, por exemplo, em um diretório` libfoo.bundled` e faça de libfoo um link simbólico para ele. Quando o agrupamento for eventualmente removido, você só precisa descartar o diretório e alterar o link simbólico para apontar para o diretório da biblioteca do sistema correspondente, sem recorrer aos scriptlets descritos abaixo.

Contornando isso com scriptlets

Para contornar esse problema, você deve incluir um scriptlet %pretrans que executa manualmente a conversão antes do RPM tentar instalar o pacote.

Observe que scriptlets '%pretrans +' DEVEM ser escritos em Lua e, portanto, usam `-p<lua>+` para funcionar durante a instalação inicial do sistema quando nenhum shell foi instalado ainda.

Por favor, use qualquer um dos dois trechos a seguir que seja necessário em pacotes que precisam desta transição, substituindo +/caminho/para/dir + pelo caminho para o diretório que está sendo convertido.

Scriptlet para substituir um diretório

O RPM não pode simplesmente remover um diretório quando ele é substituído por um arquivo ou link simbólico, uma vez que os usuários podem ter adicionado ou modificado arquivos no diretório. Para se proteger contra perda acidental de dados, você DEVE usar o seguinte scriptlet que renomeia o diretório com um sufixo .rpmmoved para que os usuários possam encontrar o diretório de backup se precisarem após o pacote ser atualizado. (Ele também acrescentará um número inteiro ao sufixo, no caso raro de que o diretório também exista.)

%pretrans -p <lua>
-- Defina o caminho para o diretório sendo substituído abaixo.
-- NÃO adicione uma barra no final.
path = "/caminho/para/dir"
st = posix.stat(path)
if st and st.type == "directory" then
  status = os.rename(path, path .. ".rpmmoved")
  if not status then
    suffix = 0
    while not status do
      suffix = suffix + 1
      status = os.rename(path .. ".rpmmoved", path .. ".rpmmoved." .. suffix)
    end
    os.rename(path, path .. ".rpmmoved")
  end
end

Além disso, você deve definir o diretório +/caminho/para/dir.rpmmoved + como uma entrada %ghost na lista %files no arquivo spec do pacote, de modo que o diretório não seja inteiramente órfão e possa ser excluído se o pacote for desinstalado e o diretório estiver vazio.

Substituir um link simbólico para um diretório por um diretório regular é muito mais simples, pois não há potencial para remover acidentalmente arquivos adicionados externamente. O scriptlet a seguir verifica e remove o link simbólico. Não há necessidade de criar o diretório aqui, pois o RPM fará isso posteriormente na transação, quando o pacote for instalado.

%pretrans -p <lua>
-- Defina o caminho para o link simbólico sendo substituído abaixo.
path = "/caminho/para/dir"
st = posix.stat(path)
if st and st.type == "link" then
  os.remove(path)
end