官术网_书友最值得收藏!

Avoiding antipatterns

Speaking of things to avoid, there is a language feature that we will only address in order to advise great caution. Puppet comes with a function called defined, which allows you to query the compiler about resources that have been declared in the manifest:

if defined(File['/etc/motd']) {
  notify { 'This machine has a MotD': }
}

The problem with the concept is that it cannot ever be reliable. Even if the resource appears in the manifest, the compiler might encounter it later than the if condition. This is potentially very problematic, because some modules will try to make themselves portable through this construct:

if ! defined(Package['apache2']) { 
  package { 'apache2': 
    ensure => 'installed' 
  } 
} 

The module author supposes that this resource definition will be skipped if the manifest declares Package['apache2'] somewhere else. As explained, this method will only be effective if the block is evaluated late enough during the compiler run. The conflict can still occur if the compiler encounters the other declaration after this one.

The manifest's behavior becomes outright unpredictable if a manifest contains multiple occurrences of the same query:

class cacti { 
  if !defined(Package['apache2']) { 
    package { 'apache2': ensure => 'present' } 
  }
}
class postfixadmin { 
  if !defined(Package['apache2'] { 
    package { 'apache2': ensure => 'latest' } 
  }
}

The first block that is seen wins. This can even shift if unrelated parts of the manifest are restructured. You cannot predict whether a given manifest will use ensure=>latest for the apache2 package or just use installed. The results become even more bizarre if such a block wants a resource removed through ensure=>absent, while the other does not.

The defined function has long been considered harmful, but there is no adequate alternative yet. The ensure_resource function from the stdlib module tries to make the scenario less problematic:

ensure_resource('package', 'apache2', { ensure => 'installed' })

By relying on this function instead of the preceding antipattern based around the defined function, you will avoid the unpredictable behavior of conflicting declarations. Instead, this will cause the compiler to fail when the declarations are passed to ensure_resource. This is still not a clean practice, though. Failed compilation is not a desirable alternative either.

Both functions should be avoided in favor of clean class structures with nonambiguous resource declarations.

主站蜘蛛池模板: 台北县| 昭觉县| 阿拉善左旗| 灯塔市| 安新县| 石楼县| 德安县| 新余市| 额尔古纳市| 化州市| 葫芦岛市| 赣榆县| 连城县| 金溪县| 齐齐哈尔市| 宁安市| 金堂县| 安龙县| 阳谷县| 黑水县| 太原市| 桃园市| 深泽县| 乳山市| 屏边| 永丰县| 吴忠市| 无极县| 湖北省| 利辛县| 五原县| 抚顺县| 德令哈市| 获嘉县| 时尚| 龙山县| 宁阳县| 铁岭县| 靖安县| 龙山县| 克拉玛依市|