s3gb 0.1.0
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.
- data/.gitignore +3 -0
- data/Rakefile +16 -0
- data/Readme.md +36 -0
- data/VERSION +1 -0
- data/bin/s3gb +19 -0
- data/lib/s3gb/base.rb +59 -0
- data/lib/s3gb/jgit.rb +56 -0
- data/lib/s3gb/s3fs.rb +36 -0
- data/lib/s3gb.rb +18 -0
- metadata +70 -0
data/.gitignore
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
project_name = 's3gb'
|
4
|
+
|
5
|
+
Jeweler::Tasks.new do |gem|
|
6
|
+
gem.name = project_name
|
7
|
+
gem.summary = "Backup stuff versioned in git to s3"
|
8
|
+
gem.email = "grosser.michael@gmail.com"
|
9
|
+
gem.homepage = "http://github.com/grosser/#{project_name}"
|
10
|
+
gem.authors = ["Michael Grosser"]
|
11
|
+
end
|
12
|
+
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
|
16
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
Collects all your stuff into a git repo, commits all changes, pushes it to s3.
|
2
|
+
|
3
|
+
Install
|
4
|
+
=======
|
5
|
+
|
6
|
+
sudo gem install s3gb
|
7
|
+
|
8
|
+
make a ~/s3gb/config.yml file in your home folder.
|
9
|
+
Enter your config: [Your S3 keys](https://www.amazon.com/ap/signin?openid.ns=http://specs.openid.net/auth/2.0&authCookies=1&openid.mode=checkid_setup&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.pape.max_auth_age=600&openid.return_to=https://www.amazon.com/gp/aws/ssop/handlers/auth-portal.html%3Fie%3DUTF8%26wreply%3Dhttps%253A%252F%252Faws-portal.amazon.com%252Fgp%252Faws%252Fdeveloper%252Faccount%252Findex.html%26awsrequestchallenge%3Dfalse%26wtrealm%3Durn%253Aaws%253AawsAccessKeyId%253A1QQFCEAYKJXP0J7S2T02%26wctx%3DactionpRmaccess-keypRm%26awsaccountstatuspolicy%3DP1%26wa%3Dwsignin1.0%26awsrequesttfa%3Dtrue&openid.assoc_handle=ssop&openid.pape.preferred_auth_policies=http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical&openid.ns.pape=http://specs.openid.net/extensions/pape/1.0&accountStatusPolicy=P1&)
|
10
|
+
bucket: s3gb
|
11
|
+
accessKeyId: --your--key--
|
12
|
+
secretAccessKey: --your--key--
|
13
|
+
acl: private
|
14
|
+
strategy: jgit
|
15
|
+
cache: ~/.s3gb_cache
|
16
|
+
sync:
|
17
|
+
- ~/.ssh
|
18
|
+
- ~/bin
|
19
|
+
- /opt/nginx/conf/nginx.conf
|
20
|
+
- ...
|
21
|
+
exclude:
|
22
|
+
- cache
|
23
|
+
- Cache
|
24
|
+
- .git
|
25
|
+
|
26
|
+
Then:
|
27
|
+
|
28
|
+
- create the bucket using e.g. S3Fox AND add a .git folder to it
|
29
|
+
- `sudo s3gb --install` to install dependencies for your chosen strategy
|
30
|
+
- `s3gb --backup`
|
31
|
+
|
32
|
+
Author
|
33
|
+
======
|
34
|
+
[Michael Grosser](http://pragmatig.wordpress.com)
|
35
|
+
grosser.michael@gmail.com
|
36
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/s3gb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
$LOAD_PATH << File.expand_path(__FILE__+"/../../lib")
|
6
|
+
require 's3gb'
|
7
|
+
|
8
|
+
options = {}
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = <<BANNER
|
11
|
+
Options are:
|
12
|
+
BANNER
|
13
|
+
opts.on("--install", "Install SUDO!") { S3gb.build.install; exit }
|
14
|
+
opts.on("--backup", "Backup given folders with a new commit") { S3gb.build.backup; exit }
|
15
|
+
opts.on("--prepare", "Prepare for backup") { S3gb.build.prepare; exit }
|
16
|
+
opts.on('--collect', 'Collect files into cache'){ S3gb.build.collect_files; exit }
|
17
|
+
opts.on('--commit', 'Commit'){ S3gb.build.commit_changes; exit }
|
18
|
+
opts.on('--push', 'Push changes to s3'){ S3gb.build.push; exit }
|
19
|
+
end.parse!
|
data/lib/s3gb/base.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
class S3gb
|
4
|
+
class Base
|
5
|
+
attr_accessor :config
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def backup
|
11
|
+
prepare
|
12
|
+
collect_files
|
13
|
+
commit_changes
|
14
|
+
push
|
15
|
+
end
|
16
|
+
|
17
|
+
def collect_files
|
18
|
+
with_exclude_file do |excludes|
|
19
|
+
config['sync'].each do |path|
|
20
|
+
puts "now comes #{path}"
|
21
|
+
full_path = "#{cache_dir}#{File.dirname(path)}"
|
22
|
+
ensure_dir full_path
|
23
|
+
`rsync -avz --delete --exclude-from #{excludes} #{path} #{full_path}`
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def commit_changes
|
29
|
+
ensure_git_repo
|
30
|
+
`cd #{cache_dir} && git add . && git commit -m "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"`
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def ensure_git_repo
|
36
|
+
`cd #{cache_dir} && git init` unless File.exist?("#{cache_dir}/.git")
|
37
|
+
end
|
38
|
+
|
39
|
+
def with_exclude_file
|
40
|
+
Tempfile.open('foo') do |t|
|
41
|
+
t.write config['exclude'] * "\n"
|
42
|
+
t.close
|
43
|
+
yield t.path
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_dir(dir)
|
48
|
+
`mkdir -p #{dir}` unless File.exist?(dir)
|
49
|
+
end
|
50
|
+
|
51
|
+
def cache_dir
|
52
|
+
@cache_dir ||= begin
|
53
|
+
dir = File.expand_path("~/.s3gb/cache")
|
54
|
+
ensure_dir dir
|
55
|
+
dir
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/s3gb/jgit.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 's3gb/base'
|
2
|
+
|
3
|
+
class S3gb
|
4
|
+
class JGit < S3gb::Base
|
5
|
+
def install
|
6
|
+
require 'open-uri'
|
7
|
+
page = open('http://www.eclipse.org/jgit/download/').read
|
8
|
+
url = page.match(/"(.*?org.eclipse.jgit.*?.sh)"/)[1]
|
9
|
+
file = File.basename(url)
|
10
|
+
to = '/usr/bin/jgit'
|
11
|
+
`sudo rm #{to}`
|
12
|
+
`cd /tmp && rm #{file} ; wget #{url} && sudo mv #{file} #{to} && sudo chmod 755 #{to}`
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
ensure_jgit_config
|
17
|
+
ensure_jgit_repo
|
18
|
+
end
|
19
|
+
|
20
|
+
def push
|
21
|
+
cmd "cd #{cache_dir} && jgit push s3 refs/heads/master"
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def jgit_s3
|
27
|
+
File.expand_path('~/.jgit_s3')
|
28
|
+
end
|
29
|
+
|
30
|
+
def ensure_jgit_repo
|
31
|
+
return if File.exist? "#{cache_dir}/.git"
|
32
|
+
out = cmd "cd #{File.dirname(cache_dir)} && jgit clone -o s3 #{public_s3_url} #{File.basename cache_dir} && echo COMPLETE"
|
33
|
+
return if out.include?('COMPLETE')
|
34
|
+
cmd "cd #{cache_dir} && git init && git remote add s3 #{s3_url}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def s3_url
|
38
|
+
"amazon-s3://.jgit_s3@#{config['bucket']}/.git"
|
39
|
+
end
|
40
|
+
|
41
|
+
def public_s3_url
|
42
|
+
"http://#{config['bucket']}.s3.amazonaws.com/.git"
|
43
|
+
end
|
44
|
+
|
45
|
+
def cmd x
|
46
|
+
puts x
|
47
|
+
`#{x}`
|
48
|
+
end
|
49
|
+
|
50
|
+
def ensure_jgit_config
|
51
|
+
File.open(jgit_s3, 'w') do |f|
|
52
|
+
f.write "accesskey: #{config['accessKeyId']}\nsecretkey: #{config['secretAccessKey']}\nacl: #{config['acl']||'private'}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/s3gb/s3fs.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 's3gb/base'
|
2
|
+
|
3
|
+
class S3gb
|
4
|
+
class S3fs < S3gb::Base
|
5
|
+
def prepare
|
6
|
+
`mkdir #{mount_dir}` unless File.exist?(mount_dir)
|
7
|
+
`/usr/bin/s3fs #{config['bucket']} -o accessKeyId=#{config['accessKeyId']} -o secretAccessKey=#{config['secretAccessKey']} #{mount_dir}`
|
8
|
+
end
|
9
|
+
|
10
|
+
def install
|
11
|
+
`sudo apt-get install build-essential libcurl4-openssl-dev libxml2-dev libfuse-dev`
|
12
|
+
require 'open-uri'
|
13
|
+
url = "http://code.google.com/p/s3fs"
|
14
|
+
page = open(url).read
|
15
|
+
path = page.match(%r{href="(.*?-source\.tar\.gz)"})[1]
|
16
|
+
url = "http://s3fs.googlecode.com/files/#{path.split('=').last}"
|
17
|
+
puts "installing from #{url}"
|
18
|
+
`cd /tmp && wget #{url} && tar -xzf s3fs* && cd s3fs && make && sudo make install`
|
19
|
+
end
|
20
|
+
|
21
|
+
def push
|
22
|
+
Dir.glob("#{cache_dir}/*", File::FNM_DOTMATCH).each do |sub_path|
|
23
|
+
sub_path = File.basename(sub_path)
|
24
|
+
next if ['.','..'].include?(sub_path)
|
25
|
+
puts "syncing #{sub_path}"
|
26
|
+
`/usr/bin/rsync -avz --delete #{cache_dir}/#{sub_path} #{mount_dir}`
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def mount_dir
|
33
|
+
File.expand_path("~/.s3gb/fs")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/s3gb.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class S3gb
|
4
|
+
def self.build
|
5
|
+
config = YAML.load(File.read(File.expand_path('~/.s3gb/config.yml')))
|
6
|
+
|
7
|
+
strategy = case config['strategy'].downcase
|
8
|
+
when 'jgit', nil then
|
9
|
+
require 's3gb/jgit'
|
10
|
+
JGit
|
11
|
+
when 's3fs' then
|
12
|
+
require 's3gb/s3fs'
|
13
|
+
S3fs
|
14
|
+
end
|
15
|
+
|
16
|
+
strategy.new config
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s3gb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Michael Grosser
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-09 00:00:00 +02:00
|
18
|
+
default_executable: s3gb
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: grosser.michael@gmail.com
|
23
|
+
executables:
|
24
|
+
- s3gb
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- .gitignore
|
31
|
+
- Rakefile
|
32
|
+
- Readme.md
|
33
|
+
- VERSION
|
34
|
+
- bin/s3gb
|
35
|
+
- lib/s3gb.rb
|
36
|
+
- lib/s3gb/base.rb
|
37
|
+
- lib/s3gb/jgit.rb
|
38
|
+
- lib/s3gb/s3fs.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/grosser/s3gb
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.6
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Backup stuff versioned in git to s3
|
69
|
+
test_files: []
|
70
|
+
|