class Chef::Provider::RemoteDirectory

Public Instance Methods

action_create() click to toggle source

Handle action :create.

Calls superclass method Chef::Provider::Directory#action_create
# File lib/chef/provider/remote_directory.rb, line 61
def action_create
  super

  # Transfer files
  files_to_transfer.each do |cookbook_file_relative_path|
    create_cookbook_file(cookbook_file_relative_path)
    # parent directories and file being transferred need to not be removed in the purge
    add_managed_file(cookbook_file_relative_path)
  end

  purge_unmanaged_files
end
action_create_if_missing() click to toggle source

Handle action :create_if_missing.

# File lib/chef/provider/remote_directory.rb, line 76
def action_create_if_missing
  # if this action is called, ignore the existing overwrite flag
  @overwrite = false
  action_create
end
managed_files() click to toggle source

Hash containing keys of the paths for all the files that we sync, plus all their parent directories.

@return [Set] Ruby Set of the files that we manage

# File lib/chef/provider/remote_directory.rb, line 55
def managed_files
  @managed_files ||= Set.new
end
overwrite?() click to toggle source

The overwrite property on the resource. Delegates to new_resource but can be mutated.

@return [Boolean] if we are overwriting

# File lib/chef/provider/remote_directory.rb, line 45
def overwrite?
  @overwrite = new_resource.overwrite if @overwrite.nil?
  !!@overwrite
end

Private Instance Methods

action_for_cookbook_file() click to toggle source

If we are overwriting, then cookbook_file sub-resources should all be action :create, otherwise they should be :create_if_missing

@return [Symbol] Action to take on cookbook_file sub-resources @api private

# File lib/chef/provider/remote_directory.rb, line 179
def action_for_cookbook_file
  overwrite? ? :create : :create_if_missing
end
add_managed_file(cookbook_file_relative_path) click to toggle source

Add a file and its parent directories to the #managed_files Hash.

@param [String] cookbook_file_relative_path relative path to the file @api private

# File lib/chef/provider/remote_directory.rb, line 89
def add_managed_file(cookbook_file_relative_path)
  if purge
    Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(path, cookbook_file_relative_path))).descend do |d|
      managed_files.add(d.to_s)
    end
  end
end
cookbook_file_resource(target_path, relative_source_path) click to toggle source

This creates the cookbook_file resource for use by create_cookbook_file.

@param [String] target_path Path on the system to create @param [String] relative_source_path Relative path in the cookbook to the base source @return [Chef::Resource::CookbookFile] The built cookbook_file resource @api private

# File lib/chef/provider/remote_directory.rb, line 205
def cookbook_file_resource(target_path, relative_source_path)
  res = Chef::Resource::CookbookFile.new(target_path, run_context)
  res.cookbook_name = resource_cookbook
  # Set the sensitivity level
  res.sensitive(new_resource.sensitive)
  res.source(::File.join(source, relative_source_path))
  if Chef::Platform.windows? && files_rights
    files_rights.each_pair do |permission, *args|
      res.rights(permission, *args)
    end
  end
  res.mode(files_mode)       if files_mode
  res.group(files_group)     if files_group
  res.owner(files_owner)     if files_owner
  res.backup(files_backup)   if files_backup

  res
end
create_cookbook_file(cookbook_file_relative_path) click to toggle source

This creates and uses a cookbook_file resource to sync a single file from the cookbook.

@param [String] cookbook_file_relative_path The relative path to the cookbook file @api private

# File lib/chef/provider/remote_directory.rb, line 188
def create_cookbook_file(cookbook_file_relative_path)
  full_path = ::File.join(path, cookbook_file_relative_path)

  ensure_directory_exists(::File.dirname(full_path))

  res = cookbook_file_resource(full_path, cookbook_file_relative_path)
  res.run_action(action_for_cookbook_file)
  new_resource.updated_by_last_action(true) if res.updated?
end
directory_resource(dir) click to toggle source

