understudy 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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
-