summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Raabe <brandocorp@gmail.com>2015-03-20 23:44:12 -0700
committerBrandon Raabe <brandocorp@gmail.com>2015-03-20 23:44:12 -0700
commit57a6de57d60a75749a8345af9807d4abf24b6924 (patch)
treed8bfd1f0d9f67ff82e90037c9eec0a9df4d3cfb3
parent19d31707dba909bcb8d24dac6293e9341ccb0b16 (diff)
downloadchef-57a6de57d60a75749a8345af9807d4abf24b6924.tar.gz
new doc formatter event, remove progress bar
-rw-r--r--lib/chef/event_dispatch/base.rb9
-rw-r--r--lib/chef/formatters/doc.rb16
-rw-r--r--lib/chef/http.rb109
-rw-r--r--lib/chef/provider/remote_file/http.rb16
-rw-r--r--lib/chef/resource/remote_file.rb1
5 files changed, 69 insertions, 82 deletions
diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb
index 7274105802..beec37134c 100644
--- a/lib/chef/event_dispatch/base.rb
+++ b/lib/chef/event_dispatch/base.rb
@@ -268,6 +268,15 @@ class Chef
def resource_action_start(resource, action, notification_type=nil, notifier=nil)
end
+ ##
+ # https://github.com/chef/chef/issues/2812
+ #
+ # 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 when a resource fails, but will retry.
def resource_failed_retriable(resource, action, retry_count, exception)
end
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 489888db8f..7605b93301 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -22,6 +22,7 @@ class Chef
@failed_audits = 0
@start_time = Time.now
@end_time = @start_time
+ @progress = {}
end
def elapsed_time
@@ -216,6 +217,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 e84115276d..8679abeed2 100644
--- a/lib/chef/http.rb
+++ b/lib/chef/http.rb
@@ -35,76 +35,6 @@ class Chef
# == Chef::HTTP
# Basic HTTP client, with support for adding features via middleware
class HTTP
- class ProgressBar
-
- attr_reader :display
- attr_reader :interval
- attr_reader :resource
-
- def initialize(size, resource)
- @total = size
- @status = 0
- @resource = resource
- @display = resource.show_progress
- @interval = resource.progress_interval
- progress_indicator if @display
- end
-
- def update(progress)
- @progress = progress
- display_progress
- end
-
- def display_progress
- return unless display
- progress_indicator if next_interval_met?
- end
-
- def next_interval_met?
- return false unless percent_complete % interval == 0
- if percent_complete > @status
- @status = percent_complete
- return true
- end
- false
- end
-
- def percent_complete
- (@progress.to_f / @total.to_f * 100).to_i
- end
-
- def display_status
- length = @status / 2
- progress_text = '=' * length
- progress_text
- end
-
- def display_remainder
- length = 100 / 2 - @status / 2
- progress_text = ' ' * length
- progress_text
- end
-
- def display_percentage
- length = 4 - @status.to_s.length
- progress_text = ' ' * length + "#{@status}/100 %"
- progress_text
- end
-
- def progress_indicator
- Chef::Log.debug '[' + display_status + display_remainder + ']' + display_percentage
- send_event 'download progress:' + display_percentage
- end
-
- def send_event(message)
- events.resource_update_applied(resource.name, resource.action, message)
- end
-
- def events
- resource.events
- end
- end
-
# Class for applying middleware behaviors to streaming
# responses. Collects stream handlers (if any) from each
@@ -157,9 +87,6 @@ class Chef
@sign_on_redirect = true
@redirects_followed = 0
@redirect_limit = 10
- @resource = options[:resource]
- @show_progress = options[:resource].show_progress
- @progress_interval = options[:resource].progress_interval
@middlewares = []
self.class.middlewares.each do |middleware_class|
@@ -226,6 +153,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.
@@ -242,7 +197,7 @@ class Chef
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)
+ tempfile = stream_to_tempfile(url, http_response, &block)
end
apply_stream_complete_middleware(http_response, rest_request, return_value)
end
@@ -439,8 +394,8 @@ class Chef
headers
end
- def stream_to_tempfile(url, response)
- progress = ProgressBar.new(response['Content-Length'], @resource)
+ 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
@@ -453,7 +408,7 @@ class Chef
response.read_body do |chunk|
tf.write(stream_handler.handle_chunk(chunk))
- progress.update tf.size
+ yield tf.size, content_length if block_given?
end
tf.close
tf
diff --git a/lib/chef/provider/remote_file/http.rb b/lib/chef/provider/remote_file/http.rb
index 68e8930634..3e61c216c0 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
@@ -112,10 +122,6 @@ class Chef
Chef::Log.debug("turning gzip compression off due to filename ending in gz")
opts[:disable_gzip] = true
end
- if want_progress?
- Chef::Log.debug("enabling progress output for streaming requests")
- opts[:resource] = new_resource
- end
opts
end
diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb
index 5da20371da..97f9835a8c 100644
--- a/lib/chef/resource/remote_file.rb
+++ b/lib/chef/resource/remote_file.rb
@@ -129,6 +129,7 @@ class Chef
set_or_return(
:show_progress,
args,
+ :default => false,
:kind_of => [ TrueClass, FalseClass ]
)
end