akupchanko-astrails-safe 0.3.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +3 -0
  3. data/.document +5 -0
  4. data/.gitignore +18 -0
  5. data/.rspec +3 -0
  6. data/CHANGELOG +35 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.markdown +250 -0
  10. data/Rakefile +8 -0
  11. data/TODO +31 -0
  12. data/akupchanko-astrails-safe.gemspec +35 -0
  13. data/bin/astrails-safe +64 -0
  14. data/lib/astrails/safe.rb +68 -0
  15. data/lib/astrails/safe/archive.rb +24 -0
  16. data/lib/astrails/safe/backup.rb +20 -0
  17. data/lib/astrails/safe/cloudfiles.rb +77 -0
  18. data/lib/astrails/safe/config/builder.rb +90 -0
  19. data/lib/astrails/safe/config/node.rb +72 -0
  20. data/lib/astrails/safe/ftp.rb +104 -0
  21. data/lib/astrails/safe/gpg.rb +46 -0
  22. data/lib/astrails/safe/gzip.rb +25 -0
  23. data/lib/astrails/safe/local.rb +51 -0
  24. data/lib/astrails/safe/mongodump.rb +23 -0
  25. data/lib/astrails/safe/mysqldump.rb +32 -0
  26. data/lib/astrails/safe/pgdump.rb +36 -0
  27. data/lib/astrails/safe/pipe.rb +17 -0
  28. data/lib/astrails/safe/s3.rb +80 -0
  29. data/lib/astrails/safe/sftp.rb +88 -0
  30. data/lib/astrails/safe/sink.rb +35 -0
  31. data/lib/astrails/safe/source.rb +47 -0
  32. data/lib/astrails/safe/stream.rb +32 -0
  33. data/lib/astrails/safe/svndump.rb +13 -0
  34. data/lib/astrails/safe/tmp_file.rb +48 -0
  35. data/lib/astrails/safe/version.rb +5 -0
  36. data/lib/extensions/mktmpdir.rb +45 -0
  37. data/spec/astrails/safe/archive_spec.rb +67 -0
  38. data/spec/astrails/safe/cloudfiles_spec.rb +175 -0
  39. data/spec/astrails/safe/config_spec.rb +307 -0
  40. data/spec/astrails/safe/gpg_spec.rb +148 -0
  41. data/spec/astrails/safe/gzip_spec.rb +64 -0
  42. data/spec/astrails/safe/local_spec.rb +109 -0
  43. data/spec/astrails/safe/mongodump_spec.rb +54 -0
  44. data/spec/astrails/safe/mysqldump_spec.rb +83 -0
  45. data/spec/astrails/safe/pgdump_spec.rb +45 -0
  46. data/spec/astrails/safe/s3_spec.rb +168 -0
  47. data/spec/astrails/safe/svndump_spec.rb +39 -0
  48. data/spec/integration/archive_integration_spec.rb +89 -0
  49. data/spec/integration/cleanup_spec.rb +62 -0
  50. data/spec/spec_helper.rb +8 -0
  51. data/templates/script.rb +183 -0
  52. metadata +178 -0
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Astrails::Safe::Pgdump do
4
+
5
+ def def_config
6
+ {
7
+ :options => "OPTS",
8
+ :user => "User",
9
+ :password => "pwd",
10
+ :host => "localhost",
11
+ :port => 7777,
12
+ :skip_tables => [:bar, :baz]
13
+ }
14
+ end
15
+
16
+ def pgdump(id = :foo, config = def_config)
17
+ Astrails::Safe::Pgdump.new(id, Astrails::Safe::Config::Node.new(nil, config))
18
+ end
19
+
20
+ before(:each) do
21
+ stub(Time).now.stub!.strftime {"NOW"}
22
+ end
23
+
24
+ after(:each) { Astrails::Safe::TmpFile.cleanup }
25
+
26
+ describe :backup do
27
+ before(:each) do
28
+ @pg = pgdump
29
+ end
30
+
31
+ {
32
+ :id => "foo",
33
+ :kind => "pgdump",
34
+ :extension => ".sql",
35
+ :filename => "pgdump-foo.NOW",
36
+ :command => "pg_dump OPTS --username='User' --host='localhost' --port='7777' foo",
37
+ }.each do |k, v|
38
+ it "should set #{k} to #{v}" do
39
+ @pg.backup.send(k).should == v
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+
3
+ describe Astrails::Safe::S3 do
4
+
5
+ def def_config
6
+ {
7
+ :s3 => {
8
+ :bucket => "_bucket",
9
+ :key => "_key",
10
+ :secret => "_secret",
11
+ },
12
+ :keep => {
13
+ :s3 => 2
14
+ }
15
+ }
16
+ end
17
+
18
+ def def_backup(extra = {})
19
+ {
20
+ :kind => "_kind",
21
+ :filename => "/backup/somewhere/_kind-_id.NOW.bar",
22
+ :extension => ".bar",
23
+ :id => "_id",
24
+ :timestamp => "NOW"
25
+ }.merge(extra)
26
+ end
27
+
28
+ def s3(config = def_config, backup = def_backup)
29
+ Astrails::Safe::S3.new(
30
+ Astrails::Safe::Config::Node.new.merge(config),
31
+ Astrails::Safe::Backup.new(backup)
32
+ )
33
+ end
34
+
35
+ describe :cleanup do
36
+
37
+ before(:each) do
38
+ @s3 = s3
39
+
40
+ @files = [4,1,3,2].map { |i| stub(o = {}).key {"aaaaa#{i}"}; o }
41
+
42
+ stub(AWS::S3::Bucket).objects("_bucket", :prefix => "_kind/_id/_kind-_id.", :max_keys => 4) {@files}
43
+ stub(AWS::S3::Bucket).objects("_bucket", :prefix => anything).stub![0].stub!.delete
44
+ end
45
+
46
+ it "should check [:keep, :s3]" do
47
+ @s3.config[:keep].data["s3"] = nil
48
+ dont_allow(@s3.backup).filename
49
+ @s3.send :cleanup
50
+ end
51
+
52
+ it "should delete extra files" do
53
+ mock(AWS::S3::Bucket).objects("_bucket", :prefix => "aaaaa1").mock![0].mock!.delete
54
+ mock(AWS::S3::Bucket).objects("_bucket", :prefix => "aaaaa2").mock![0].mock!.delete
55
+ @s3.send :cleanup
56
+ end
57
+
58
+ end
59
+
60
+ describe :active do
61
+ before(:each) do
62
+ @s3 = s3
63
+ end
64
+
65
+ it "should be true when all params are set" do
66
+ @s3.should be_active
67
+ end
68
+
69
+ it "should be false if bucket is missing" do
70
+ @s3.config[:s3].data["bucket"] = nil
71
+ @s3.should_not be_active
72
+ end
73
+
74
+ it "should be false if key is missing" do
75
+ @s3.config[:s3].data["key"] = nil
76
+ @s3.should_not be_active
77
+ end
78
+
79
+ it "should be false if secret is missing" do
80
+ @s3.config[:s3].data["secret"] = nil
81
+ @s3.should_not be_active
82
+ end
83
+ end
84
+
85
+ describe :path do
86
+ before(:each) do
87
+ @s3 = s3
88
+ end
89
+ it "should use s3/path 1st" do
90
+ @s3.config[:s3].data["path"] = "s3_path"
91
+ @s3.config[:local] = {:path => "local_path"}
92
+ @s3.send(:path).should == "s3_path"
93
+ end
94
+
95
+ it "should use local/path 2nd" do
96
+ @s3.config.merge local: {path: "local_path"}
97
+ @s3.send(:path).should == "local_path"
98
+ end
99
+
100
+ it "should use constant 3rd" do
101
+ @s3.send(:path).should == "_kind/_id"
102
+ end
103
+
104
+ end
105
+
106
+ describe :save do
107
+ def add_stubs(*stubs)
108
+ stubs.each do |s|
109
+ case s
110
+ when :connection
111
+ stub(AWS::S3::Base).establish_connection!(:access_key_id => "_key", :secret_access_key => "_secret", :use_ssl => true)
112
+ when :stat
113
+ stub(File).stat("foo").stub!.size {123}
114
+ when :create_bucket
115
+ stub(AWS::S3::Bucket).find('_bucket') { raise_error AWS::S3::NoSuchBucket }
116
+ stub(AWS::S3::Bucket).create
117
+ when :file_open
118
+ stub(File).open("foo") {|f, block| block.call(:opened_file)}
119
+ when :s3_store
120
+ stub(AWS::S3::S3Object).store(@full_path, :opened_file, "_bucket")
121
+ end
122
+ end
123
+ end
124
+
125
+ before(:each) do
126
+ @s3 = s3(def_config, def_backup(:path => "foo"))
127
+ @full_path = "_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar"
128
+ end
129
+
130
+ it "should fail if no backup.file is set" do
131
+ @s3.backup.path = nil
132
+ proc {@s3.send(:save)}.should raise_error(RuntimeError)
133
+ end
134
+
135
+ it "should establish s3 connection" do
136
+ mock(AWS::S3::Base).establish_connection!(:access_key_id => "_key", :secret_access_key => "_secret", :use_ssl => true)
137
+ add_stubs(:stat, :create_bucket, :file_open, :s3_store)
138
+ @s3.send(:save)
139
+ end
140
+
141
+ it "should open local file" do
142
+ add_stubs(:connection, :stat, :create_bucket)
143
+ mock(File).open("foo")
144
+ @s3.send(:save)
145
+ end
146
+
147
+ it "should upload file" do
148
+ add_stubs(:connection, :stat, :create_bucket, :file_open)
149
+ mock(AWS::S3::S3Object).store(@full_path, :opened_file, "_bucket")
150
+ @s3.send(:save)
151
+ end
152
+
153
+ it "should fail on files bigger then 5G" do
154
+ add_stubs(:connection)
155
+ mock(File).stat("foo").stub!.size {5*1024*1024*1024+1}
156
+ mock(STDERR).puts(anything)
157
+ dont_allow(Benchmark).realtime
158
+ @s3.send(:save)
159
+ end
160
+
161
+ it 'should not create a bucket that already exists' do
162
+ add_stubs(:connection, :stat, :file_open, :s3_store)
163
+ stub(AWS::S3::Bucket).find('_bucket') { true }
164
+ dont_allow(AWS::S3::Bucket).create
165
+ @s3.send(:save)
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Astrails::Safe::Svndump do
4
+ def def_config
5
+ {
6
+ :options => "OPTS",
7
+ :repo_path => "bar/baz"
8
+ }
9
+ end
10
+
11
+ def svndump(id = :foo, config = def_config)
12
+ Astrails::Safe::Svndump.new(id, Astrails::Safe::Config::Node.new(nil, config))
13
+ end
14
+
15
+ before(:each) do
16
+ stub(Time).now.stub!.strftime {"NOW"}
17
+ end
18
+
19
+ after(:each) { Astrails::Safe::TmpFile.cleanup }
20
+
21
+ describe :backup do
22
+ before(:each) do
23
+ @svn = svndump
24
+ end
25
+
26
+ {
27
+ :id => "foo",
28
+ :kind => "svndump",
29
+ :extension => ".svn",
30
+ :filename => "svndump-foo.NOW",
31
+ :command => "svnadmin dump OPTS bar/baz",
32
+ }.each do |k, v|
33
+ it "should set #{k} to #{v}" do
34
+ @svn.backup.send(k).should == v
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ require "fileutils"
4
+ include FileUtils
5
+
6
+ describe "tar backup" do
7
+ before(:all) do
8
+ # need both local and instance vars
9
+ # instance variables are used in tests
10
+ # local variables are used in the backup definition (instance vars can't be seen)
11
+ @root = root = "tmp/archive_backup_example"
12
+
13
+ # clean state
14
+ rm_rf @root
15
+ mkdir_p @root
16
+
17
+ # create source tree
18
+ @src = src = "#{@root}/src"
19
+ mkdir_p "#{@src}/q/w/e"
20
+ mkdir_p "#{@src}/a/s/d"
21
+
22
+ File.open("#{@src}/qwe1", "w") {|f| f.write("qwe") }
23
+ File.open("#{@src}/q/qwe2", "w") {|f| f.write("qwe"*2) }
24
+ File.open("#{@src}/q/w/qwe3", "w") {|f| f.write("qwe"*3) }
25
+ File.open("#{@src}/q/w/e/qwe4", "w") {|f| f.write("qwe"*4) }
26
+
27
+ File.open("#{@src}/asd1", "w") {|f| f.write("asd") }
28
+ File.open("#{@src}/a/asd2", "w") {|f| f.write("asd" * 2) }
29
+ File.open("#{@src}/a/s/asd3", "w") {|f| f.write("asd" * 3) }
30
+
31
+ @dst = dst = "#{@root}/backup"
32
+ mkdir_p @dst
33
+
34
+ @now = Time.now
35
+ @timestamp = @now.strftime("%y%m%d-%H%M")
36
+
37
+ stub(Time).now {@now} # Freeze
38
+
39
+ config = Astrails::Safe.safe do
40
+ local :path => "#{dst}/:kind"
41
+ tar do
42
+ archive :test1 do
43
+ files src
44
+ exclude "#{src}/q/w"
45
+ exclude "#{src}/q/w/e"
46
+ end
47
+ end
48
+ end
49
+ Astrails::Safe.process config
50
+
51
+ @backup = "#{dst}/archive/archive-test1.#{@timestamp}.tar.gz"
52
+ end
53
+
54
+ it "should create backup file" do
55
+ File.exists?(@backup).should be_true
56
+ end
57
+
58
+ describe "after extracting" do
59
+ before(:all) do
60
+ # prepare target dir
61
+ @target = "#{@root}/test"
62
+ mkdir_p @target
63
+ system "tar -zxvf #{@backup} -C #{@target}"
64
+
65
+ @test = "#{@target}/#{@root}/src"
66
+ puts @test
67
+ end
68
+
69
+ it "should include asd1/2/3" do
70
+ File.exists?("#{@test}/asd1").should be_true
71
+ File.exists?("#{@test}/a/asd2").should be_true
72
+ File.exists?("#{@test}/a/s/asd3").should be_true
73
+ end
74
+
75
+ it "should only include qwe 1 and 2 (no 3)" do
76
+ File.exists?("#{@test}/qwe1").should be_true
77
+ File.exists?("#{@test}/q/qwe2").should be_true
78
+ File.exists?("#{@test}/q/w/qwe3").should be_false
79
+ File.exists?("#{@test}/q/w/e/qwe4").should be_false
80
+ end
81
+
82
+ it "should preserve file content" do
83
+ File.read("#{@test}/qwe1").should == "qwe"
84
+ File.read("#{@test}/q/qwe2").should == "qweqwe"
85
+ File.read("#{@test}/a/s/asd3").should == "asdasdasd"
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ require "fileutils"
4
+ include FileUtils
5
+
6
+ describe "tar backup" do
7
+ before(:all) do
8
+ # need both local and instance vars
9
+ # instance variables are used in tests
10
+ # local variables are used in the backup definition (instance vars can't be seen)
11
+ @root = root = "tmp/cleanup_example"
12
+
13
+ # clean state
14
+ rm_rf @root
15
+ mkdir_p @root
16
+
17
+ # create source tree
18
+ @src = src = "#{@root}/src"
19
+ mkdir_p src
20
+
21
+ File.open(qwe = "#{@src}/qwe", "w") {|f| f.write("qwe") }
22
+
23
+ @dst = dst = "#{@root}/backup"
24
+ mkdir_p "#{@dst}/archive"
25
+
26
+ @now = Time.now
27
+ @timestamp = @now.strftime("%y%m%d-%H%M")
28
+
29
+ stub(Time).now {@now} # Freeze
30
+
31
+ cp qwe, "#{dst}/archive/archive-foo.000001.tar.gz"
32
+ cp qwe, "#{dst}/archive/archive-foo.000002.tar.gz"
33
+ cp qwe, "#{dst}/archive/archive-foobar.000001.tar.gz"
34
+ cp qwe, "#{dst}/archive/archive-foobar.000002.tar.gz"
35
+
36
+ config = Astrails::Safe.safe do
37
+ local :path => "#{dst}/:kind"
38
+ tar do
39
+ keep :local => 1 # only leave the latest
40
+ archive :foo do
41
+ files src
42
+ end
43
+ end
44
+ end
45
+ Astrails::Safe.process config
46
+
47
+ @backup = "#{dst}/archive/archive-foo.#{@timestamp}.tar.gz"
48
+ end
49
+
50
+ it "should create backup file" do
51
+ File.exists?(@backup).should be_true
52
+ end
53
+
54
+ it "should remove old backups" do
55
+ Dir["#{@dst}/archive/archive-foo.*"].should == [@backup]
56
+ end
57
+
58
+ it "should NOT remove backups with base having same prefix" do
59
+ Dir["#{@dst}/archive/archive-foobar.*"].sort.should == ["#{@dst}/archive/archive-foobar.000001.tar.gz", "#{@dst}/archive/archive-foobar.000002.tar.gz"]
60
+ end
61
+
62
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'astrails/safe'
4
+ require 'debugger'
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :rr
8
+ end
@@ -0,0 +1,183 @@
1
+ safe do
2
+ # same as --verbose on the command line
3
+ # verbose true
4
+
5
+ # same as --local on the command line
6
+ # local_only true
7
+
8
+ # same as --dry-run on the command line
9
+ # dry_run true
10
+
11
+ # backup file path (not including filename)
12
+ # supported substitutions:
13
+ # :kind -> backup 'engine' kind, e.g. "mysqldump" or "archive"
14
+ # :id -> backup 'id', e.g. "blog", "production", etc.
15
+ # :timestamp -> current run timestamp (same for all the backups in the same 'run')
16
+ # you can set separate :path for all backups (or once globally here)
17
+ local do
18
+ path "/backup/:kind"
19
+ end
20
+
21
+ ## uncomment to enable uploads to Amazon S3
22
+ ## Amazon S3 auth (optional)
23
+ # s3 do
24
+ # key YOUR_S3_KEY
25
+ # secret YOUR_S3_SECRET
26
+ # bucket S3_BUCKET
27
+ # # path for uploads to S3. supports same substitution like :local/:path
28
+ # path ":kind/" # this is default
29
+ # end
30
+
31
+ ## alternative style:
32
+ # s3 :key => YOUR_S3_KEY, :secret => YOUR_S3_SECRET, :bucket => S3_BUCKET, :path => ":kind/"
33
+
34
+ ## uncomment to enable uploads to Rackspace Cloud Files
35
+ ## http://www.rackspacecloud.com/cloud_hosting_products/files
36
+ ## Rackspace auth (optional)
37
+ # cloudfiles do
38
+ # user "YOUR_RACKSPACE_CLOUD_USERNAME"
39
+ # api_key "YOUR_RACKSPACE_API_KEY"
40
+ # container "YOUR_CONTAINER_NAME"
41
+ # # path for uploads to Cloud Files, supports same substitution like :local/:path
42
+ # path ":kind/" # this is default
43
+ # # If you are running the backup from a system within the Rackspace/Slicehost network and would like
44
+ # # to back up over the private (unbilled) service net, set this value to true.
45
+ # # service_net true
46
+ # end
47
+
48
+ ## uncomment to enable uploads via SFTP
49
+ # sftp do
50
+ # host "YOUR_REMOTE_HOSTNAME"
51
+ # user "YOUR_REMOTE_USERNAME"
52
+ # # port "NON STANDARD SSH PORT"
53
+ # password "YOUR_REMOTE_PASSWORD"
54
+ # path ":kind/:id" # this is the default
55
+ # end
56
+
57
+ ## uncomment to enable uploads via FTP
58
+ # ftp do
59
+ # host "YOUR_REMOTE_HOSTNAME"
60
+ # user "YOUR_REMOTE_USERNAME"
61
+ # # port "NON STANDARD FTP PORT"
62
+ # password "YOUR_REMOTE_PASSWORD"
63
+ # path ":kind/:id" # this is the default
64
+ # end
65
+
66
+ ## uncomment to enable GPG encryption.
67
+ ## Note: you can use public 'key' or symmetric password but not both!
68
+ # gpg do
69
+ # # you can specify your own gpg executable with the 'command' options
70
+ # # this can be useful for example to choose b/w gpg and gpg2 if both are installed
71
+ # # some gpg installations will automatically set 'use-agent' option in the
72
+ # # config file on the 1st run. see README for more details
73
+ # options "--no-use-agent"
74
+ # # command "/usr/local/bin/gpg"
75
+ # # key "backup@astrails.com"
76
+ # password "astrails"
77
+ # end
78
+
79
+ ## uncomment to enable backup rotation. keep only given number of latest
80
+ ## backups. remove the rest
81
+ # keep do
82
+ # local 4 # keep 4 local backups
83
+ # s3 20 # keep 20 S3 backups
84
+ # end
85
+
86
+ # backup mysql databases with mysqldump
87
+ mysqldump do
88
+ # you can override any setting from parent in a child:
89
+ options "-ceKq --single-transaction --create-options"
90
+
91
+ user "astrails"
92
+ password ""
93
+ # host "localhost"
94
+ # port 3306
95
+ socket "/var/run/mysqld/mysqld.sock"
96
+
97
+ # database is a 'collection' element. it must have a hash or block parameter
98
+ # it will be 'collected' in a 'databases', with database id (1st arg) used as hash key
99
+ # the following code will create mysqldump/databases/blog and mysqldump/databases/mysql configuration 'nodes'
100
+
101
+ # backup database with default values
102
+ # database :blog
103
+
104
+ # backup overriding some values
105
+ # database :production do
106
+ # # you can override 'partially'
107
+ # keep :local => 3
108
+ # # keep/local is 3, and keep/s3 is 20 (from parent)
109
+
110
+ # # local override for gpg password
111
+ # gpg do
112
+ # password "custom-production-pass"
113
+ # end
114
+ # # skip those tables during backup
115
+ # # you can pass an array
116
+ # skip_tables [:logger_exceptions, :request_logs]
117
+ # # or pass them all separately
118
+ # skip_tables :test1
119
+ # skip_tables :test2
120
+ # end
121
+
122
+ end
123
+
124
+ # # uncomment to enable
125
+ # # backup PostgreSQL databases with pg_dump
126
+ # pgdump do
127
+ # options "-i -x -O"
128
+ #
129
+ # user "markmansour"
130
+ # # password "" - leave this out if you have ident setup
131
+ #
132
+ # # database is a 'collection' element. it must have a hash or block parameter
133
+ # # it will be 'collected' in a 'databases', with database id (1st arg) used as hash key
134
+ # database :blog
135
+ # database :production
136
+ # end
137
+
138
+ tar do
139
+ # options "-h" # uncomment this to dereference symbolic links
140
+
141
+ # 'archive' is a collection item, just like 'database'
142
+ # archive "git-repositories" do
143
+ # # files and directories to backup
144
+ # files "/home/git/repositories"
145
+ # # can have more then one 'files' lines or/and use an array
146
+ # files ["/home/dev/work/foo", "/home/dev/work/bar"]
147
+ # end
148
+
149
+ # archive "etc-files" do
150
+ # files "/etc"
151
+ # # exlude those files/directories
152
+ # exclude "/etc/puppet/other"
153
+ # # can have multiple 'exclude' lines or/and use an array
154
+ # exclude ["/etc/tmp/a", "/etc/tmp/b"]
155
+ # end
156
+
157
+ # archive "dot-configs" do
158
+ # files "/home/*/.[^.]*"
159
+ # end
160
+
161
+ # archive "blog" do
162
+ # files "/var/www/blog.astrails.com/"
163
+ # # specify multiple files/directories as array
164
+ # exclude ["/var/www/blog.astrails.com/log", "/var/www/blog.astrails.com/tmp"]
165
+ # end
166
+
167
+ # archive "site" do
168
+ # files "/var/www/astrails.com/"
169
+ # exclude ["/var/www/astrails.com/log", "/var/www/astrails.com/tmp"]
170
+ # end
171
+
172
+ # archive :misc do
173
+ # files [ "/backup/*.rb" ]
174
+ # end
175
+ end
176
+
177
+ # svndump do
178
+ # repo :my_repo do
179
+ # repo_path "/home/svn/my_repo"
180
+ # end
181
+ # end
182
+
183
+ end