yore 0.0.1 → 0.0.2

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/Manifest.txt CHANGED
@@ -14,9 +14,6 @@ README.rdoc
14
14
  script/console
15
15
  script/destroy
16
16
  script/generate
17
- spec/rewind_spec.rb
18
- spec/spec.opts
19
- spec/spec_helper.rb
20
- spec/test_job_a.xml
21
- spec/yore_spec.rb
22
- tasks/rspec.rake
17
+ test/test_job_a.xml
18
+ test/test_job_b.xml
19
+ test/yore_test.rb
data/README.rdoc CHANGED
@@ -1,32 +1,43 @@
1
1
  = yore
2
2
 
3
- * FIX (url)
3
+ * RubyForge Project : http://rubyforge.org/projects/buzzware
4
+ * Author : http://www.buzzware.com.au
4
5
 
5
6
  == DESCRIPTION:
6
7
 
7
- FIX (describe your package)
8
+ yore (as in "days of yore") is hands-off scheduled backup utility designed for web servers.
9
+ It does backups of files and databases (MySQL only at present) to Amazon S3.
8
10
 
9
11
  == FEATURES/PROBLEMS:
10
12
 
11
- * FIX (list of features or problems)
13
+ * Compressed, encrypted, single file backups of folders and mysql databases
14
+ * Designed to be called regularly
15
+ * Backups are uploaded to Amazon S3
16
+ * will later remove old files that don't match the configurable scheme for backup history
12
17
 
13
18
  == SYNOPSIS:
14
19
 
15
- FIX (code sample of usage)
20
+ yore backup yore_config.xml
16
21
 
17
22
  == REQUIREMENTS:
18
23
 
