-2

I want to comment "Defaults requiretty" line present in /etc/sudoers file using Chef. If it is already commented, the ruby code should skip commenting it. I'm using CentOS 6.7 operating system. So far I have done this in my recipe:

files = Dir.glob("/home/cent/etc/*")

files.each do |file_name|
  text = File.read(sudoers)
  replace = text.gsub!(/Defaults    requiretty/, "#Defaults    requiretty")
  File.open(sudoers, "w") { |file| file.puts replace }
end
StephenKing
  • 36,187
  • 11
  • 83
  • 112

3 Answers3

2

The correct solution is to use a template resource to control the file content, rather than performing differential updates against a distro-provided file. This ensures overall convergent behavior and makes it easier to mentally model the state of the system.

coderanger
  • 52,400
  • 4
  • 52
  • 75
1

To expand on the other answers and comments. One of the principles of Chef is that cookbooks and recipes should idempotent and convergent. They specify the state you want your nodes to be in, they check what needs to be done to bring it into that state, and apply only those changes.

This logically makes sense, minimizes unnecessary changes and how Chef is structured to run under-the-hood.

Running the Ruby code in your example, will not add extra '#' symbols, but it will update your file everytime it is run. This is misleading and could have an impact if some application checks your file's update time to see if a config change has occurred.

The template resource suggested by @coderanger will only update the file if required. Also, a template is more likely clearer than some Ruby Code. This approach is how must other (good) Chef code works

matt freake
  • 4,877
  • 4
  • 27
  • 56
-3

We've got the answer!

ruby_block "replace_line" do
  block do
    file = Chef::Util::FileEdit.new("/etc/sudoers")
    file.search_file_replace_line(/Defaults    requiretty/, "#Defaults    requiretty")
    file.write_file
  end
end
StephenKing
  • 36,187
  • 11
  • 83
  • 112
  • does the recipe you are using have a sudoers template? or does it just use the default. Normally I create my own template as opposed to trying to regex/comment out lines, – Doon Feb 04 '16 at 12:52
  • @Doon Hi.. No we did not use any template. – Shesh Kumar Bhombore Feb 04 '16 at 13:36
  • 1
    Using FileEdit is not recommended. Notably this will update the file every time because your regex isn't idempotent. – coderanger Feb 04 '16 at 15:33
  • @coderanger We ran this recipe again and again just to see if there are multiple "#" prefixed to "Defaults requiretty" line. But it did not do that. We could see single '#' symbol prefixed :) – Shesh Kumar Bhombore Feb 05 '16 at 07:30