我怎样才能告诉 Puppet“如果我声明了 X 类,则在 Y 类之前应用其资源”?

我怎样才能告诉 Puppet“如果我声明了 X 类,则在 Y 类之前应用其资源”?

在我的 Puppet 配置中,我想说“如果我声明了类 X,则在类 Y 之前应用其资源。”换句话说,我想声明一个顺序,但对于是否应用类 X 保持沉默。

如果我正确理解了“之前”的元参数,那么:

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

class Y {
    ...
}

node N {
    include Y
}

node M {
    include X
    include Y
}

将在节点 M 和 N 上都包含 X 和 Y 的资源。相反,我想要分别表达“仅应用 Y”或“应用 X 和 Y,并在 Y 之前应用 X”。

更具体地说,我想做的是确保在 Puppet 应用包资源之前配置我的 Yum 存储库。我想从某些节点省略一些存储库。我希望我的包资源定义对相应的存储库保持简单;我不想让我的包资源定义充斥着对特定存储库的依赖。

我尝试使用运行阶段,但除了最简单的配置之外,它们似乎会导致依赖循环。例如,这将起作用:

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

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

class Y {
    ...
}

node N {
    include Y
}

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

但这不会:

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
}

在后者中,Puppet 认为存在依赖循环。我认为这是因为 Z 被声明并且其资源在两个不同的阶段进行管理。我可以在“第一”阶段简化我需要的类,以避免我在实践中看到的依赖循环问题,但 Puppet 文档却恐惧、疑虑和不确定因素关于运行阶段。

以下是一些让我不太喜欢 Run Stages 的具体配置。在开发虚拟机中,我通过“devrepo”在本地引导 Yum 服务器。

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'],
    }
}

我想在某些节点上包含我的生产 Yum 存储库,并在其他节点上包含开发存储库。

如果我将yum::serveryum::devrepo放在“第一”阶段,那么稍后其他类中的 httpd 声明会导致问题,因为其他类将 httpd 放在主阶段。

如果 Puppet 可以表达“如果我声明类 X,则在类 Y 之前应用其资源”,那么该怎么做?如果不能,我如何才能获得我想要的顺序,而没有依赖循环,也不包括我想要省略的 Yum 存储库资源?

答案1

不确定它是否会起作用,但也许您可以尝试在节点级别范围上定义依赖项。例如:

class X {
    ...
}

class Y {
    ...
}

node N {
   include Y
}

node M {
    Class['X'] -> Class['Y']
    include X
    include Y
}

答案2

看起来像golja 的回答可能会有效。这是我自己找到的模式。到目前为止,它似乎很有效。

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.

}

相关内容