s3snapshot 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.markdown +23 -4
- data/changelog.markdown +3 -0
- data/lib/s3snapshot/backup_manager.rb +13 -13
- data/lib/s3snapshot/version.rb +1 -1
- data/s3snapshot.gemspec +1 -1
- metadata +56 -74
- data/Gemfile.lock.bak +0 -34
- data/README.rdoc +0 -7
data/Readme.markdown
CHANGED
@@ -6,6 +6,15 @@ This gem is designed to sync an immutable directory to a timestamped prefix on A
|
|
6
6
|
|
7
7
|
gem install s3snapshot
|
8
8
|
|
9
|
+
# Building the gem
|
10
|
+
|
11
|
+
From the directory the project is checked out in, run:
|
12
|
+
|
13
|
+
gem build s3snapshot.gemspec
|
14
|
+
# to install the gem you just built, run the following two commands.
|
15
|
+
gem uninstall -x s3snapshot
|
16
|
+
gem install s3snapshot-*.gem
|
17
|
+
|
9
18
|
# Operations
|
10
19
|
|
11
20
|
* Backup a directory
|
@@ -14,11 +23,11 @@ This gem is designed to sync an immutable directory to a timestamped prefix on A
|
|
14
23
|
* List all prefixes
|
15
24
|
* List all times for prefixes
|
16
25
|
* Clean incomplete uploads (Use wisely, can delete a backup in progress)
|
17
|
-
* Perform rolling cleanup. Can keep a user defined number of daily and weekly backups with user specified day.
|
26
|
+
* Perform rolling cleanup. Can keep a user defined number of daily and weekly backups with user specified day. All days and weeks are deltas calculated from the timestamp of the last successful backup to s3.
|
18
27
|
|
19
28
|
# Algorithm
|
20
29
|
|
21
|
-
Below is a general outline on how the plugin was designed to work.
|
30
|
+
Below is a general outline on how the plugin was designed to work. Every time this plugin is launched it performs an analysis of S3 to ensure it is always using a correct state of backups. 2 instances should never access the same prefix concurrently, this could cause issues with data consistency.
|
22
31
|
|
23
32
|
## Snapshot path
|
24
33
|
|
@@ -32,13 +41,23 @@ Remove all incomplete backups before start time
|
|
32
41
|
|
33
42
|
Analyze all time stamps, if more than one backup is present per day, only keep the latest complete backup for that day
|
34
43
|
|
35
|
-
For all backups, if older than the max weekly, remove it
|
44
|
+
For all backups, if older than the max weekly, remove it, of between oldest weekly and oldest daily, only keep it if it falls on the day specified
|
36
45
|
|
37
46
|
|
38
47
|
# Notes
|
39
48
|
|
40
49
|
Occasionally a cleanup operation will miss a time stamp. From my testing this appears to be due to the amazon eventual consistency, and the timestamp not being returned on a delim search. On the next run it is usually deleted
|
41
50
|
|
51
|
+
This should only be run on machines with the *nix split command available. May work on windows with cygwin, but is untested.
|
52
|
+
If a file is over 5GB, the only way to upload it to S3 is to use multipart uploads. To split the file into parts, s3snapshot relies on the split command. The file parts are uploaded sequentially, so there is no speed boost in using multipart upload.
|
53
|
+
|
54
|
+
This has only been tested on Ruby 1.8.7, but appears to work on Ruby 1.9.3.
|
55
|
+
|
56
|
+
|
42
57
|
#Future features
|
43
58
|
|
44
|
-
* Use native s3 copying for unmodified files (similar to s3sync). If a file exists in the previous completed backup and has not changed, copy it on the new path in s3, this will avoid the need to upload unmodified files.
|
59
|
+
* Use native s3 copying for unmodified files (similar to s3sync). If a file exists in the previous completed backup and has not changed, copy it on the new path in s3, this will avoid the need to upload unmodified files.
|
60
|
+
|
61
|
+
# Change Log
|
62
|
+
|
63
|
+
See the [change log|changelog.markdown] for changes.
|
data/changelog.markdown
ADDED
@@ -0,0 +1,3 @@
|
|
1
|
+
# v0.0.12
|
2
|
+
|
3
|
+
backup_manager.read_complete method now checks if the s3snapshot complete marker exists for a particular prefix rather than relying on the common prefixes response from the S3 query. This change was made because sometimes the common_prefixes method was not returning a prefix that was expected, leading the backup manager to handle completed backups incorrectly.
|
@@ -22,7 +22,7 @@ module S3snapshot
|
|
22
22
|
|
23
23
|
##
|
24
24
|
#Get all prefixes in the bucket
|
25
|
-
|
25
|
+
##
|
26
26
|
def prefixes
|
27
27
|
bucket.files.all(:delimiter => "/").common_prefixes
|
28
28
|
end
|
@@ -104,9 +104,9 @@ module S3snapshot
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
|
107
|
+
##
|
108
108
|
#Delete all files from a snapshot. Will remove the complete file first to avoid other clients using the backup
|
109
|
-
|
109
|
+
##
|
110
110
|
def remove(prefix, timestamp)
|
111
111
|
complete_marker = bucket.files.get(complete_path(prefix, timestamp))
|
112
112
|
|
@@ -137,7 +137,7 @@ module S3snapshot
|
|
137
137
|
|
138
138
|
##
|
139
139
|
#Perform a rolling delete for the given prefix. Keeps the "newest" daily backup for the given day, and keeps a backup for the day of the week specified by day of week. day_of_week follows cron style syntax, 0 = sunday and 6 = saturday
|
140
|
-
|
140
|
+
##
|
141
141
|
def roll(prefix, num_days, num_weeks, day_of_week)
|
142
142
|
|
143
143
|
start = TimeFactory.utc_time
|
@@ -188,19 +188,17 @@ module S3snapshot
|
|
188
188
|
|
189
189
|
private
|
190
190
|
|
191
|
-
|
192
|
-
#Returns true if the backup is complete, false otherwise.
|
191
|
+
##
|
192
|
+
#Returns true if the backup is complete, false otherwise. A backup is complete if the s3snapshot complete marker exists.
|
193
|
+
##
|
193
194
|
def read_complete?(prefix, time)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
!found_prefixes.nil? && found_prefixes.length > 0
|
195
|
+
marker = complete_path(prefix, time)
|
196
|
+
!bucket.files.head(marker).nil?
|
199
197
|
end
|
200
198
|
|
201
199
|
##
|
202
|
-
#
|
203
|
-
|
200
|
+
# Returns true if the time occurs on the same day_of_week. day_of_week follows cron style syntax, 0 = sunday and 6 = saturday
|
201
|
+
##
|
204
202
|
def same_day(time, day_of_week)
|
205
203
|
|
206
204
|
unless day_of_week > -1 && day_of_week < 7
|
@@ -242,7 +240,9 @@ module S3snapshot
|
|
242
240
|
end
|
243
241
|
end
|
244
242
|
|
243
|
+
##
|
245
244
|
#returns true if the first and second time occur in the same date (assumes utc time)
|
245
|
+
##
|
246
246
|
def samedate?(first, second)
|
247
247
|
# puts "first: #{first};#{first.nil? ? "nil": first.yday}, second #{second};#{second.nil? ? "nil": second.yday}"
|
248
248
|
!first.nil? && !second.nil? && first.yday == second.yday
|
data/lib/s3snapshot/version.rb
CHANGED
data/s3snapshot.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = S3snapshot::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Todd Nine", "Andrew Esler"]
|
10
|
-
s.email = ["todd@spidertracks.co.nz"]
|
10
|
+
s.email = ["todd@spidertracks.co.nz", "andrew.esler@spidertracks.co.nz"]
|
11
11
|
s.homepage = "https://github.com/spidertracks/s3snapshot"
|
12
12
|
s.summary = %q{Uploads to s3}
|
13
13
|
s.description = %q{see summary}
|
metadata
CHANGED
@@ -1,90 +1,82 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3snapshot
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 11
|
10
|
-
version: 0.0.11
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Todd Nine
|
14
9
|
- Andrew Esler
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2013-10-20 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: fog
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
19
|
+
requirements:
|
27
20
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 25
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 3
|
33
|
-
- 1
|
21
|
+
- !ruby/object:Gem::Version
|
34
22
|
version: 1.3.1
|
35
23
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: thor
|
39
24
|
prerelease: false
|
40
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 1.3.1
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: thor
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
41
34
|
none: false
|
42
|
-
requirements:
|
35
|
+
requirements:
|
43
36
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 43
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
- 14
|
49
|
-
- 6
|
37
|
+
- !ruby/object:Gem::Version
|
50
38
|
version: 0.14.6
|
51
39
|
type: :runtime
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: dictionary
|
55
40
|
prerelease: false
|
56
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
42
|
none: false
|
58
|
-
requirements:
|
43
|
+
requirements:
|
59
44
|
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.14.6
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: dictionary
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
66
54
|
version: 1.0.0
|
67
55
|
type: :runtime
|
68
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.0.0
|
69
63
|
description: see summary
|
70
|
-
email:
|
64
|
+
email:
|
71
65
|
- todd@spidertracks.co.nz
|
72
|
-
|
66
|
+
- andrew.esler@spidertracks.co.nz
|
67
|
+
executables:
|
73
68
|
- s3snapshot
|
74
69
|
extensions: []
|
75
|
-
|
76
70
|
extra_rdoc_files: []
|
77
|
-
|
78
|
-
files:
|
71
|
+
files:
|
79
72
|
- .gitignore
|
80
73
|
- .loadpath
|
81
74
|
- .project
|
82
75
|
- Gemfile
|
83
|
-
- Gemfile.lock.bak
|
84
|
-
- README.rdoc
|
85
76
|
- Rakefile
|
86
77
|
- Readme.markdown
|
87
78
|
- bin/s3snapshot
|
79
|
+
- changelog.markdown
|
88
80
|
- lib/s3snapshot.rb
|
89
81
|
- lib/s3snapshot/backup_manager.rb
|
90
82
|
- lib/s3snapshot/cli.rb
|
@@ -97,36 +89,26 @@ files:
|
|
97
89
|
- s3snapshot.gemspec
|
98
90
|
homepage: https://github.com/spidertracks/s3snapshot
|
99
91
|
licenses: []
|
100
|
-
|
101
92
|
post_install_message:
|
102
93
|
rdoc_options: []
|
103
|
-
|
104
|
-
require_paths:
|
94
|
+
require_paths:
|
105
95
|
- lib
|
106
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
97
|
none: false
|
108
|
-
requirements:
|
109
|
-
- -
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
|
112
|
-
|
113
|
-
- 0
|
114
|
-
version: "0"
|
115
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
103
|
none: false
|
117
|
-
requirements:
|
118
|
-
- -
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
|
121
|
-
segments:
|
122
|
-
- 0
|
123
|
-
version: "0"
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
124
108
|
requirements: []
|
125
|
-
|
126
109
|
rubyforge_project: s3snapshot
|
127
|
-
rubygems_version: 1.8.
|
110
|
+
rubygems_version: 1.8.25
|
128
111
|
signing_key:
|
129
112
|
specification_version: 3
|
130
113
|
summary: Uploads to s3
|
131
114
|
test_files: []
|
132
|
-
|
data/Gemfile.lock.bak
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
s3snapshot (0.0.1)
|
5
|
-
fog (~> 0.8.1)
|
6
|
-
thor (~> 0.14.6)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
builder (3.0.0)
|
12
|
-
excon (0.6.3)
|
13
|
-
fog (0.8.1)
|
14
|
-
builder
|
15
|
-
excon (~> 0.6.1)
|
16
|
-
formatador (>= 0.1.3)
|
17
|
-
json
|
18
|
-
mime-types
|
19
|
-
net-ssh (>= 2.1.3)
|
20
|
-
nokogiri (>= 1.4.4)
|
21
|
-
ruby-hmac
|
22
|
-
formatador (0.1.3)
|
23
|
-
json (1.5.1)
|
24
|
-
mime-types (1.16)
|
25
|
-
net-ssh (2.1.4)
|
26
|
-
nokogiri (1.4.4)
|
27
|
-
ruby-hmac (0.4.0)
|
28
|
-
thor (0.14.6)
|
29
|
-
|
30
|
-
PLATFORMS
|
31
|
-
ruby
|
32
|
-
|
33
|
-
DEPENDENCIES
|
34
|
-
s3snapshot!
|
data/README.rdoc
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
A simple backup utility to create time based snapshots similar to time machine on s3.
|
2
|
-
All options are command line based so they can easily be scripted with cron.
|
3
|
-
Supports multiple daily backups, as well as rolling daily and weekly.
|
4
|
-
For daily, it keeps the newest complete backup for the day, for weekly it keeps the last day in the week.
|
5
|
-
|
6
|
-
Note that this should only be run on machines with the *nix split command available. May work on windows with cygwin, but is untested.
|
7
|
-
If a file is over 5GB, the only way to upload it to S3 is to use multipart uploads. To split the file into parts, s3snapshot relies on the split command. The file parts are uploaded sequentially, so there is no speed boost in using multipart upload. s3snapshot is developed on MRI 1.8.7 so multi thread upload does not work.
|