19
- * FIX (list of requirements)
24
+ * s3sync (http://rubyforge.org/projects/s3sync/)
25
+ * RequirePaths (http://rubyforge.org/projects/blackwhitelogin)
26
+ * cmdparse (http://cmdparse.rubyforge.org)
27
+ * shairontoledo-popen4 (http://github.com/shairontoledo/popen4)
28
+ * tar, bzip2, openssl, mysql
29
+ * tested on MacOS and Linux
20
30
 
21
31
  == INSTALL:
22
32
 
23
- * FIX (sudo gem install, anything else)
33
+ sudo gem sources -a http://gems.github.com
34
+ sudo gem install yore
24
35
 
25
36
  == LICENSE:
26
37
 
27
38
  (The MIT License)
28
39
 
29
- Copyright (c) 2009 FIXME full name
40
+ Copyright (c) 2009 Gary McGhee, Buzzware Solutions
30
41
 
31
42
  Permission is hereby granted, free of charge, to any person obtaining
32
43
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,12 +1,11 @@
1
1
  require 'rubygems'
2
2
  require 'rake/rdoctask'
3
3
  require 'rake/testtask'
4
- require 'spec/rake/spectask'
5
4
  %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
6
5
  require File.dirname(__FILE__) + '/lib/yore.orig'
7
6
 
8
7
  # built following http://newgem.rubyforge.org/
9
- # using RSpec option
8
+ # using RSpec option (later converted to shoulda)
10
9
  # and had to add processor_ids from dr nic :
11
10
  # http://groups.google.com/group/new-gem-generator/browse_thread/thread/648f70da782e607a/928ea0fe8319d886?lnk=raot
12
11
 
@@ -20,7 +19,8 @@ $hoe = Hoe.new('yore', Yore::VERSION) do |p|
20
19
  p.extra_deps = [
21
20
  ['RequirePaths','>= 1.0.1'],
22
21
  ['cmdparse', '>= 2.0.2'],
23
- ['s3sync', '>= 1.2.5']
22
+ ['s3sync', '>= 1.2.5'],
23
+ ['shairontoledo-popen4', '>= 0.1.2']
24
24
  ]
25
25
  p.extra_dev_deps = [
26
26
  ['newgem', ">= #{::Newgem::VERSION}"]
@@ -51,7 +51,7 @@ Dir['tasks/**/*.rake'].each { |t| load t }
51
51
  # t.test_files = FileList['test/**/*.rb']
52
52
  # end
53
53
 
54
- Spec::Rake::SpecTask.new do |t|
55
- t.spec_files = FileList['spec/**/*.rb']
56
- end
54
+ #Spec::Rake::SpecTask.new do |t|
55
+ # t.spec_files = FileList['spec/**/*.rb']
56
+ #end
57
57
 
data/lib/yore.orig.rb CHANGED
@@ -2,5 +2,5 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module Yore
5
- VERSION = '0.0.1'
5
+ VERSION = '0.0.2'
6
6
  end
@@ -2,6 +2,9 @@ require 'rubygems'
2
2
  gem 'RequirePaths'; require 'require_paths'
3
3
  require_paths '.','..'
4
4
 
5
+ gem 'Platform'; require 'platform'
6
+ gem 'shairontoledo-popen4'; require 'popen4'
7
+
5
8
  require 'fileutils'
6
9
  require 'net/smtp'
7
10
 
@@ -13,6 +16,66 @@ require 'ihl_ruby/extend_base_classes'
13
16
  THIS_FILE = __FILE__
14
17
  THIS_DIR = File.dirname(THIS_FILE)
15
18
 
19
+ module POpen4
20
+
21
+ class ExecuteError < StandardError
22
+
23
+ attr_reader :result #,:stderr,:stdout,:exitcode,:pid
24
+
25
+ def initialize(aArg)
26
+ if aArg.is_a? Hash
27
+ super(aArg[:stdout] || '')
28
+ @result = aArg
29
+ # @stderr = aArg[:stderr]
30
+ # @stdout = aArg[:stdout]
31
+ # @exitcode = aArg[:exitcode]
32
+ # @pid = aArg[:pid]
33
+ else
34
+ super(aArg)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ # Usage :
41
+ # result = POpen4::shell('somebinary') do |r| # block gives opportunity to adjust result, and avoid exception raised from non-zero exit codes
42
+ # if r[:exitcode]==254 # eg. say this binary returns 254 to mean something special but not an error
43
+ # r[:stdout] = 'some correct output'
44
+ # r[:stderr] = ''
45
+ # r[:exitcode] = 0
46
+ # end
47
+ # end
48
+ #
49
+ # OR
50
+ #
51
+ # result = POpen4::shell('somebinary');
52
+ # puts result[:stdout]
53
+ def self.shell(aCommand,aWorkingDir=nil,aTimeout=nil)
54
+ raise ExecuteError.new('aWorkingDir doesnt exist') unless !aWorkingDir || File.exists?(aWorkingDir)
55
+ orig_wd = Dir.getwd
56
+ result = {:command => aCommand, :dir => (aWorkingDir || orig_wd)}
57
+ status = nil
58
+ begin
59
+ Dir.chdir(aWorkingDir) if aWorkingDir
60
+ Timeout.timeout(aTimeout,ExecuteError) do # nil aTimeout will not time out
61
+ status = POpen4::popen4(aCommand) do |stdout, stderr, stdin, pid|
62
+ result[:stdout] = stdout.read
63
+ result[:stderr] = stderr.read
64
+ result[:pid] = pid
65
+ end
66
+ end
67
+ ensure
68
+ Dir.chdir(orig_wd)
69
+ end
70
+ result[:exitcode] = (status && status.exitstatus) || 1
71
+ yield(result) if block_given?
72
+ raise ExecuteError.new(result) if result[:exitcode] != 0
73
+ return result
74
+ end
75
+
76
+ end
77
+
78
+
16
79
  module YoreCore
17
80
 
18
81
  class KeepDaily
@@ -163,8 +226,8 @@ module YoreCore
163
226
  :keep_daily => 14,
164
227
  :keep_weekly => 12,
165
228
  :keep_monthly => 12,
166
- :crypto_iv => "3A63775C1E3F291B0925578165EB917E",
167
- :crypto_key => "07692FC8656F04AE5518B80D38681E038A3C12050DF6CC97CEEC33D800D5E2FE",
229
+ :crypto_iv => "3A63775C1E3F291B0925578165EB917E", # apparently a string of up to 32 random hex digits
230
+ :crypto_key => "07692FC8656F04AE5518B80D38681E038A3C12050DF6CC97CEEC33D800D5E2FE", # apparently a string of up to 64 random hex digits
168
231
  :first_hour => 4,
169
232
  :prefix => 'backup',
170
233
  :log_level => 'DEBUG',
@@ -190,7 +253,7 @@ module YoreCore
190
253
  attr_reader :basepath
191
254
 
192
255
  def initialize(aConfig=nil)
193
- DEFAULT_CONFIG[:email_report] = true # fixes some bug where this was nil
256
+ DEFAULT_CONFIG[:email_report] = false # fixes some bug where this was nil
194
257
  configure(aConfig || DEFAULT_CONFIG)
195
258
  end
196
259
 
@@ -242,10 +305,11 @@ module YoreCore
242
305
  #@filelist =
243
306
  end
244
307
 
245
- def shell(aCommandline)
246
- reporter.debug aCommandline
247
- reporter.debug response = `#{aCommandline}`
248
- response
308
+ def shell(aCommandline,&aBlock)
309
+ reporter.debug "To shell: " + aCommandline
310
+ result = block_given? ? POpen4::shell(aCommandline,nil,nil,&aBlock) : POpen4::shell(aCommandline)
311
+ reporter.debug "From shell: '#{result[:stdout]}'"
312
+ return result[:stdout]
249
313
  end
250
314
 
251
315
  def get_log
@@ -303,8 +367,14 @@ module YoreCore
303
367
  shell "openssl enc -d -aes-256-cbc -K #{config[:crypto_key]} -iv #{config[:crypto_iv]} -in #{aFileIn} -out #{aFileOut}"
304
368
  end
305
369
 
370
+ def ensure_bucket(aBucket=nil)
371
+ aBucket ||= config[:bucket]
372
+ shell "s3cmd createbucket #{aBucket}"
373
+ end
374
+
306
375
  # uploads the given file to the current bucket as its basename
307
376
  def upload(aFile)
377
+ ensure_bucket()
308
378
  shell "s3cmd put #{config[:bucket]}:#{File.basename(aFile)} #{aFile}"
309
379
  end
310
380
 
@@ -323,7 +393,7 @@ module YoreCore
323
393
  # :first_hour
324
394
  # :
325
395
  def encode_file_name(aTimeNow=Time.now)
326
- "#{config[:prefix]}-#{backup_date(aTimeNow).date_numeric}.rew"
396
+ "#{config[:prefix]}-#{backup_date(aTimeNow).date_numeric}.yor"
327
397
  end
328
398
 
329
399
  # return date based on filename
@@ -337,6 +407,7 @@ module YoreCore
337
407
  #end
338
408
 
339
409
  def backup_process(aSourceFiles,aTimeNow=Time.now,aTempDir=nil)
410
+ #require 'ruby-debug'; debugger
340
411
  aTempDir ||= MiscUtils.make_temp_dir('yore_')
341
412
  temp_file = File.expand_path('backup.tar',aTempDir)
342
413
  collect(aSourceFiles,temp_file)
@@ -411,12 +482,14 @@ module YoreCore
411
482
  xmlRoot = XmlUtils.get_file_root(job)
412
483
 
413
484
  filelist = []
485
+ sourceFound = false
414
486
 
415
487
  REXML::XPath.each(xmlRoot, '/Yore/Sources/Source') do |xmlSource|
416
- case xmlSource['Type']
488
+ case xmlSource.attributes['Type']
417
489
  when 'File' then
418
490
  REXML::XPath.each(xmlSource, 'IncludePath') do |xmlPath|
419
- filelist += MiscUtils::recursive_file_list(File.expand_path(xmlPath.text,config[:basepath]))
491
+ filelist += MiscUtils::recursive_file_list(MiscUtils::path_combine(config[:basepath],xmlPath.text))
492
+ sourceFound = true
420
493
  end
421
494
  when 'MySql' then
422
495
  #<Source Type="MySql" >
@@ -431,11 +504,14 @@ module YoreCore
431
504
  raise Error.new("Invalid or missing parameter")
432
505
  end
433
506
  db_to_file(args,file)
434
- filelist += file
507
+ filelist += file
508
+ sourceFound = true
435
509
  end
436
510
  end
437
511
  end
438
512
 
513
+ raise Error.new("Backup source found but file list empty") if sourceFound && filelist.empty?
514
+
439
515
  filelist.uniq!
440
516
  filelist.sort!
441
517
 
File without changes
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Yore>
3
+ <SimpleItems>
4
+ <Item Name="keep_daily">14</Item>
5
+ <Item Name="keep_weekly">12</Item>
6
+ <Item Name="keep_monthly">12</Item>
7
+ <Item Name="crypto_iv">56FD29B5CE3F291B0925577435EBEE7E</Item>
8
+ <Item Name="crypto_key">07692FC3456A345055B45A37560A85390A3565A0436E035E35636A603A5A2FE</Item>
9
+ <Item Name="bucket">yoretest</Item>
10
+ <Item Name="first_hour">4</Item>
11
+ <Item Name="prefix">yoretest</Item>
12
+ <Item Name="log_level">DEBUG</Item>
13
+ <Item Name="email_report">false</Item>
14
+
15
+ <Item Name="mail_host">mail.authsmtp.com</Item>
16
+ <Item Name="mail_port">25</Item>
17
+ <Item Name="mail_helodomain">finwa.org.au</Item>
18
+ <Item Name="mail_user">ac37391</Item>
19
+ <Item Name="mail_password">mbju7wwzv</Item>
20
+ <Item Name="mail_from">noreply@buzzware.com.au</Item>
21
+ <Item Name="mail_from_alias">FINWA Web Server</Item>
22
+ <Item Name="mail_to">familyincnet@gmail.com</Item>
23
+ <Item Name="mail_to_alias">FINWA</Item>
24
+ <Item Name="mail_auth">login</Item>
25
+
26
+ <Item Name="mysqldump">/usr/local/mysql/bin/mysqldump</Item>
27
+
28
+ </SimpleItems>
29
+ <Sources>
30
+ <Source Type="File">
31
+ <IncludePath>/tmp/yoretest</IncludePath>
32
+ <!-- <ExcludePath></ExcludePath> -->
33
+ </Source>
34
+ <!--<Source Type="MySql" > -->
35
+ <!-- <Database Name="joomla_db" Host="localhost" User="root" Password="prot123ection">-->
36
+ <!-- <ToFile>/Users/gary/temp/test.sql</ToFile> -->
37
+ <!-- </Database> -->
38
+ <!--</Source> -->
39
+ </Sources>
40
+ </Yore>
41
+
@@ -1,18 +1,10 @@
1
1
  require 'rubygems'
2
- require File.dirname(__FILE__) + '/spec_helper.rb'
3
-
4
2
  gem 'RequirePaths'; require 'require_paths'
5
3
  require_paths '../lib','../../..'
6
4
 
5
+ require 'test/unit'
6
+ gem 'Shoulda'; require 'shoulda'
7
7
 
8
- ## Time to add your specs!
9
- # http://rspec.info/
10
- #describe "Place your specs here" do
11
- #
12
- # it "find this spec in spec directory" do
13
- # violated "Be sure to write your specs"
14
- # end
15
- #end
16
8
 
17
9
  require 'ihl_ruby/misc_utils'
18
10
 
@@ -25,14 +17,15 @@ def ensure_clean_bucket(aName)
25
17
  `s3cmd deleteall #{aName}`
26
18
  end
27
19
 
28
- describe YoreCore::Yore do
29
- before(:each) do
20
+ class YoreTest < Test::Unit::TestCase
21
+
22
+ def setup
30
23
  @yore = YoreCore::Yore.new
31
24
  end
32
25
 
33
- it "should collect a list of files into a single file with a .contents file" do
26
+ should "collect a list of files into a single file with a .contents file" do
34
27
  # create a temp dir
35
- temp_dir = MiscUtils::make_temp_dir('yore_spec')
28
+ temp_dir = MiscUtils::make_temp_dir('yore_test')
36
29
  # create source and dest subfolders
37
30
  source_dir = File.expand_path('source',temp_dir)
38
31
  dest_dir = File.expand_path('dest',temp_dir)
@@ -55,14 +48,14 @@ describe YoreCore::Yore do
55
48
  i = 0
56
49
  filelist_out.each_line {|line|
57
50
  next if line==".contents\n"
58
- i.should < filelist.length
59
- line.chomp("\n").should == MiscUtils.path_debase(filelist[i],source_dir) # .bite('/')
51
+ assert i < filelist.length
52
+ assert_equal line.chomp("\n"), MiscUtils.path_debase(filelist[i],source_dir) # .bite('/')
60
53
  i += 1
61
54
  }
62
55
  # could also check .contents file against actual contents
63
56
  end
64
57
 
65
- it "should encrypt and unencrypt a file with a standard iv but a supplied key" do
58
+ should "encrypt and unencrypt a file with a standard iv but a supplied key" do
66
59
  orig_content = 'abcdef123456'
67
60
  temp_file1 = MiscUtils.make_temp_file(nil,nil,orig_content)
68
61
  temp_file2 = temp_file1+'.enc'
@@ -72,23 +65,23 @@ describe YoreCore::Yore do
72
65
  @yore.unpack(temp_file2,temp_file3)
73
66
 
74
67
  file3_content = MiscUtils.string_from_file(temp_file3)
75
- file3_content.should == orig_content
68
+ assert_equal file3_content, orig_content
76
69
  end
77
70
 
78
- it "should create a backup filename combining a prefix, date, day and standard extension, and be able to decode the filename back to a date" do
71
+ should "create a backup filename combining a prefix, date, day and standard extension, and be able to decode the filename back to a date" do
79
72
  @yore.configure({
80
- :prefix => 'spec',
73
+ :prefix => 'test',
81
74
  :first_hour => 4
82
75
  })
83
76
  now = Time.local(2009, 1, 1, 0, 0, 0, 0)
84
- exp_filename = "spec-20081231.rew"
77
+ exp_filename = "test-20081231.yor"
85
78
  calc_filename = @yore.encode_file_name(now)
86
- calc_filename.should == exp_filename
87
- @yore.decode_file_name(calc_filename).should == Time.local(2008, 12, 31)
79
+ assert_equal calc_filename, exp_filename
80
+ assert_equal Time.local(2008, 12, 31), @yore.decode_file_name(calc_filename)
88
81
  end
89
82
 
90
- it "should upload and download files intact" do
91
- bucket = 'yore_spec'
83
+ should "upload and download files intact" do
84
+ bucket = 'yore_test'
92
85
  ensure_clean_bucket(bucket)
93
86
  @yore.configure({
94
87
  :bucket => bucket
@@ -101,19 +94,19 @@ describe YoreCore::Yore do
101
94
  File.rename(temp_file, orig_file)
102
95
  puts @yore.download(temp_file)
103
96
  down_file_content = MiscUtils.string_from_file(temp_file)
104
- down_file_content.should == content
97
+ assert_equal content, down_file_content
105
98
  end
106
99
 
107
- it "should backup and restore multiple directories of file" do
100
+ should "backup and restore multiple directories of file" do
108
101
  # create a temp dir
109
- temp_dir = MiscUtils::make_temp_dir('yore_spec')
102
+ temp_dir = MiscUtils::make_temp_dir('yore_test')
110
103
  # create source and dest subfolders
111
104
  source_dir = File.expand_path('source',temp_dir)
112
105
  source1 = File.join(source_dir,'source1')
113
106
  source2 = File.join(source_dir,'source2')
114
107
  dest_dir = File.expand_path('dest',temp_dir)
115
- bucket = 'yore_spec'
116
-
108
+ bucket = 'yore_test'
109
+
117
110
  FileUtils.mkdir_p([source1,source2,dest_dir])
118
111
  # create some dirs and files in source
119
112
  ['a','a/1','b','c'].each {|p| FileUtils.mkdir_p(File.expand_path(p,source1))}
@@ -137,7 +130,7 @@ job_template = <<EOF
137
130
  <Item Name="bucket">${BUCKET}</Item>
138
131
  </SimpleItems>
139
132
  <Sources>
140
- <Source>
133
+ <Source Type="File">
141
134
  <IncludePath>${SOURCE1}</IncludePath>
142
135
  <IncludePath>${SOURCE2}</IncludePath>
143
136
  </Source>
@@ -158,8 +151,13 @@ EOF
158
151
  })
159
152
 
160
153
  # call yore script with ruby from the command line, then download result and check contents
161
- puts cmd = "ruby #{File.expand_path('../bin/yore.rb',THIS_DIR)} backup #{job_file}"
162
- puts result = `#{cmd}`
154
+ begin
155
+ result = @yore.shell("ruby #{File.expand_path('../../bin/yore',THIS_DIR)} backup #{job_file}")
156
+ rescue ::StandardError => e
157
+ flunk e.inspect
158
+ end
159
+
160
+ puts result
163
161
 
164
162
  retrieved_fname = File.expand_path(@yore.encode_file_name(), dest_dir)
165
163
  collection_fname = MiscUtils::temp_file
@@ -171,9 +169,9 @@ EOF
171
169
 
172
170
  # check contains filelist files ignoring .contents
173
171
  cmd = "tar --list --file=#{collection_fname}"
174
- filelist_out = `#{cmd}`
172
+ filelist_out = @yore.shell(cmd)
175
173
  filelist_out = filelist_out.split("\n").sort
176
- filelist_out.should == filelist
174
+ assert_equal filelist, filelist_out
177
175
  # i = 0
178
176
  # filelist_out.each {|line|
179
177
  # next if line==".contents\n"
@@ -184,16 +182,15 @@ EOF
184
182
  # could also check .contents file against actual contents
185
183
  end
186
184
 
187
- it "should assign proper boolean values" do
188
- class Blah
189
- SOMECONSTANT = {:a => 'AAA', :b => true, :c => false}
190
- end
191
-
192
- puts Blah::SOMECONSTANT.inspect
193
- end
194
-
185
+ should "handle test_file_b" do
186
+ aController = YoreCore::Yore.new # main program object
187
+ job = File.expand_path('../../test/test_job_b.xml',THIS_DIR)
188
+ xmlRoot = XmlUtils.get_file_root(job)
189
+ aController.configure(xmlRoot,nil,{:basepath => File.dirname(File.expand_path(job))})
190
+ aController.backup(job)
191
+ end
195
192
 
196
- it "should provide configurable criteria for keeping old files"
193
+ should "provide configurable criteria for keeping old files"
197
194
 
198
- it "should clean a folder full of files, removing files that don't match configurable criteria for keeping old files"
195
+ should "clean a folder full of files, removing files that don't match configurable criteria for keeping old files"
199
196
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gary McGhee
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-25 00:00:00 +09:00
12
+ date: 2009-02-04 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,16 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.2.5
44
44
  version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: shairontoledo-popen4
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.1.2
54
+ version:
45
55
  - !ruby/object:Gem::Dependency
46
56
  name: newgem
47
57
  type: :development
@@ -62,7 +72,7 @@ dependencies:
62
72
  - !ruby/object:Gem::Version
63
73
  version: 1.8.0
64
74
  version:
65
- description: FIX (describe your package)
75
+ description: yore (as in "days of yore") is hands-off scheduled backup utility designed for web servers. It does backups of files and databases (MySQL only at present) to Amazon S3.
66
76
  email:
67
77
  - contact@buzz@ware@com@au
68
78
  executables:
@@ -91,14 +101,11 @@ files:
91
101
  - script/console
92
102
  - script/destroy
93
103
  - script/generate
94
- - spec/rewind_spec.rb
95
- - spec/spec.opts
96
- - spec/spec_helper.rb
97
- - spec/test_job_a.xml
98
- - spec/yore_spec.rb
99
- - tasks/rspec.rake
104
+ - test/test_job_a.xml
105
+ - test/test_job_b.xml
106
+ - test/yore_test.rb
100
107
  has_rdoc: true
101
- homepage: FIX (url)
108
+ homepage: "RubyForge Project : http://rubyforge.org/projects/buzzware"
102
109
  post_install_message:
103
110
  rdoc_options:
104
111
  - --main
@@ -123,6 +130,6 @@ rubyforge_project: buzzware
123
130
  rubygems_version: 1.3.1
124
131
  signing_key:
125
132
  specification_version: 2
126
- summary: FIX (describe your package)
133
+ summary: yore (as in "days of yore") is hands-off scheduled backup utility designed for web servers
127
134
  test_files: []
128
135
 
data/spec/rewind_spec.rb DELETED
@@ -1,187 +0,0 @@
1
- require 'rubygems'
2
- gem 'RequirePaths'; require 'require_paths'
3
- require_paths '../../..'
4
-
5
- require 'ihl_ruby/misc_utils'
6
-
7
- require 'fileutils'
8
-
9
- require 'yore_core'
10
-
11
- def ensure_clean_bucket(aName)
12
- `s3cmd createbucket #{aName}`
13
- `s3cmd deleteall #{aName}`
14
- end
15
-
16
- describe YoreCore::Yore do
17
- before(:each) do
18
- @yore = YoreCore::Yore.new
19
- end
20
-
21
- it "should collect a list of files into a single file with a .contents file" do
22
- # create a temp dir
23
- temp_dir = MiscUtils::make_temp_dir('yore_spec')
24
- # create source and dest subfolders
25
- source_dir = File.expand_path('source',temp_dir)
26
- dest_dir = File.expand_path('dest',temp_dir)
27
- FileUtils.mkdir_p([source_dir,dest_dir])
28
- # create some dirs and files in source
29
- ['a','a/1','b','c'].each {|p| FileUtils.mkdir_p(File.expand_path(p,source_dir))}
30
- %w(a/blah.txt a/1/blahblah.txt b/apples.txt c/carrots.txt).each do |f|
31
- MiscUtils::make_temp_file(f,source_dir)
32
- end
33
- # collect into dest file
34
- # get recursive file list, without carrots
35
- filelist = MiscUtils::recursive_file_list(source_dir) {|p| not p =~ /carrots.txt/}
36
- dest_file = File.join(dest_dir,'destfile.bzb')
37
-
38
- @yore.collect(filelist,dest_file)
39
-
40
- # check contains filelist files ignoring .contents
41
- cmd = "tar --list --file=#{dest_file}"
42
- filelist_out = `#{cmd}`
43
- i = 0
44
- filelist_out.each_line {|line|
45
- next if line==".contents\n"
46
- i.should < filelist.length
47
- line.chomp("\n").should == MiscUtils.path_debase(filelist[i],source_dir) # .bite('/')
48
- i += 1
49
- }
50
- # could also check .contents file against actual contents
51
- end
52
-
53
- it "should encrypt and unencrypt a file with a standard iv but a supplied key" do
54
- orig_content = 'abcdef123456'
55
- temp_file1 = MiscUtils.make_temp_file(nil,nil,orig_content)
56
- temp_file2 = temp_file1+'.enc'
57
- temp_file3 = temp_file1+'.dec'
58
-
59
- @yore.pack(temp_file1,temp_file2)
60
- @yore.unpack(temp_file2,temp_file3)
61
-
62
- file3_content = MiscUtils.string_from_file(temp_file3)
63
- file3_content.should == orig_content
64
- end
65
-
66
- it "should create a backup filename combining a prefix, date, day and standard extension, and be able to decode the filename back to a date" do
67
- @yore.configure({
68
- :prefix => 'spec',
69
- :first_hour => 4
70
- })
71
- now = Time.local(2009, 1, 1, 0, 0, 0, 0)
72
- exp_filename = "spec-20081231.rew"
73
- calc_filename = @yore.encode_file_name(now)
74
- calc_filename.should == exp_filename
75
- @yore.decode_file_name(calc_filename).should == Time.local(2008, 12, 31)
76
- end
77
-
78
- it "should upload and download files intact" do
79
- bucket = 'yore_spec'
80
- ensure_clean_bucket(bucket)
81
- @yore.configure({
82
- :bucket => bucket
83
- })
84
- content = 'this is my test content'
85
- temp_dir = MiscUtils.make_temp_dir()
86
- temp_file = MiscUtils.make_temp_file(nil, temp_dir, content)
87
- puts @yore.upload(temp_file)
88
- orig_file = temp_file+'.orig'
89
- File.rename(temp_file, orig_file)
90
- puts @yore.download(temp_file)
91
- down_file_content = MiscUtils.string_from_file(temp_file)
92
- down_file_content.should == content
93
- end
94
-
95
- it "should backup and restore multiple directories of file" do
96
- # create a temp dir
97
- temp_dir = MiscUtils::make_temp_dir('yore_spec')
98
- # create source and dest subfolders
99
- source_dir = File.expand_path('source',temp_dir)
100
- source1 = File.join(source_dir,'source1')
101
- source2 = File.join(source_dir,'source2')
102
- dest_dir = File.expand_path('dest',temp_dir)
103
- bucket = 'yore_spec'
104
-
105
- FileUtils.mkdir_p([source1,source2,dest_dir])
106
- # create some dirs and files in source
107
- ['a','a/1','b','c'].each {|p| FileUtils.mkdir_p(File.expand_path(p,source1))}
108
- %w(a/blah.txt a/1/blahblah.txt b/apples.txt c/carrots.txt).each do |f|
109
- MiscUtils::make_temp_file(f,source1)
110
- end
111
- ['w','x/1','y/2','z'].each {|p| FileUtils.mkdir_p(File.expand_path(p,source2))}
112
- %w(w/zonk.txt x/1/eggs.txt y/2/bloop.txt z/zax.txt).each do |f|
113
- MiscUtils::make_temp_file(f,source2)
114
- end
115
-
116
- # create job file
117
- job_template = <<EOF
118
- <?xml version="1.0" encoding="UTF-8"?>
119
- <Yore>
120
- <SimpleItems>
121
- <Item Name="crypto_iv">3A63775C1E3F291B0925578165EB917E</Item>
122
- <Item Name="crypto_key">07692FC8656F04AE5518B80D38681E038A3C12050DF6CC97CEEC33D800D5E2FE</Item>
123
- <Item Name="prefix">backup</Item>
124
- <Item Name="log_level">DEBUG</Item>
125
- <Item Name="bucket">${BUCKET}</Item>
126
- </SimpleItems>
127
- <Sources>
128
- <Source>
129
- <IncludePath>${SOURCE1}</IncludePath>
130
- <IncludePath>${SOURCE2}</IncludePath>
131
- </Source>
132
- </Sources>
133
- </Yore>
134
- EOF
135
-
136
- job_content = StringUtils::render_template(job_template,{
137
- 'SOURCE1' => source1,
138
- 'SOURCE2' => source2,
139
- 'BUCKET' => bucket
140
- })
141
- MiscUtils::string_to_file(job_content,job_file = MiscUtils::temp_file)
142
-
143
- ensure_clean_bucket(bucket)
144
- @yore.configure({
145
- :bucket => bucket
146
- })
147
-
148
- # call yore script with ruby from the command line, then download result and check contents
149
- puts cmd = "#{File.expand_path('../lib/yore',THIS_DIR)} backup #{job_file}"
150
- puts result = `#{cmd}`
151
-
152
- retrieved_fname = File.expand_path(@yore.encode_file_name(), dest_dir)
153
- collection_fname = MiscUtils::temp_file
154
-
155
- puts @yore.download(retrieved_fname)
156
- puts @yore.unpack(retrieved_fname,collection_fname)
157
-
158
- filelist = MiscUtils::recursive_file_list(source_dir,false)
159
-
160
- # check contains filelist files ignoring .contents
161
- cmd = "tar --list --file=#{collection_fname}"
162
- filelist_out = `#{cmd}`
163
- filelist_out = filelist_out.split("\n").sort
164
- filelist_out.should == filelist
165
- # i = 0
166
- # filelist_out.each {|line|
167
- # next if line==".contents\n"
168
- # i.should < filelist.length
169
- # line.chomp("\n").should == MiscUtils.path_debase(filelist[i],source_dir) # .bite('/')
170
- # i += 1
171
- # }
172
- # could also check .contents file against actual contents
173
- end
174
-
175
- it "should assign proper boolean values" do
176
- class Blah
177
- SOMECONSTANT = {:a => 'AAA', :b => true, :c => false}
178
- end
179
-
180
- puts Blah::SOMECONSTANT.inspect
181
- end
182
-
183
- it "should provide configurable criteria for keeping old files"
184
-
185
- it "should clean a folder full of files, removing files that don't match configurable criteria for keeping old files"
186
- end
187
-
data/spec/spec.opts DELETED
@@ -1 +0,0 @@
1
- --colour
data/spec/spec_helper.rb DELETED
@@ -1,10 +0,0 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems'
5
- gem 'rspec'
6
- require 'spec'
7
- end
8
-
9
- $:.unshift(File.dirname(__FILE__) + '/../lib')
10
- require 'yore'
data/tasks/rspec.rake DELETED
@@ -1,21 +0,0 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems'
5
- require 'spec'
6
- end
7
- begin
8
- require 'spec/rake/spectask'
9
- rescue LoadError
10
- puts <<-EOS
11
- To use rspec for testing you must install rspec gem:
12
- gem install rspec
13
- EOS
14
- exit(0)
15
- end
16
-
17
- desc "Run the specs under spec/models"
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
21
- end