skip to Main Content

I am trying to change owner, group and permissions of every file in directories:

%w(/etc/nginx/ /etc/nginx/conf.d/ /var/l0g/nginx/).each do |path|
  directory path do
    owner "owner1"
    group "group1"
    mode '0755'
  end
end

however it only changes values of directories, specified in %w(), i was expecting this do be recursive especially with directory keyword.

How can i make this script change owner, group and permission of all files in specified dirs including directories themselves?

Thanks for help!

2

Answers


  1. There is a recursive property for the directory resource which is documented as such:

    recursive
    Ruby Type: true, false | Default Value: false

    Create parent directories recursively, or delete directory and all children recursively. For the owner, group, and mode properties, the value of this property applies only to the leaf directory.

    As such, there is no builtin way to recursively set the permissions of all files within a directory. This would also NOT be a good idea in any case as your mode of 755 would mark all configuration files as executable for everyone. As nginx configuration files are generally not intended to be executable, this would likely do the wrong thing!

    Still, if you absolutely want to do this, you could write a bit of Ruby in a ruby_block resource, such as

    require 'fileutils'
    
    %w(/etc/nginx/ /etc/nginx/conf.d/ /var/l0g/nginx/).each do |path|
      ruby_block "Set recursive permissions for #{path}" do
        block do
          FileUtils.chmod_R(0755, path)
          FileUtils.chown_R("owner1", "group1", path)
        end
      end
    end
    

    A slightly more "correct" version would be:

    %w(/etc/nginx/ /etc/nginx/conf.d/ /var/l0g/nginx/).each do |path|
      ruby_block "Set recursive permissions for #{path}" do
        block do
          FileUtils.chmod_R("u=rw+X,go=r+X", path)
          FileUtils.chown_R("owner1", "group1", path)
        end
      end
    end
    

    Here, we use a symbolic mode description instead of the strictly numeric one. This allows us to use the X specification rather than just x. The chmod specification reads here:

    • For the owner, set the read and write bits. If the file is a directory or currently has the execute bit set, the the execute bit
    • For the group and others, set just the read bit. If the file is a directory or currently has the execute bit set, the the execute bit.

    With this, all directories will have the execute/search bit set, and only those files who previously had the execute bit set will retain it (but no new files fill gain the execute bit).

    As some final notes:

    • As /etc/nginx/conf.d is already included in /etc/nginx, you can omit it from the list.
    • Instead of /var/l0g/nginx/ (with a "zero" character in the path), you likely mean /var/log/nginx/ (with a small o) instead.
    Login or Signup to reply.
  2. The answer from @Holger Just already covers the implications of changing permissions/ownership. Other than that, Chef being a configuration as code tool, is very efficient in managing the state of defined resources. Hence, using it to alter resources such as files/directories not directly managed by it, cannot guarantee idempotent actions.

    Taking all this into consideration, one option is to run the relevant Linux commands using script or execute resource.

    Example using execute resource:

    execute 'change nginx paths ownership' do
      command 'chown --recursive owner1:group1 /etc/nginx/ /var/log/nginx/'
    end
    
    execute 'change nginx paths permissions' do
      command 'chmod --recursive 0755 /etc/nginx/ /var/log/nginx/'
    end
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search