class Chef::ChefFS::ChefFSDataStore
Attributes
chef_fs[R]
Public Class Methods
new(chef_fs)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 31 def initialize(chef_fs) @chef_fs = chef_fs @memory_store = ChefZero::DataStore::MemoryStore.new end
Public Instance Methods
create(path, name, data, *options)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 56 def create(path, name, data, *options) if use_memory_store?(path) @memory_store.create(path, name, data, *options) elsif path[0] == 'cookbooks' && path.length == 2 # Do nothing. The entry gets created when the cookbook is created. else if !data.is_a?(String) raise "set only works with strings" end with_dir(path) do |parent| begin parent.create_child(chef_fs_filename(path + [name]), data) rescue Chef::ChefFS::FileSystem::AlreadyExistsError => e raise ChefZero::DataStore::DataAlreadyExistsError.new(to_zero_path(e.entry), e) end end end end
create_dir(path, name, *options)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 42 def create_dir(path, name, *options) if use_memory_store?(path) @memory_store.create_dir(path, name, *options) else with_dir(path) do |parent| begin parent.create_child(chef_fs_filename(path + [name]), nil) rescue Chef::ChefFS::FileSystem::AlreadyExistsError => e raise ChefZero::DataStore::DataAlreadyExistsError.new(to_zero_path(e.entry), e) end end end end
delete(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 154 def delete(path) if use_memory_store?(path) @memory_store.delete(path) else with_entry(path) do |entry| begin if path[0] == 'cookbooks' && path.length >= 3 entry.delete(true) else entry.delete(false) end rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end end end
delete_dir(path, *options)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 172 def delete_dir(path, *options) if use_memory_store?(path) @memory_store.delete_dir(path, *options) else with_entry(path) do |entry| begin entry.delete(options.include?(:recursive)) rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end end end
exists?(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 239 def exists?(path) if use_memory_store?(path) @memory_store.exists?(path) else path_always_exists?(path) || Chef::ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists? end end
exists_dir?(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 247 def exists_dir?(path) if use_memory_store?(path) @memory_store.exists_dir?(path) elsif path[0] == 'cookbooks' && path.length == 2 list([ path[0] ]).include?(path[1]) else Chef::ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)).exists? end end
get(path, request=nil)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 78 def get(path, request=nil) if use_memory_store?(path) @memory_store.get(path) elsif path[0] == 'file_store' && path[1] == 'repo' entry = Chef::ChefFS::FileSystem.resolve_path(chef_fs, path[2..-1].join('/')) begin entry.read rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end else with_entry(path) do |entry| if path[0] == 'cookbooks' && path.length == 3 # get /cookbooks/NAME/version result = nil begin result = entry.chef_object.to_hash rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end result.each_pair do |key, value| if value.is_a?(Array) value.each do |file| if file.is_a?(Hash) && file.has_key?('checksum') relative = ['file_store', 'repo', 'cookbooks'] if Chef::Config.versioned_cookbooks relative << "#{path[1]}-#{path[2]}" else relative << path[1] end relative = relative + file[:path].split('/') file['url'] = ChefZero::RestBase::build_uri(request.base_uri, relative) end end end end JSON.pretty_generate(result) else begin entry.read rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end end end end
list(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 186 def list(path) if use_memory_store?(path) @memory_store.list(path) elsif path[0] == 'cookbooks' && path.length == 1 with_entry(path) do |entry| begin if Chef::Config.versioned_cookbooks # /cookbooks/name-version -> /cookbooks/name entry.children.map { |child| split_name_version(child.name)[0] }.uniq else entry.children.map { |child| child.name } end rescue Chef::ChefFS::FileSystem::NotFoundError # If the cookbooks dir doesn't exist, we have no cookbooks (not 404) [] end end elsif path[0] == 'cookbooks' && path.length == 2 if Chef::Config.versioned_cookbooks result = with_entry([ 'cookbooks' ]) do |entry| # list /cookbooks/name = filter /cookbooks/name-version down to name entry.children.map { |child| split_name_version(child.name) }. select { |name, version| name == path[1] }. map { |name, version| version } end if result.empty? raise ChefZero::DataStore::DataNotFoundError.new(path) end result else # list /cookbooks/name = <single version> version = get_single_cookbook_version(path) [version] end else with_entry(path) do |entry| begin entry.children.map { |c| zero_filename(c) }.sort rescue Chef::ChefFS::FileSystem::NotFoundError => e # /cookbooks, /data, etc. never return 404 if path_always_exists?(path) [] else raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end end end end
publish_description()
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 36 def publish_description "Reading and writing data to #{chef_fs.fs_description}" end
set(path, data, *options)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 130 def set(path, data, *options) if use_memory_store?(path) @memory_store.set(path, data, *options) else if !data.is_a?(String) raise "set only works with strings: #{path} = #{data.inspect}" end # Write out the files! if path[0] == 'cookbooks' && path.length == 3 write_cookbook(path, data, *options) else with_dir(path[0..-2]) do |parent| child = parent.child(chef_fs_filename(path)) if child.exists? child.write(data) else parent.create_child(chef_fs_filename(path), data) end end end end end
Private Instance Methods
_to_chef_fs_path(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 311 def _to_chef_fs_path(path) if path[0] == 'data' path = path.dup path[0] = 'data_bags' if path.length >= 3 path[2] = "#{path[2]}.json" end elsif path[0] == 'cookbooks' if path.length == 2 raise ChefZero::DataStore::DataNotFoundError.new(path) elsif Chef::Config.versioned_cookbooks if path.length >= 3 # cookbooks/name/version -> cookbooks/name-version path = [ path[0], "#{path[1]}-#{path[2]}" ] + path[3..-1] end else if path.length >= 3 # cookbooks/name/version/... -> /cookbooks/name/... iff metadata says so version = get_single_cookbook_version(path) if path[2] == version path = path[0..1] + path[3..-1] else raise ChefZero::DataStore::DataNotFoundError.new(path) end end end elsif path.length == 2 path = path.dup path[1] = "#{path[1]}.json" end path end
chef_fs_filename(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 307 def chef_fs_filename(path) _to_chef_fs_path(path)[-1] end
get_dir(path, create=false)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 401 def get_dir(path, create=false) result = Chef::ChefFS::FileSystem.resolve_path(chef_fs, path.join('/')) if result.exists? result elsif create get_dir(path[0..-2], create).create_child(result.name, nil) else raise ChefZero::DataStore::DataNotFoundError.new(path) end end
get_single_cookbook_version(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 412 def get_single_cookbook_version(path) dir = Chef::ChefFS::FileSystem.resolve_path(chef_fs, path[0..1].join('/')) metadata = ChefZero::CookbookData.metadata_from(dir, path[1], nil, []) metadata[:version] || '0.0.0' end
path_always_exists?(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 379 def path_always_exists?(path) return path.length == 1 && %w(clients cookbooks data environments nodes roles users).include?(path[0]) end
split_name_version(entry_name)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 296 def split_name_version(entry_name) name_version = entry_name.split('-') name = name_version[0..-2].join('-') version = name_version[-1] [name,version] end
to_chef_fs_path(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 303 def to_chef_fs_path(path) _to_chef_fs_path(path).join('/') end
to_zero_path(entry)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 344 def to_zero_path(entry) path = entry.path.split('/')[1..-1] if path[0] == 'data_bags' path = path.dup path[0] = 'data' if path.length >= 3 path[2] = path[2][0..-6] end elsif path[0] == 'cookbooks' if Chef::Config.versioned_cookbooks # cookbooks/name-version/... -> cookbooks/name/version/... if path.length >= 2 name, version = split_name_version(path[1]) path = [ path[0], name, version ] + path[2..-1] end else if path.length >= 2 # cookbooks/name/... -> cookbooks/name/version/... version = get_single_cookbook_version(path) path = path[0..1] + [version] + path[2..-1] end end elsif path.length == 2 && path[0] != 'cookbooks' path = path.dup path[1] = path[1][0..-6] end path end
use_memory_store?(path)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 259 def use_memory_store?(path) return path[0] == 'sandboxes' || path[0] == 'file_store' && path[1] == 'checksums' || path == [ 'environments', '_default' ] end
with_dir(path) { |get_dir(_to_chef_fs_path(path), create)| ... }
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 391 def with_dir(path) # Do not automatically create data bags create = !(path[0] == 'data' && path.size >= 2) begin yield get_dir(_to_chef_fs_path(path), create) rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end
with_entry(path) { |resolve_path(chef_fs, to_chef_fs_path(path))| ... }
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 383 def with_entry(path) begin yield Chef::ChefFS::FileSystem.resolve_path(chef_fs, to_chef_fs_path(path)) rescue Chef::ChefFS::FileSystem::NotFoundError => e raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e) end end
write_cookbook(path, data, *options)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 263 def write_cookbook(path, data, *options) if Chef::Config.versioned_cookbooks cookbook_path = File.join('cookbooks', "#{path[1]}-#{path[2]}") else cookbook_path = File.join('cookbooks', path[1]) end # Create a little Chef::ChefFS memory filesystem with the data cookbook_fs = Chef::ChefFS::FileSystem::MemoryRoot.new('uploading') cookbook = JSON.parse(data, :create_additions => false) cookbook.each_pair do |key, value| if value.is_a?(Array) value.each do |file| if file.is_a?(Hash) && file.has_key?('checksum') file_data = @memory_store.get(['file_store', 'checksums', file['checksum']]) cookbook_fs.add_file(File.join(cookbook_path, file['path']), file_data) end end end end # Create the .uploaded-cookbook-version.json cookbooks = chef_fs.child('cookbooks') if !cookbooks.exists? cookbooks = chef_fs.create_child('cookbooks') end # We are calling a cookbooks-specific API, so get multiplexed_dirs out of the way if it is there if cookbooks.respond_to?(:multiplexed_dirs) cookbooks = cookbooks.write_dir end cookbooks.write_cookbook(cookbook_path, data, cookbook_fs) end
zero_filename(entry)
click to toggle source
# File lib/chef/chef_fs/chef_fs_data_store.rb, line 375 def zero_filename(entry) to_zero_path(entry)[-1] end