class ChefBackup::Strategy::TarBackup

ChefBackup::Tar class. Used to backup Standalone and Tier Servers that aren't installed on LVM

Constants

DEFAULT_STATEFUL_SERVICES

Attributes

backup_time[R]

Public Class Methods

new() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 17
def initialize
  @backup_time = Time.now.strftime('%Y-%m-%d-%H-%M-%S')
end

Public Instance Methods

add_ha_services() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 103
def add_ha_services
  if ha? && !config_only?
    data_map.add_service('keepalived', service_config['keepalived']['dir'])
    data_map.add_ha_info('provider', service_config['ha']['provider'])
    data_map.add_ha_info('path', service_config['ha']['path'])
  end
end
ask_to_go_offline() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 241
def ask_to_go_offline
  msg = 'WARNING:  Offline backup mode must stop your Chef server before '
  msg << 'continuing.  You can skip this message by passing a "--yes" '
  msg << 'argument. Do you wish to proceed? (y/N):'

  require "tty-prompt" unless defined?(TTY::Prompt)
  exit(1) unless TTY::Prompt.new(interrupt: :exit).ask(msg) =~ /^y/i
end
backup() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 161
def backup
  log "Starting Chef Server backup #{config_only? ? '(config only)' : ''}"
  populate_data_map
  stopped = false
  if backend? && !config_only?
    if !online?
      ask_to_go_offline unless offline_permission_granted?
      stop_chef_server(except: %i[keepalived postgresql])
      dump_db
      stop_service(:postgresql)
      stopped = true
    else
      dump_db
    end
  end
  write_manifest
  create_tarball
  start_chef_server if stopped
  export_tarball
  cleanup
  log 'Backup Complete!'
rescue => e
  log "Something went terribly wrong, aborting backup", :error
  log e.message, :error
  cleanup
  start_chef_server
  raise e
end
chpst() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 66
def chpst
  "#{base_install_dir}/embedded/bin/chpst"
end
config_directories() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 139
def config_directories
  [project_name] + enabled_addons.keys
end
config_only?() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 237
def config_only?
  service_config['backup']['config_only']
end
create_tarball() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 190
def create_tarball
  log 'Creating backup tarball'
  cmd = [
    "tar -czf #{tmp_dir}/#{export_filename}",
    data_map.services.map { |_, v| v['data_dir'] }.compact.join(' '),
    data_map.configs.map { |_, v| v['data_dir'] }.compact.join(' '),
    Dir["#{tmp_dir}/*"].map { |f| File.basename(f) }.join(' ')
  ].join(' ').strip

  res = shell_out!(cmd, cwd: tmp_dir)
  res
end
data_map() click to toggle source

The data_map is a working record of all of the data that is backed up.

# File lib/chef_backup/strategy/backup/tar.rb, line 148
def data_map
  @data_map ||= ChefBackup::DataMap.new do |data|
    data.backup_time = backup_time
    data.strategy = strategy
    data.topology = topology
  end
end
dump_db() click to toggle source

Perform a pg_dump

@return [TrueClass, FalseClass]

# File lib/chef_backup/strategy/backup/tar.rb, line 47
def dump_db
  return true unless pg_dump?
  if external_pg?
    log('Cannot backup external postgresql', :warn)
    return false
  end
  pg_user = service_config['postgresql']['username']
  sql_file = "#{tmp_dir}/chef_backup-#{backup_time}.sql"
  cmd = [chpst,
         "-u #{pg_user}",
         pg_dumpall,
         "> #{sql_file}"].join(' ')
  log "Dumping Postgresql database to #{sql_file}"
  shell_out!(cmd, env: ["PGOPTIONS=#{pg_options}"])
  data_map.services['postgresql']['pg_dump_success'] = true
  data_map.services['postgresql']['username'] = pg_user
  true
end
export_dir() click to toggle source

Ensures existence of an export directory for the backup

@return [String] A path to the export_dir

# File lib/chef_backup/strategy/backup/tar.rb, line 26
def export_dir
  @export_dir ||= begin
    dir =
      if service_config['backup']['export_dir']
        service_config['backup']['export_dir']
      else
        msg = ["backup['export_dir'] has not been set.",
               'defaulting to: /var/opt/chef-backups'].join(' ')
        log(msg, :warn)
        '/var/opt/chef-backups'
      end
    FileUtils.mkdir_p(dir) unless File.directory?(dir)
    dir
  end
end
export_filename() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 211
def export_filename
  postfix = if config_only?
              '-config'
            else
              ''
            end
  "chef-backup#{postfix}-#{backup_time}.tgz"
end
export_tarball() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 203
def export_tarball
  log "Exporting tarball to #{export_dir}"
  cmd = "rsync -chaz #{tmp_dir}/#{export_filename} #{export_dir}/"

  res = shell_out!(cmd)
  res
end
external_pg?() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 224
def external_pg?
  service_config['postgresql']['external']
end
manifest() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 111
def manifest
  data_map.manifest
end
not_implemented() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 156
def not_implemented
  msg = "#{caller[0].split[1]} is not implemented for this strategy"
  raise NotImplementedError, msg
end
offline_permission_granted?() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 233
def offline_permission_granted?
  service_config['backup']['agree_to_go_offline']
end
pg_dump?() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 228
def pg_dump?
  # defaults to true
  service_config['backup']['always_dump_db']
end
pg_dumpall() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 70
def pg_dumpall
  "#{base_install_dir}/embedded/bin/pg_dumpall"
end
populate_data_map() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 74
def populate_data_map
  unless config_only?
    stateful_services.each do |service|
      next unless service_config.key?(service)
      data_map.add_service(service, service_config[service]['data_dir'])
    end
  end

  config_directories.each do |config|
    data_map.add_config(config, "/etc/#{config}")
  end

  populate_versions

  # Don't forget the upgrades!
  if service_config.key?('upgrades')
    data_map.add_service('upgrades', service_config['upgrades']['dir'])
  end

  add_ha_services
end
populate_versions() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 96
def populate_versions
  project_names.each do |project|
    path = File.join(addon_install_dir(project), '/version-manifest.json')
    data_map.add_version(project, version_from_manifest_file(path))
  end
end
project_names() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 143
def project_names
  ([project_name] + enabled_addons.keys).uniq
end
service_enabled?(service) click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 220
def service_enabled?(service)
  service_config[service] && service_config[service]['enable'] && !service_config[service]['external']
end
stateful_services() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 129
def stateful_services
  if service_config.key?('drbd') && service_config['drbd']['enable'] == true
    ['drbd']
  else
    DEFAULT_STATEFUL_SERVICES.select do |service|
      service_enabled?(service)
    end
  end
end
write_manifest() click to toggle source
# File lib/chef_backup/strategy/backup/tar.rb, line 115
def write_manifest
  log 'Writing backup manifest'
  File.open("#{tmp_dir}/manifest.json", 'w') do |file|
    file.write(JSON.pretty_generate(manifest))
  end
end