How to move/copy files locally with Chef
I haven't yet come across a Chef resource that will copy/move files locally. For example, I want to download jetty hightide and unzip it. Once done, copy all the files into a particular folder, like this:
# mv /var/tmp/jetty-hightide-7.4.5.v20110725/* /opt/jetty/
BTW, jettyhightide when unzipped, gives you a folder and inside that folder rest of the files are located. Hence unzip jetty-hightide-7.4.5.v20110725.zip -d /opt/jetty/
is useless because it will create a directory /opt/jetty/jetty-hightide-7.4.5.v20110725/*
whereas what I really want is /opt/jetty/*
. Hence I am looking for a local copy/move resource in Chef.
How to copy single file
First way
I use file
statement to copy file (compile-time check)
file "/etc/init.d/someService" do
owner 'root'
group 'root'
mode 0755
content ::File.open("/home/someService").read
action :create
end
here :
-
"/etc/init.d/someService"
- target file, -
"/home/someService"
- source file
Also you can wrap ::File.open("/home/someService").read
in lazy
block
...
lazy { ::File.open("/home/someService").read }
...
Second way
User remote_file
statement (run-time check)
remote_file "Copy service file" do
path "/etc/init.d/someService"
source "file:///home/someService"
owner 'root'
group 'root'
mode 0755
end
Third way
Also you can use shell/batch
For-each directory
Dir[ "/some/directory/resources/**/*" ].each do |curr_path|
file "/some/target/dir/#{Pathname.new(curr_path).basename}" do
owner 'root'
group 'root'
mode 0755
content lazy { IO.read(curr_path, mode: 'rb').read }
action :create
end if File.file?(curr_path)
directory "/some/target/dir/#{File.dirname(curr_path)}" do
path curr_path
owner 'root'
group 'root'
mode 0755
action :create
end if File.directory?(curr_path)
end
This is just idea, because sub-paths in this example is not handled correctly.
I got it working by using bash
resource as below:
bash "install_jettyhightide" do
code <<-EOL
unzip /var/tmp/jetty-hightide-7.4.5.v20110725.zip -d /opt/jetty/
mv /opt/jetty/jetty-hightide-7.4.5.v20110725/* /opt/jetty/
cp /opt/jetty/bin/jetty.sh /etc/init.d/jetty
update-rc.d jetty defaults
EOL
end
But I was really hoping for a chef way of doing it. copying/moving files locally would be the most generic task a sysadmin will need to do.
I know this question have already been answered, and discussed, but here is the method I use when creating files.
- First include the file under the cookbook's files/default folder
- Then on your recipe use the
cookbook_file
resource
e.g:
cookbook_file "/server/path/to/file.ext" do
source "filename.ext"
owner "root"
group "root"
mode 00600
action :create_if_missing
end
From chef documentation: https://docs.chef.io/resources/cookbook_file/
The cookbook_file resource is used to transfer files from a sub-directory of the files/ directory in a cookbook to a specified path that is located on the host running the chef-client or chef-solo.