Skip to content

Commit

Permalink
Added the Local Storage.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael van Rooijen committed Jun 4, 2011
1 parent 743c853 commit cfa33d2
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/backup.rb
Expand Up @@ -17,7 +17,7 @@ module Backup
# You can do:
# database MySQL do |mysql|
DATABASES = ['MySQL', 'PostgreSQL', 'MongoDB', 'Redis']
STORAGES = ['S3', 'CloudFiles', 'Dropbox', 'FTP', 'SFTP', 'SCP', 'RSync']
STORAGES = ['S3', 'CloudFiles', 'Dropbox', 'FTP', 'SFTP', 'SCP', 'RSync', 'Local']
COMPRESSORS = ['Gzip', 'Bzip2']
ENCRYPTORS = ['OpenSSL', 'GPG']
SYNCERS = ['RSync', 'S3']
Expand Down Expand Up @@ -88,6 +88,7 @@ module Storage
autoload :SFTP, File.join(CONFIGURATION_PATH, 'storage', 'sftp')
autoload :SCP, File.join(CONFIGURATION_PATH, 'storage', 'scp')
autoload :RSync, File.join(CONFIGURATION_PATH, 'storage', 'rsync')
autoload :Local, File.join(CONFIGURATION_PATH, 'storage', 'local')
end

module Syncer
Expand Down Expand Up @@ -116,6 +117,7 @@ module Storage
autoload :SFTP, File.join(STORAGE_PATH, 'sftp')
autoload :SCP, File.join(STORAGE_PATH, 'scp')
autoload :RSync, File.join(STORAGE_PATH, 'rsync')
autoload :Local, File.join(STORAGE_PATH, 'local')
end

##
Expand Down
17 changes: 17 additions & 0 deletions lib/backup/configuration/storage/local.rb
@@ -0,0 +1,17 @@
# encoding: utf-8

module Backup
module Configuration
module Storage
class Local < Base
class << self

##
# Path to store backups to
attr_accessor :path

end
end
end
end
end
78 changes: 78 additions & 0 deletions lib/backup/storage/local.rb
@@ -0,0 +1,78 @@
# encoding: utf-8

##
# Load the Ruby FileUtils library
require 'fileutils'

module Backup
module Storage
class Local < Base

##
# Path to store backups to
attr_accessor :path

##
# Creates a new instance of the Local storage object
# First it sets the defaults (if any exist) and then evaluates
# the configuration block which may overwrite these defaults
def initialize(&block)
load_defaults!

@path ||= "#{ENV['HOME']}/backups"

instance_eval(&block) if block_given?

@time = TIME
fix_path!
end

##
# This is the remote path to where the backup files will be stored.
# Eventhough it says "remote", it's actually the "local" path, but
# the naming is necessary for compatibility reasons
def remote_path
File.join(path, TRIGGER)
end

##
# Performs the backup transfer
def perform!
transfer!
cycle!
end

private

##
# Transfers the archived file to the specified local path
def transfer!
Logger.message("#{ self.class } started transferring \"#{ remote_file }\".")
create_local_directories!
FileUtils.cp(
File.join(local_path, local_file),
File.join(remote_path, remote_file)
)
end

##
# Removes the transferred archive file from the local path
def remove!
FileUtils.rm(File.join(remote_path, remote_file))
end

##
# Creates the path to where the backups are stored if it doesn't exist yet
def create_local_directories!
FileUtils.mkdir_p(remote_path)
end

##
# Replaces ~/ with the full path to the users $HOME directory
def fix_path!
@path = path.sub(/^\~\//, "#{ENV['HOME']}/")
end

end
end
end
7 changes: 7 additions & 0 deletions lib/templates/storage/local
@@ -0,0 +1,7 @@
##
# Local (Copy) [Storage]
#
store_with Local do |local|
local.path = '~/backups/'
local.keep = 5
end
28 changes: 28 additions & 0 deletions spec/configuration/storage/local_spec.rb
@@ -0,0 +1,28 @@
# encoding: utf-8

require File.dirname(__FILE__) + '/../../spec_helper'

describe Backup::Configuration::Storage::Local do
before do
Backup::Configuration::Storage::Local.defaults do |local|
local.path = 'my_backups'
local.keep = 20
end
end

it 'should set the default local configuration' do
local = Backup::Configuration::Storage::Local
local.path.should == 'my_backups'
local.keep.should == 20
end

describe '#clear_defaults!' do
it 'should clear all the defaults, resetting them to nil' do
Backup::Configuration::Storage::Local.clear_defaults!

local = Backup::Configuration::Storage::Local
local.path.should == nil
local.keep.should == nil
end
end
end
84 changes: 84 additions & 0 deletions spec/storage/local_spec.rb
@@ -0,0 +1,84 @@
# encoding: utf-8

require File.dirname(__FILE__) + '/../spec_helper'

describe Backup::Storage::Local do

let(:local) do
Backup::Storage::Local.new do |local|
local.path = '~/backups/'
local.keep = 20
end
end

before do
Backup::Configuration::Storage::Local.clear_defaults!
end

it 'should have defined the configuration properly' do
local.path.should == "#{ENV['HOME']}/backups/"
local.keep.should == 20
end

it 'should use the defaults if a particular attribute has not been defined' do
Backup::Configuration::Storage::Local.defaults do |local|
local.path = '~/backups'
end

local = Backup::Storage::Local.new do |local|
local.path = '~/my-backups'
end

local.path.should == "#{ENV['HOME']}/my-backups"
end

it 'should have its own defaults' do
local = Backup::Storage::Local.new
local.path.should == "#{ENV['HOME']}/backups"
end

describe '#transfer!' do
before do
local.stubs(:create_local_directories!)
Backup::Logger.stubs(:message)
end

it 'should transfer the provided file to the path' do
Backup::Model.new('blah', 'blah') {}
file = mock("Backup::Storage::Local::File")

local.expects(:create_local_directories!)

FileUtils.expects(:cp).with(
File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar"),
File.join("#{ENV['HOME']}/backups/myapp", "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
)

local.send(:transfer!)
end
end

describe '#remove!' do
it 'should remove the file from the remote server path' do
FileUtils.expects(:rm).with("#{ENV['HOME']}/backups/myapp/#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
local.send(:remove!)
end
end

describe '#create_remote_directories!' do
it 'should properly create remote directories one by one' do
local.path = "#{ENV['HOME']}/backups/some_other_folder/another_folder"
FileUtils.expects(:mkdir_p).with("#{ENV['HOME']}/backups/some_other_folder/another_folder/myapp")
local.send(:create_local_directories!)
end
end

describe '#perform' do
it 'should invoke transfer! and cycle!' do
local.expects(:transfer!)
local.expects(:cycle!)
local.perform!
end
end

end

0 comments on commit cfa33d2

Please sign in to comment.