Class: ChefBackup::Strategy::TarRestore

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Chef::Mixin::DeepMerge, Exceptions, Helpers
Defined in:
lib/chef_backup/strategy/restore/tar.rb

Overview

Basic Tar Restore Strategy

Constant Summary

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, #chpst, #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, #service_enabled?, #shell_out, #shell_out!, #standalone?, #start_chef_server, #start_service, #stop_chef_server, #stop_service, #strategy, #tier?, #tmp_dir, #topology

Constructor Details

#initialize(path) ⇒ TarRestore

Returns a new instance of TarRestore.



22
23
24
25
# File 'lib/chef_backup/strategy/restore/tar.rb', line 22

def initialize(path)
  @tarball_path = path
  @log = ChefBackup::Logger.logger(service_config['backup']['logfile'] || nil)
end

Instance Attribute Details

#manifestObject



50
51
52
53
54
55
56
57
# File 'lib/chef_backup/strategy/restore/tar.rb', line 50

def manifest
  @manifest ||= begin
    manifest = File.expand_path(File.join(ChefBackup::Config['restore_dir'],
                                          'manifest.json'))
    ensure_file!(manifest, InvalidManifest, "#{manifest} not found")
    JSON.parse(File.read(manifest))
  end
end

#tarball_pathObject

Returns the value of attribute tarball_path.



17
18
19
# File 'lib/chef_backup/strategy/restore/tar.rb', line 17

def tarball_path
  @tarball_path
end

Instance Method Details

#backup_nameObject



111
112
113
# File 'lib/chef_backup/strategy/restore/tar.rb', line 111

def backup_name
  @backup_name ||= Pathname.new(tarball_path).basename.sub_ext('').to_s
end

#check_ha_volumeObject



125
126
127
128
129
130
131
132
# File 'lib/chef_backup/strategy/restore/tar.rb', line 125

def check_ha_volume
  log 'Checking that the HA storage volume is mounted'
  ha_data_dir = manifest['ha']['path']

  unless ha_data_dir_mounted?(ha_data_dir)
    raise "Please mount the data directory #{ha_data_dir} and perform any DRBD configuration before continuing"
  end
end

#cleanse_chef_server(agree) ⇒ Object



149
150
151
152
# File 'lib/chef_backup/strategy/restore/tar.rb', line 149

def cleanse_chef_server(agree)
  log 'Cleaning up any old files'
  shell_out!("#{ctl_command} cleanse #{agree || ''}")
end

#fix_ha_pluginsObject



115
116
117
118
119
120
121
122
123
# File 'lib/chef_backup/strategy/restore/tar.rb', line 115

def fix_ha_plugins
  log 'Fixing HA plugins directory (https://github.com/chef/chef-server/issues/115)'
  plugins_dir = '/var/opt/opscode/plugins'
  drbd_plugin = File.join(plugins_dir, 'chef-ha-drbd.rb')

  FileUtils.mkdir_p(plugins_dir) unless Dir.exist?(plugins_dir)
  FileUtils.ln_sf('/opt/opscode/chef-server-plugin.rb', drbd_plugin) unless
    File.exist?(drbd_plugin)
end

#ha_data_dir_mounted?(ha_data_dir) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/chef_backup/strategy/restore/tar.rb', line 134

def ha_data_dir_mounted?(ha_data_dir)
  File.read('/proc/mounts').split("\n").grep(/#{ha_data_dir}/).count > 0
end

#import_dbObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/chef_backup/strategy/restore/tar.rb', line 65

def import_db
  start_service('postgresql')
  sql_file = File.join(ChefBackup::Config['restore_dir'],
                       "chef_backup-#{manifest['backup_time']}.sql")
  ensure_file!(sql_file, InvalidDatabaseDump, "#{sql_file} not found")

  cmd = [chpst,
         "-u #{manifest['services']['postgresql']['username']}",
         pgsql,
         "-U #{manifest['services']['postgresql']['username']}",
         "-d #{database_name}",
         "< #{sql_file}"
        ].join(' ')
  log 'Importing Database dump'
  shell_out!(cmd, env: ["PGOPTIONS=#{pg_options}"])
end

#reconfigure_serverObject



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

def reconfigure_server
  log 'Reconfiguring the Chef Server'
  shell_out("#{ctl_command} reconfigure")
end

#restoreObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/chef_backup/strategy/restore/tar.rb', line 27

def restore
  log 'Restoring Chef Server from backup'
  cleanse_chef_server(config['agree_to_cleanse'])
  if ha?
    log 'Performing HA restore - please ensure that keepalived is not running on the standby host'
    fix_ha_plugins
    check_ha_volume
    touch_drbd_ready
  end
  restore_configs
  restore_services unless frontend?
  touch_sentinel
  reconfigure_marketplace if marketplace?
  reconfigure_server
  update_config
  import_db if restore_db_dump?
  start_chef_server
  reconfigure_add_ons
  restart_add_ons
  cleanup
  log 'Restoration Completed!'
end

#restore_configsObject



88
89
90
91
92
# File 'lib/chef_backup/strategy/restore/tar.rb', line 88

def restore_configs
  manifest.key?('configs') && manifest['configs'].keys.each do |config|
    restore_data(:configs, config)
  end
end

#restore_data(type, name) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/chef_backup/strategy/restore/tar.rb', line 101

def restore_data(type, name)
  source = File.expand_path(File.join(config['restore_dir'],
                                      manifest[type.to_s][name]['data_dir']))
  destination = manifest[type.to_s][name]['data_dir']
  FileUtils.mkdir_p(destination) unless File.directory?(destination)
  cmd = "rsync -chaz --delete #{source}/ #{destination}"
  log "Restoring the #{name} data"
  shell_out!(cmd)
end

#restore_db_dump?Boolean

Returns:

  • (Boolean)


59
60
61
62
63
# File 'lib/chef_backup/strategy/restore/tar.rb', line 59

def restore_db_dump?
  manifest['services']['postgresql']['pg_dump_success'] && !frontend?
rescue NoMethodError
  false
end

#restore_servicesObject



82
83
84
85
86
# File 'lib/chef_backup/strategy/restore/tar.rb', line 82

def restore_services
  manifest.key?('services') && manifest['services'].keys.each do |service|
    restore_data(:services, service)
  end
end

#running_configObject



154
155
156
157
# File 'lib/chef_backup/strategy/restore/tar.rb', line 154

def running_config
  @running_config ||=
    JSON.parse(File.read(running_filepath)) || {}
end

#touch_drbd_readyObject



138
139
140
141
142
# File 'lib/chef_backup/strategy/restore/tar.rb', line 138

def touch_drbd_ready
  log 'Touching drbd_ready file'
  FileUtils.touch('/var/opt/opscode/drbd/drbd_ready') unless
    File.exist?('/var/opt/opscode/drbd/drbd_ready')
end

#touch_sentinelObject



94
95
96
97
98
99
# File 'lib/chef_backup/strategy/restore/tar.rb', line 94

def touch_sentinel
  dir = '/var/opt/opscode'
  sentinel = File.join(dir, 'bootstrapped')
  FileUtils.mkdir_p(dir) unless File.directory?(dir)
  File.open(sentinel, 'w') { |file| file.write 'bootstrapped!' }
end

#update_configObject



159
160
161
# File 'lib/chef_backup/strategy/restore/tar.rb', line 159

def update_config
  ChefBackup::Config.config = deep_merge(config.dup, running_config)
end