diff options
Diffstat (limited to 'lib/chef/file_cache.rb')
-rw-r--r-- | lib/chef/file_cache.rb | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/lib/chef/file_cache.rb b/lib/chef/file_cache.rb new file mode 100644 index 0000000000..89e934ea05 --- /dev/null +++ b/lib/chef/file_cache.rb @@ -0,0 +1,220 @@ +# +# Author:: Adam Jacob (<adam@opscode.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 'chef/mixin/params_validate' +require 'chef/mixin/create_path' +require 'chef/exceptions' +require 'chef/json_compat' +require 'fileutils' + +class Chef + class FileCache + class << self + include Chef::Mixin::ParamsValidate + include Chef::Mixin::CreatePath + + # Write a file to the File Cache. + # + # === Parameters + # path<String>:: The path to the file you want to put in the cache - should + # be relative to file_cache_path + # contents<String>:: A string with the contents you want written to the file + # perm<String>:: Sets file permission bits. Permission bits are platform + # dependent; on Unix systems, see open(2) for details. + # + # === Returns + # true + def store(path, contents, perm=0640) + validate( + { + :path => path, + :contents => contents + }, + { + :path => { :kind_of => String }, + :contents => { :kind_of => String }, + } + ) + + file_path_array = File.split(path) + file_name = file_path_array.pop + cache_path = create_cache_path(File.join(file_path_array)) + File.open(File.join(cache_path, file_name), "w", perm) do |io| + io.print(contents) + end + true + end + + # Move a file into the cache. Useful with the REST raw file output. + # + # === Parameters + # file<String>:: The path to the file you want in the cache + # path<String>:: The relative name you want the new file to use + def move_to(file, path) + validate( + { + :file => file, + :path => path + }, + { + :file => { :kind_of => String }, + :path => { :kind_of => String }, + } + ) + + file_path_array = File.split(path) + file_name = file_path_array.pop + if File.exists?(file) && File.writable?(file) + FileUtils.mv( + file, + File.join(create_cache_path(File.join(file_path_array), true), file_name) + ) + else + raise RuntimeError, "Cannot move #{file} to #{path}!" + end + end + + # Read a file from the File Cache + # + # === Parameters + # path<String>:: The path to the file you want to load - should + # be relative to file_cache_path + # read<True/False>:: Whether to return the file contents, or the path. + # Defaults to true. + # + # === Returns + # String:: A string with the file contents, or the path to the file. + # + # === Raises + # Chef::Exceptions::FileNotFound:: If it cannot find the file in the cache + def load(path, read=true) + validate( + { + :path => path + }, + { + :path => { :kind_of => String } + } + ) + cache_path = create_cache_path(path, false) + raise Chef::Exceptions::FileNotFound, "Cannot find #{cache_path} for #{path}!" unless File.exists?(cache_path) + if read + File.read(cache_path) + else + cache_path + end + end + + # Delete a file from the File Cache + # + # === Parameters + # path<String>:: The path to the file you want to delete - should + # be relative to file_cache_path + # + # === Returns + # true + def delete(path) + validate( + { + :path => path + }, + { + :path => { :kind_of => String }, + } + ) + cache_path = create_cache_path(path, false) + if File.exists?(cache_path) + File.unlink(cache_path) + end + true + end + + # List all the files in the Cache + # + # === Returns + # Array:: An array of files in the cache, suitable for use with load, delete and store + def list + find("**#{File::Separator}*") + end + + ## + # Find files in the cache by +glob_pattern+ + # === Returns + # [String] - An array of file cache keys matching the glob + def find(glob_pattern) + keys = Array.new + Dir[File.join(file_cache_path, glob_pattern)].each do |f| + if File.file?(f) + keys << f[/^#{Regexp.escape(Dir[file_cache_path].first) + File::Separator}(.+)/, 1] + end + end + keys + end + + # Whether or not this file exists in the Cache + # + # === Parameters + # path:: The path to the file you want to check - is relative + # to file_cache_path + # + # === Returns + # True:: If the file exists + # False:: If it does not + def has_key?(path) + validate( + { + :path => path + }, + { + :path => { :kind_of => String }, + } + ) + full_path = create_cache_path(path, false) + if File.exists?(full_path) + true + else + false + end + end + + # Create a full path to a given file in the cache. By default, + # also creates the path if it does not exist. + # + # === Parameters + # path:: The path to create, relative to file_cache_path + # create_if_missing:: True by default - whether to create the path if it does not exist + # + # === Returns + # String:: The fully expanded path + def create_cache_path(path, create_if_missing=true) + cache_dir = File.expand_path(File.join(file_cache_path, path)) + if create_if_missing + create_path(cache_dir) + else + cache_dir + end + end + + private + + def file_cache_path + Chef::Config[:file_cache_path] + end + + end + end +end |