【问题标题】:How to run the same class multiple times?如何多次运行相同的课程?
【发布时间】:2014-08-19 10:30:10
【问题描述】:

我有一个 puppet 模块,它部署一个 JAR 文件并编写一些属性文件(通过使用 ERB 模板)。 最近我们为应用程序添加了“模式”功能,这意味着应用程序可以根据清单中输入的值以不同的模式运行。 我的层次结构如下:

设置

*配置

**文件

*安装

意思是setup调用config类和install类。 install类根据模式部署相关的RPM文件

config 类检查模式,并为每个模式调用具有特定模式和目录参数的 files 类,这种结构的原因是属性的值取决于实际模式。

技术问题是,如果清单中有多种模式(这是我的目标),我需要调用文件类两次:

if grep($modesArray, $online_str) == [$online_str] {
    class { 'topology::files' :
      dir   => $code_dir,
      mode  => $online_str
    }
  }

  $offline_str = "offline"
  $offline_suffix = "_$offline_str"
  if grep($modesArray, $offline_str) == [$offline_str] {
    $dir = "$code_dir$offline_suffix"
    class { 'topology::files' :
      dir   => $dir,
      mode  => $offline_str
    }

但是,在 puppet 中,你不能两次声明同一个类。

我试图弄清楚如何调用一个类两次或者一个方法,我可以从我的 ERB 文件中访问其参数,但我无法弄清楚

文档说这是可能的,但没有说明如何(我在这里查看https://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#declaring-classes)。

所以总结一下有没有办法:

  1. 使用不同的参数多次调用同一个类
  2. (其他方式)基于同一个 ERB 文件创建多个文件(每次使用不同的参数)

【问题讨论】:

  • 您可能想要创建自定义资源:docs.puppetlabs.com/guides/custom_types.html
  • 我将如何使用它来解决我的问题?
  • 不是创建一个类(不能多次使用),而是创建一个自定义资源,它与您的类完全一样,可以多次使用。然而,这是一项相当广泛的任务,因此您需要阅读文档并尝试自己编写,或者您可以等待其他答案,这可能更合适。
  • 我现在正在尝试在函数中创建不涉及 ERB 的所有内容(这也很难做到),然后我将为需要的一个文件创建两个不同的 ERB再培训局。在 puppet 中编写可移植代码非常困难

标签: ruby puppet


【解决方案1】:

您可以简单地将您的类声明为定义:

define topology::files($dir,$mode){
  file{"${dir}/filename":
    content=> template("topology/${mode}.erb"), 
  }
}

这将为每种模式应用不同的模板

然后,根据需要多次实例化它:

if grep($modesArray, $online_str) == [$online_str] {
    topology::files{ "topology_files_${online_str}" :
      dir   => $code_dir,
      mode  => $online_str
    }
  }

  $offline_str = "offline"
  $offline_suffix = "_$offline_str"
  if grep($modesArray, $offline_str) == [$offline_str] {
    $dir = "$code_dir$offline_suffix"
    topology::files{ "topology_files_${online_str}" :
      dir   => $dir,
      mode  => $offline_str
    }

【讨论】:

  • 但请记住,每个实例的$dir 必须不同。 Puppet 不能同步同一个文件在事务的不同阶段有两个不同的内容。 Puppet 必须确保只有一个目标状态。
【解决方案2】:

您对文档的解释不合时宜。

Puppet 中的类应该被视为单例。每个类只有一个实例。它是节点清单的一部分,或者不是。清单可以使用include 关键字随时声明类。

注意使用类似资源的语法声明。

class { 'classname': }

这可以在清单中最多出现一次。参数值现在永久绑定到您的类。您的节点已选择该类应为其采用的特定形状。

没有看到您课程的代码,您的问题让我相信您正在尝试将 Puppet 用作脚本引擎。它不是。 Puppet 只允许您对目标状态进行建模。有一些强大的机制可以实现复杂的工作流程以实现该状态,但您不能使用它以任意顺序运行任意转换。

如果您添加类代码,我们可以尝试提供一些建议,说明如何对其进行重构,以使 Puppet 满足您的需求。不过,恐怕这可能是不可能的。如果确实有必要在事务期间将一个或多个资源在不同时间同步到不同状态(脚本引擎?;-),您应该将整个工作流程实现为实际脚本,并让 Puppet 通过exec 资源运行它在适当的时候。

【讨论】:

  • 嗨,Felix,我们有完全相同的应用程序,它以两种不同的模式运行。唯一的区别是输入流不同,输出表不同。当我可以使用相同的 puppet 脚本部署两种模式(单独或同时部署两种模式)时,我认为没有理由复制整个代码
  • 好吧,如果两个应用程序确实相互独立,那么 Raul Andres 的回答基本上应该满足您的需求。那么您的用例确实不是用于类,而是用于定义的类型。
  • 谢谢菲利克斯。我正在尝试 Raul 的解决方案,它仍然无法正常工作,但我认为我走在正确的道路上
  • 当然。请考虑分享课程代码以获得更好的答案。
  • 剩下的就是创建文件和一个ERB
猜你喜欢
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
相关资源
最近更新 更多