Class: UBSafe::Commands::Backup

Inherits:
Object
  • Object
show all
Defined in:
lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb

Direct Known Subclasses

MySqlBackup, PostgresBackup, SVNBackup

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Backup

Create a new backup instance

Parameters:

  • args (Array)

    Command-line arguments



40
41
42
43
44
45
46
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 40

def initialize(args)
  @config = UBSafe::Config.config
  @config.load(args)
  @backup_name = @config.options[:backup_name]
  @backup_options = @config.full_options(@backup_name)
  @log = @config.log
end

Class Method Details

.instance(args) ⇒ Object

Get backup-specific backup instance

Parameters:

  • args (Array)

    Command-line arguments



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 18

def instance(args)
  @config = UBSafe::Config.config
  @config.load(args)
  @backup_name = @config.options[:backup_name]
  @backup_options = @config.full_options(@backup_name)
  backup_class = @backup_options[:backup_class]
  backup_instance = nil
  if backup_class == :default
    backup_instance = UBSafe::Commands::Backup.new(args)
  else
    eval("backup_instance = #{backup_class.to_s}.new(args)")
  end
  return backup_instance
end

Instance Method Details

#after_clean_sourceSymbol

Hook to allow customization after cleaning source

Returns:

  • (Symbol)

    :success or :failure



342
343
344
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 342

def after_clean_source
  return :success
end

#after_copy_backupSymbol

Hook to allow customization after copying backup

Returns:

  • (Symbol)

    :success or :failure



290
291
292
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 290

def after_copy_backup
  return :success
end

#after_rotate_destination_filesSymbol

Hook to allow customization after rotating destination files

Returns:

  • (Symbol)

    :success or :failure



151
152
153
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 151

def after_rotate_destination_files
  return :success
end

#after_source_backupSymbol

Hook to allow customization after creating source backup

Returns:

  • (Symbol)

    :success or :failure



91
92
93
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 91

def after_source_backup
  return :success
end

#all_backup_names(backup_options = nil) ⇒ Array

Get ordered list of all possible backup names given the supplied configuration

Parameters:

  • backup_options (Hash) (defaults to: nil)

    Backup options

Returns:

  • (Array)

    Ordered list of backup names - newest first



444
445
446
447
448
449
450
451
452
453
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 444

def all_backup_names(backup_options = nil)
  backup_options ||= @backup_options
  all_possible_file_names = []
  total_possible_file_names = backup_options[:backups_to_retain]
  total_possible_file_names.times do |current_generation|
    all_possible_file_names[current_generation] = get_backup_file_name_with_generation(backup_options,current_generation)
  end
  @backup_options[:all_possible_file_names] = all_possible_file_names
  return all_possible_file_names
end

#backupInteger

Perform backup

Returns:

  • (Integer)

    Exit code 0 success, 1 otherwise



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 53

def backup
  # Create backup file in source tree
  # Rotate destination files
  # Copy to destination
  # Remove from source tree
  backup_steps = [
    :before_rotate_destination_files, :rotate_destination_files, :after_rotate_destination_files,
    :before_source_backup,:create_source_backup,:after_source_backup,
    :before_copy_backup, :copy_backup, :after_copy_backup,
    :before_clean_source, :clean_source, :after_clean_source
    ]
  backup_steps.each do |backup_step|
    status = self.send(backup_step)
    if status == :failure
      @log.error("Backup #{@backup_name} backup step #{backup_step.to_s} failed.")
      email_notify(:failure,backup_step)
      return 1
    end
  end
  @log.info("Backup  #{@backup_name} succeeded")
  email_notify(:success,nil)
  return 0
end

#before_clean_sourceSymbol

Hook to allow customization before cleaning source

Returns:

  • (Symbol)

    :success or :failure



333
334
335
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 333

def before_clean_source
  return :success
end

#before_copy_backupSymbol

Hook to allow customization before copying backup

Returns:

  • (Symbol)

    :success or :failure



