summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Campbell <hikeit@gmail.com>2013-02-05 11:07:58 -0500
committerBryan McLellan <btm@opscode.com>2013-02-26 11:11:43 -0800
commit7a2975342ea3e51d0875c125f0061d52bd559d6a (patch)
tree48873938865cb29581ab82bc403c3e2ab6cf230a
parentef9b1a83df9055ecf4c1e93632669f817f52e689 (diff)
downloadchef-7a2975342ea3e51d0875c125f0061d52bd559d6a.tar.gz
pull ftp functionality out of remote_file.rb, move to remote_file/ftp.rb
add file://
-rw-r--r--lib/chef/provider/remote_file.rb77
-rw-r--r--lib/chef/provider/remote_file/ftp.rb82
2 files changed, 101 insertions, 58 deletions
diff --git a/lib/chef/provider/remote_file.rb b/lib/chef/provider/remote_file.rb
index cf4d129bea..27ee95acd3 100644
--- a/lib/chef/provider/remote_file.rb
+++ b/lib/chef/provider/remote_file.rb
@@ -19,10 +19,9 @@
require 'chef/provider/file'
require 'rest_client'
+require 'chef/provider/remote_file/ftp'
require 'uri'
require 'tempfile'
-require 'net/https'
-require 'net/ftp'
class Chef
class Provider
@@ -48,11 +47,16 @@ class Chef
if URI::HTTP === uri
#HTTP or HTTPS
raw_file = RestClient::Request.execute(:method => :get, :url => source, :raw_response => true).file
- else
+ elsif URI::FTP === uri
#FTP
- raw_file = ftp_fetch(uri)
+ raw_file = FTP::fetch(uri, @new_resource.ftp_active_mode)
+ elsif uri.scheme == "file"
+ #local/network file
+ raw_file = ::File.new(uri.path, "r")
+ else
+ raise ArgumentError, "Invalid uri. Only http(s), ftp, and file are currently supported"
end
- rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Net::HTTPFatalError => e
+ rescue => 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")
@@ -71,12 +75,20 @@ class Chef
backup_new_resource
FileUtils.cp raw_file.path, @new_resource.path
Chef::Log.info "#{@new_resource} updated"
- raw_file.close!
+ if raw_file.is_a? Tempfile
+ raw_file.close!
+ else
+ raw_file.close
+ end
end
# whyrun mode cleanup - the temp file will never be used,
# so close/unlink it here.
if whyrun_mode?
- raw_file.close!
+ if raw_file.is_a? Tempfile
+ raw_file.close!
+ else
+ raw_file.close
+ end
end
end
end
@@ -109,57 +121,6 @@ class Chef
backup @new_resource.path
end
end
-
- private
-
- def ftp_fetch(uri)
- # Shamelessly stolen from open-uri
- # Fetches the file using Net::FTP, returning a Tempfile
- path = uri.path
- path = path.sub(%r{\A/}, '%2F') # re-encode the beginning slash because uri library decodes it.
- directories = path.split(%r{/}, -1)
- directories.each {|d|
- d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
- }
- unless filename = directories.pop
- raise ArgumentError, "no filename: #{uri.inspect}"
- end
- directories.each {|d|
- if /[\r\n]/ =~ d
- raise ArgumentError, "invalid directory: #{d.inspect}"
- end
- }
- if /[\r\n]/ =~ filename
- raise ArgumentError, "invalid filename: #{filename.inspect}"
- end
- typecode = uri.typecode
- if typecode && /\A[aid]\z/ !~ typecode
- raise ArgumentError, "invalid typecode: #{typecode.inspect}"
- end
-
- tempfile = Tempfile.new(filename)
-
- # The access sequence is defined by RFC 1738
- ftp = Net::FTP.new
- ftp.connect(uri.hostname, uri.port)
- ftp.passive = true if !@new_resource.ftp_active_mode
- # todo: extract user/passwd from .netrc.
- user = 'anonymous'
- passwd = nil
- user, passwd = uri.userinfo.split(/:/) if uri.userinfo
- ftp.login(user, passwd)
- directories.each {|cwd|
- ftp.voidcmd("CWD #{cwd}")
- }
- if typecode
- # xxx: typecode D is not handled.
- ftp.voidcmd("TYPE #{typecode.upcase}")
- end
- ftp.getbinaryfile(filename, tempfile.path)
- ftp.close
-
- tempfile
- end
end
end
end
diff --git a/lib/chef/provider/remote_file/ftp.rb b/lib/chef/provider/remote_file/ftp.rb
new file mode 100644
index 0000000000..9973822223
--- /dev/null
+++ b/lib/chef/provider/remote_file/ftp.rb
@@ -0,0 +1,82 @@
+#
+# Author:: Jesse Campbell (<hikeit@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'uri'
+require 'tempfile'
+require 'net/ftp'
+
+class Chef
+ class Provider
+ class RemoteFile < Chef::Provider::File
+ class FTP
+
+ # Fetches the file at uri using Net::FTP, returning a Tempfile
+ # Parts shamelessly stolen from open-uri
+ def self.fetch(uri, ftp_active_mode)
+ path = uri.path
+ path = path.sub(%r{\A/}, '%2F') # re-encode the beginning slash because uri library decodes it.
+ directories = path.split(%r{/}, -1)
+ directories.each {|d|
+ d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
+ }
+ unless filename = directories.pop
+ raise ArgumentError, "no filename: #{uri.inspect}"
+ end
+ directories.each {|d|
+ if /[\r\n]/ =~ d
+ raise ArgumentError, "invalid directory: #{d.inspect}"
+ end
+ }
+ if /[\r\n]/ =~ filename
+ raise ArgumentError, "invalid filename: #{filename.inspect}"
+ end
+ typecode = uri.typecode
+ if typecode && /\A[aid]\z/ !~ typecode
+ raise ArgumentError, "invalid typecode: #{typecode.inspect}"
+ end
+
+ tempfile = Tempfile.new(filename)
+
+ # The access sequence is defined by RFC 1738
+ ftp = Net::FTP.new
+ ftp.connect(uri.hostname, uri.port)
+ ftp.passive = true if !ftp_active_mode
+ # todo: extract user/passwd from .netrc.
+ user = 'anonymous'
+ passwd = nil
+ if uri.userinfo
+ user = URI.unescape(uri.user)
+ passwd = URI.unescape(uri.password)
+ end
+ ftp.login(user, passwd)
+ directories.each {|cwd|
+ ftp.voidcmd("CWD #{cwd}")
+ }
+ if typecode
+ # xxx: typecode D is not handled.
+ ftp.voidcmd("TYPE #{typecode.upcase}")
+ end
+ ftp.getbinaryfile(filename, tempfile.path)
+ ftp.close
+
+ tempfile
+ end
+ end
+ end
+ end
+end