Module: ChefBackup::Helpers

Included in:
Runner, Strategy::TarBackup, Strategy::TarRestore
Defined in:
lib/chef_backup/helpers.rb

Overview

Common helper methods that are usefull in many classes

Constant Summary collapse

SERVER_ADD_ONS =

rubocop:enable IndentationWidth

{
  'opscode-manage' => {
    'config_file' => '/etc/opscode-manage/manage.rb',
    'ctl_command' => 'opscode-manage-ctl'
  },
  'opscode-reporting' => {
    'config_file' => '/etc/opscode-reporting/opscode-reporting.rb',
    'ctl_command' => 'opscode-reporting-ctl'
  },
  'opscode-push-jobs-server' => {
    'config_file' => '/etc/opscode-push-jobs-server/opscode-push-jobs-server.rb',
    'ctl_command' => 'opscode-push-jobs-server-ctl'
  },
  'opscode-analytics' => {
    'config_file' => '/etc/opscode-analytics/opscode-analytics.rb',
    'ctl_command' => 'opscode-analytics-ctl'
  },
  'chef-ha' => {
    'config_file' => '/etc/opscode/chef-server.rb'
  },
  'chef-sync' => {
    'config_file' => '/etc/chef-sync/chef-sync.rb',
    'ctl_command' => 'chef-sync-ctl'
  },
  'chef-marketplace' => {
    'config_file' => '/etc/chef-marketplace/marketplace.rb',
    'ctl_command' => 'chef-marketplace-ctl'
  }
}.freeze
DEFAULT_PG_OPTIONS =
'-c statement_timeout=3600000'.freeze

Instance Method Summary collapse

Instance Method Details

#addon_install_dir(name) ⇒ Object



121
122
123
124
# File 'lib/chef_backup/helpers.rb', line 121

def addon_install_dir(name)
  # can use extra field in SERVER_ADD_ONS to extend if someone isn't following this pattern.
  "/opt/#{name}"
end

#all_servicesObject



144
145
146
# File 'lib/chef_backup/helpers.rb', line 144

def all_services
  Dir["#{base_install_dir}/sv/*"].map { |f| File.basename(f) }.sort
end

#backend?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/chef_backup/helpers.rb', line 223

def backend?
  service_config['role'] =~ /backend|standalone/
end

#base_config_dirObject



126
127
128
# File 'lib/chef_backup/helpers.rb', line 126

def base_config_dir
  "/etc/#{project_name}"
end

#base_install_dirObject



117
118
119
# File 'lib/chef_backup/helpers.rb', line 117

def base_install_dir
  "/opt/#{project_name}"
end

#chpstObject



130
131
132
# File 'lib/chef_backup/helpers.rb', line 130

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

#cleanupObject



260
261
262
263
264
265
# File 'lib/chef_backup/helpers.rb', line 260

def cleanup
  log "Cleaning up #{tmp_dir}"
  FileUtils.rm_r(tmp_dir)
rescue Errno::ENOENT
  true
end

#configObject



46
47
48
# File 'lib/chef_backup/helpers.rb', line 46

def config
  ChefBackup::Config
end

#config_baseObject



50
51
52
# File 'lib/chef_backup/helpers.rb', line 50

def config_base
  ChefBackup::Config['config_base']
end

#ctl_commandObject



58
59
60
# File 'lib/chef_backup/helpers.rb', line 58

def ctl_command
  service_config['backup']['ctl-command']
end

#database_nameObject



66
67
68
# File 'lib/chef_backup/helpers.rb', line 66

def database_name
  service_config['backup']['database_name']
end

#disabled_servicesObject



152
153
154
# File 'lib/chef_backup/helpers.rb', line 152

def disabled_services
  all_services.reject { |sv| service_enabled?(sv) }
end

#enabled_addonsObject



203
204
205
206
207
208
209
# File 'lib/chef_backup/helpers.rb', line 203

def enabled_addons
  SERVER_ADD_ONS.select do |name, config|
    !config['config_file'].nil? &&
      File.directory?(File.dirname(config['config_file'])) &&
      File.directory?(addon_install_dir(name))
  end
end

#enabled_servicesObject



148
149
150
# File 'lib/chef_backup/helpers.rb', line 148

def enabled_services
  all_services.select { |sv| service_enabled?(sv) }
end

#ensure_file!(file, exception, message) ⇒ TrueClass, FalseClass

Parameters:

  • file (String)

    A path to a file on disk

  • exception (Exception)

    An exception to raise if file is not present

  • message (String)

    Exception message to raise

Returns:

  • (TrueClass, FalseClass)


94
95
96
# File 'lib/chef_backup/helpers.rb', line 94

def ensure_file!(file, exception, message)
  File.exist?(file) ? true : raise(exception, message)
end

#frontend?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'lib/chef_backup/helpers.rb', line 219

def frontend?
  service_config['role'] == 'frontend'
end

#ha?Boolean

Returns:

  • (Boolean)


231
232
233
# File 'lib/chef_backup/helpers.rb', line 231

def ha?
  topology == 'ha'
end

#log(message, level = :info) ⇒ Object



70
71
72
# File 'lib/chef_backup/helpers.rb', line 70

def log(message, level = :info)
  ChefBackup::Logger.logger.log(message, level)
end

#marketplace?Boolean

Returns:

  • (Boolean)


243
244
245
# File 'lib/chef_backup/helpers.rb', line 243

def marketplace?
  shell_out('which chef-marketplace-ctl').exitstatus == 0
end

#online?Boolean

Returns:

  • (Boolean)


227
228
229
# File 'lib/chef_backup/helpers.rb', line 227

def online?
  service_config['backup']['mode'] == 'online'
end

#pg_optionsObject



