class ChefFS::Config

Helpers to take Chef::Config and create chef_fs and local_fs from it

Constants

PATH_VARIABLES

Attributes

chef_config[R]
cookbook_version[R]
cwd[R]

Public Class Methods

new(chef_config = Chef::Config, cwd = Dir.pwd, options = {}) click to toggle source
# File lib/chef_fs/config.rb, line 27
def initialize(chef_config = Chef::Config, cwd = Dir.pwd, options = {})
  @chef_config = chef_config
  @cwd = cwd
  @cookbook_version = options[:cookbook_version]
  configure_repo_paths
end

Public Instance Methods

base_path() click to toggle source

The current directory, relative to server root

# File lib/chef_fs/config.rb, line 107
def base_path
  @base_path ||= begin
    if @chef_config[:chef_repo_path]
      server_path(File.expand_path(@cwd))
    else
      nil
    end
  end
end
chef_fs() click to toggle source
# File lib/chef_fs/config.rb, line 40
def chef_fs
  @chef_fs ||= create_chef_fs
end
create_chef_fs() click to toggle source
# File lib/chef_fs/config.rb, line 44
def create_chef_fs
  require 'chef_fs/file_system/chef_server_root_dir'
  ChefFS::FileSystem::ChefServerRootDir.new("remote", @chef_config, :cookbook_version => @cookbook_version)
end
create_local_fs() click to toggle source
# File lib/chef_fs/config.rb, line 53
def create_local_fs
  require 'chef_fs/file_system/chef_repository_file_system_root_dir'
  ChefFS::FileSystem::ChefRepositoryFileSystemRootDir.new(object_paths)
end
format_path(entry) click to toggle source

Print the given server path, relative to the current directory

# File lib/chef_fs/config.rb, line 118
def format_path(entry)
  server_path = entry.path
  if base_path && server_path[0,base_path.length] == base_path
    if server_path == base_path
      return "."
    elsif server_path[base_path.length,1] == "/"
      return server_path[base_path.length + 1, server_path.length - base_path.length - 1]
    elsif base_path == "/" && server_path[0,1] == "/"
      return server_path[1, server_path.length - 1]
    end
  end
  server_path
end
local_fs() click to toggle source
# File lib/chef_fs/config.rb, line 49
def local_fs
  @local_fs ||= create_local_fs
end
require_chef_repo_path() click to toggle source
# File lib/chef_fs/config.rb, line 132
def require_chef_repo_path
  if !@chef_config[:chef_repo_path]
    Chef::Log.error("Must specify either chef_repo_path or cookbook_path in Chef config file")
    exit(1)
  end
end
server_path(file_path) click to toggle source

Returns the given real path's location relative to the server root.

If chef_repo is /home/jkeiser/chef_repo, and pwd is /home/jkeiser/chef_repo/cookbooks, server_path('blah') == '/cookbooks/blah' server_path('../roles/blah.json') == '/roles/blah' server_path('../../readme.txt') == nil server_path('*/ab') == '/cookbooks/*/ab' server_path('/home/jkeiser/chef_repo/cookbooks/blah') == '/cookbooks/blah' server_path('/home/*/chef_repo/cookbooks/blah') == nil

If there are multiple paths (cookbooks, roles, data bags, etc. can all have separate paths), and cwd+the path reaches into one of them, we will return a path relative to that. Otherwise we will return a path to chef_repo.

Globs are allowed as well, but globs outside server paths are NOT (presently) supported. See above examples. TODO support that.

If the path does not reach into ANY specified directory, nil is returned.

# File lib/chef_fs/config.rb, line 78
def server_path(file_path)
  pwd = File.expand_path(Dir.pwd)
  absolute_path = ChefFS::PathUtils.realest_path(File.expand_path(file_path, pwd))

  # Check all object paths (cookbooks_dir, data_bags_dir, etc.)
  object_paths.each_pair do |name, paths|
    paths.each do |path|
      realest_path = ChefFS::PathUtils.realest_path(path)
      if absolute_path[0,realest_path.length] == realest_path &&
        (absolute_path.length == realest_path.length ||
          absolute_path[realest_path.length,1] =~ /#{PathUtils.regexp_path_separator}/)
        relative_path = ChefFS::PathUtils::relative_to(absolute_path, realest_path)
        return relative_path == '.' ? "/#{name}" : "/#{name}/#{relative_path}"
      end
    end
  end

  # Check chef_repo_path
  Array(@chef_config[:chef_repo_path]).flatten.each do |chef_repo_path|
    realest_chef_repo_path = ChefFS::PathUtils.realest_path(chef_repo_path)
    if absolute_path == realest_chef_repo_path
      return '/'
    end
  end

  nil
end

Private Instance Methods

configure_repo_paths() click to toggle source
# File lib/chef_fs/config.rb, line 163
def configure_repo_paths
  # Smooth out some (for now) inappropriate defaults set by Chef
  if @chef_config[:cookbook_path] == [ @chef_config.platform_specific_path("/var/chef/cookbooks"),
                @chef_config.platform_specific_path("/var/chef/site-cookbooks") ]
    @chef_config[:cookbook_path] = nil
  end
  if @chef_config[:data_bag_path] == @chef_config.platform_specific_path('/var/chef/data_bags')
    @chef_config[:data_bag_path] = nil
  end
  if @chef_config[:node_path] == '/var/chef/node'
    @chef_config[:node_path] = nil
  end
  if @chef_config[:role_path] == @chef_config.platform_specific_path('/var/chef/roles')
    @chef_config[:role_path] = nil
  end
  if @chef_config[:environment_path] == @chef_config.platform_specific_path('/var/chef/environments')
    @chef_config[:environment_path] = nil
  end

  # Infer chef_repo_path from cookbook_path if not speciifed
  if !@chef_config[:chef_repo_path]
    if @chef_config[:cookbook_path]
      @chef_config[:chef_repo_path] = Array(@chef_config[:cookbook_path]).flatten.map { |path| File.expand_path('..', path) }
    end
  end

  # Default to getting *everything* from the server.
  if !@chef_config[:repo_mode]
    if @chef_config[:chef_server_url] =~ /\/+organizations\/.+/
      @chef_config[:repo_mode] = 'hosted_everything'
    else
      @chef_config[:repo_mode] = 'everything'
    end
  end

  # Infer any *_path variables that are not specified
  if @chef_config[:chef_repo_path]
    PATH_VARIABLES.each do |variable_name|
      chef_repo_paths = Array(@chef_config[:chef_repo_path]).flatten
      variable = variable_name.to_sym
      if !@chef_config[variable]
        # cookbook_path -> cookbooks
        @chef_config[variable] = chef_repo_paths.map { |path| File.join(path, "#{variable_name[0..-6]}s") }
      end
    end
  end
end
object_paths() click to toggle source
# File lib/chef_fs/config.rb, line 141
def object_paths
  @object_paths ||= begin
    require_chef_repo_path

    result = {}
    case @chef_config[:repo_mode]
    when 'static'
      object_names = %w(cookbooks data_bags environments roles)
    when 'hosted_everything'
      object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles)
    else
      object_names = %w(clients cookbooks data_bags environments nodes roles users)
    end
    object_names.each do |object_name|
      variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
      paths = Array(@chef_config[variable_name]).flatten
      result[object_name] = paths.map { |path| File.expand_path(path) }
    end
    result
  end
end