按特定顺序傀儡 file_line

Nen*_*nzo 2 authentication environment-variables sh puppet

我尝试向 /etc/profile 添加三个系统强化行:

TMOUT=43200
readonly TMOUT
export TMOUT
Run Code Online (Sandbox Code Playgroud)

当然,这些行需要按照这个特定的顺序排列,而且我还必须预料到文件会被弄乱并且顺序错误。 我无法使用模板,因为有些主机具有无法更改的自定义配置文件。所以我必须能够附加这三行

所以我在清单中写道:

file_line { 'TMOUT':
  path     => '/etc/profile',
  ensure   => present,
  line     => 'TMOUT=43200',
  multiple => true,
  before   => 'readonly TMOUT',
  match    => '^TMOUT',
}
file_line { 'readonly TMOUT':
  path     => '/etc/profile',
  ensure   => present,
  line     => 'readonly TMOUT',
  multiple => true,
  before   => 'export TMOUT',
  after    => '^TMOUT=43200',
  match    => '^readonly TMOUT',
}
file_line { 'export TMOUT':
  path     => '/etc/profile',
  ensure   => present,
  line     => 'export TMOUT',
  multiple => true,
  after    => '^readonly TMOUT',
  match    => '^export TMOUT',
}
Run Code Online (Sandbox Code Playgroud)

Puppet 以正确的顺序创建行,但是当我编辑文件并更改顺序时,它在重新运行期间不会得到纠正,例如

readonly TMOUT
export TMOUT
TMOUT=43200
Run Code Online (Sandbox Code Playgroud)

我是否犯了一个错误,或者我必须切换到像奥吉斯这样的其他东西?

提前致谢

Tod*_*obs 6

长话短说

您基本上有三个选择:尝试创建有序依赖项(这不是真正的 Puppet 方式)、创建复合语句或使用/etc/profile.d(如果您的发行版支持)。虽然没有单一的“最佳”方法来处理这个问题,但复合语句或声明可能是最简单的解决方案。

有序依赖项

Puppet 不保证大多数操作的顺序,除非您显式声明依赖项。以下未经测试,但可能适合您。

file_line { 'set TMOUT':
  ensure => present,
  path   => '/etc/profile',
  line   => 'TMOUT=43200',
  match  => '^TMOUT',
} ->
file_line { 'export TMOUT':
  ensure => present,
  path   => '/etc/profile',
  line   => 'export TMOUT',
  after  => '^TMOUT=',
} ->
file_line { 'set TMOUT as readonly':
  ensure => present,
  path   => '/etc/profile',
  line   => 'readonly TMOUT',
  after  => '^export TMOUT',
}
Run Code Online (Sandbox Code Playgroud)

这应该可以满足您的要求,但比它需要的更脆弱。还有更强大的选择。

复合语句和变量声明

大多数(如果不是全部)Bourne 兼容 shell 应该支持复合语句,因此您最好跳过单个原子行操作的排序。例如:

file_line { 'profile TMOUT':
  ensure => present,
  path   => '/etc/profile',
  line   => 'TMOUT=43200; export TMOUT; readonly TMOUT',
  match  => '^TMOUT',
}
Run Code Online (Sandbox Code Playgroud)

更好的是,使用 shell 的声明语法在一次操作中完成所有操作!例如:

file_line { 'profile TMOUT':
  ensure => present,
  path   => '/etc/profile',
  line   => 'declare -r -x TMOUT=43200',
  match  => '^TMOUT',
}
Run Code Online (Sandbox Code Playgroud)

注意:只读变量仍然可以在不直接设置只读属性的子 shell 中分配。这就是它的工作原理。

将文件放入 Profile.d

在支持它的发行版上,使用/etc/profile.d几乎总是比在/etc/profile这样的整体脚本中胡闹更好的选择。它也不太可能被其他脚本、系统更新等破坏。但是,有一些注意事项,我在下面指出。

# Create your snippet in the /etc/profile.d directory.
file {'/etc/profile.d/tmout.sh':
  ensure => present,
  content => "TMOUT=43200\nexport TMOUT\nreadonly TMOUT",
} ->

# Remove the lines in /etc/profile if they exist.
file_line { 'profile TMOUT':
  ensure            => absent,
  path              => '/etc/profile',
  match             => 'TMOUT',
  match_for_absence => true,
  multiple          => true,
}
Run Code Online (Sandbox Code Playgroud)

这里有一些注意事项需要注意:

  1. 存在微妙的竞争条件(即使使用依赖链),因为更改是连续的而不是原子的。可能有一个小窗口,其中 TMOUT 在多个位置定义。
  2. 由于 profile.d 是特定于供应商的,因此除非您对其进行配置,否则它可能根本不受支持(甚至可能不存在)。检查您的分发文档。
  3. 同样,由于 profile.d 是特定于供应商的,因此 profile.d 中的脚本的来源顺序可能会有所不同。它们通常源自主/etc/profile脚本,并且设置相同值的多个脚本的存在可能会使结果不确定。