This creates the directory resource for ensure_directory_exists.

@param [String] dir Directory path on the system @return [Chef::Resource::Directory] The built directory resource @api private

# File lib/chef/provider/remote_directory.rb, line 244
def directory_resource(dir)
  res = Chef::Resource::Directory.new(dir, run_context)
  res.cookbook_name = resource_cookbook
  if Chef::Platform.windows? && rights
    # rights are only meant to be applied to the toppest-level directory;
    # Windows will handle inheritance.
    if dir == path
      rights.each do |r|
        r = r.dup # do not update the new_resource
        permissions = r.delete(:permissions)
        principals = r.delete(:principals)
        res.rights(permissions, principals, r)
      end
    end
  end
  res.mode(mode) if mode
  res.group(group) if group
  res.owner(owner) if owner
  res.recursive(true)

  res
end
ensure_directory_exists(dir) click to toggle source

This creates and uses a directory resource to create a directory if it is needed.

@param [String] dir The path to the directory to create. @api private

# File lib/chef/provider/remote_directory.rb, line 229
def ensure_directory_exists(dir)
  # doing the check here and skipping the resource should be more performant
  unless ::File.directory?(dir)
    res = directory_resource(dir)
    res.run_action(:create)
    new_resource.updated_by_last_action(true) if res.updated?
  end
end
files_to_transfer() click to toggle source

Get the files to tranfer. This returns files in lexicographical sort order.

FIXME: it should do breadth-first, see CHEF-5080 (please use a performant sort)

@return [Array<String>] The list of files to transfer @api private

# File lib/chef/provider/remote_directory.rb, line 157
def files_to_transfer
  cookbook = run_context.cookbook_collection[resource_cookbook]
  files = cookbook.relative_filenames_in_preferred_directory(node, :files, source)
  files.sort_by! { |x| x.count(::File::SEPARATOR) }
end
purge_directory(dir) click to toggle source

Use a Chef directory sub-resource to remove a directory.

@param [String] dir The path of the directory to remove @api private

# File lib/chef/provider/remote_directory.rb, line 133
def purge_directory(dir)
  res = Chef::Resource::Directory.new(dir, run_context)
  res.run_action(:delete)
  new_resource.updated_by_last_action(true) if res.updated?
end
purge_file(file) click to toggle source

Use a Chef file sub-resource to remove a file.

@param [String] file The path of the file to remove @api private

# File lib/chef/provider/remote_directory.rb, line 144
def purge_file(file)
  res = Chef::Resource::File.new(file, run_context)
  res.run_action(:delete)
  new_resource.updated_by_last_action(true) if res.updated?
end
purge_unmanaged_files() click to toggle source

Remove all files not in the #managed_files Set.

@api private

# File lib/chef/provider/remote_directory.rb, line 101
def purge_unmanaged_files
  if purge
    Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob_dir(path), "**", "*"), ::File::FNM_DOTMATCH).sort!.reverse!.each do |file|
      # skip '.' and '..'
      next if [".", ".."].include?(Pathname.new(file).basename().to_s)

      # Clean the path.  This is required because of the ::File.join
      file = Chef::Util::PathHelper.cleanpath(file)

      # Skip files that we've sync'd and their parent dirs
      next if managed_files.include?(file)

      if ::File.directory?(file)
        if !Chef::Platform.windows? && file_class.symlink?(file.dup)
          # Unix treats dir symlinks as files
          purge_file(file)
        else
          # Unix dirs are dirs, Windows dirs and dir symlinks are dirs
          purge_directory(file)
        end
      else
        purge_file(file)
      end
    end
  end
end
resource_cookbook() click to toggle source

Either the explicit cookbook that the user sets on the resource, or the implicit cookbook_name that the resource was declared in.

@return [String] Cookbook to get file from. @api private

# File lib/chef/provider/remote_directory.rb, line 169
def resource_cookbook
  cookbook || cookbook_name
end