Class: Chef::Provider::RemoteFile

Inherits:
File show all
Includes:
Mixin::EnforceOwnershipAndPermissions
Defined in:
lib/chef/provider/remote_file.rb

Constant Summary

Constants included from Mixin::ShellOut

Mixin::ShellOut::DEPRECATED_OPTIONS

Instance Attribute Summary

Attributes inherited from Chef::Provider

#action, #current_resource, #new_resource, #run_context

Instance Method Summary collapse

Methods included from Mixin::EnforceOwnershipAndPermissions

#access_controls, #enforce_ownership_and_permissions

Methods inherited from File

#action_create_if_missing, #action_delete, #action_touch, #backup, #compare_content, #define_resource_requirements, #deploy_tempfile, #diff_current, #diff_current_from_content, #is_binary?, #set_all_access_controls, #set_content, #setup_acl, #update_new_file_state, #whyrun_supported?

Methods included from Mixin::ShellOut

#run_command_compatible_options, #shell_out, #shell_out!

Methods included from Mixin::Checksum

#checksum

Methods inherited from Chef::Provider

#action_nothing, #cleanup_after_converge, #cookbook_name, #define_resource_requirements, #events, #initialize, #node, #process_resource_requirements, #requirements, #resource_collection, #run_action, #set_updated_status, #whyrun_mode?, #whyrun_supported?

Methods included from DSL::Recipe

#method_missing

Methods included from Mixin::ConvertToClassName

#convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #snake_case_basename

Constructor Details

This class inherits a constructor from Chef::Provider

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Chef::DSL::Recipe

Instance Method Details

#action_createObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/chef/provider/remote_file.rb', line 36

def action_create
  Chef::Log.debug("#{@new_resource} checking for changes")

  if current_resource_matches_target_checksum?
    Chef::Log.debug("#{@new_resource} checksum matches target checksum (#{@new_resource.checksum}) - not updating")
  else
    sources = @new_resource.source
    source = sources.shift
    begin
      rest = Chef::REST.new(source, nil, nil, http_client_opts(source))
      raw_file = rest.streaming_request(rest.create_url(source), {})
    rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Net::HTTPFatalError => e
      Chef::Log.debug("#{@new_resource} cannot be downloaded from #{source}")
      if source = sources.shift
        Chef::Log.debug("#{@new_resource} trying to download from another mirror")
        retry
      else
        raise e
      end
    end
    if matches_current_checksum?(raw_file)
      Chef::Log.debug "#{@new_resource} target and source checksums are the same - not updating"
    else
      description = [] 
      description << "copy file downloaded from #{@new_resource.source} into #{@new_resource.path}"
      description << diff_current(raw_file.path)
      converge_by(description) do
        backup_new_resource
        FileUtils.cp raw_file.path, @new_resource.path
        Chef::Log.info "#{@new_resource} updated"
        raw_file.close!
      end
      # whyrun mode cleanup - the temp file will never be used,
      # so close/unlink it here. 
      if whyrun_mode?
        raw_file.close!
      end
    end
  end
  set_all_access_controls
  update_new_file_state
end

#backup_new_resourceObject



98
99
100
101
102
103
# File 'lib/chef/provider/remote_file.rb', line 98

def backup_new_resource
  if ::File.exists?(@new_resource.path)
    Chef::Log.debug "#{@new_resource} checksum changed from #{@current_resource.checksum} to #{@new_resource.checksum}"
    backup @new_resource.path
  end
end

#current_resource_matches_target_checksum?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/chef/provider/remote_file.rb', line 79

def current_resource_matches_target_checksum?
  @new_resource.checksum && @current_resource.checksum && @current_resource.checksum =~ /^#{Regexp.escape(@new_resource.checksum)}/
end

#http_client_opts(source) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/chef/provider/remote_file.rb', line 115

def http_client_opts(source)
  opts={}
  # CHEF-3140
  # 1. If it's already compressed, trying to compress it more will
  # probably be counter-productive.
  # 2. Some servers are misconfigured so that you GET $URL/file.tgz but
  # they respond with content type of tar and content encoding of gzip,
  # which tricks Chef::REST into decompressing the response body. In this
  # case you'd end up with a tar archive (no gzip) named, e.g., foo.tgz,
  # which is not what you wanted.
  if @new_resource.path =~ /gz$/ or source =~ /gz$/
    opts[:disable_gzip] = true
  end
  opts
end

#load_current_resourceObject



31
32
33
34
# File 'lib/chef/provider/remote_file.rb', line 31

def load_current_resource
  @current_resource = Chef::Resource::RemoteFile.new(@new_resource.name)
  super
end

#matches_current_checksum?(candidate_file) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/chef/provider/remote_file.rb', line 83

def matches_current_checksum?(candidate_file)
  Chef::Log.debug "#{@new_resource} checking for file existence of #{@new_resource.path}"
  if ::File.exists?(@new_resource.path)
    Chef::Log.debug "#{@new_resource} file exists at #{@new_resource.path}"
    @new_resource.checksum(checksum(candidate_file.path))
    Chef::Log.debug "#{@new_resource} target checksum: #{@current_resource.checksum}"
    Chef::Log.debug "#{@new_resource} source checksum: #{@new_resource.checksum}"

    @new_resource.checksum == @current_resource.checksum
  else
    Chef::Log.debug "#{@new_resource} creating #{@new_resource.path}"
    false
  end
end

#source_file(source, current_checksum, &block) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/chef/provider/remote_file.rb', line 105

def source_file(source, current_checksum, &block)
  if absolute_uri?(source)
    fetch_from_uri(source, &block)
  elsif !Chef::Config[:solo]
    fetch_from_chef_server(source, current_checksum, &block)
  else
    fetch_from_local_cookbook(source, &block)
  end
end