How to recursively change the owner and group on a directory with Chef?

后端 未结 5 2323
情歌与酒
情歌与酒 2021-02-18 15:45

the resource_directory has only 2 actions available: create and delete

I need to update the owner and group of a directory recursi

相关标签:
5条回答
  • 2021-02-18 16:22

    I would use plain resource directory with action :create. Per documentation:

    :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

    0 讨论(0)
  • 2021-02-18 16:25

    We could write a chef resource which iterates through your directory hierarchy and creates a file or directory resource for every file that it finds and then set it up to manage the owner and group on those files. You won't like that, however, since if you have a thousand files in that directory then you'll get a thousand chef resources and your converges will be slow.

    If you want to you can, in fact, roll your own code which does something like that which I wrote in the ticket tickets.opscode.com/browse/CHEF-690 which @name referenced, but I wouldn't recommend it.

    If you're trying to prevent "tampering" and fix random corruption of user and group attributes then your solution is probably correct. You'll always execute that command on every chef convergence and the resource will always show as being updated, but the command will run as fast as possible (chown -R is basically convergent and idempotent as it checks the perms before trying to set the perms). You will not get reporting back on fixed perms which is the only downside.

    If you are just trying to fix the perms once on building a server, then you should throw a not_if conditional in there to check that if the root directory has the correct perms you don't run it every time. That will give you idempotent behavior and will not execute the command on every run, but the downside is clearly that if one of the files under that directory structure has its perms mangled by someone or something in the future, then it will not get corrected.

    There's a possible use case here for a single resource which behaves like chown -R and then reports what it fixed (and array of files that had perms changed) which would be useful for cases like SOX and PCI-DSS reporting, but we don't currently cover that use case.

    tl;dr is that your solution is fine and you can add a not_if guard if you like

    0 讨论(0)
  • 2021-02-18 16:27

    You can set the default action to nothing then have resources that may screw things up notify the perm fixer:

    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
    

    with more options you could have the action :run but not if the parent folder is already the correct perms. You could alter this to include a deeper/problem file/directory, or with a find command similar to 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) = "www-data" ]'
    end
    

    Edit: fix to reflect comment below

    0 讨论(0)
  • 2021-02-18 16:30

    If this as a one-off to fix permissions your shortest path might be just knife ssh. (I just did that after ending up here on my own search.)

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

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

    If I were setting this up from scratch I think I'd need to set up the directory path and proper permissions with one line (NOTE: explicitly apply the perms to each parent in the path)

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

    and then create each individual file as a cookbook_file.

    0 讨论(0)
  • 2021-02-18 16:31

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

    Answer met my need but there is an issue with grep command, even if the user is apache2 or apach the grep exit code will be 0, but I needed the user to exactly be apache (Apache web server user on CentOS 7.7).

    Here is my recipe:

    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
    

    For comparison:

    P.S.: to check group as well:

    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
    
    0 讨论(0)
提交回复
热议问题