138
139
140
141
142
# File 'lib/chef_backup/helpers.rb', line 138

def pg_options
  config['pg_options'] ||
    (service_config && service_config['backup']['pg_options']) ||
    DEFAULT_PG_OPTIONS
end

#pgsqlObject



134
135
136
# File 'lib/chef_backup/helpers.rb', line 134

def pgsql
  "#{base_install_dir}/embedded/bin/psql"
end

#project_nameObject



113
114
115
# File 'lib/chef_backup/helpers.rb', line 113

def project_name
  service_config['backup']['project_name']
end

#reconfigure_add_onsObject



186
187
188
189
190
# File 'lib/chef_backup/helpers.rb', line 186

def reconfigure_add_ons
  enabled_addons.each do |_name, config|
    shell_out("#{config['ctl_command']} reconfigure") if config.key?('ctl_command')
  end
end

#reconfigure_marketplaceObject



198
199
200
201
# File 'lib/chef_backup/helpers.rb', line 198

def reconfigure_marketplace
  log 'Setting up Chef Marketplace'
  shell_out('chef-marketplace-ctl reconfigure')
end

#restart_add_onsObject



192
193
194
195
196
# File 'lib/chef_backup/helpers.rb', line 192

def restart_add_ons
  enabled_addons.each do |_name, config|
    shell_out("#{config['ctl_command']} restart") if config.key?('ctl_command')
  end
end

#restart_chef_serverObject



182
183
184
# File 'lib/chef_backup/helpers.rb', line 182

def restart_chef_server
  shell_out("#{ctl_command} restart #{service}")
end

#running_filepathObject



62
63
64
# File 'lib/chef_backup/helpers.rb', line 62

def running_filepath
  service_config['backup']['running_filepath']
end

#service_configObject



54
55
56
# File 'lib/chef_backup/helpers.rb', line 54

def service_config
  ChefBackup::Config[config_base]
end

#service_enabled?(service) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/chef_backup/helpers.rb', line 156

def service_enabled?(service)
  File.symlink?("#{base_install_dir}/service/#{service}")
end

#shell_out(*command) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/chef_backup/helpers.rb', line 98

def shell_out(*command)
  options = command.last.is_a?(Hash) ? command.pop : {}
  opts_with_defaults = { 'timeout' => shell_timeout }.merge(options)
  cmd = Mixlib::ShellOut.new(*command, opts_with_defaults)
  cmd.live_stream ||= $stdout.tty? ? $stdout : nil
  cmd.run_command
  cmd
end

#shell_out!(*command) ⇒ Object



107
108
109
110
111
# File 'lib/chef_backup/helpers.rb', line 107

def shell_out!(*command)
  cmd = shell_out(*command)
  cmd.error!
  cmd
end

#shell_timeoutObject

Note that when we are in the backup codepath, we have access to a running chef server and hence, the ctl command puts all our flags under the current running service namespace. The lets the default configuration of the server provide flags that the user doesn’t necessarily provide on the command line.

During the restore codepath, there may be no running chef server. This means that we need to be paranoid about the existence of the service_config hash.



81
82
83
84
85
# File 'lib/chef_backup/helpers.rb', line 81

def shell_timeout
  option = config['shell_out_timeout'] ||
           (service_config && service_config['backup']['shell_out_timeout'])
  option.to_f unless option.nil?
end

#standalone?Boolean

Returns:

  • (Boolean)


239
240
241
# File 'lib/chef_backup/helpers.rb', line 239

def standalone?
  topology == 'standalone'
end

#start_chef_serverObject



177
178
179
180
# File 'lib/chef_backup/helpers.rb', line 177

def start_chef_server
  log 'Bringing up the Chef Server'
  enabled_services.each { |sv| start_service(sv) }
end

#start_service(service) ⇒ Object



165
166
167
168
# File 'lib/chef_backup/helpers.rb', line 165

def start_service(service)
  res = shell_out("#{ctl_command} start #{service}")
  res
end

#stop_chef_server(params = {}) ⇒ Object



170
171
172
173
174
175
# File 'lib/chef_backup/helpers.rb', line 170

def stop_chef_server(params = {})
  log 'Bringing down the Chef Server'
  services = enabled_services
  services -= params[:except].map(&:to_s) if params.key?(:except)
  services.each { |sv| stop_service(sv) }
end

#stop_service(service) ⇒ Object



160
161
162
163
# File 'lib/chef_backup/helpers.rb', line 160

def stop_service(service)
  res = shell_out("#{ctl_command} stop #{service}")
  res
end

#strategyObject



211
212
213
# File 'lib/chef_backup/helpers.rb', line 211

def strategy
  service_config['backup']['strategy']
end

#tier?Boolean

Returns:

  • (Boolean)


235
236
237
# File 'lib/chef_backup/helpers.rb', line 235

def tier?
  topology == 'tier'
end

#tmp_dirObject



247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/chef_backup/helpers.rb', line 247

def tmp_dir
  @tmp_dir ||= begin
    dir = safe_key { config['tmp_dir'] } ||
          safe_key { service_config['backup']['tmp_dir'] }
    if dir
      FileUtils.mkdir_p(dir) unless File.directory?(dir)
      dir
    else
      Dir.mktmpdir('chef_backup')
    end
  end
end

#topologyObject



215
216
217
# File 'lib/chef_backup/helpers.rb', line 215

def topology
  service_config['topology']
end

#version_from_manifest_file(file) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/chef_backup/helpers.rb', line 267

def version_from_manifest_file(file)
  return :no_version if file.nil?

  path = File.expand_path(file)
  if File.exist?(path)
    config = JSON.parse(File.read(path))
    { 'version' => config['build_version'],
      'revision' => config['build_git_revision'],
      'path' => path }
  else
    :no_version
  end
end