cloud_sync 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+
2
+
3
+ ##The Idea...
4
+
5
+ CloudSync.schedule do
6
+ every 12.hours do
7
+ archive "/home/user/documents", :to => "filesystem:/mnt/external/snapshots"
8
+ end
9
+
10
+ every 30.minutes do
11
+ system "mysqldump mydb -u special > /tmp/dump.sql"
12
+ archive "/tmp/dump.sql", :to => "filesystem:/backups/sql/mydb"
13
+ archive "/tmp/dump.sql", :to => "s3:/backups/mydb"
14
+ end
15
+
16
+ every 5.minutes do
17
+ synchronize "/some/directory", :with => "remote:special", :target => "/other/path"
18
+ end
19
+
20
+ on_change "/some/dir" do
21
+ # ...
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc "Run All Specs"
5
+ Spec::Rake::SpecTask.new("spec") do |t|
6
+ t.spec_files = FileList["spec/**/*_spec.rb"]
7
+ end
@@ -0,0 +1,30 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'cloud_sync'
3
+ s.version = '0.1'
4
+ s.date = '2010-06-16'
5
+ s.summary = 'A tool for syncing files between clouds'
6
+ s.email = 'dan.simpson@gmail.com'
7
+ s.homepage = 'http://github.com/dansimpson/cloud_sync'
8
+ s.description = 'A tool for syncing files between clouds'
9
+ s.has_rdoc = true
10
+
11
+ s.authors = ['Dan Simpson']
12
+ s.add_dependency('cloudfiles', '>= 1.4.7')
13
+ s.add_dependency('aws-s3', '>= 0.6.2')
14
+
15
+ s.files = [
16
+ 'README.markdown',
17
+ 'cloud_sync.gemspec',
18
+ 'Rakefile',
19
+ 'lib/cloud_sync.rb',
20
+ 'lib/cloud_sync/archiver.rb',
21
+ 'lib/cloud_sync/configuration.rb',
22
+ 'lib/cloud_sync/log.rb',
23
+ 'lib/cloud_sync/resource.rb',
24
+ 'lib/cloud_sync/synchronizer.rb',
25
+ 'lib/cloud_sync/media/base.rb',
26
+ 'lib/cloud_sync/media/filesystem.rb',
27
+ 'lib/cloud_sync/media/rackspace.rb',
28
+ 'lib/cloud_sync/media/s3.rb'
29
+ ]
30
+ end
@@ -0,0 +1,36 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require "rubygems"
4
+ require "cloudfiles"
5
+ require "aws/s3"
6
+ require "pp"
7
+
8
+ module CloudSync
9
+
10
+ VERSION = 0.1
11
+
12
+ def self.copy source, destination
13
+ Resource.new(source).copy(Resource.new(destination))
14
+ end
15
+
16
+ def self.archive source, destination
17
+ Archiver.new(source, destination).archive
18
+ end
19
+
20
+ def self.synchronize source, destination
21
+ Synchronizer.new(source).synchronize(destination)
22
+ end
23
+
24
+ end
25
+
26
+ #archivers
27
+ require "cloud_sync/configuration"
28
+ require "cloud_sync/media/base"
29
+ require "cloud_sync/media/filesystem"
30
+ require "cloud_sync/media/rackspace"
31
+ require "cloud_sync/media/s3"
32
+ require "cloud_sync/resource"
33
+ require "cloud_sync/log"
34
+ require "cloud_sync/archiver"
35
+ require "cloud_sync/synchronizer"
36
+
@@ -0,0 +1,39 @@
1
+ module CloudSync
2
+ class Archiver
3
+
4
+ attr_accessor :source, :destination
5
+
6
+ def initialize source, destination
7
+ @source = Resource.new source
8
+ @destination = Resource.new destination
9
+ end
10
+
11
+ def archive
12
+
13
+ unless source
14
+ return Log.error "Invalid syntax for resource #{source}"
15
+ end
16
+
17
+ unless destination
18
+ return Log.error "Invalid syntax for resource #{destination}"
19
+ end
20
+
21
+ tar = Resource.new("filesystem:#{archive_path}")
22
+ system "tar czvf #{archive_path} #{source.path}"
23
+ destination.istream("/home/dan/moo.tgz") << tar.ostream
24
+ system "rm #{archive_path}"
25
+
26
+ end
27
+
28
+ protected
29
+
30
+ def archive_path
31
+ "/tmp/#{archive_name}"
32
+ end
33
+
34
+ def archive_name
35
+ @archive_name ||= "#{File.basename(source.path)}.#{Time.now.strftime("%Y%j%H%M%S")}.tgz"
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,41 @@
1
+ module CloudSync
2
+
3
+ class Configuration
4
+
5
+ @map = {
6
+ }
7
+
8
+ def self.get key
9
+ @map[key.to_sym]
10
+ end
11
+
12
+ def self.put key, val
13
+ @map[key.to_sym] = val
14
+ end
15
+
16
+ def self.method_missing method, *args
17
+ if method.to_s =~ /=$/
18
+ return put method.to_s.chop, args.first
19
+ else
20
+ return get method
21
+ end
22
+ super
23
+ end
24
+
25
+ def self.load file
26
+ begin
27
+ configure YAML.load_file(file)
28
+ rescue
29
+ raise IOError, "#{file} could not be loaded."
30
+ end
31
+ end
32
+
33
+ def self.configure map
34
+ map.each do |k,v|
35
+ put k, v
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,58 @@
1
+ module CloudSync
2
+
3
+ class Log
4
+
5
+ @threshhold = 1
6
+
7
+ @descriptor = {
8
+ 1 => "DBUG",
9
+ 2 => "WARN",
10
+ 3 => "INFO",
11
+ 4 => "ERROR"
12
+ }
13
+
14
+ def self.debug msg
15
+ log(msg,1) if @threshhold <= 1
16
+ end
17
+
18
+ def self.warning msg
19
+ log(msg,2) if @threshhold <= 2
20
+ end
21
+
22
+ def self.info msg
23
+ log(msg,3) if @threshhold <= 3
24
+ end
25
+
26
+ def self.error msg
27
+ log(msg,4) if @threshhold <= 4
28
+ end
29
+
30
+ def self.debug!
31
+ @threshhold = 1
32
+ end
33
+
34
+ def self.warn!
35
+ @threshhold = 2
36
+ end
37
+
38
+ def self.info!
39
+ @threshhold = 3
40
+ end
41
+
42
+ def self.shutthefuckup!
43
+ @threshhold = 4
44
+ end
45
+
46
+ def self.is_debug?
47
+ @threshhold == 1
48
+ end
49
+
50
+ private
51
+
52
+ def self.log msg, level
53
+ puts "[#{@descriptor[level]}] #{Time.now} - #{msg}"
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,19 @@
1
+ module CloudSync
2
+ module Media
3
+ class Base
4
+
5
+ def exists? path
6
+ raise "#{self.class}.exists? not implemented"
7
+ end
8
+
9
+ def writer path
10
+ raise "#{self.class}.writer not implemented"
11
+ end
12
+
13
+ def reader path
14
+ raise "#{self.class}.reader not implemented"
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module CloudSync
2
+ module Media
3
+ class Filesystem < Base
4
+
5
+ def exists? path
6
+ File.exists? path
7
+ end
8
+
9
+ def is_container? path
10
+ File.directory? path
11
+ end
12
+
13
+ def is_object? path
14
+ File.exists? path
15
+ end
16
+
17
+ def reader path
18
+ File.open(path, "r")
19
+ end
20
+
21
+ def writer path
22
+ File.open(path, "w")
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,65 @@
1
+ module CloudFiles
2
+ class StorageObject
3
+ def read
4
+ data
5
+ end
6
+ end
7
+ end
8
+
9
+ module CloudSync
10
+ module Media
11
+ class Rackspace < Base
12
+
13
+ def initialize
14
+ raise "rackspace_user not set" unless Configuration.rackspace_user
15
+ raise "rackspace_key not set" unless Configuration.rackspace_key
16
+ @conn = CloudFiles::Connection.new(Configuration.rackspace_user, Configuration.rackspace_key)
17
+ end
18
+
19
+ def list container
20
+ @conn.container(container).objects
21
+ end
22
+
23
+ def exists? path
24
+ container, object = parse path
25
+ object_exists?(container, object)
26
+ end
27
+
28
+ def reader path
29
+ container, object = parse path
30
+ get_object(container, object)
31
+ end
32
+
33
+ def writer path
34
+ container, object = parse path
35
+ get_object(container, object)
36
+ end
37
+
38
+ protected
39
+
40
+ def parse path
41
+ parts = path.split "/"
42
+ container = parts.shift
43
+ [container, parts.join("/")]
44
+ end
45
+
46
+ def container_exists? container
47
+ @conn.container_exists?(container)
48
+ end
49
+
50
+ def object_exists? container, object
51
+ container_exists?(container) && @conn.container(container).object_exists?(object)
52
+ end
53
+
54
+ def get_container container
55
+ container_exists?(container) ? @conn.container(container) : @conn.create_container(container)
56
+ end
57
+
58
+ def get_object container, object
59
+ tmp = get_container(container)
60
+ tmp.object_exists?(object) ? tmp.object(object) : tmp.create_object(object, true)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,60 @@
1
+ module CloudSync
2
+ module Media
3
+ class S3 < Base
4
+
5
+ def initialize
6
+ raise "s3_access_key not set" unless Configuration.s3_access_key
7
+ raise "s3_secret_key not set" unless Configuration.s3_secret_key
8
+
9
+ AWS::S3::Base.establish_connection!({
10
+ :access_key_id => Configuration.s3_access_key,
11
+ :secret_access_key => Configuration.s3_secret_key
12
+ })
13
+ end
14
+
15
+ def exists? path
16
+ bucket, object = parse path
17
+ object_exists?(bucket, object)
18
+ end
19
+
20
+ def reader path
21
+ bucket, object = parse path
22
+ get_object(bucket, object)
23
+ end
24
+
25
+ def writer path
26
+ bucket, object = parse path
27
+ get_object(bucket, object)
28
+ end
29
+
30
+ protected
31
+
32
+ def parse path
33
+ parts = path.split "/"
34
+ bucket = parts.shift
35
+ [bucket, parts.join("/")]
36
+ end
37
+
38
+ def bucket_exists? bucket
39
+ AWS::S3::Bucket.find(bucket) rescue false
40
+ end
41
+
42
+ def object_exists? bucket, object
43
+ AWS::S3::S3Object.exists?(object, bucket)
44
+ end
45
+
46
+ def get_bucket bucket
47
+ unless bucket_exists?(bucket)
48
+ AWS::S3::Bucket.create(bucket)
49
+ end
50
+ AWS::S3::Bucket.find(bucket)
51
+ end
52
+
53
+ def get_object bucket, object
54
+ object_exists?(bucket, object) ? AWS::S3::S3Object.find(object, bucket) : nil
55
+ end
56
+
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,50 @@
1
+ module CloudSync
2
+
3
+ MediaTypes = {
4
+ :filesystem => CloudSync::Media::Filesystem,
5
+ :rackspace => CloudSync::Media::Rackspace,
6
+ :s3 => CloudSync::Media::S3
7
+ }
8
+
9
+ class Resource
10
+
11
+ attr_accessor :medium, :path, :type, :uri
12
+
13
+ def initialize uri
14
+ raise "Invalid resource string #{uri}" unless uri =~ /\w+:/
15
+
16
+ @uri = uri
17
+ @type, @path = uri.split(":")
18
+ @type = @type.to_sym
19
+
20
+ raise "Invalid medium type: #{@type}" unless MediaTypes.has_key?(@type)
21
+
22
+ @medium = MediaTypes[@type].new
23
+ end
24
+
25
+ def exists?
26
+ @medium.exists?(@path)
27
+ end
28
+
29
+ def copy to
30
+
31
+ raise "Resource #{@uri} does not exist" unless exists?
32
+
33
+ input = reader
34
+ output = to.writer
35
+ output.write(input.read)
36
+
37
+ input.close if input.respond_to? :close
38
+ output.close if output.respond_to? :close
39
+ end
40
+
41
+ def writer
42
+ @medium.writer @path
43
+ end
44
+
45
+ def reader
46
+ @medium.reader @path
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module CloudSync
2
+ class Synchronizer
3
+
4
+ attr_accessor :source, :destination
5
+
6
+ def initialize source, destination
7
+ @source = Resource.new source
8
+ @destination = Resource.new destination
9
+ end
10
+
11
+ def synchronize
12
+ raise "Not implemented"
13
+ end
14
+
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloud_sync
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Dan Simpson
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-16 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: cloudfiles
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 1
31
+ - 4
32
+ - 7
33
+ version: 1.4.7
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: aws-s3
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ - 6
48
+ - 2
49
+ version: 0.6.2
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ description: A tool for syncing files between clouds
53
+ email: dan.simpson@gmail.com
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - README.markdown
62
+ - cloud_sync.gemspec
63
+ - Rakefile
64
+ - lib/cloud_sync.rb
65
+ - lib/cloud_sync/archiver.rb
66
+ - lib/cloud_sync/configuration.rb
67
+ - lib/cloud_sync/log.rb
68
+ - lib/cloud_sync/resource.rb
69
+ - lib/cloud_sync/synchronizer.rb
70
+ - lib/cloud_sync/media/base.rb
71
+ - lib/cloud_sync/media/filesystem.rb
72
+ - lib/cloud_sync/media/rackspace.rb
73
+ - lib/cloud_sync/media/s3.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/dansimpson/cloud_sync
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.7
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: A tool for syncing files between clouds
108
+ test_files: []
109
+