5

我在 Amazon Linux 2012.09 上使用 Puppet 3,我的清单之一设置并重新配置了一些目录。其中一项任务是将文件夹所有者和组 recursivelt 更改为另一个用户 - 但是,这需要 60 秒才能完成,并且目录中几乎没有任何内容 - 终端中的 chown myuser:myuser /var/lib/jenkins不到一秒钟。

我的问题是:有没有更好/更快的方法在 Puppet 中递归更改目录所有权?

谢谢

 file {'/var/lib/jenkins':
   ensure  => 'directory',
   owner   => myuser,
   group   => myuser,
   recurse => true,
   require => Package['jenkins'],
 }
4

2 回答 2

4

我也看到了这种缓慢,这似乎是由于 Puppet/var/lib/jenkins单独检查每个文件以确保它具有正确的所有者权限,这需要时间,因为$JENKINS_HOME.

我在我们的 Jenkins 服务器上解决了这个问题,只要顶层目录不属于所需的用户,而是运行一个简单的chown -R命令(带):exec

define modify_owner() {
  exec { "modify_owner_${title}" :
    command => "/bin/chown -R ${user}:${user} '${title}'",
    onlyif => "/usr/bin/stat -c %U '${title}' | grep '^${default_user}$'"
  }
}

modify_owner { ['/var/lib/jenkins', '/var/log/jenkins', '/var/cache/jenkins']: }

$user/是我希望这些目录拥有$user的所有者/组组合。这使我的 Puppet 时间恢复到正常水平。

注意:我使用过stat -c %U,但您可能需要根据您的操作系统调整确切的格式选项。此命令打印所有者的文本名称并在 Linux 上为我工作。)

于 2013-04-17T00:15:26.317 回答
0

@stuart-m 的解决方法是正确的基本结构。如果您需要深入,请使用 find 和 xargs。我没有幸运地拥有他的还原用例!

请注意,Puppet 的缓慢不仅仅是因为它必须检查的文件数量。这是 Puppet 在某些任务上的速度非常慢。

我在 wordpress 目录树(Debian 10)上对此进行了测试。

# time find /var/www/*/wordpress/wp-content/ -type f | wc -l
50661

real    0m0.148s
user    0m0.048s
sys     0m0.107s

所以那里有五万个文件——这需要大约七分之一秒才能确定。现在我们检查实际的文件所有权属性:

# time find /var/www/*/wordpress/wp-content/ -not -group www-data | wc -l
38603

real    0m0.236s
user    0m0.056s
sys     0m0.188s

更深入一点——这花了大约四分之一秒。

让我们全部更改:

time find /var/www/*/wordpress/wp-content/ -type f -exec chmod 0640 {} \; 


real    0m44.392s
user    0m29.520s
sys     0m14.729s

# time find /var/www/*/wordpress/wp-content/ -type d -exec chmod 2750 {} \; 

real    0m4.935s
user    0m3.288s
sys     0m1.666s

好的,五十秒。其中有多少是 shell 调用?

# time bash -c "find /var/www/*/wordpress/wp-content/ -type f -print0 | xargs -0 chmod 0640"

real    0m0.452s
user    0m0.148s
sys     0m0.513s

# time bash -c "find /var/www/*/wordpress/wp-content/ -type d -print0 |xargs -0 chmod 2750 "

real    0m0.149s
user    0m0.024s
sys     0m0.158s

好,天哪,几乎所有的都是贝壳叉子——实际上只花了大约一秒钟。

我在这里结束是因为directory : recurse=>true在同一棵树上的 a 大约需要 800 秒。这对于 shell 命令可以在一两秒内完成的事情来说太慢了。

我不喜欢浪费 I/O,但考虑到这方面的时间安排,如果你的文件系统是本地的(这只是一台 7 美元/月的主机,带有 spin-rust 驱动器),你可能有能力执行 find/xargs /ch[own/mod] 每次运行。

编辑:我编写了一个 puppet 函数来“完成它”,它在 2 秒内运行 18 个单独的实例,涵盖 50,000 个文件。让 Puppet 处理它的速度大约提高了 400 倍。第一部分,定义类型:

define my_class::permissions_tree (
                                    String $owner = 'root',
                                    String $group = 'root',
                                    String $fmode = '0644',
                                    String $dmode = '0755',
                                   ) {

  $path = $title

  case $os_family {
    'Debian' : {
      $find  = '/usr/bin/find'
      $xargs = '/usr/bin/xargs'
      $chmod = '/bin/chmod'
      $chown = '/bin/chown'
    }
  }

  $permissions_command_owner = "${find} $path \( -not -user ${owner} -or -not -group ${group} \) -print0 | $xargs -0 --replace=found $chown ${owner}:${group} found"
  $permissions_command_dirs  = "${find} $path \( -type d -and -not -perm ${dmode} \) -print0 | $xargs -0 --replace=found $chmod ${dmode} found"
  $permissions_command_files = "${find} $path \( -type f -and -not -perm ${fmode} \) -print0 | $xargs -0 --replace=found $chmod ${fmode} found"
  $permissions_command = join([$permissions_command_owner,$permissions_command_dirs,$permissions_command_files], ";")

  exec { "permissions_tree_${path}" :
    path     => [ '/sbin', '/bin', '/usr/sbin', '/usr/bin' ],
    command  => $permissions_command,
    provider => shell,
  }

} # permissions_tree

第 2 部分,使用它,例如:

  my_class::permissions_tree { "$some_dir/subdir" :
    owner   => $my_owner,
    group   => $my_group,
    dmode   => '2750', 
    fmode   => '0640',
    require => File[$some_dir],
  }

require 只是一个元参数,在那里使用你需要的任何东西。如果不是 Debian,请添加您的操作系统路径。

编辑 2:添加了 print0 布尔值所需的括号

于 2020-03-25T23:33:52.483 回答