281
282
283
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 281

def before_copy_backup
  return :success
end

#before_rotate_destination_filesSymbol

Hook to allow customization before rotating destination files

Returns:

  • (Symbol)

    :success or :failure



142
143
144
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 142

def before_rotate_destination_files
  return :success
end

#before_source_backupSymbol

Hook to allow customization before creating source backup

Returns:

  • (Symbol)

    :success or :failure



82
83
84
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 82

def before_source_backup
  return :success
end

#clean_source(backup_options = nil, backup_name = nil) ⇒ Symbol

Clean Source - remove (temporary) backup files from source

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



353
354
355
356
357
358
359
360
361
362
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 353

def clean_source(backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  # Fully qualify directories
  tmp_dir = File.expand_path(backup_options[:temporary_directory])
  backup_file_name = File.join(tmp_dir,get_backup_file_name(backup_options))
  cmd_output = `rm -f #{backup_file_name}`
  cmd_status = $?
  return cmd_status == 0 ? :success : :failure
end

#copy_backup(backup_options = nil, backup_name = nil) ⇒ Symbol

Copy backup

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 311

def copy_backup(backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  # Fully qualify directories
  tmp_dir = File.expand_path(backup_options[:temporary_directory])
  backup_file_name = get_backup_file_name(backup_options)
  qualified_backup_file_name = File.join(tmp_dir,backup_file_name)
  remote_directory_name = File.join(backup_options[:base_backup_directory],backup_name)
  qualified_remote_file_name = File.join(remote_directory_name,backup_file_name)
  unless remote_file_exists?(qualified_remote_file_name)
    # Only copy file if it's not there
    cmd_status, cmd_output = scp_cmd(qualified_backup_file_name,remote_directory_name,backup_options,backup_name)
    return :failure unless cmd_status == :success
  end
  return :success
end

#create_and_copy_backup(backup_options = nil, backup_name = nil) ⇒ Symbol

Create and copy backup

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



301
302
303
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 301

def create_and_copy_backup(backup_options = nil,backup_name = nil)

end

#create_source_backup(backup_options = nil, backup_name = nil) ⇒ Symbol

Create source backup

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 102

def create_source_backup(backup_options = nil,backup_name = nil)

  backup_options ||= @backup_options
  backup_name ||= @backup_name
  
  # Don't bother to create the backup if it already exists on the destination - i.e. hasn't been rolled
  return :success if remote_file_exists?
  
  # Fully qualify directories
  source_tree = File.expand_path(backup_options[:source_tree])
  tmp_dir = File.expand_path(backup_options[:temporary_directory])
    
  if backup_options[:backup_style] == :tar_gz
    status = nil
    # Run command somewhere sensible
    FileUtils.mkdir_p(tmp_dir)
    Dir.chdir(tmp_dir) do |dir|
      backup_cmd_tempate = "tar cfz %s -C %s ."
      full_cmd = sprintf(backup_cmd_tempate,get_backup_file_name,source_tree)
      @log.debug("create_source_backup #{full_cmd}")
      cmd_result = `#{full_cmd}`
      cmd_status = $?
      status = cmd_status == 0 ? :success : :failure
      if status == :success
        @log.info("Backup '#{backup_name}' succeeded")
      else
        @log.error("Backup '#{backup_name}' failed")
      end
    end
    return status
  end
  @log.error("Backup '#{backup_name}' - backup type specified is not supported")
  return :failure
end

#email_notify(status = :failure, processing_step = nil) ⇒ Symbol

Notify via email

Parameters:

  • status (Symbol) (defaults to: :failure)
  • processing_step (Symbol) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 371

def email_notify(status = :failure,processing_step = nil)
  mail_config = @config.options[:backup_email]
  return :success unless mail_config[:enabled]
  backup_options = @backup_options
  backup_name = @backup_name
  hostname = `hostname`.chomp.strip
  log_directory = File.expand_path(@config.options[:logging][:log_directory])
  if status == :success
    subject = "#{mail_config[:mail_subject_prefix]} backup '#{backup_name}' OK"
    body = "Backup '#{backup_name}' succeeded"
    body << "\n\nLogs are available at #{hostname}:#{log_directory}"
  else
    processing_step = processing_step ? processing_step.to_s : 'unknown'
    subject = "#{mail_config[:mail_subject_prefix]} backup '#{backup_name}' failed at backup stage '#{processing_step}'"
    body = "backup '#{backup_name}' failed at backup stage '#{processing_step}'"
    body << "\n\nLogs are available at #{hostname}:#{log_directory}"
  end
  email_date = Time.now.utc.strftime('%a, %d %b %y %H:%M:%S')
  recipients = mail_config[:mail_to]
  recipients.each do |recipient|
    
        full_body = <<BODY
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed
To: #{recipient}
From: #{mail_config[:mail_from]}
Subject: #{subject}
Date: #{email_date}

#{body}

BODY
   if mail_config[:mail_style] == :smtp
      Net::SMTP.start(mail_config[:smtp_host]) do |session|
        session.sendmail(full_body, mail_config[:mail_from] , recipient)
      end
    else
      tmp_dir = Dir.tmpdir
      mail_msg_file = File.join(tmp_dir,'mail.txt')
      File.open(mail_msg_file,'w') do |file|
        file.write full_body
      end
      cmd = "cat #{mail_msg_file} | sendmail #{recipient}"
      #puts "email_notify cat_sendmail issuing command \"#{cmd}\""
      cmd_output = `#{cmd}`
      cmd_status = $?
      File.delete(mail_msg_file)
      @log.debug("email_notify: cat_sendmail status #{cmd_status} output #{cmd_output}")
    end
  end
  return :success
end

#get_backup_file_name(backup_options = nil) ⇒ String

Get backup name - use the template defined in the configuration file

Parameters:

  • backup_options (Hash) (defaults to: nil)

    Backup options

Returns:

  • (String)

    Unqualified name of backup file



433
434
435
436
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 433

def get_backup_file_name(backup_options = nil)
  backup_options ||= @backup_options
  return get_backup_file_name_with_generation(backup_options,0)
end

#get_backup_file_name_with_generation(backup_options = nil, generation = 1) ⇒ String

Get backup name with the specified generation- use the template defined in the configuration file

Parameters:

  • backup_options (Hash) (defaults to: nil)

    Backup options

  • generation (Integer) (defaults to: 1)

    Generation number

Returns:

  • (String)

    Unqualified name of backup file



462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 462

def get_backup_file_name_with_generation(backup_options = nil, generation = 1)
  backup_options ||= @backup_options
  template = backup_options[:backup_file_name_template]
  file_name = backup_options[:backup_name]
  # The new backup is always 1
  file_number = generation
  # Get default time zone
  time_zone = (backup_options[:time_zone] || 'UTC').to_s.upcase
  current_time = time_zone == 'UTC' ? Time.now.utc : Time.now
  time_stamp = current_time.strftime(backup_options[:timestamp_format])
  date_stamp = current_time.strftime(backup_options[:date_format])
  # Translate the template to a sprintf format string
  # %f => file name
  # %n => backup_options[:number_format] for file number
  # %t => backup_options[:timestamp_format]
  # %d => backup_options[:date_format]
  sprintf_template = template.gsub(/\%f/,'%s')
  sprintf_template = sprintf_template.gsub(/\%n/,backup_options[:number_format])
  sprintf_template = sprintf_template.gsub(/\%t/,'%s')
  sprintf_template = sprintf_template.gsub(/\%d/,'%s')
  # Now, figure out the order for the sprintf call
  sprintf_fields = []
  template_size = template.size
  # We're matching a two-character placeholder string, so stop 2 chars from end
  0.upto(template_size - 2) do |pos|
    if template[pos,2] == '%f'
      sprintf_fields << file_name
    elsif template[pos,2] == '%n'
      sprintf_fields << file_number
    elsif template[pos,2] == '%t'
      sprintf_fields << time_stamp
    elsif template[pos,2] == '%d'
      sprintf_fields << date_stamp
    end
  end
  backup_file_name = sprintf(sprintf_template,*sprintf_fields)
  return backup_file_name
end

#get_remote_modified_timestamp(file_name, backup_options = nil, backup_name = nil) ⇒ Time

Get the modified time stamp for a remote file

Parameters:

  • file_name (String)

    Fully qualified file name

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Time)

    File modification time or nil if no file found remotely



509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 509

def get_remote_modified_timestamp(file_name,backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  remote_bin_dir = backup_options[:bin_dir] ? "#{backup_options[:bin_dir]}/" : ''
  remote_cmd = "#{remote_bin_dir}ubsafe_file_mtime #{file_name}"
  cmd_status, cmd_output = ssh_cmd(remote_cmd,backup_options,backup_name)
  file_mtime = nil
  if cmd_status == :success and (not cmd_output.empty?) and (cmd_output[0] != '')
    #puts "get_remote_modified_timestamp file_name #{file_name} #{cmd_output[0]}"
    file_mtime = Time.utc(*ParseDate.parsedate(cmd_output[0]))
  end
  return file_mtime  
end

#remote_file_exists?(remote_file_name = nil, backup_options = nil, backup_name = nil) ⇒ Boolean

Does remote file exist?

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Boolean)

    true or false



605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 605

def remote_file_exists?(remote_file_name = nil,backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  if remote_file_name
    remote_directory_name = File.dirname(remote_file_name)
  else  
    backup_file_name = get_backup_file_name(backup_options)
    remote_directory_name = File.join(backup_options[:base_backup_directory],backup_name)
    remote_file_name = File.join(remote_directory_name,backup_file_name)
  end
  remote_bin_dir = backup_options[:bin_dir] ? "#{backup_options[:bin_dir]}/" : ''
  remote_cmd = "#{remote_bin_dir}ubsafe_file_exists #{remote_file_name}"
  cmd_status, cmd_output = ssh_cmd(remote_cmd)
  if cmd_status == :failure or cmd_output[0].chomp.strip == '1'
    return false
  end
  
  # remote_cmd = "ls #{remote_directory_name}"
  # #puts "remote_file_exists? Looking for #{remote_directory_name}"
  # cmd_status, cmd_output = ssh_cmd(remote_cmd)
  # if cmd_status == :failure or cmd_output.join("\n") =~ /no\ssuch/i
  #   #puts "remote_file_exists? #{remote_directory_name} does not exist"
  #   return false
  # else
  #   remote_cmd = "ls #{remote_file_name}"
  #   #puts "remote_file_exists? Looking for #{remote_file_name}"
  #   cmd_status, cmd_output = ssh_cmd(remote_cmd)
  #   #puts "remote_file_exists? cmd_status #{cmd_status}"
  #   if cmd_status == :failure or cmd_output.join("\n") =~ /no\ssuch/i
  #     #puts "remote_file_exists? #{remote_file_name} does not exist"
  #     return false
  #   end
  # end
  
  return true
end

#rotate_destination_files(backup_options = nil, backup_name = nil) ⇒ Symbol

Rotate destination files. Check all the conditions

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 162

def rotate_destination_files(backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  begin
    # Make sure remote directory exists
    remote_directory = File.join(backup_options[:base_backup_directory],backup_name)
    remote_cmd = "mkdir -p #{remote_directory}"
    cmd_status, cmd_output = ssh_cmd(remote_cmd)
    return :failure unless cmd_status == :success
    
    backup_file_name = get_backup_file_name(backup_options)
    remote_file_name = File.join(remote_directory,backup_file_name)
    remote_file_mtime = get_remote_modified_timestamp(remote_file_name,backup_options,backup_name)
    return_status = nil

    backup_frequency = backup_options[:backup_frequency]
    case backup_frequency
      when Integer
        # Explicit age
        if remote_file_mtime
          if (Time.now.utc - remote_file_mtime ) > backup_frequency
            return_status = rotate_destination_files_unconditionally(backup_options,backup_name)
          end
        end
      when :daily
        if remote_file_mtime
          now = Time.now.utc
          if (now.day != remote_file_mtime.day) or (now - remote_file_mtime) > 1.day
            return_status = rotate_destination_files_unconditionally(backup_options,backup_name)
          end
        end
      when :weekly
        if remote_file_mtime
          if (Time.now.utc - remote_file_mtime) > 1.week
            return_status = rotate_destination_files_unconditionally(backup_options,backup_name)
          end
        end
      when :monthly
        if remote_file_mtime
          now = Time.now.utc
          if (now.month != remote_file_mtime.month) or (now - remote_file_mtime) > 1.month
            return_status = rotate_destination_files_unconditionally(backup_options,backup_name)
          end
        end
    end
  rescue Exception => ex
    @log.error("Error detected while determining whether to rotate files")
    @log.error(ex.to_s)
    @log.error(ex.backtrace.join("\n"))
    return_status = :failure
  end
  
  return return_status
  
end

#rotate_destination_files_unconditionally(backup_options = nil, backup_name = nil) ⇒ Symbol

Rotate destination files unconditionally. Assume someone else has checked whether this is needed.

Parameters:

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Symbol)

    :success or :failure



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 225

def rotate_destination_files_unconditionally(backup_options = nil,backup_name = nil)
  # Assume that all checks have been performed before calling this method. 
  # This method will rotate files unconditionally

  backup_options ||= @backup_options
  backup_name ||= @backup_name
  
  return :failure unless backup_options[:backup_file_name_template] =~ /\%n/
  
  remote_directory_name = File.join(backup_options[:base_backup_directory],backup_name)
  remote_cmd = "mkdir -p #{remote_directory_name}"
  cmd_status, cmd_output = ssh_cmd(remote_cmd)
  return :failure unless cmd_status == :success
  remote_cmd = "ls -1t #{remote_directory_name}"
  cmd_status, cmd_output = ssh_cmd(remote_cmd)
  return :failure unless cmd_status == :success
  remote_backup_files = cmd_output.reject {|line| line =~ /^\.$/ or line =~ /^\.\.$/ }
  # Make sure we're initialized
  backup_options[:all_possible_file_names] = all_backup_names(backup_options)
  backups_to_retain = backup_options[:backups_to_retain]
  # If no entries don't rotate
  # If entries > 0 and entries < max, move all files down one position
  # If entries >= max, remove last entry, then move all files down one position
  unless remote_backup_files.empty?
    # if entries >= max, 
    if remote_backup_files.size >= backups_to_retain
      # .. remove last entry
      last_entry = remote_backup_files.pop
      remote_cmd = "rm -f #{File.join(remote_directory_name,last_entry)}"
      cmd_status, cmd_output = ssh_cmd(remote_cmd)
      return :failure unless cmd_status == :success
    end
    # Need to reverse order
    remote_backup_files.size.downto(1) do |current_generation|
      #puts "rotate_destination_files_unconditionally current_generation #{current_generation}"
      file_name_current_generation = remote_backup_files[current_generation - 1]
      #puts "rotate_destination_files_unconditionally file_name_current_generation #{file_name_current_generation}"
      file_name_previous_generation = backup_options[:all_possible_file_names][current_generation]
      #puts "rotate_destination_files_unconditionally file_name_previous_generation #{file_name_previous_generation}"
      remote_cmd = "mv #{File.join(remote_directory_name,file_name_current_generation)} #{File.join(remote_directory_name,file_name_previous_generation)}"
      cmd_status, cmd_output = ssh_cmd(remote_cmd)
      @log.debug("Rotated #{File.join(remote_directory_name,file_name_current_generation)} to  #{File.join(remote_directory_name,file_name_previous_generation)} Status #{cmd_status}")
      return :failure unless cmd_status == :success
    end
    
  end
    
  return :success

end

#scp_cmd(source_file, destination_dir, backup_options = nil, backup_name = nil) ⇒ Array

Issue an scp command

Parameters:

  • source_file (String)

    Fully qualified name of file to send

  • destination_dir (String)

    Destination directory on remote host

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Array)
    command status, command output


569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 569

def scp_cmd(source_file,destination_dir,backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  ssh_user = backup_options[:user_name]
  ssh_host = backup_options[:hostname]
  ssh_password = backup_options[:password]
  if ssh_password
    # Need to use expect for the password if certs don't work
    cmd_exe = File.expand_path(File.join(::UBSAFE_ROOT, 'bin','ubsafe_scp_cmd.expect'))
    full_cmd = "#{cmd_exe} #{ssh_user}@#{ssh_host} \"#{ssh_password}\" #{source_file} #{destination_dir}"
    masked_full_cmd = "#{cmd_exe} #{ssh_user}@#{ssh_host} [PASSWORD] #{source_file} #{destination_dir}"
  else
    # Certs assumed if no password
    full_cmd = "scp #{source_file} #{ssh_user}@#{ssh_host}:#{destination_dir}"
    masked_full_cmd = full_cmd
  end
  #puts "About to issue \"#{full_cmd}\""
  cmd_output = `#{full_cmd}`
  cmd_status = $?
  @log.debug("Executed scp status #{cmd_status} command \"#{masked_full_cmd}\"")
  cmd_output_lines = cmd_output.split("\n").reject {|line| line =~ /spawn/i or line =~ /password/i }
  cmd_output_cleaned = []
  cmd_output_lines.each do |cmd_output_line|
    cmd_output_cleaned << cmd_output_line.strip.chomp
  end
  cmd_status = cmd_status == 0 ? :success : :failure
  return [cmd_status,cmd_output_cleaned]
end

#ssh_cmd(cmd, backup_options = nil, backup_name = nil) ⇒ Array

Issue an ssh command

Parameters:

  • cmd (String)

    Command to send

  • backup_options (Hash) (defaults to: nil)
  • backup_name (String) (defaults to: nil)

Returns:

  • (Array)
    command status, command output


531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
# File 'lib/ubsafe/ubsafe_commands/ubsafe_command_backup.rb', line 531

def ssh_cmd(cmd,backup_options = nil,backup_name = nil)
  backup_options ||= @backup_options
  backup_name ||= @backup_name
  ssh_user = backup_options[:user_name]
  ssh_host = backup_options[:hostname]
  ssh_password = backup_options[:password]
  if ssh_password
    # Need to use expect for the password if certs don't work
    cmd_exe = File.expand_path(File.join(::UBSAFE_ROOT, 'bin','ubsafe_ssh_cmd.expect'))
    full_cmd = "#{cmd_exe} #{ssh_user}@#{ssh_host} \"#{ssh_password}\" \"#{cmd}\""
    masked_full_cmd = "#{cmd_exe} #{ssh_user}@#{ssh_host} [PASSWORD] \"#{cmd}\""
  else
    # Certs assumed if no password
    full_cmd = "ssh #{ssh_user}@#{ssh_host} \"#{cmd}\""
    masked_full_cmd = full_cmd
  end
  #puts "About to issue \"#{full_cmd}\""
  cmd_output = `#{full_cmd}`
  cmd_status = $?
  @log.debug("Executed ssh status #{cmd_status} command \"#{masked_full_cmd}\"")
  cmd_output_lines = cmd_output.split("\n").reject {|line| line =~ /spawn/i or line =~ /password/i }
  cmd_output_cleaned = []
  cmd_output_lines.each do |cmd_output_line|
    cmd_output_cleaned << cmd_output_line.strip.chomp
  end
  cmd_status = cmd_status == 0 ? :success : :failure
  return [cmd_status,cmd_output_cleaned]
end