So here's where I've landed. I am using ruby blocks which spider the
directories and create new chef resource objects. I've been testing it and
it seems to be working pretty well. Since I'm relying on Chef resources -
even though they're dynamically generated during the execution phase - the
cookbook is idempotent and Chef isn't executing any unnecessary actions.
The code looks something like this:
Begin Policy Cookbook Snippet
Cookbook: mule-policy
Recipe: default
Set up a RunContext for later use
@events = Chef::EventDispatch::Dispatcher.new()
run_context = Chef::RunContext.new( node, {}, @events )
Run the library cookbook
include_recipe "mule"
Remove example applications
directory "#{node[:mule][:home]}/examples" do
recursive true
action :delete
end
Restrict access to config files
ruby_block "restrict_config_files" do
notifies :restart, "service[mule]"
action :create
block do
Dir[ "#{node[:mule][:home]}/conf/*" ].each do |path|
conf_file = Chef::Resource::File.new( path, run_context )
conf_file.owner node[:mule][:user]
conf_file.group node[:mule][:group]
conf_file.mode "0640"
conf_file.run_action :create
end
end
end
Restrict access to library files
This was the gnarly bit due to the number of .jar files
ruby_block "restrict_library_files" do
notifies :restart, "service[mule]"
action :create
block do
Dir[ "#{node[:mule][:home]}/lib/**/*" ].each do |path|
if File.file?( path )
lib_file = Chef::Resource::File.new( path, run_context )
lib_file.owner node[:mule][:user]
lib_file.group node[:mule][:group]
lib_file.mode "0640"
lib_file.run_action :create
elsif File.directory?( path )
lib_dir= Chef::Resource::Directory.new( path, run_context )
lib_dir.owner node[:mule][:user]
lib_dir.group node[:mule][:group]
lib_dir.mode "0750"
lib_dir.run_action :create
end
end
end
end
End Policy Cookbook Snippet
I'm pretty happy with it. If anyone has any further comments or
suggestions, I'd be glad to hear them.
Thanks,
-Rob
On Fri, Oct 11, 2013 at 12:25 PM, Andrew Gross andrew@yipit.com wrote:
Some additional options instead of using file
, just change the
notification.
execute "Set Permissions" do
command "chmod -R 644 /etc/foo/bar
action :nothing
only_if { ::File.exists?("/etc/foo/bar/baz.conf")}
end
We can also outsource the directory spidering to Ruby (
filesystems - One-liner to recursively list directories in Ruby? - Stack Overflow
)
Set files
Dir.glob("/etc/foo/**/*").each do |f|
file "Set permissions for #{f}" do
mode 00644
action :create
end if ::File.exists?("/etc/foo")
Set Directories
Dir.glob("/etc/foo/**/*/").each do |d|
directory "Set permissions for #{d}" do
mode 00755
action :create
end if ::File.exists?("/etc/foo")
On Fri, Oct 11, 2013 at 11:49 AM, Rob Curtis robert.h.curtis@gmail.comwrote:
Andrew,
First, thanks for the quick response. It's always a bit nerve-wracking
submitting your first question to a new mailing list.
It seems like if I go down that road, I'll end up having to explicitly
define a file or directory resource for everything in the package, which
would leave me with a huge policy cookbook that may need a major overhaul
when we upgrade to a newer version of the COTS package.
I was really hoping to do things a little more dynamically, but simply
writing a Ruby block that walks the tree of subdirectories and files at
execution time changing ownership and permission seems less "correct" than
using file and directory resources.
Chef isn't psychic, so I have to believe that my attempt to dynamically
create file and directory resources during the compile phase for stuff that
won't exist until the execution phase is just doomed to fail.
The more I think about it, the more I think I'm just going to have to
write some execution phase code to walk through the file system and make
the necessary ownership and permission changes on the installed files and
directories.
On Fri, Oct 11, 2013 at 10:19 AM, Andrew Gross andrew@yipit.com wrote:
Hey Rob,
The normal pattern for this sort of thing is to have the post install
modification use 'action :nothing' and then send them a notification from
the package install to kick off a chain of events. Something similar to
this:
package "foo" do
version "bar"
action :install
notifies :create, "file[/etc/foo/bar]", :immediately
end
file "/etc/foo/bar" do
mode 00644
action :nothing
end
On Fri, Oct 11, 2013 at 11:12 AM, Rob Curtis robert.h.curtis@gmail.comwrote:
Executive Summary:
I'm using Chef to install a package and then update (ownership,
permissions)
many of the files installed with the package. Because the files don't
exist
before the package is installed in the execution phase, resources for
those
files can't be dynamically generated in the compile phase. What is the
most
correct (idempotent, efficient) way to update the package's files after
install? Do I just use a Ruby block to chown/chmod the files? Do I
create an
explicit resource for each and every file?
The longer version:
We are using Chef to install and configure a particular software bundle
(Mule
ESB). In keeping with what we understand to be the best practices, we
have a
library cookbook that simply does the bare-bones install and a policy
cookbook
that wraps the library cookbook and performs our own customization.
Most of the customization we want to perform is modifying the ownership
and
permissions on many of the files that get installed by the library
cookbook to
make our security guys happy. My first cut at the default recipe in
the policy
cookbook looks something like this:
Do things that happen before installing Mule
Chef::Log.debug("Pre-Mule")
Install Mule
include_recipe "mule"
Do things that happen after installing Mule
Chef::Log.debug("Post-Mule")
Remove example applications
directory "#{node[:mule][:home]}/examples" do
recursive true
action :delete
end
Restrict access to config files
Dir[ "#{node[:mule][:home]}/conf/*" ].each do |path|
file path do
owner node[:mule-policy][:user]
group node[:mule-policy][:group]
mode "0640"
end if File.file?(path)
end
End of cookbook snippet
The problem is that when I run the mule-policy cookbook on a fresh VM,
Chef
attempts to create the config file resources during the compile phase
but since
Mule doesn't actually get installed until the execution phase, there
are no
config files for which to generate resources. It's not a huge deal
with the
config files since there are only 3 of them, but it's a bigger problem
when we
start getting into the /lib directory, which contains dozens of .jar
files and
the security guys want those locked down, too.
Any advice would be greatly appreciated.
Thanks,
-Rob