understudy 0.0.8 → 0.0.9

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/Gemfile CHANGED
@@ -2,15 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in understudy.gemspec
4
4
  gemspec
5
-
6
- group :development, :test do
7
- gem "rspec", "~> 2"
8
- gem "rake"
9
- gem "coveralls"
10
- gem "fakefs"
11
- end
12
-
13
- group :development do
14
- gem "bundler", "~> 1.3"
15
- gem 'guard-rspec', :require => false
16
- end
data/bin/understudy CHANGED
@@ -1,119 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- ENV['TMPDIR']='/tmp/backup/'
4
- require 'optparse'
5
- require 'ostruct'
6
- require 'fileutils'
7
- require 'rdiff_simple'
3
+ # Trap interrupts to quit cleanly.
4
+ # See https://twitter.com/mitchellh/status/283014103189053442
5
+ Signal.trap("INT") { exit 1 }
8
6
 
9
- options = OpenStruct.new
10
- @verbose = false
11
-
12
- usage = "Usage: understudy [options] job-name"
13
-
14
- OptionParser.new do |opts|
15
- opts.banner = usage
16
- opts.on '-v', '--verbose', 'Output extra information' do |v|
17
- @verbose = v
18
- end
19
- opts.on '-f', '--first-time', 'Force first-time run' do |f|
20
- options.first = f
21
- end
22
- end.parse!
23
-
24
- def error msg
25
- STDERR.puts "ERROR: #{msg}"
26
- exit 255
27
- end
28
-
29
- error usage if ARGV.length != 1
30
-
31
- job_name = ARGV.shift
32
-
33
- config_file = "/etc/understudy/#{job_name}.conf"
34
-
35
- error "Cannot find '#{config_file}'" unless File.exist? config_file
36
-
37
- DATA_DIR = "/var/lib/understudy/#{job_name}"
38
-
39
- FileUtils.mkdir_p DATA_DIR
40
-
41
- lockfile = File.open( "#{DATA_DIR}/LOCK", File::RDWR|File::CREAT, 0644 )
42
- unless lockfile.flock File::LOCK_EX|File::LOCK_NB
43
- error "Job #{job_name} is already running"
44
- end
45
- lockfile.puts $$
46
- lockfile.flush
47
-
48
- config = OpenStruct.new
49
-
50
- # Any options that aren't our options go to rdiff-backup
51
- OUR_OPTIONS = %w{source dest command}
52
-
53
- rdiff_args = []
54
-
55
- File.read( config_file ).split( /\n/ ).each do |line|
56
- line.sub! /#.*$/, ''
57
- line.sub! /^\s+/, ''
58
- line.sub! /\s+$/, ''
59
- next if line.empty?
60
-
61
- line =~ /^([-\w]+)(\s+=\s+(.*))?$/ or raise "Strange line in config: #{line}"
62
- key = $1
63
- val = $3
64
- if OUR_OPTIONS.member? key
65
- config.send "#{key}=".to_sym, val
66
- else
67
- rdiff_args.push "--#{key}" + ( val ? "=#{val}" : "" )
68
- end
69
- end
70
-
71
- error "Missing 'dest' config option" unless config.dest
72
- error "Missing 'source' config option" unless config.source
73
-
74
- rdiff_data = "#{config.dest}/rdiff-backup-data"
75
- exists = File.directory? rdiff_data
76
- if exists && options.first
77
- error "Cannot force first time, destination '#{config.dest}' already exists"
78
- elsif !exists && !options.first
79
- error "Destination '#{config.dest}' does not appear to exist, try again with --first-time"
80
- end
81
-
82
- def info message
83
- return unless @verbose
84
- end
85
-
86
- def run command
87
- friendly = nil
88
- if command.is_a? Array
89
- friendly = command.map { |i| i =~ /[^-=\/\.\w]/ ? "#{i}" : i }.join ' '
90
- info "Running: #{friendly}"
91
- RdiffSimple.execute( friendly ) or error "Could not run #{friendly}"
92
- else
93
- friendly = command
94
- info "Running: #{friendly}"
95
- RdiffSimple.execute( friendly ) or error "Could not run #{friendly}"
96
- end
97
- if $? != 0
98
- error "Could not run #{friendly}"
99
- end
100
- end
101
-
102
- ENV['PATH'] += ":/etc/understudy"
103
- run config.command if config.command
104
-
105
- command = []
106
-
107
- command << "--terminal-verbosity=5" if @verbose
108
- command << "--print-statistics"
109
-
110
- command += rdiff_args
111
-
112
- command << config.source
113
- command << config.dest
114
-
115
- run command
116
-
117
- info "Backup successful"
118
-
119
- exit 0
7
+ require 'understudy'
8
+ Understudy::CLI.start
@@ -0,0 +1,103 @@
1
+ require 'ostruct'
2
+ require 'fileutils'
3
+
4
+ module Understudy
5
+ class CLI < Thor
6
+
7
+ desc "perform [job]", "Perform backup [job]"
8
+ method_option :verbose, type: :boolean, banner: "Enable verbose output mode", aliases: "-v", default: false
9
+ method_option "first-time", type: :boolean, banner: "Force first-time run", aliases: "-f", default: false
10
+ def perform(job)
11
+ ENV['PATH'] += ":/etc/understudy"
12
+ ENV['TMPDIR']='/tmp/understudy/'
13
+
14
+ log = Logger.new(STDOUT)
15
+ log.level = Logger::INFO if options[:verbose]
16
+
17
+ job_name = job
18
+
19
+ config_file = "/etc/understudy/#{job_name}.conf"
20
+
21
+ log.error "Cannot find '#{config_file}'" unless File.exist? config_file
22
+
23
+ data_dir = "/tmp/understudy-#{job_name}"
24
+
25
+ FileUtils.mkdir_p data_dir
26
+
27
+ lockfile = File.open( "#{data_dir}/LOCK", File::RDWR|File::CREAT, 0644 )
28
+ unless lockfile.flock File::LOCK_EX|File::LOCK_NB
29
+ log.error "Job #{job_name} is already running"
30
+ end
31
+ lockfile.puts $$
32
+ lockfile.flush
33
+
34
+ config = OpenStruct.new
35
+
36
+ # Any options that aren't our options go to rdiff-backup
37
+ our_options = %w{source dest command}
38
+
39
+ rdiff_args = []
40
+
41
+ File.read( config_file ).split( /\n/ ).each do |line|
42
+ line.sub! /#.*$/, ''
43
+ line.sub! /^\s+/, ''
44
+ line.sub! /\s+$/, ''
45
+ next if line.empty?
46
+
47
+ line =~ /^([-\w]+)(\s+=\s+(.*))?$/ or raise "Strange line in config: #{line}"
48
+ key = $1
49
+ val = $3
50
+ if our_options.member? key
51
+ config.send "#{key}=".to_sym, val
52
+ else
53
+ rdiff_args.push "--#{key}" + ( val ? "=#{val}" : "" )
54
+ end
55
+ end
56
+
57
+ log.error "Missing 'dest' config option" unless config.dest
58
+ log.error "Missing 'source' config option" unless config.source
59
+
60
+ rdiff_data = "#{config.dest}/rdiff-backup-data"
61
+ exists = File.directory? rdiff_data
62
+
63
+ if exists && options["first-time"]
64
+ log.error "Cannot force first time, destination '#{config.dest}' already exists"
65
+ elsif !exists && !options["first-time"]
66
+ log.error "Destination '#{config.dest}' does not appear to exist, try again with --first-time"
67
+ end
68
+
69
+ run config.command if config.command
70
+
71
+ command = []
72
+
73
+ command << "--terminal-verbosity=5" if options[:verbose]
74
+ command << "--print-statistics"
75
+
76
+ command += rdiff_args
77
+
78
+ command << config.source
79
+ command << config.dest
80
+
81
+ run command, log
82
+
83
+ log.info "Backup successful"
84
+ end
85
+
86
+ private
87
+ def run(command, log)
88
+ friendly = nil
89
+ if command.is_a? Array
90
+ friendly = command.map { |i| i =~ /[^-=\/\.\w]/ ? "#{i}" : i }.join ' '
91
+ log.info "Running: #{friendly}"
92
+ RdiffSimple.execute( friendly ) or log.error "Could not run #{friendly}"
93
+ else
94
+ friendly = command
95
+ log.info "Running: #{friendly}"
96
+ RdiffSimple.execute( friendly ) or log.error "Could not run #{friendly}"
97
+ end
98
+ if $? != 0
99
+ log.error "Could not run #{friendly}"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -1,3 +1,3 @@
1
1
  module Understudy
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
data/lib/understudy.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'thor'
1
2
  require 'rdiff_simple'
