diff options
author | Thom May <thom@chef.io> | 2016-03-03 10:11:29 +0000 |
---|---|---|
committer | Thom May <thom@chef.io> | 2016-03-03 10:11:29 +0000 |
commit | 788ec4597c9f1517c26d85703bdc79ea01e5ff53 (patch) | |
tree | 23364a04f0906df0697565ba84f9163b48a61298 | |
parent | a4d98365c1d68d7a24fba62783538951d2bbd2e0 (diff) | |
parent | 9c7bc8730af9ddba70d5095301517ae9e07e5024 (diff) | |
download | chef-788ec4597c9f1517c26d85703bdc79ea01e5ff53.tar.gz |
Merge branch 'remote-file-download-progress' of https://github.com/brandocorp/chef into tm/remote_file_download_progress
-rw-r--r-- | lib/chef/event_dispatch/base.rb | 6 | ||||
-rw-r--r-- | lib/chef/formatters/doc.rb | 16 | ||||
-rw-r--r-- | lib/chef/http.rb | 36 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/http.rb | 16 | ||||
-rw-r--r-- | lib/chef/resource/remote_file.rb | 18 |
5 files changed, 90 insertions, 2 deletions
diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index a6a18718c2..65cb519dc7 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -297,6 +297,12 @@ class Chef # - resource_completed # + # Called when a progress notification should be sent to the user to + # indicate the overall progress of a long running operation, such as + # a large file download. + def resource_action_progress(resource, current, total, interval) + end + # Called before action is executed on a resource. def resource_action_start(resource, action, notification_type = nil, notifier = nil) end diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index 5462241049..31732066a8 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -23,6 +23,7 @@ class Chef @start_time = Time.now @end_time = @start_time @skipped_resources = 0 + @progress = {} end def elapsed_time @@ -258,6 +259,21 @@ class Chef indent end + def resource_action_progress(resource, current, total, interval) + @progress[resource] ||= 0 + + percent_complete = (current.to_f / total.to_f * 100).to_i + + if percent_complete > @progress[resource] + + @progress[resource] = percent_complete + + if percent_complete % interval == 0 + start_line " - Progress: #{percent_complete}/100 %", :green + end + end + end + # Called when a resource fails, but will retry. def resource_failed_retriable(resource, action, retry_count, exception) end diff --git a/lib/chef/http.rb b/lib/chef/http.rb index a3673ce281..c90f799cd9 100644 --- a/lib/chef/http.rb +++ b/lib/chef/http.rb @@ -74,6 +74,9 @@ class Chef attr_reader :redirect_limit attr_reader :options + attr_reader :show_progress + attr_reader :progress_interval + attr_reader :middlewares # Create a HTTP client object. The supplied +url+ is used as the base for @@ -153,6 +156,34 @@ class Chef raise end + + def streaming_request_with_progress(path, headers={}, &progress_block) + url = create_url(path) + response, rest_request, return_value = nil, nil, nil + tempfile = nil + + method = :GET + method, url, headers, data = apply_request_middleware(method, url, headers, data) + + response, rest_request, return_value = send_http_request(method, url, headers, data) do |http_response| + if http_response.kind_of?(Net::HTTPSuccess) + tempfile = stream_to_tempfile(url, http_response, &progress_block) + end + apply_stream_complete_middleware(http_response, rest_request, return_value) + end + return nil if response.kind_of?(Net::HTTPRedirection) + unless response.kind_of?(Net::HTTPSuccess) + response.error! + end + tempfile + rescue Exception => e + log_failed_request(response, return_value) unless response.nil? + if e.respond_to?(:chef_rest_request=) + e.chef_rest_request = rest_request + end + raise + end + # Makes a streaming download request, streaming the response body to a # tempfile. If a block is given, the tempfile is passed to the block and # the tempfile will automatically be unlinked after the block is executed. @@ -389,7 +420,8 @@ class Chef headers end - def stream_to_tempfile(url, response) + def stream_to_tempfile(url, response, &progress_block) + content_length = response['Content-Length'] tf = Tempfile.open("chef-rest") if Chef::Platform.windows? tf.binmode # required for binary files on Windows platforms @@ -402,6 +434,7 @@ class Chef response.read_body do |chunk| tf.write(stream_handler.handle_chunk(chunk)) + yield tf.size, content_length if block_given? end tf.close tf @@ -425,3 +458,4 @@ class Chef end end + diff --git a/lib/chef/provider/remote_file/http.rb b/lib/chef/provider/remote_file/http.rb index 6fa574e777..3b97d116aa 100644 --- a/lib/chef/provider/remote_file/http.rb +++ b/lib/chef/provider/remote_file/http.rb @@ -39,6 +39,10 @@ class Chef @current_resource = current_resource end + def events + new_resource.events + end + def headers conditional_get_headers.merge(new_resource.headers) end @@ -57,7 +61,13 @@ class Chef def fetch http = Chef::HTTP::Simple.new(uri, http_client_opts) - tempfile = http.streaming_request(uri, headers) + if want_progress? + tempfile = http.streaming_request_with_progress(uri, headers) do |size, total| + events.resource_action_progress(new_resource, size, total, new_resource.progress_interval) + end + else + tempfile = http.streaming_request(uri, headers) + end if tempfile update_cache_control_data(tempfile, http.last_response) tempfile.close @@ -78,6 +88,10 @@ class Chef @cache_control_data ||= CacheControlData.load_and_validate(uri, current_resource.checksum) end + def want_progress? + new_resource.show_progress + end + def want_mtime_cache_control? new_resource.use_last_modified end diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb index b42cf4ba5f..b615297c24 100644 --- a/lib/chef/resource/remote_file.rb +++ b/lib/chef/resource/remote_file.rb @@ -122,6 +122,24 @@ class Chef ) end + def show_progress(args=nil) + set_or_return( + :show_progress, + args, + :default => false, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + def progress_interval(args=nil) + set_or_return( + :progress_interval, + args, + :default => 10, + :equal_to => [1, 5, 10, 20, 25] + ) + end + private include Chef::Mixin::Uris |