Skip to content

Commit dd586d6

Browse files
committed
use Chef::REST#fetch for remote files; fixes CHEF-424
1 parent 88951b1 commit dd586d6

2 files changed

Lines changed: 135 additions & 105 deletions

File tree

‎chef/lib/chef/provider/remote_file.rb‎

Lines changed: 76 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -45,43 +45,20 @@ def action_create_if_missing
4545
def do_remote_file(source, path)
4646
retval = true
4747

48-
if(@new_resource.checksum && @current_resource.checksum && @current_resource.checksum =~ /^#{@new_resource.checksum}/)
49-
Chef::Log.debug("File #{@new_resource} checksum matches, not updating")
48+
if current_resource_matches_target_checksum?
49+
Chef::Log.debug("File #{@new_resource} checksum matches target checksum (#{@new_resource.checksum}), not updating")
5050
else
5151
begin
52-
# The remote filehandle
53-
Chef::Log.info "Downloading remote file #{@new_resource.source}"
54-
raw_file = get_from_uri(source) ||
55-
get_from_server(source, @current_resource.checksum) ||
56-
get_from_local_cookbook(source)
57-
58-
# If the file exists
59-
Chef::Log.debug "#{@new_resource}: Checking for file existence of #{@new_resource.path}"
60-
if ::File.exists?(@new_resource.path)
61-
# And it matches the checksum of the raw file
62-
@new_resource.checksum(self.checksum(raw_file.path))
63-
Chef::Log.debug "#{@new_resource}: File exists at #{@new_resource.path}"
64-
Chef::Log.debug "#{@new_resource}: Target checksum: #{@current_resource.checksum}"
65-
Chef::Log.debug "#{@new_resource}: Source checksum: #{@new_resource.checksum}"
66-
if @new_resource.checksum != @current_resource.checksum
67-
# Updating target file, let's perform a backup!
68-
Chef::Log.debug "#{@new_resource}: checksum changed from #{@current_resource.checksum} to #{@new_resource.checksum}"
69-
Chef::Log.info "#{@new_resource}: Updating #{@new_resource.path}"
70-
backup @new_resource.path
52+
source_file(source, @current_resource.checksum) do |raw_file|
53+
if matches_current_checksum?(raw_file)
54+
Chef::Log.debug "#{@new_resource}: Target and Source checksums are the same, taking no action"
55+
else
56+
backup_new_resource
57+
Chef::Log.debug "copying remote file from origin #{raw_file.path} to destination #{@new_resource.path}"
7158
FileUtils.cp raw_file.path, @new_resource.path
7259
@new_resource.updated = true
73-
else
74-
Chef::Log.debug "#{@new_resource}: Target and Source checksums are the same, taking no action"
7560
end
76-
else
77-
# We're creating a new file
78-
Chef::Log.info "#{@new_resource}: Creating #{@new_resource.path}"
79-
FileUtils.cp raw_file.path, @new_resource.path
80-
@new_resource.updated = true
8161
end
82-
83-
# We're done with the file, so make sure to close it if it was open.
84-
raw_file.close unless raw_file.closed?
8562
rescue Net::HTTPRetriableError => e
8663
if e.response.kind_of?(Net::HTTPNotModified)
8764
Chef::Log.debug("File #{path} is unchanged")
@@ -90,38 +67,78 @@ def do_remote_file(source, path)
9067
raise e
9168
end
9269
end
70+
71+
Chef::Log.debug "#{@new_resource} completed"
72+
retval
9373
end
94-
74+
enforce_ownership_and_permissions
75+
76+
retval
77+
end
78+
79+
def enforce_ownership_and_permissions
9580
set_owner if @new_resource.owner
9681
set_group if @new_resource.group
9782
set_mode if @new_resource.mode
98-
99-
retval
83+
10084
end
101-
102-
def get_from_uri(source)
103-
begin
104-
uri = URI.parse(source)
105-
if uri.absolute
106-
r = Chef::REST.new(source, nil, nil)
107-
Chef::Log.debug("Downloading from absolute URI: #{source}")
108-
r.get_rest(source, true).open
109-
end
110-
rescue URI::InvalidURIError
111-
nil
85+
86+
def current_resource_matches_target_checksum?
87+
@new_resource.checksum && @current_resource.checksum && @current_resource.checksum =~ /^#{@new_resource.checksum}/
88+
end
89+
90+
def matches_current_checksum?(candidate_file)
91+
Chef::Log.debug "#{@new_resource}: Checking for file existence of #{@new_resource.path}"
92+
if ::File.exists?(@new_resource.path)
93+
Chef::Log.debug "#{@new_resource}: File exists at #{@new_resource.path}"
94+
@new_resource.checksum(checksum(candidate_file.path))
95+
Chef::Log.debug "#{@new_resource}: Target checksum: #{@current_resource.checksum}"
96+
Chef::Log.debug "#{@new_resource}: Source checksum: #{@new_resource.checksum}"
97+
@new_resource.checksum == @current_resource.checksum
98+
else
99+
Chef::Log.info "#{@new_resource}: Creating #{@new_resource.path}"
100+
false
112101
end
113102
end
114-
115-
def get_from_server(source, current_checksum)
116-
unless Chef::Config[:solo]
117-
r = Chef::REST.new(Chef::Config[:remotefile_url])
118-
url = generate_url(source, "files", :checksum => current_checksum)
119-
Chef::Log.debug("Downloading from server: #{url}")
120-
r.get_rest(url, true).open
103+
104+
def backup_new_resource
105+
if ::File.exists?(@new_resource.path)
106+
Chef::Log.debug "#{@new_resource}: checksum changed from #{@current_resource.checksum} to #{@new_resource.checksum}"
107+
Chef::Log.info "#{@new_resource}: Updating #{@new_resource.path}"
108+
backup @new_resource.path
109+
end
110+
end
111+
112+
def source_file(source, current_checksum, &block)
113+
if absolute_uri?(source)
114+
fetch_from_uri(source, &block)
115+
elsif !Chef::Config[:solo]
116+
fetch_from_chef_server(source, current_checksum, &block)
117+
else
118+
fetch_from_local_cookbook(source, &block)
121119
end
122120
end
121+
122+
private
123+
124+
def absolute_uri?(source)
125+
URI.parse(source).absolute?
126+
rescue URI::InvalidURIError
127+
false
128+
end
129+
130+
def fetch_from_uri(source)
131+
Chef::Log.debug("Downloading from absolute URI: #{source}")
132+
Chef::REST.new(source, nil, nil).fetch(source) { |tmp_file| yield tmp_file }
133+
end
123134

124-
def get_from_local_cookbook(source)
135+
def fetch_from_chef_server(source, current_checksum)
136+
url = generate_url(source, "files", :checksum => current_checksum)
137+
Chef::Log.debug("Downloading #{@new_resource} from server: #{url}")
138+
Chef::REST.new(Chef::Config[:remotefile_url]).fetch(url) { |tmp_file| yield tmp_file }
139+
end
140+
141+
def fetch_from_local_cookbook(source)
125142
if Chef::Config[:solo]
126143
cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
127144
filename = find_preferred_file(
@@ -133,7 +150,12 @@ def get_from_local_cookbook(source)
133150
@node[:platform_version]
134151
)
135152
Chef::Log.debug("Using local file for remote_file:#{filename}")
136-
::File.open(filename)
153+
begin
154+
file = ::File.open(filename)
155+
yield file
156+
ensure
157+
file.close
158+
end
137159
end
138160
end
139161

0 commit comments

Comments
 (0)