class SelBackup

SelBackup Class

Enables connection to s3 server and uploads files

Attributes

access_key[RW]

Attributes: informations required for connection to s3 server

access_secret[RW]

Attributes: informations required for connection to s3 server

bucket_name[RW]

Attributes: informations required for connection to s3 server

region[RW]

Attributes: informations required for connection to s3 server

Public Class Methods

new(key, secret, bucket, region = 'eu-west-1') click to toggle source

Public: Initialize a new SelBackup instance.

key

A String representing the AWS ACCESS KEY ID.

secret

A String representing the AWS ACCESS KEY SECRET.

bucket

A String representing the name of the bucket ot use.

:region (optional)

A String representing the region to conect to (default: 'eu-west-1').

Examples

SelectraBackup.new('key', 'secret', 'bucket', region: 'us-east-1')

Returns the newly instanciated object.

# File lib/selbackup.rb, line 29
def initialize(key, secret, bucket, region = 'eu-west-1')
  @access_key = key
  @access_secret = secret
  @bucket_name = bucket
  @region = region
end

Public Instance Methods

bucket() click to toggle source

Public: Returns the S3 bucket.

Returns a Fog::Storage::AWS::Directory instance.

# File lib/selbackup.rb, line 40
def bucket
  @bucket ||= connection.directories.get(bucket_name)
end
check_daily(filename, nb_day) click to toggle source

Public: daily check algorythm

filename

String which contains a filename. If you upload '2013-01-01-file.tgz', filename will be 'file.tgz'

  • If 7 daily files or less: does nothing

  • If more than 7 daily files but less than one week datediff between the latest daily file and the most recent weekly file: deletes the latest daily file

  • If more than 7 daily files but less than one week datediff between the latest daily file and the most recent weekly file: pushes the latest daily file to weekly file

    2013-01-01-daily-file.tgz -> 2013-01-01-weekly-file.tgz

Returns true if a file as been push. False in other cases

# File lib/selbackup.rb, line 57
def check_daily(filename, nb_day)
  return_value = false
  daily_directory = give_me_files(filename, "daily")
  if ! daily_good?(daily_directory, nb_day)
    weekly_directory = give_me_files(filename, "weekly")
    latest_daily_file = give_me_latest_file(daily_directory)
    recent_weekly_file = give_me_recent_file(weekly_directory)
    if weekly_directory == [] || should_weekly?(latest_daily_file.key, recent_weekly_file.key)
      weekly_file = gen_weekly_file({ key: latest_daily_file.key, body: latest_daily_file.body})
      push_file(weekly_file)
      return_value = true
    end
    delete_file(latest_daily_file)
  end
  return return_value
end
check_monthly(filename, nb_month) click to toggle source

Public: montlhy check algorythm

filename

String which contains a filename. If you upload '2013-01-01-file.tgz', filename will be 'file.tgz'

  • If 3 monthly files or less: does nothing

  • if more than 3 monthly files: deletes the latest monthly file

Returns true if a file as been delete. False in other cases

# File lib/selbackup.rb, line 84
def check_monthly(filename, nb_month)
  return_value = false
  monthly_directory = give_me_files(filename, "monthly")
  if ! monthly_good?(monthly_directory, nb_month)
    latest_monthly_file = give_me_latest_file(monthly_directory)
    delete_file(latest_monthly_file)
    return_value = true
  end
  return return_value
end
check_weekly(filename, nb_week) click to toggle source

Public: weekly check algorythm

filename

String which contains a filename. If you upload '2013-01-01-file.tgz', filename will be 'file.tgz'

  • If 4 weekly files or less: does nothing

  • If more than 4 weekly files but less than one month datediff between the latest weekly file and the most recent monthly file: deletes the latest weekly file

  • If more than 4 weekly files but less than one week datediff between the latest weekly file and the most recent monthly file: pushes the latest weekly file to monthly file

    2013-01-01-weekly-file.tgz -> 2013-01-01-monthly-file.tgz

Returns true if a file as been push. False in other cases

# File lib/selbackup.rb, line 108
def check_weekly(filename, nb_week)
  return_value = false
  weekly_directory = give_me_files(filename, "weekly")
  if ! weekly_good?(weekly_directory, nb_week)
    monthly_directory = give_me_files(filename, "monthly")
    latest_weekly_file = give_me_latest_file(weekly_directory)
    recent_monthly_file = give_me_recent_file(monthly_directory)
    if monthly_directory == [] || should_monthly?(latest_weekly_file.key, recent_monthly_file.key)
      monthly_file = gen_monthly_file({ key: latest_weekly_file.key, body: latest_weekly_file.body})
      push_file(monthly_file)
      return_value = true
    end
    delete_file(latest_weekly_file)
  end
  return return_value
