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

#addon_install_dir, #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!, #shell_timeout, #standalone?, #start_chef_server, #start_service, #stop_chef_server, #stop_service, #strategy, #tier?, #tmp_dir, #topology, #version_from_manifest_file

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

#add_ha_servicesObject



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

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_offlineObject



242
243
244
245
246
247
248
# File 'lib/chef_backup/strategy/backup/tar.rb', line 242

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



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/chef_backup/strategy/backup/tar.rb', line 162

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

#chpstObject



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

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

#config_directoriesObject



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

def config_directories
  [project_name] + enabled_addons.keys
end

#config_only?Boolean

Returns:

  • (Boolean)


238
239
240
# File 'lib/chef_backup/strategy/backup/tar.rb', line 238

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

#create_tarballObject



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/chef_backup/strategy/backup/tar.rb', line 191

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.



149
150
151
152
153
154
155
# File 'lib/chef_backup/strategy/backup/tar.rb', line 149

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
# 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



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

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

#export_tarballObject



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

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)


225
226
227
# File 'lib/chef_backup/strategy/backup/tar.rb', line 225

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

#manifestObject



112
113
114
# File 'lib/chef_backup/strategy/backup/tar.rb', line 112

def manifest
  data_map.manifest
end

#not_implementedObject



157
158
159
160
# File 'lib/chef_backup/strategy/backup/tar.rb', line 157

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

#offline_permission_granted?Boolean

Returns:

  • (Boolean)


234
235
236
# File 'lib/chef_backup/strategy/backup/tar.rb', line 234

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

#pg_dump?Boolean

Returns:

  • (Boolean)


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

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

#pg_dumpallObject



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

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

#populate_data_mapObject



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

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_versionsObject



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

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_namesObject



144
145
146
# File 'lib/chef_backup/strategy/backup/tar.rb', line 144

def project_names
  ([project_name] + enabled_addons.keys).uniq
end

#service_enabled?(service) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#stateful_servicesObject



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

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



116
117
118
119
120
121
# File 'lib/chef_backup/strategy/backup/tar.rb', line 116

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