如何使用Chef以递归方式更改目录上的所有者和组?

时间:2014-05-28 20:56:10

标签: chef

resource_directory只有2个可用的操作:createdelete

我需要递归更新目录的所有者和组。

我该怎么做?

使用简单的resource_execute

execute "chown-data-www" do
  command "chown -R www-data:www-data /var/www/myfoler"
  user "root"
  action :run
end

5 个答案:

答案 0 :(得分:10)

您可以将默认操作设置为空,然后使用可能搞砸的资源通知perm修复程序:

execute "chown-data-www" do
  command "chown -R www-data:www-data /var/www/myfoler"
  user "root"
  action :nothing
end

resource "that may screw up perms" do
  stuff "one two three"
  notifies :run, execute "chown-data-www"
end

使用更多选项可以执行操作:运行但不是如果父文件夹已经是正确的权限。您可以将其更改为包含更深/有问题的文件/目录,或者使用类似于this的查找命令

execute "chown-data-www" do
  command "chown -R www-data:www-data /var/www/myfoler"
  user "root"
  action :run
  not_if "stat -c %U /var/www/myfolder |grep www-data"
end

修改:修正以反映下面的评论

答案 1 :(得分:2)

我们可以编写一个主厨资源,它遍历您的目录层次结构,并为找到的每个文件创建文件或目录资源,然后将其设置为管理这些文件的所有者和组。但是,你不会喜欢这样,因为如果你在该目录中有一千个文件,那么你将获得一千个主厨资源,你的收敛速度会很慢。

如果你愿意的话,事实上,你可以推出你自己的代码,这些代码就像我在@name引用的票证tickets.opscode.com/browse/CHEF-690中写的一样,但我不推荐它。

如果您正试图阻止"篡改"并修复用户和组属性的随机损坏,那么您的解决方案可能是正确的。您将始终在每个主厨收敛时执行该命令,并且资源将始终显示为更新,但命令将尽可能快地运行(chown -R基本上是收敛的,并且在尝试设置之前检查权限时是幂等的烫发)。你不会得到关于固定烫发的报告,这是唯一的缺点。

如果您只是在构建服务器时尝试修复烫发一次,那么您应该在那里抛出一个not_if条件来检查如果根目录具有正确的权限,您每次都不会运行它。这将为您提供幂等行为,并且不会在每次运行时执行该命令,但缺点显然是如果该目录结构下的某个文件的某个或某些东西在将来损坏了它的权限,那么它将无法得到纠正。

这里有一个可能的用例,用于单个资源,其行为类似于chown -R,然后报告它修复的内容(以及更改了perms的文件数组),这对于SOX和PCI-DSS等情况很有用报告,但我们目前不介绍该用例。

tl; dr是你的解决方案很好,如果你愿意,可以添加一个not_if后卫

答案 2 :(得分:2)

如果这是一次性修复权限,你的最短路径可能只是刀ssh。 (我在自己的搜索结束后就这样做了。)

knife ssh 'name:*' "sudo chown -R $user:$group /full/path/to/directory"

knife ssh 'name:*' "sudo chmod -R 770 /full/path/to/directory"

如果我从头开始设置这个,我想我需要设置directory路径和一行适当的权限(注意:明确地将权限应用于路径中的每个父级)< / p>

%w[ /foo /foo/bar /foo/bar/baz ].each do |path|
  directory path do
    owner 'root'
    group 'root'
    mode '0755'
  end

然后将每个人file创建为cookbook_file。

答案 3 :(得分:2)

https://stackoverflow.com/a/28283020/11822923

答案满足了我的需求,但是grep命令存在问题,即使用户是apache2apach,grep退出代码也将是0,但是我需要该用户确切为apache(CentOS 7.7上的Apache Web服务器用户)。

这是我的食谱:

node["apache"]["sites"].each do |sitename, data|
  document_root = "/content/sites/#{sitename}"

  directory document_root do
    action :create
    mode "0755"
    recursive true
    owner "apache"
    group "apache"
  end

  execute "chown_to_apache_user" do
    command "chown -R apache:apache /content"
    user "root"
    action :run
    not_if '[ $(stat -c %U /content/) = "apache" ]'
  end

  template "/etc/httpd/conf.d/#{sitename}.conf" do
    source "vhost.erb"
    mode "0644"
    variables(
      :document_root => document_root,
      :port => data["port"],
      :domain => data["domain"]
    )
    notifies :restart, "service[httpd]"
  end

end

为进行比较:

enter image description here

P.S .:还要检查group

node["apache"]["sites"].each do |sitename, data|
  document_root = "/content/sites/#{sitename}"

  directory document_root do
    action :create
    mode "0755"
    recursive true
    owner "apache"
    group "apache"
  end

  execute "chown_to_apache_user" do
    command "chown -R apache:apache /content"
    user "root"
    action :run
    not_if '[ $(stat -c %U /content/) = "apache" ] && [ $(stat -c %G /content/) = "apache" ]'
  end

  template "/etc/httpd/conf.d/#{sitename}.conf" do
    source "vhost.erb"
    mode "0644"
    variables(
      :document_root => document_root,
      :port => data["port"],
      :domain => data["domain"]
    )
    notifies :restart, "service[httpd]"
  end

end

答案 4 :(得分:0)

我会将普通资源目录action :create一起使用。 每个文档:

:create
Default. Create a directory. If a directory already exists (but does not match), update that directory to match

https://docs.chef.io/resource_directory.html