zkfhu | 29 Aug 03:47 2011
Picon

Resource for copy local file?

Which chef resource type can I use to copy a local file, for example, copy
local file from /tmp/1.txt to /root/1.txt?

I know in puppet I can do like this: 
file{ “/root/1.txt”, ensure => present, source => “/tmp/1.txt”, }

But how can I do this by chef? I looked into file, template, cookbook_file,
remotefile, it looks no resource type can handle it. Could anyone give me some
advice on this?
Joshua Timberman | 29 Aug 05:06 2011

Re: Resource for copy local file?

Hello,

On Sun, Aug 28, 2011 at 7:47 PM,  <zkfhu <at> yahoo.com> wrote:
> Which chef resource type can I use to copy a local file, for example, copy
> local file from /tmp/1.txt to /root/1.txt?
>
> I know in puppet I can do like this:
> file{ “/root/1.txt”, ensure => present, source => “/tmp/1.txt”, }
>
> But how can I do this by chef? I looked into file, template, cookbook_file,
> remotefile, it looks no resource type can handle it. Could anyone give me some
> advice on this?

To directly answer the question, you want to use the "content"
parameter of the file resource, using the Ruby IO.read() method.

file "/root/1.txt" do
  content IO.read("/tmp/1.txt")
end

However, I ask why are you doing this? Is the source coming from Chef
in the first place? Or is it a "state" file dropped off by some other
process or resource such as an execute or bash script? Better knowing
the use case may lead to a better, more reliable solution.

--

-- 
Opscode, Inc
Joshua Timberman, Director of Training and Services
IRC, Skype, Twitter, Github: jtimberman

(Continue reading)

zkfhu | 29 Aug 05:26 2011
Picon

Re: Re: Resource for copy local file?

Many thanks Joshua. You solution works!

You are right. I want to backup files and logs generated by other processes
periodically using chef.

zkfhu | 29 Aug 05:30 2011
Picon

Re: Re: Resource for copy local file?

Many thanks Joshua. You solution works!

You are right. I want to backup files and logs generated by other processes
periodically using chef.

zkfhu | 31 Aug 05:00 2011
Picon

resource for copy local file?

I got another problem regarding resource for copy local file. 
eg. Download one file from http server, then backup the file:

remote_file "/httpfile" do
	source "http://wiki.opscode.com/display/chef/Home"
	mode "0666"
end
file "/httpfile.bak" do
	content IO.read("/httpfile")
end

I got error: FATAL: Errno::ENOENT: No such file or directory - /httpfile

This is because /httpfile is non-exist when I start chef-client. How can I copy
such kind of file? 

andi abes | 31 Aug 05:11 2011
Picon

Re: resource for copy local file?

Add an only_if File.exists to the backup

On Aug 30, 2011, at 23:01, "zkfhu <at> yahoo.com" <zkfhu <at> yahoo.com> wrote:

> I got another problem regarding resource for copy local file.
> eg. Download one file from http server, then backup the file:
>
> remote_file "/httpfile" do
>    source "http://wiki.opscode.com/display/chef/Home"
>    mode "0666"
> end
> file "/httpfile.bak" do
>    content IO.read("/httpfile")
> end
>
> I got error: FATAL: Errno::ENOENT: No such file or directory - /httpfile
>
> This is because /httpfile is non-exist when I start chef-client. How can I copy
> such kind of file?

zkfhu | 31 Aug 05:29 2011
Picon

Re: Re: resource for copy local file?

I still got error: FATAL: Errno::ENOENT: No such file or directory - /httpfile
after I add only_if statement

remote_file "/httpfile" do
    source "http://wiki.opscode.com/display/chef/Home"
    mode "0666"
end
file "/httpfile.bak" do
    content IO.read("/httpfile")
    only_if {File.exists?("/httpfile")}    
end

I 

Charles Duffy | 31 Aug 21:23 2011
Picon

Re: Re: Re: resource for copy local file?

No surprise -- the read is happening at compile time, but the remote_file resource is actually _created_ at execution time.

You could force it to run at compile time, I suppose, but the better answer is that trying to use the "content IO.read" approach doesn't make sense if you're trying to read things which prior execution-time resources change.

Anyhow, it's a bad idea for large files, as it means you need to have enough memory to store the whole thing -- not a great pattern to use often.

Perhaps you could implement the copy in a ruby_block resource? That will make it happen at execution time properly.

On Tue, Aug 30, 2011 at 10:29 PM, <zkfhu <at> yahoo.com> wrote:
I still got error: FATAL: Errno::ENOENT: No such file or directory - /httpfile
after I add only_if statement

remote_file "/httpfile" do
   source "http://wiki.opscode.com/display/chef/Home"
   mode "0666"
end
file "/httpfile.bak" do
   content IO.read("/httpfile")
   only_if {File.exists?("/httpfile")}
end

I

Adam Jacob | 1 Sep 01:17 2011

Re: Re: Re: Re: resource for copy local file?

This is a quick, untested hack - but stick this in a library in a
cookbook, and use it like the gist says, and you should get the copy
behavior you want.

https://gist.github.com/1185022

Adam