2
- require 'understudy/stage'
3
+ require 'understudy/cli'
3
4
  require 'understudy/version'
data/understudy.gemspec CHANGED
@@ -23,4 +23,11 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_dependency "thor"
25
25
  spec.add_dependency "rdiff-simple"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.3"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "rspec", "~> 2"
30
+ spec.add_development_dependency "coveralls"
31
+ spec.add_development_dependency "fakefs"
32
+ spec.add_development_dependency "guard-rspec"
26
33
  end
metadata CHANGED
@@ -1,43 +1,144 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: understudy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ prerelease:
5
+ version: 0.0.9
5
6
  platform: ruby
6
7
  authors:
7
8
  - Ryan Hansen
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-07-15 00:00:00.000000000 Z
12
+ date: 2013-08-09 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ none: false
21
+ prerelease: false
14
22
  name: thor
23
+ type: :runtime
15
24
  requirement: !ruby/object:Gem::Requirement
16
25
  requirements:
17
- - - '>='
26
+ - - ! '>='
18
27
  - !ruby/object:Gem::Version
19
28
  version: '0'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ none: false
37
+ prerelease: false
38
+ name: rdiff-simple
20
39
  type: :runtime
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ~>
50
+ - !ruby/object:Gem::Version
51
+ version: '1.3'
52
+ none: false
21
53
  prerelease: false
