Como posso dizer ao Puppet “Se eu declarar a classe X, aplique seus recursos antes da classe Y”?

4

Na minha configuração do Puppet, eu quero dizer "Se eu declarar a classe X, aplique seus recursos antes da classe Y." Em outras palavras, quero declarar uma ordenação, mas permaneço em silêncio sobre aplicar ou não a classe X.

Se eu entendi o metaparameter "before" corretamente, dizendo:

class X {
    ...
    before => Class['Y'],
}

class Y {
    ...
}

node N {
    include Y
}

node M {
    include X
    include Y
}

incluirá os recursos de X e Y em ambos os nós M e N. Em vez disso, o que eu quero é expressar separadamente, "Aplicar apenas Y", "Aplicar X e Y e aplicar X antes de Y".

Para o contexto, o que eu quero fazer mais concretamente é garantir que meus repositórios Yum sejam configurados antes que o Puppet aplique os recursos do pacote. Eu quero omitir alguns repositórios de alguns nós. Eu quero que minhas definições de recurso de pacote permaneçam ingênuas sobre os repositórios correspondentes; Eu não quero ninhar minhas definições de recursos de pacotes com dependências em repositórios específicos.

Eu tentei usar Run Stages, mas além da configuração mais simples, eles parecem causar ciclos de dependência. Por exemplo, isso funcionaria:

stage { 'first': before => Stage['main'] }

class X {
    ...
    before => Class['Y'],
}

class Y {
    ...
}

node N {
    include Y
}

node M {
    class { "X": stage => first }
    include Y
}

Mas isso não aconteceria:

stage { 'first': before => Stage['main'] }

class X {
    ...
    class { "Z": stage => first } # to avoid Z "floating off"
    before => Class['Y'],
}

class Y {
    ...
    include Z
}

class Z { ... }

node N {
    include Y
}

node M {
    class { "X": stage => first }
    include Y
}

No último, Puppet acha que existe um ciclo de dependência. Eu presumo que seja devido a Z ser declarado e seus recursos serem gerenciados em dois estágios diferentes. Eu poderia potencialmente simplificar as classes que eu preciso no estágio "primeiro" para evitar os problemas do ciclo de dependência que estou vendo na prática, mas a documentação do Puppet se espalha FUD sobre os estágios de execução.

Aqui está o bit específico de configuração que faz com que os Run Stages sejam realmente pouco atraentes para mim. No desenvolvimento de VMs eu estou inicializando um servidor Yum localmente através de um "devrepo".

class yum::devrepo {

    # Ensures httpd is running as a Yum server before anything else
    # tries to install packages from it.
    exec { 'httpd-for-yum':
        command => '/sbin/service httpd restart',
        require => Class['yum::server'],
    }

    yumrepo {
        "devrepo":
            require    => [Exec['httpd-for-yum'],],
            descr      => "Local Dev YUM Repo",
            baseurl    => "http://localhost/repos/redhat/5/x86_64/",
            gpgcheck   => "0",
            enabled    => "1",
    }
}

class yum::server {

    include httpd

    package { ['createrepo']:
        ensure => present;
    }

    exec { 'update-repo-metadata':
        require => [ Package['createrepo']],
        cwd => '/var/www/html/yum',
        command => '/usr/bin/createrepo --update -d repos/redhat/5/x86_64/',
        creates => '/var/www/html/yum/repos/redhat/5/x86_64/repodata/repomd.xml',
    }

    file {'/etc/httpd/conf.d/yum.conf':
        ensure  => file,
        mode    => 0644,
        source  => "puppet:///modules/yum/yum_httpd.conf",
        require => Package['httpd'],
        notify  => Service['httpd'],
    }
}

Eu quero incluir meu repositório Yum de produção em alguns nós e o repo de desenvolvimento em outros.

Se eu colocar yum::server e yum::devrepo no estágio "primeiro", as declarações posteriores do httpd em outras classes causarão problemas mais tarde, porque as outras classes colocam o httpd no cenário principal.

Se o Puppet puder expressar "Se eu declarar a classe X, aplique seus recursos antes da classe Y", como? Se não, como posso obter a ordem desejada sem ciclos de dependência e sem incluir recursos do repositório Yum que eu queira omitir?

    
por Matt McClure 20.09.2012 / 07:23

2 respostas

2

Não tenho certeza se isso funcionará, mas talvez você possa tentar definir as dependências em um escopo no nível do nó. Por exemplo:

class X {
    ...
}

class Y {
    ...
}

node N {
   include Y
}

node M {
    Class['X'] -> Class['Y']
    include X
    include Y
}
    
por 20.09.2012 / 15:03
1

Parece que a resposta de golja pode funcionar. Aqui está o padrão que eu pousei em mim mesmo. Parece estar funcionando até agora.

class yum::reposareready {

    # The sole and critical purpose of this class is to act as an
    # intermediary between various repositories and the package
    # resources. It lets us do things like:

    # class yum::repofoo { ... }

    # class applicationbar {
    #     package { 'bazfromtherightrepo': ..., require => yum::reposareready, }
    # }

    # node n {
    #     class { 'yum::repofoo': before => Class['yum::reposareready'] }
    # }

    # With this pattern:

    # 1. The repository resource doesn't need to know about its ordering.

    # 2. Nodes can mix in repository resources, including and excluding
    #    repositories as needed.

    # 3. Classes that declare package resources need only require a
    #    generic "repos are ready" class rather than the knowing the
    #    specific repository from which to get a package.

    # DO NOT DO THIS:

    # class yum::repofoo { before => Class['yum::reposareready'] }
    # class yum::repobar { before => Class['yum::reposareready'] }
    #
    # node n {
    #     include yum::repofoo
    # }
    #
    # node m {
    #     include yum::repobar
    # }

    # The former scopes the ordering dependency to the node, whereas the
    # latter does not. The latter would make Puppet apply yum::repofoo
    # to both nodes n and m, whereas the former only applies
    # yum::repofoo to node n.

}
    
por 21.09.2012 / 18:53

Tags