end
connection() click to toggle source

Public: Returns the S3 connection.

Returns a Fog::Storage::AWS::Real instance.

# File lib/selbackup.rb, line 129
def connection
  @connection ||= Fog::Storage.new(provider: 'AWS', aws_access_key_id: access_key, aws_secret_access_key: access_secret, region: region)
end
daily_good?(directoryFiles, nb_day) click to toggle source

Public: Check daily files number

directoryFiles

Array of daily files

['file/2013-01-01-daily-file.tgz', 'file/2013-01-02-daily-file.tgz', ...]

Returns false if there is more than 7 daily files. False in other cases

# File lib/selbackup.rb, line 140
def daily_good?(directoryFiles, nb_day)
  return directoryFiles.length > nb_day ? false : true;
end
date_from_filename(filename) click to toggle source

Public: Returns the parsed date.

filename: “2016-11-26-daily-server_name-project1234.pgsql.gz” for example

Returns a Date instance.

# File lib/selbackup.rb, line 187
def date_from_filename(filename)
  Date.parse(filename.match(/\d{4}-\d{2}-\d{2}/).to_s)
end
delete_file(file) click to toggle source

Public: deletes a file

file

Fog::Storage::AWS::Files file

returns nothing

# File lib/selbackup.rb, line 150
def delete_file(file)
  file.destroy
end
directory(path) click to toggle source

Public: Returns a virtual S3 directory.

S3 doesn't know such a thing as a directory but it is possible to use a prefix to select only the files having a key starting with this prefix.

path

A String representing the prefix to use.

Examples

sb = SelectraBackup.new('key', 'secret', 'bucket')
backup = sb.directory('backup/')
backup.files
# => <Fog::Storage::AWS::Files ...>

Returns a Fog::Storage::AWS::Directory instance.

# File lib/selbackup.rb, line 169
def directory(path)
  connection.directories.get(bucket_name, prefix: path)
end
files() click to toggle source

Public: Returns the list of files.

Returns a Fog::Storage::AWS::Files instances.

# File lib/selbackup.rb, line 177
def files
  bucket.files
end
gen_daily_file(file) click to toggle source

Public: gen a daily file

file

file you want to upload

Returns an hash containing the filename, the key and the body of the daily file

# File lib/selbackup.rb, line 260
def gen_daily_file(file)
  name = File.basename(file)
  if name =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}(\.\w*)?$/
    return false
  elsif !(name =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}-/)
    name = "#{Date.today.to_s}-#{name}"
  end
  myname = name.split(/[0-9]{4}-[0-9]{2}-[0-9]{2}-/).last
  mydate = name.split("-#{myname}").first
  key = "#{myname}/#{mydate}-daily-#{myname}"
  return { myname: myname, key: key, body: File.open(file) }
end
gen_monthly_file(file) click to toggle source

Public: gen a monthly file

file

hash containing the key and the body of the weekly file you want to push to monthly file

Returns an hash containing the key and the body of the monthly file

# File lib/selbackup.rb, line 279
def gen_monthly_file(file)
  if file[:key] =~ /[\w+.-]+\/[\w+.-]+-\d{4}-\d{2}-\d{2}-[\w+.-]+/
    monthly_name = file[:key].sub("/weekly-", "/monthy-")
  else
    monthly_name = file[:key].sub("-weekly-", "-monthly-")
  end
  return { key: monthly_name, body: file[:body] }
end
gen_weekly_file(file) click to toggle source

Public: gen a weekly file

file

hash containing the key and the body of the daily file you want to push to weekly file

Returns an hash containing the key and the body of the weekly file

# File lib/selbackup.rb, line 294
def gen_weekly_file(file)
  if file[:key] =~ /[\w+.-]+\/[\w+.-]+-\d{4}-\d{2}-\d{2}-[\w+.-]+/
    weekly_name = file[:key].sub("/daily-", "/weekly-")
  else
    weekly_name = file[:key].sub("-daily-", "-weekly-")
  end
  return { key: weekly_name, body: file[:body] }
end
give_me_files(filename, type) click to toggle source

Public: returns lists of file

filename: “file.tgz” for example

type: specify if you want daily, weekly or monthly files

Returns a sorted array

