File: backups.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (86 lines) | stat: -rw-r--r-- 2,549 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
require 'find'
require 'fileutils'
module Puppet::Util::Backups

  # Deal with backups.
  def perform_backup(file = nil)
    # if they specifically don't want a backup, then just say
    # we're good
    return true unless self[:backup]

    # let the path be specified
    file ||= self[:path]
    return true unless Puppet::FileSystem.exist?(file)

    return(self.bucket ? perform_backup_with_bucket(file) : perform_backup_with_backuplocal(file, self[:backup]))
  end

  private

  def perform_backup_with_bucket(fileobj)
    file = (fileobj.class == String) ? fileobj : fileobj.name
    case Puppet::FileSystem.lstat(file).ftype
    when "directory"
      # we don't need to backup directories when recurse is on
      return true if self[:recurse]
      info _("Recursively backing up to filebucket")
      Find.find(self[:path]) { |f| backup_file_with_filebucket(f) if File.file?(f) }
    when "file"; backup_file_with_filebucket(file)
    when "link";
    end
    true
  end

  def perform_backup_with_backuplocal(fileobj, backup)
    file = (fileobj.class == String) ? fileobj : fileobj.name
    newfile = file + backup

    remove_backup(newfile)

    begin
      bfile = file + backup

      # N.B. cp_r works on both files and directories
      FileUtils.cp_r(file, bfile, :preserve => true)
      return true
    rescue => detail
      # since they said they want a backup, let's error out
      # if we couldn't make one
      self.fail Puppet::Error, _("Could not back %{file} up: %{message}") % { file: file, message: detail.message }, detail
    end
  end

  def remove_backup(newfile)
    if self.class.name == :file and self[:links] != :follow
      method = :lstat
    else
      method = :stat
    end

    begin
      stat = Puppet::FileSystem.send(method, newfile)
    rescue Errno::ENOENT
      return
    end

    if stat.ftype == "directory"
      raise Puppet::Error, _("Will not remove directory backup %{newfile}; use a filebucket") % { newfile: newfile }
    end

    info _("Removing old backup of type %{file_type}") % { file_type: stat.ftype }

    begin
      Puppet::FileSystem.unlink(newfile)
    rescue => detail
      message = _("Could not remove old backup: %{detail}") % { detail: detail }
      self.log_exception(detail, message)
      self.fail Puppet::Error, message, detail
    end
  end

  def backup_file_with_filebucket(f)
    sum = self.bucket.backup(f)
    self.info _("Filebucketed %{f} to %{filebucket} with sum %{sum}") % { f: f, filebucket: self.bucket.name, sum: sum }
    return sum
  end
end