Method: Chef::Provider::File#backup

Defined in:
lib/chef/provider/file.rb

#backup(file = nil) ⇒ Object


275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/chef/provider/file.rb', line 275

def backup(file=nil)
  file ||= @new_resource.path
  if @new_resource.backup != false && @new_resource.backup > 0 && ::File.exist?(file)
    time = Time.now
    savetime = time.strftime("%Y%m%d%H%M%S")
    backup_filename = "#{@new_resource.path}.chef-#{savetime}"
    backup_filename = backup_filename.sub(/^([A-Za-z]:)/, "") #strip drive letter on Windows
    # if :file_backup_path is nil, we fallback to the old behavior of
    # keeping the backup in the same directory. We also need to to_s it
    # so we don't get a type error around implicit to_str conversions.
    prefix = Chef::Config[:file_backup_path].to_s
    backup_path = ::File.join(prefix, backup_filename)
    FileUtils.mkdir_p(::File.dirname(backup_path)) if Chef::Config[:file_backup_path]
    FileUtils.cp(file, backup_path, :preserve => true)
    Chef::Log.info("#{@new_resource} backed up to #{backup_path}")

    # Clean up after the number of backups
    slice_number = @new_resource.backup
    backup_files = Dir[::File.join(prefix, ".#{@new_resource.path}.chef-*")].sort { |a,b| b <=> a }
    if backup_files.length >= @new_resource.backup
      remainder = backup_files.slice(slice_number..-1)
      remainder.each do |backup_to_delete|
        FileUtils.rm(backup_to_delete)
        Chef::Log.info("#{@new_resource} removed backup at #{backup_to_delete}")
      end
    end
  end
end