Class: ChefBackup::Strategy::TarBackup

Inherits:
Object
  • Object
show all
Includes:
Exceptions, Helpers
Defined in:
lib/chef_backup/strategy/backup/tar.rb

Overview

installed on LVM

Direct Known Subclasses

CustomBackup, EbsBackup, LvmBackup, ObjectBackup

Constant Summary collapse

DEFAULT_STATEFUL_SERVICES =
%w(rabbitmq
opscode-solr4
elasticsearch
redis_lb
postgresql
bookshelf).freeze

Constants included from Helpers

Helpers::DEFAULT_PG_OPTIONS, Helpers::SERVER_ADD_ONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#all_services, #backend?, #base_config_dir, #base_install_dir, #cleanup, #config, #config_base, #ctl_command, #database_name, #disabled_services, #enabled_addons, #enabled_services, #ensure_file!, #frontend?, #ha?, #log, #marketplace?, #online?, #pg_options, #pgsql, #project_name, #reconfigure_add_ons, #reconfigure_marketplace, #restart_add_ons, #restart_chef_server, #running_filepath, #service_config, #shell_out, #shell_out!, #standalone?, #start_chef_server, #start_service, #stop_chef_server, #stop_service, #strategy, #tier?, #tmp_dir, #topology

Constructor Details

#initializeTarBackup

Returns a new instance of TarBackup.



18
19
20
# File 'lib/chef_backup/strategy/backup/tar.rb', line 18

def initialize
  @backup_time = Time.now.strftime('%Y-%m-%d-%H-%M-%S')
end

Instance Attribute Details

#backup_timeObject (readonly)

Returns the value of attribute backup_time.



16
17
18
# File 'lib/chef_backup/strategy/backup/tar.rb', line 16

def backup_time
  @backup_time
end

Instance Method Details

#ask_to_go_offlineObject



226
227
228
229
230
231
232
# File 'lib/chef_backup/strategy/backup/tar.rb', line 226

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):'

  exit(1) unless ask(msg) =~ /^y/i
end

#backupObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/chef_backup/strategy/backup/tar.rb', line 146

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: [: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 wen't terribly wrong, aborting backup", :error
  log e.message, :error
  cleanup
  start_chef_server
  raise e
end

#chpstObject



68
69
70
# File 'lib/chef_backup/strategy/backup/tar.rb', line 68

def chpst
  "#{base_install_dir}/embedded/bin/chpst"
end

#config_directoriesObject



128
129
130
# File 'lib/chef_backup/strategy/backup/tar.rb', line 128

def config_directories
  [project_name] + enabled_addons.keys
end

#config_only?Boolean

Returns:

  • (Boolean)


222
223
224
# File 'lib/chef_backup/strategy/backup/tar.rb', line 222

def config_only?
  service_config['backup']['config_only']
end

#create_tarballObject



175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/chef_backup/strategy/backup/tar.rb', line 175

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_mapObject

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



133
134
135
136
137
138
139
# File 'lib/chef_backup/strategy/backup/tar.rb', line 133

def data_map
  @data_map ||= ChefBackup::DataMap.new do |data|
    data.backup_time = backup_time
    data.strategy = strategy
    data.topology = topology
  end
end

#dump_dbTrueClass, FalseClass

Perform a pg_dump

Returns:

  • (TrueClass, FalseClass)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/chef_backup/strategy/backup/tar.rb', line 48

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_dirString

Ensures existence of an export directory for the backup

Returns:

  • (String)

    A path to the export_dir



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/chef_backup/strategy/backup/tar.rb', line 27

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_filenameObject



196
197
198
199
200
201
202
203
# File 'lib/chef_backup/strategy/backup/tar.rb', line 196

def export_filename
  postfix = if config_only?
              '-config'
            else
              ''
            end
  "chef-backup#{postfix}-#{backup_time}.tgz"
end

#export_tarballObject



188
189
190
191
192
193
194
# File 'lib/chef_backup/strategy/backup/tar.rb', line 188

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?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/chef_backup/strategy/backup/tar.rb', line 209

def external_pg?
  service_config['postgresql']['external']
end

#manifestObject



100
101
102
# File 'lib/chef_backup/strategy/backup/tar.rb', line 100

def manifest
  data_map.manifest
end

#not_implementedObject



141
142
143
144
# File 'lib/chef_backup/strategy/backup/tar.rb', line 141

def not_implemented
  msg = "#{caller[0].split[1]} is not implemented for this strategy"
  raise NotImplementedError, msg
end

#offline_permission_granted?Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/chef_backup/strategy/backup/tar.rb', line 218

def offline_permission_granted?
  service_config['backup']['agree_to_go_offline']
end

#pg_dump?Boolean

Returns:

  • (Boolean)


213
214
215
216
# File 'lib/chef_backup/strategy/backup/tar.rb', line 213

def pg_dump?
  # defaults to true
  service_config['backup']['always_dump_db']
end

#pg_dumpallObject



72
73
74
# File 'lib/chef_backup/strategy/backup/tar.rb', line 72

def pg_dumpall
  "#{base_install_dir}/embedded/bin/pg_dumpall"
end

#populate_data_mapObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/chef_backup/strategy/backup/tar.rb', line 76

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

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

  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

#service_enabled?(service) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/chef_backup/strategy/backup/tar.rb', line 205

def service_enabled?(service)
  service_config[service] && service_config[service]['enable'] && !service_config[service]['external']
end

#stateful_servicesObject



118
119
120
121
122
123
124
125
126
# File 'lib/chef_backup/strategy/backup/tar.rb', line 118

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_manifestObject



104
105
106
107
108
109
# File 'lib/chef_backup/strategy/backup/tar.rb', line 104

def write_manifest
  log 'Writing backup manifest'
  File.open("#{tmp_dir}/manifest.json", 'w') do |file|
    file.write(JSON.pretty_generate(manifest))
  end
end