summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-05-05 12:20:02 -0500
committerJay Mundrawala <jdmundrawala@gmail.com>2015-05-05 12:07:11 -0700
commite4721a3e89e24614eebd6302e53b3b91d4535a92 (patch)
treeb4fa8c94c01690604f51c392f5d9c451964d7ecc
parent8c92948746bc418fac09218814a9cfb9e4894b5d (diff)
downloadchef-e4721a3e89e24614eebd6302e53b3b91d4535a92.tar.gz
remote_file support for windows network shares
```ruby remote_file 'C:\Foo.tar.gz' do source "\\\\foohost\\fooshare\\Foo.tar.gz" end ```
-rw-r--r--lib/chef/provider/remote_file/content.rb6
-rw-r--r--lib/chef/provider/remote_file/fetcher.rb30
-rw-r--r--lib/chef/provider/remote_file/network_file.rb48
-rw-r--r--lib/chef/providers.rb1
-rw-r--r--lib/chef/resource/remote_file.rb2
5 files changed, 77 insertions, 10 deletions
diff --git a/lib/chef/provider/remote_file/content.rb b/lib/chef/provider/remote_file/content.rb
index ef55dd77cd..938a7e58f4 100644
--- a/lib/chef/provider/remote_file/content.rb
+++ b/lib/chef/provider/remote_file/content.rb
@@ -45,7 +45,11 @@ class Chef
sources = sources.dup
source = sources.shift
begin
- uri = URI.parse(source)
+ uri = if Chef::Provider::RemoteFile::Fetcher.network_share?(source)
+ source
+ else
+ URI.parse(source)
+ end
raw_file = grab_file_from_uri(uri)
rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPServerException, Net::HTTPFatalError, Net::FTPError => e
Chef::Log.warn("#{@new_resource} cannot be downloaded from #{source}: #{e.to_s}")
diff --git a/lib/chef/provider/remote_file/fetcher.rb b/lib/chef/provider/remote_file/fetcher.rb
index 249b29186f..91ad11aa34 100644
--- a/lib/chef/provider/remote_file/fetcher.rb
+++ b/lib/chef/provider/remote_file/fetcher.rb
@@ -23,15 +23,29 @@ class Chef
class Fetcher
def self.for_resource(uri, new_resource, current_resource)
- case uri.scheme
- when "http", "https"
- Chef::Provider::RemoteFile::HTTP.new(uri, new_resource, current_resource)
- when "ftp"
- Chef::Provider::RemoteFile::FTP.new(uri, new_resource, current_resource)
- when "file"
- Chef::Provider::RemoteFile::LocalFile.new(uri, new_resource, current_resource)
+ if network_share?(uri)
+ Chef::Provider::RemoteFile::NetworkFile.new(uri, new_resource, current_resource)
else
- raise ArgumentError, "Invalid uri, Only http(s), ftp, and file are currently supported"
+ case uri.scheme
+ when "http", "https"
+ Chef::Provider::RemoteFile::HTTP.new(uri, new_resource, current_resource)
+ when "ftp"
+ Chef::Provider::RemoteFile::FTP.new(uri, new_resource, current_resource)
+ when "file"
+ Chef::Provider::RemoteFile::LocalFile.new(uri, new_resource, current_resource)
+ else
+ raise ArgumentError, "Invalid uri, Only http(s), ftp, and file are currently supported"
+ end
+ end
+ end
+
+ # Windows network share: \\computername\share\file
+ def self.network_share?(source)
+ case source
+ when String
+ !!(%r{\A\\\\[A-Za-z][A-Za-z0-9+\-\.]*} =~ source)
+ else
+ false
end
end
diff --git a/lib/chef/provider/remote_file/network_file.rb b/lib/chef/provider/remote_file/network_file.rb
new file mode 100644
index 0000000000..093a388d2a
--- /dev/null
+++ b/lib/chef/provider/remote_file/network_file.rb
@@ -0,0 +1,48 @@
+#
+# Author:: Jesse Campbell (<hikeit@gmail.com>)
+# Copyright:: Copyright (c) 2013 Jesse Campbell
+# 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 'chef/provider/remote_file'
+
+class Chef
+ class Provider
+ class RemoteFile
+ class NetworkFile
+
+ attr_reader :new_resource
+
+ def initialize(source, new_resource, current_resource)
+ @new_resource = new_resource
+ @source = source
+ end
+
+ # Fetches the file on a network share, returning a Tempfile-like File handle
+ # windows only
+ def fetch
+ tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile
+ Chef::Log.debug("#{new_resource} staging #{@source} to #{tempfile.path}")
+ FileUtils.cp(@source, tempfile.path)
+ tempfile.close if tempfile
+ tempfile
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index a5f5386de3..18500d4669 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -122,6 +122,7 @@ require 'chef/provider/deploy/timestamped'
require 'chef/provider/remote_file/ftp'
require 'chef/provider/remote_file/http'
require 'chef/provider/remote_file/local_file'
+require 'chef/provider/remote_file/network_file'
require 'chef/provider/remote_file/fetcher'
require "chef/provider/lwrp_base"
diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb
index e56f69941d..69614f0298 100644
--- a/lib/chef/resource/remote_file.rb
+++ b/lib/chef/resource/remote_file.rb
@@ -140,7 +140,7 @@ class Chef
end
def absolute_uri?(source)
- source.kind_of?(String) and URI.parse(source).absolute?
+ Chef::Provider::RemoteFile::Fetcher.network_share?(source) or (source.kind_of?(String) and URI.parse(source).absolute?)
rescue URI::InvalidURIError
false
end