# File lib/selbackup.rb, line 199
def give_me_files(filename, type)
  full_directory = directory("#{filename}/")
  files = []
  full_directory.files.each do | file |
    if file.key =~ /#{filename}\/\d{4}-\d{2}-\d{2}-#{type}-[\w+.]+/ ||
       file.key =~ /#{filename}\/#{type}-\d{4}-\d{2}-\d{2}-[\w+.]+/
        files.push(file)
    end
  end
  return files
end
give_me_latest_file(files) click to toggle source

Public: returns latest file

files: array of AWS object file

Returns the latest file, based on the date

# File lib/selbackup.rb, line 217
def give_me_latest_file(files)
  latest_file = files.first
  files.each do | file |
    if date_from_filename(file.key) < date_from_filename(latest_file.key)
      latest_file = file
    end
  end
  return latest_file
end
give_me_recent_file(files) click to toggle source

Public: returns most recent file

files: array of AWS object file

Returns the most recent file, based on the date

# File lib/selbackup.rb, line 233
def give_me_recent_file(files)
  recent_file = files.first
  files.each do | file |
    if date_from_filename(file.key) > date_from_filename(recent_file.key)
      recent_file = file
    end
  end
  return recent_file
end
monthly_good?(files, nb_month) click to toggle source

Public: Check monthly files number

files

Array of monthly files

['file/2013-01-01-monthly-file.tgz', 'file/2013-01-02-monthly-file.tgz', ...]

Returns false if there is more than 3 monthly files. False in other cases

# File lib/selbackup.rb, line 250
def monthly_good?(files, nb_month)
  return files.length > nb_month ? false : true
end
push_file(file) click to toggle source

Public: pushes a file to s3 server

file

hash containing the key and the body of the file you want to upload

Returns nothing

# File lib/selbackup.rb, line 309
def push_file(file)
  if file[:key] =~ /[\w+.-]+\/[\w+.-]+-\d{4}-\d{2}-\d{2}-[\w+.-]+/
    filename = file[:key].split('/').first
    name_parts = file[:key].split('/').last.split('-')
    file[:key] = "#{filename}/#{name_parts[1]}-#{name_parts[2]}-#{name_parts[3]}-#{name_parts[0]}-#{filename}"
  end
  # 104857600 bytes => 100 megabytes
  bucket.files.create(key: file[:key], body: file[:body], multipart_chunk_size: 104857600)
end
should_monthly?(file1, file2) click to toggle source

Public: date diff

file1

latest weekly file

file2

most recent monthly file

Returns true if datediff between the two files is upper than 1 month. False in other cases

# File lib/selbackup.rb, line 347
def should_monthly?(file1, file2)
  begin
    date1 = date_from_filename(file1).prev_month
    date2 = date_from_filename(file2)
  rescue
    print "Wrong date (Date.parse in should_monthly)."
    return false
  end
  return date1 >= date2 ? true : false
end
should_weekly?(file1, file2) click to toggle source

Public: date diff

file1

latest daily file

file2

most recent weekly file

Returns true if datediff between the two files is upper than 7 days. False in other cases

# File lib/selbackup.rb, line 327
def should_weekly?(file1, file2)
  begin
    date1 = date_from_filename(file1)
    date2 = date_from_filename(file2)
  rescue
    print "Wrong date (Date.parse in should_monthly)."
    return false
  end
  date_diff = date1 - date2
  return date_diff.abs >= 7 ? true : false
end
upload_file(file, nb_day = 7, nb_week = 4, nb_month = 3) click to toggle source

Public: upload file algorythm

file

file you want to upload

Uploads file as daily file and check daily, weekly and monthly full.

Returns nothing

# File lib/selbackup.rb, line 365
def upload_file(file, nb_day = 7, nb_week = 4, nb_month = 3)
  daily_file = gen_daily_file(file)
  if daily_file == false
    return false
  end
  push_file(daily_file)
  if check_daily(daily_file[:myname], nb_day)
    if check_weekly(daily_file[:myname], nb_week)
      check_monthly(daily_file[:myname], nb_month)
    end
  end
end
weekly_good?(directoryFiles, nb_week) click to toggle source

Public: Check weekly files number

files

Array of daily files

['file/2013-01-01-weekly-file.tgz', 'file/013-01-02-weekly-2file.tgz', ...]

Returns false if there is more than 4 weekly files. False in other cases

# File lib/selbackup.rb, line 385
def weekly_good?(directoryFiles, nb_week)
  return directoryFiles.length > nb_week ? false : true
end