Please review pull request #251: Don't try to read the body of a file content response twice opened by (nicklewis)
Description:
Previously, get_file_from_source was calling Net::HTTP#request_get to
request file content, and yielding the response to
chunk_file_from_source, which would read the body. However, when called
without a block, request_get will read the body itself before returning
the response. This caused an error when chunk_file_from_source then
tried to read (and inflate if necessary) the body.
Now, get_file_from_source will pass its block along to request_get,
which will yield the unread response, rather than yielding the result of
request_get, which is a read response. This prevents a double read
error, and also allows us to properly inflate the body.
This fixes sourcing remote files.
- Opened: Wed Dec 07 21:47:19 UTC 2011
- Based on: puppetlabs:master (3406081b3d91bb796f8fa666d22a05054fda42f4)
- Requested merge: nicklewis:fix-read_body-called-twice (491b6e39c8bd4ee89e45f71b9e608541a14cd592)
Diff follows:
diff --git a/acceptance/tests/resource/file/source_attribtute.rb b/acceptance/tests/resource/file/source_attribtute.rb deleted file mode 100644 index 3fa447a..0000000 --- a/acceptance/tests/resource/file/source_attribtute.rb +++ /dev/null @@ -1,106 +0,0 @@ -test_name "The source attribute" - -step "Ensure the test environment is clean" -on agents, 'rm -f /tmp/source_file_test.txt' - -# TODO: Add tests for puppet:// URIs with master/agent setups. -# step "when using a puppet:/// URI with a master/agent setup" -# step "when using a puppet://$server/ URI with a master/agent setup" - -step "Using a local file path" -on agents, "echo 'Yay, this is the local file.' > /tmp/local_source_file_test.txt" -manifest = "file { '/tmp/source_file_test.txt': source => '/tmp/local_source_file_test.txt', ensure => present }" - -apply_manifest_on agents, manifest -agents.each do |host| - on host, "cat /tmp/source_file_test.txt" do - assert_match(/Yay, this is the local file./, stdout, "FIRST: File contents not matched on #{host}") - end -end - -step "Ensure the test environment is clean" -on agents, 'rm -f /tmp/source_file_test.txt' - -step "Using a puppet:/// URI with puppet apply" - -on agents, puppet_agent("--configprint modulepath") do - modulepath = stdout.split(':')[0] - modulepath = modulepath.chomp - on agents, "mkdir -p #{modulepath}/test_module/files" - #on agents, "echo 'Yay, this is the puppet:/// file.' > #{modulepath}/test_module/files/test_file.txt" - on agents, "echo 'Yay, this is the puppetfile.' > #{modulepath}/test_module/files/test_file.txt" -end - -on agents, %q{echo "file { '/tmp/source_file_test.txt': source => 'puppet:///modules/test_module/test_file.txt', ensure => present }" > /tmp/source_test_manifest.pp} -on agents, puppet_apply("/tmp/source_test_manifest.pp") - -agents.each do |host| - on host, "cat /tmp/source_file_test.txt" do - assert_match(/Yay, this is the puppetfile./, stdout, "SECOND: File contents not matched on #{host}") - end -end - -# Oops. We (Jesse & Jacob) ended up writing this before realizing that you -# can't actually specify "source => 'http://...'". However, we're leaving it -# here, since there have been feature requests to support doing this. -# -- Mon, 07 Mar 2011 16:12:56 -0800 -# -#step "Ensure the test environment is clean" -#on agents, 'rm -f /tmp/source_file_test.txt' -# -#step "when using an http:// file path" -# -#File.open '/tmp/puppet-acceptance-webrick-script.rb', 'w' do |file| -# file.puts %q{#!/usr/bin/env ruby -# -#require 'webrick' -# -#class Simple < WEBrick::HTTPServlet::AbstractServlet -# def do_GET(request, response) -# status, content_type, body = do_stuff_with(request) -# -# response.status = status -# response['Content-Type'] = content_type -# response.body = body -# end -# -# def do_stuff_with(request) -# return 200, "text/plain", "you got a page" -# end -#end -# -#class SimpleTwo < WEBrick::HTTPServlet::AbstractServlet -# def do_GET(request, response) -# status, content_type, body = do_stuff_with(request) -# -# response.status = status -# response['Content-Type'] = content_type -# response.body = body -# end -# -# def do_stuff_with(request) -# return 200, "text/plain", "you got a different page" -# end -#end -# -#server = WEBrick::HTTPServer.new :Port => 8081 -#trap "INT" do server.shutdown end -#trap "TERM" do server.shutdown end -#trap "QUIT" do server.shutdown end -# -#server.mount "/", SimpleTwo -#server.mount "/foo.txt", Simple -#server.start -#} -#end -# -#scp_to master, '/tmp/puppet-acceptance-webrick-script.rb', '/tmp' -#on master, "chmod +x /tmp/puppet-acceptance-webrick-script.rb && /tmp/puppet-acceptance-webrick-script.rb &" -# -#manifest = "file { '/tmp/source_file_test.txt': source => 'http://#{master}:8081/foo.txt', ensure => present }" -# -#apply_manifest_on agents, manifest -# -#on agents, 'test "$(cat /tmp/source_file_test.txt)" = "you got a page"' -# -#on master, "killall puppet-acceptance-webrick-script.rb" diff --git a/acceptance/tests/resource/file/source_attribute.rb b/acceptance/tests/resource/file/source_attribute.rb new file mode 100644 index 0000000..c406c32 --- /dev/null +++ b/acceptance/tests/resource/file/source_attribute.rb @@ -0,0 +1,127 @@ +test_name "The source attribute" + +step "Ensure the test environment is clean" +on agents, 'rm -f /tmp/source_file_test.txt' + +step "when using a puppet:/// URI with a master/agent setup" +modulepath = nil +on master, puppet_master('--configprint modulepath') do + modulepath = stdout.split(':')[0].chomp +end + +result_file = "/tmp/#{$$}-result-file" +source_file = File.join(modulepath, 'source_test_module', 'files', 'source_file') +manifest = "/tmp/#{$$}-source-test.pp" + +on master, "mkdir -p #{File.dirname(source_file)}" +on master, "echo 'the content is present' > #{source_file}" +on master, %Q[echo "file { '#{result_file}': source => 'puppet:///modules/source_test_module/source_file', ensure => present }" > #{source_file}] + +with_master_running_on master, "--autosign true --manifest #{manifest}" do + run_agent_on agents, "--test --server #{master}" do + on agents, "cat #{result_file}" do + assert_match(/the content is present/, stdout, "Result file not created") + end + end +end + +# TODO: Add tests for puppet:// URIs with multi-master/agent setups. +# step "when using a puppet://$server/ URI with a master/agent setup" + +step "Using a local file path" +on agents, "echo 'Yay, this is the local file.' > /tmp/local_source_file_test.txt" +manifest = "file { '/tmp/source_file_test.txt': source => '/tmp/local_source_file_test.txt', ensure => present }" + +apply_manifest_on agents, manifest +agents.each do |host| + on host, "cat /tmp/source_file_test.txt" do + assert_match(/Yay, this is the local file./, stdout, "FIRST: File contents not matched on #{host}") + end +end + +step "Ensure the test environment is clean" +on agents, 'rm -f /tmp/source_file_test.txt' + +step "Using a puppet:/// URI with puppet apply" + +on agents, puppet_agent("--configprint modulepath") do + modulepath = stdout.split(':')[0] + modulepath = modulepath.chomp + on agents, "mkdir -p #{modulepath}/test_module/files" + #on agents, "echo 'Yay, this is the puppet:/// file.' > #{modulepath}/test_module/files/test_file.txt" + on agents, "echo 'Yay, this is the puppetfile.' > #{modulepath}/test_module/files/test_file.txt" +end + +on agents, %q{echo "file { '/tmp/source_file_test.txt': source => 'puppet:///modules/test_module/test_file.txt', ensure => present }" > /tmp/source_test_manifest.pp} +on agents, puppet_apply("/tmp/source_test_manifest.pp") + +agents.each do |host| + on host, "cat /tmp/source_file_test.txt" do + assert_match(/Yay, this is the puppetfile./, stdout, "SECOND: File contents not matched on #{host}") + end +end + +# Oops. We (Jesse & Jacob) ended up writing this before realizing that you +# can't actually specify "source => 'http://...'". However, we're leaving it +# here, since there have been feature requests to support doing this. +# -- Mon, 07 Mar 2011 16:12:56 -0800 +# +#step "Ensure the test environment is clean" +#on agents, 'rm -f /tmp/source_file_test.txt' +# +#step "when using an http:// file path" +# +#File.open '/tmp/puppet-acceptance-webrick-script.rb', 'w' do |file| +# file.puts %q{#!/usr/bin/env ruby +# +#require 'webrick' +# +#class Simple < WEBrick::HTTPServlet::AbstractServlet +# def do_GET(request, response) +# status, content_type, body = do_stuff_with(request) +# +# response.status = status +# response['Content-Type'] = content_type +# response.body = body +# end +# +# def do_stuff_with(request) +# return 200, "text/plain", "you got a page" +# end +#end +# +#class SimpleTwo < WEBrick::HTTPServlet::AbstractServlet +# def do_GET(request, response) +# status, content_type, body = do_stuff_with(request) +# +# response.status = status +# response['Content-Type'] = content_type +# response.body = body +# end +# +# def do_stuff_with(request) +# return 200, "text/plain", "you got a different page" +# end +#end +# +#server = WEBrick::HTTPServer.new :Port => 8081 +#trap "INT" do server.shutdown end +#trap "TERM" do server.shutdown end +#trap "QUIT" do server.shutdown end +# +#server.mount "/", SimpleTwo +#server.mount "/foo.txt", Simple +#server.start +#} +#end +# +#scp_to master, '/tmp/puppet-acceptance-webrick-script.rb', '/tmp' +#on master, "chmod +x /tmp/puppet-acceptance-webrick-script.rb && /tmp/puppet-acceptance-webrick-script.rb &" +# +#manifest = "file { '/tmp/source_file_test.txt': source => 'http://#{master}:8081/foo.txt', ensure => present }" +# +#apply_manifest_on agents, manifest +# +#on agents, 'test "$(cat /tmp/source_file_test.txt)" = "you got a page"' +# +#on master, "killall puppet-acceptance-webrick-script.rb" diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb index 81edeca..f68ed95 100755 --- a/lib/puppet/type/file/content.rb +++ b/lib/puppet/type/file/content.rb @@ -199,12 +199,12 @@ def chunk_file_from_disk(source_or_content) end end - def get_from_source(source_or_content) + def get_from_source(source_or_content, &block) request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path.sub(/^\//,'')) request.do_request(:fileserver) do |req| connection = Puppet::Network::HttpPool.http_instance(req.server, req.port) - return yield connection.request_get(indirection2uri(req), add_accept_encoding({"Accept" => "raw"})) + connection.request_get(indirection2uri(req), add_accept_encoding({"Accept" => "raw"}), &block) end end
--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.