Especificando pré-requisitos para fatos personalizados do Puppet?

2

Eu escrevi um fato personalizado do Puppet que requer que a ferramenta biosdevname seja instalada. Não tenho certeza de como configurar as coisas corretamente, para que essa ferramenta seja instalada antes que facter tente instanciar o fato personalizado.

Os fatos são carregados no início do processo, então não posso simplesmente colocar um package { biosdevname: ensure => installed } no manifesto, já que até o momento em que o Puppet chegar até aqui, o costume já falhou.

Eu estava curioso para saber se poderia resolver isso através dos estágios do Puppet. Eu tentei:

stage { pre: before => Stage[main] }
class { biosdevname: stage => pre }

E:

class biosdevname {
  package { biosdevname: ensure => installed }
}

Mas isso não funciona ... O Puppet carrega os fatos antes de entrar no estágio pre :

info: Loading facts in physical_network_config
./physical_network_config.rb:33: command not found: biosdevname -i eth0
info: Applying configuration version '1320248045'
notice: /Stage[pre]/Biosdevname/Package[biosdevname]/ensure: created

Etc. Existe alguma maneira de fazer isso funcionar?

EDIT : Eu devo deixar claro que eu entendo, dada uma declaração package adequada, que o fato será executado corretamente em subseqüentes execuções. A dificuldade aqui é que isso faz parte do nosso processo inicial de configuração. Estamos executando o Puppet no kickstart e queremos que a configuração de rede esteja em vigor antes da primeira reinicialização.

Parece que a única solução viável é simplesmente executar o Puppet duas vezes durante a configuração inicial do sistema, o que garantirá que os pacotes necessários estejam no lugar.

Além disso, para Zoredache:

# This produces a fact called physical_network_config that describes
# the number of NICs available on the motherboard, on PCI bus 1, and on
# PCI bus 2.  The fact value is of the form <x>-<y>-<z>, where <x>
# is the number of embedded interfaces, <y> is the number of interfaces
# on PCI bus 1, and <z> is the number of interfaces on PCI bus 2.

em = 0
pci1 = 0
pci2 = 0

Dir['/sys/class/net/*'].each {
    |file| devname=File.basename(file)
    biosname=%x[biosdevname -i #{devname}]
    case 
    when biosname.match('^pci1')
        pci1 += 1
    when biosname.match('^pci2')
        pci2 += 1
    when biosname.match('^em[0-9]')
        em += 1
    end
}

Facter.add(:physical_network_config) do
    setcode do
        "#{em}-#{pci1}-#{pci2}"
    end
end
    
por larsks 02.11.2011 / 16:36

3 respostas

5

Tanto quanto eu sei, você não pode. Deixar falhar ou detectar e falhar normalmente. Eu tenho um número de plugins que só funcionam no Debian que falham na Red Hat sem conseqüências.

Além disso, lembre-se de que é IMPOSSÍVEL ter um fato avaliado APÓS algumas configurações. A arquitetura não suporta:

Client                               Server
Compute facts
Ask for catalog passing facts =>     Receive Catalog request
                                     Compute catalog using facts
                              <=     Return Catalog
Based on the dependency tree,
  For each configuration with satisfied dependencies
    Apply configuration
    Mark (or not) dependency as satisfied
Send report, if configured so

Então, você vê, a configuração só é aplicada por muito tempo, muito tempo depois que os fatos foram processados, e não há como voltar atrás. O que pode acontecer é que a execução next agora será capaz de gerar esse fato.

Veja também o truque usado pelo módulo comum para lidar com a falta de lsbrelease no Debian sem produzir erros fatais. / p>     

por 02.11.2011 / 17:24
1

Adicione um cheque ao próprio código de fato. Verifique se o biosdevname existe antes de tentar executá-lo. Se não existir, defina o valor como undef. Use se instruções dentro de seus manifestos que exigem que o fato tenha um certo valor.

    
por 02.11.2011 / 17:34
0

Você pode adicionar condicionais em seus plugins para verificar várias coisas antes de adicionar fatos e, adicionalmente, o Facter tem um método de "confinar" que só executará a descoberta do Facter com base em condições em outros fatos (por exemplo, o suporte do Windows ao Facter é altamente dependente em confinar)

Exemplo de um fato condicional:

if File.exists?("/usr/bin/mysql")
  Facter.add(:mysql_version) do
    %x[#{mysqlcmd} "SELECT VERSION()"].to_s.strip
  end
end

Exemplo de Confinar:

# Packaging on OpenBSD.  Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
  desc "OpenBSD's form of 'pkg_add' support."
  commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
  defaultfor :operatingsystem => :openbsd
  confine :operatingsystem => :openbsd
    
por 21.11.2011 / 18:41