On Wed, Aug 31, 2011 at 12:23 PM, Charles Duffy <charles <at> dyfis.net> wrote:
> No surprise -- the read is happening at compile time, but the remote_file
> resource is actually _created_ at execution time.
>
> You could force it to run at compile time, I suppose, but the better answer
> is that trying to use the "content IO.read" approach doesn't make sense if
> you're trying to read things which prior execution-time resources change.
>
> Anyhow, it's a bad idea for large files, as it means you need to have enough
> memory to store the whole thing -- not a great pattern to use often.
>
> Perhaps you could implement the copy in a ruby_block resource? That will
> make it happen at execution time properly.
>
> On Tue, Aug 30, 2011 at 10:29 PM, <zkfhu <at> yahoo.com> wrote:
>>
>> I still got error: FATAL: Errno::ENOENT: No such file or directory -
>> /httpfile
>> after I add only_if statement
>>
>> remote_file "/httpfile" do
>>    source "http://wiki.opscode.com/display/chef/Home"
>>    mode "0666"
>> end
>> file "/httpfile.bak" do
>>    content IO.read("/httpfile")
>>    only_if {File.exists?("/httpfile")}
>> end
>>
>> I
>
>

--

-- 
Opscode, Inc.
Adam Jacob, Chief Product Officer
T: (206) 619-7151 E: adam <at> opscode.com

Alex Kiernan | 9 Sep 11:44 2011
Picon

Re: Re: Re: Re: Re: resource for copy local file?

Couple of typos, but solves a particular itch for me!

--- file_provider_copy.rb.orig	2011-09-09 10:43:20.000000000 +0100
+++ file_provider_copy.rb	2011-09-09 10:34:03.000000000 +0100
 <at>  <at>  -3,7 +3,7  <at>  <at> 
 class Chef
   class Provider
     class File
-      class Copy << Chef::Provider::File
+      class Copy < Chef::Provider::File

         def compare_content
           checksum( <at> current_resource.path) == checksum( <at> new_resource.content)
 <at>  <at>  -12,7 +12,7  <at>  <at> 
         def set_content
           unless compare_content
             backup  <at> new_resource.path if ::File.exists?( <at> new_resource.path)
-            ::File.cp_r( <at> new_resource.content,  <at> new_resource.path)
+            ::FileUtils.cp_r( <at> new_resource.content,  <at> new_resource.path)
             Chef::Log.info("#{ <at> new_resource.content} copied to
#{ <at> new_resource.path}")
              <at> new_resource.updated_by_last_action(true)

On Thu, Sep 1, 2011 at 12:17 AM, Adam Jacob <adam <at> opscode.com> wrote:
> This is a quick, untested hack - but stick this in a library in a
> cookbook, and use it like the gist says, and you should get the copy
> behavior you want.
>
> https://gist.github.com/1185022
>
> Adam
>
> On Wed, Aug 31, 2011 at 12:23 PM, Charles Duffy <charles <at> dyfis.net> wrote:
>> No surprise -- the read is happening at compile time, but the remote_file
>> resource is actually _created_ at execution time.
>>
>> You could force it to run at compile time, I suppose, but the better answer
>> is that trying to use the "content IO.read" approach doesn't make sense if
>> you're trying to read things which prior execution-time resources change.
>>
>> Anyhow, it's a bad idea for large files, as it means you need to have enough
>> memory to store the whole thing -- not a great pattern to use often.
>>
>> Perhaps you could implement the copy in a ruby_block resource? That will
>> make it happen at execution time properly.
>>
>> On Tue, Aug 30, 2011 at 10:29 PM, <zkfhu <at> yahoo.com> wrote:
>>>
>>> I still got error: FATAL: Errno::ENOENT: No such file or directory -
>>> /httpfile
>>> after I add only_if statement
>>>
>>> remote_file "/httpfile" do
>>>    source "http://wiki.opscode.com/display/chef/Home"
>>>    mode "0666"
>>> end
>>> file "/httpfile.bak" do
>>>    content IO.read("/httpfile")
>>>    only_if {File.exists?("/httpfile")}
>>> end
>>>
>>> I
>>
>>
>
>
>
> --
> Opscode, Inc.
> Adam Jacob, Chief Product Officer
> T: (206) 619-7151 E: adam <at> opscode.com
>

--

-- 
Alex Kiernan

zkfhu | 13 Sep 04:27 2011
Picon

Re: Re: Re: Re: Re: Re: resource for copy local file?

I followed the instruction, but can't work as expected. Any suggestions?

Below is my recipe:
#cat /root/cookbooks/a/recipes/default.rb
file "/copied.txt" do
content "/tmp/1.txt"
provider Chef::Provider::File::Copy
end

The content of /copied.txt is not the content of /tmp/1.txt 
#cat /copied.txt
/tmp/1.txt

Below is my library file:
# cat /root/cookbooks/a/libraries/file_provider_copy.rb
class Chef
  class Provider
    class File
      class Copy < Chef::Provider::File

	def compare_content
	  checksum( <at> current_resource.path) == checksum( <at> new_resource.content)
	end

	def set_content
	  unless compare_content
	    backup  <at> new_resource.path if ::File.exists?( <at> new_resource.path)
  #	     ::File.cp_r( <at> new_resource.content,  <at> new_resource.path)
::FileUtils.cp_r( <at> new_resource.content,  <at> new_resource.path)

	    Chef::Log.info("#{ <at> new_resource.content} copied to
#{ <at> new_resource.path}")
	     <at> new_resource.updated_by_last_action(true)
	  end
	end
      end
    end
  end
end

zkfhu | 13 Sep 09:00 2011
Picon

Re: Re: Re: Re: Re: Re: Re: resource for copy local file?

Finally I get it works. Many thanks for all your help!

The reason is I run chef with a normal user account in chef-solo mode.

chef-solo needs to access /var/chef/backup and /var/chef/cache folders. But
chef-solo has no permission to open those folders under non-root account.

What I do is mkdir /var/chef/backup  and  /var/chef/cache with non-root
account, then I can successfully copy local files with File Copy provider.

It will be more convenient if chef has build-in support for local file copy
function.  


Gmane