54
+ name: bundler
55
+ type: :development
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: '1.3'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
22
63
  version_requirements: !ruby/object:Gem::Requirement
23
64
  requirements:
24
- - - '>='
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ none: false
69
+ prerelease: false
70
+ name: rake
71
+ type: :development
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
25
75
  - !ruby/object:Gem::Version
26
76
  version: '0'
77
+ none: false
27
78
  - !ruby/object:Gem::Dependency
28
- name: rdiff-simple
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: '2'
84
+ none: false
85
+ prerelease: false
86
+ name: rspec
87
+ type: :development
29
88
  requirement: !ruby/object:Gem::Requirement
30
89
  requirements:
31
- - - '>='
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ version: '2'
93
+ none: false
94
+ - !ruby/object:Gem::Dependency
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ! '>='
32
98
  - !ruby/object:Gem::Version
33
99
  version: '0'
34
- type: :runtime
100
+ none: false
101
+ prerelease: false
102
+ name: coveralls
103
+ type: :development
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ none: false
110
+ - !ruby/object:Gem::Dependency
111
+ version_requirements: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ none: false
35
117
  prerelease: false
118
+ name: fakefs
119
+ type: :development
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ none: false
126
+ - !ruby/object:Gem::Dependency
36
127
  version_requirements: !ruby/object:Gem::Requirement
37
128
  requirements:
38
- - - '>='
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ none: false
133
+ prerelease: false
134
+ name: guard-rspec
135
+ type: :development
136
+ requirement: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ! '>='
39
139
  - !ruby/object:Gem::Version
40
140
  version: '0'
141
+ none: false
41
142
  description: Automated system backups via rdiff-backup
42
143
  email:
43
144
  - ketiko@gmail.com
@@ -58,16 +159,14 @@ files:
58
159
  - Rakefile
59
160
  - bin/understudy
60
161
  - lib/understudy.rb
162
+ - lib/understudy/cli.rb
61
163
  - lib/understudy/stage.rb
62
164
  - lib/understudy/version.rb
63
- - spec/lib/stage_spec.rb
64
165
  - spec/spec_helper.rb
65
- - spec/understudy_spec.rb
66
166
  - understudy.gemspec
67
167
  homepage: http://github.com/ketiko/understudy
68
168
  licenses:
69
169
  - MIT
70
- metadata: {}
71
170
  post_install_message:
72
171
  rdoc_options:
73
172
  - --charset=UTF-8
@@ -75,21 +174,27 @@ require_paths:
75
174
  - lib
76
175
  required_ruby_version: !ruby/object:Gem::Requirement
77
176
  requirements:
78
- - - '>='
177
+ - - ! '>='
79
178
  - !ruby/object:Gem::Version
179
+ segments:
180
+ - 0
181
+ hash: 3610360581697942929
80
182
  version: '0'
183
+ none: false
81
184
  required_rubygems_version: !ruby/object:Gem::Requirement
82
185
  requirements:
83
- - - '>='
186
+ - - ! '>='
84
187
  - !ruby/object:Gem::Version
188
+ segments:
189
+ - 0
190
+ hash: 3610360581697942929
85
191
  version: '0'
192
+ none: false
86
193
  requirements: []
87
194
  rubyforge_project:
88
- rubygems_version: 2.0.2
195
+ rubygems_version: 1.8.23
89
196
  signing_key:
90
- specification_version: 4
197
+ specification_version: 3
91
198
  summary: Automated system backups via rdiff-backup
92
199
  test_files:
93
- - spec/lib/stage_spec.rb
94
200
  - spec/spec_helper.rb
95
- - spec/understudy_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: a0878c926cb6750c7670444a59b2eb790a634232
4
- data.tar.gz: 5936917e05495ad5dcc334e98c1f64a1cf7370fe
5
- SHA512:
6
- metadata.gz: 10082a9e57c61cb860c460553164d6207a9f81e8d252a4091107e75bd66b685acfd196d5ac8ed90fd02825d32f9b2813ebee564e95c0cc07c10c13595f9405b9
7
- data.tar.gz: 98849071bb5e28420693abca8a9a6ba561d2388037bd97f016b07072b676ae8bbea71f2c91edc6d1873a583bb28897f4ca3e3d2afe142e26bc2df9cfa815f243
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Understudy::Stage do
4
- describe "#setup" do
5
- before(:each) do
6
- Understudy::Stage.setup
7
- end
8
-
9
- it "should create the default configuration directory" do
10
- File.exists?(Understudy::Stage::DEFAULT_DIRECTORY).should be_true
11
- end
12
-
13
- it "should a configuration file for the machine" do
14
- File.exists?(File.join(Understudy::Stage::DEFAULT_DIRECTORY, "#{`hostname`.chomp}.config")).should be_true
15
- end
16
- end
17
- end
18
-
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Understudy do
4
- it "should be defined" do
5
- defined?(Understudy).should == 'constant'
6
- end
7
- end
8
-