rudy 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +32 -17
- data/README.rdoc +74 -40
- data/bin/rudy +66 -10
- data/bin/rudy-ec2 +3 -1
- data/examples/authorize.rb +15 -0
- data/examples/gem-test.rb +11 -5
- data/examples/solaris.rb +35 -0
- data/examples/windows.rb +101 -0
- data/lib/rudy.rb +7 -1
- data/lib/rudy/aws.rb +2 -2
- data/lib/rudy/aws/ec2.rb +29 -22
- data/lib/rudy/aws/ec2/group.rb +1 -1
- data/lib/rudy/aws/ec2/image.rb +1 -29
- data/lib/rudy/aws/ec2/instance.rb +4 -32
- data/lib/rudy/aws/ec2/keypair.rb +1 -6
- data/lib/rudy/aws/ec2/snapshot.rb +2 -20
- data/lib/rudy/aws/ec2/volume.rb +11 -19
- data/lib/rudy/aws/ec2/zone.rb +1 -6
- data/lib/rudy/aws/sdb.rb +1 -1
- data/lib/rudy/cli/aws/ec2/addresses.rb +4 -10
- data/lib/rudy/cli/aws/ec2/groups.rb +0 -1
- data/lib/rudy/cli/aws/ec2/images.rb +1 -4
- data/lib/rudy/cli/aws/ec2/info.rb +63 -0
- data/lib/rudy/cli/aws/ec2/instances.rb +3 -5
- data/lib/rudy/cli/aws/ec2/keypairs.rb +3 -5
- data/lib/rudy/cli/aws/ec2/snapshots.rb +2 -6
- data/lib/rudy/cli/aws/ec2/zones.rb +2 -4
- data/lib/rudy/cli/backups.rb +20 -9
- data/lib/rudy/cli/base.rb +60 -3
- data/lib/rudy/cli/candy.rb +1 -1
- data/lib/rudy/cli/disks.rb +65 -7
- data/lib/rudy/cli/execbase.rb +0 -2
- data/lib/rudy/cli/images.rb +97 -0
- data/lib/rudy/cli/info.rb +48 -0
- data/lib/rudy/cli/keypairs.rb +43 -0
- data/lib/rudy/cli/machines.rb +41 -36
- data/lib/rudy/cli/networks.rb +68 -0
- data/lib/rudy/cli/routines.rb +3 -10
- data/lib/rudy/config/objects.rb +0 -1
- data/lib/rudy/disks.rb +4 -0
- data/lib/rudy/global.rb +1 -1
- data/lib/rudy/huxtable.rb +9 -3
- data/lib/rudy/machines.rb +1 -1
- data/lib/rudy/metadata.rb +4 -1
- data/lib/rudy/metadata/backup.rb +2 -2
- data/lib/rudy/metadata/disk.rb +7 -4
- data/lib/rudy/metadata/machine.rb +66 -2
- data/lib/rudy/routines.rb +2 -1
- data/lib/rudy/routines/base.rb +4 -157
- data/lib/rudy/routines/handlers/base.rb +6 -3
- data/lib/rudy/routines/handlers/disks.rb +127 -42
- data/lib/rudy/routines/handlers/group.rb +45 -10
- data/lib/rudy/routines/handlers/host.rb +16 -10
- data/lib/rudy/routines/handlers/keypair.rb +26 -10
- data/lib/rudy/routines/handlers/rye.rb +171 -0
- data/lib/rudy/routines/handlers/script.rb +2 -1
- data/lib/rudy/routines/passthrough.rb +2 -2
- data/lib/rudy/routines/reboot.rb +2 -2
- data/lib/rudy/routines/shutdown.rb +2 -2
- data/lib/rudy/routines/startup.rb +4 -2
- data/rudy.gemspec +17 -10
- data/tryouts/10_require_time/10_rudy_tryouts.rb +1 -1
- data/tryouts/12_config/20_defaults_tryouts.rb +1 -1
- data/tryouts/12_config/40_machines_tryouts.rb +1 -1
- data/tryouts/15_huxtable/20_user_tryouts.rb +1 -1
- data/tryouts/25_ec2/10_keypairs_tryouts.rb +1 -0
- data/tryouts/30_metadata/10_include_tryouts.rb +1 -1
- data/tryouts/30_metadata/13_object_tryouts.rb +4 -0
- data/tryouts/30_metadata/50_disk_tryouts.rb +4 -2
- data/tryouts/30_metadata/51_disk_digest_tryouts.rb +1 -1
- data/tryouts/30_metadata/53_disk_list_tryouts.rb +2 -1
- data/tryouts/30_metadata/56_disk_volume_tryouts.rb +1 -1
- data/tryouts/30_metadata/60_backup_tryouts.rb +4 -2
- data/tryouts/30_metadata/63_backup_list_tryouts.rb +1 -1
- data/tryouts/30_metadata/64_backup_disk_tryouts.rb +3 -1
- data/tryouts/30_metadata/66_backup_snapshot_tryouts.rb +1 -1
- data/tryouts/30_metadata/70_machine_tryouts.rb +5 -2
- data/tryouts/30_metadata/73_machine_list_tryouts.rb +1 -1
- data/tryouts/30_metadata/76_machine_instance_tryouts.rb +15 -3
- data/tryouts/30_metadata/77_machines_tryouts.rb +1 -1
- data/tryouts/40_routines/10_keypair_handler_tryouts.rb +6 -5
- data/tryouts/40_routines/11_group_handler_tryouts.rb +1 -1
- metadata +14 -7
- data/lib/rudy/cli/status.rb +0 -60
data/lib/rudy/config/objects.rb
CHANGED
data/lib/rudy/disks.rb
CHANGED
data/lib/rudy/global.rb
CHANGED
@@ -70,7 +70,7 @@ module Rudy
|
|
70
70
|
# value from the defaults config.
|
71
71
|
# WARNING: Don't add bucket either or any machines configuration param
|
72
72
|
# TODO: investigate removing this apply_config method
|
73
|
-
%w[region zone environment role position
|
73
|
+
%w[region zone environment role position bucket
|
74
74
|
localhost nocolor quiet auto force parallel].each do |name|
|
75
75
|
curval, defval = self.send(name), config.defaults.send(name)
|
76
76
|
if curval.nil? && !defval.nil?
|
data/lib/rudy/huxtable.rb
CHANGED
@@ -177,8 +177,8 @@ module Rudy
|
|
177
177
|
end
|
178
178
|
|
179
179
|
def current_machine_address(position='01')
|
180
|
-
raise NoConfig unless @@config
|
181
|
-
raise NoMachinesConfig unless @@config.machines
|
180
|
+
#raise NoConfig unless @@config
|
181
|
+
#raise NoMachinesConfig unless @@config.machines
|
182
182
|
raise "Position cannot be nil" if position.nil?
|
183
183
|
addresses = [fetch_machine_param(:addresses)].flatten.compact
|
184
184
|
addresses[position.to_i-1]
|
@@ -275,7 +275,7 @@ module Rudy
|
|
275
275
|
end
|
276
276
|
disks.each_pair do |path, props|
|
277
277
|
unless disk_defs.has_key?(path)
|
278
|
-
li "#{path} is not defined. Check your
|
278
|
+
li "#{path} is not defined. Check your machines config.".color(:red)
|
279
279
|
routine.disks[raction].delete(path)
|
280
280
|
next
|
281
281
|
end
|
@@ -288,6 +288,12 @@ module Rudy
|
|
288
288
|
routine
|
289
289
|
end
|
290
290
|
|
291
|
+
def self.generate_rudy_command(name, *args)
|
292
|
+
cmd = "rudy "
|
293
|
+
cmd << "-C " << @@global.config.join(' -C ') if @@global.config
|
294
|
+
"#{cmd} #{name} " << args.join(' ')
|
295
|
+
end
|
296
|
+
|
291
297
|
# Is +action+ a valid routine for the current machine group?
|
292
298
|
def valid_routine?(action)
|
293
299
|
!fetch_routine_config(action).nil?
|
data/lib/rudy/machines.rb
CHANGED
data/lib/rudy/metadata.rb
CHANGED
@@ -106,11 +106,14 @@ module Rudy
|
|
106
106
|
criteria
|
107
107
|
end
|
108
108
|
|
109
|
+
|
110
|
+
# These methods are common to all plural metadata classes:
|
111
|
+
# Rudy::Machines, Rudy::Disks, Rudy::Backups, etc...
|
112
|
+
#
|
109
113
|
module ClassMethods
|
110
114
|
extend self
|
111
115
|
extend Rudy::Huxtable
|
112
116
|
|
113
|
-
# TODO: MOVE TO Rudy:Disks etc...
|
114
117
|
def list(fields={}, less=[], &block)
|
115
118
|
fields = Rudy::Metadata.build_criteria self::RTYPE, fields, less
|
116
119
|
records_raw, records = Rudy::Metadata.select(fields), []
|
data/lib/rudy/metadata/backup.rb
CHANGED
@@ -67,8 +67,8 @@ module Rudy
|
|
67
67
|
@second = @created.sec.to_s.rjust(2, '0')
|
68
68
|
end
|
69
69
|
|
70
|
-
def to_s(
|
71
|
-
|
70
|
+
def to_s(*args)
|
71
|
+
[self.name.bright, self.snapid, self.volid, self.size, self.fstype].join '; '
|
72
72
|
end
|
73
73
|
|
74
74
|
def name
|
data/lib/rudy/metadata/disk.rb
CHANGED
@@ -16,6 +16,9 @@ module Rudy
|
|
16
16
|
field :size
|
17
17
|
field :fstype
|
18
18
|
|
19
|
+
field :name # Windows, used for label
|
20
|
+
field :index # Windows, used for diskpart
|
21
|
+
|
19
22
|
#field :backups => Array
|
20
23
|
|
21
24
|
# Is the associated volume formatted? One of: true, false
|
@@ -45,7 +48,7 @@ module Rudy
|
|
45
48
|
|
46
49
|
opts = {
|
47
50
|
:size => 1,
|
48
|
-
:device => '
|
51
|
+
:device => current_machine_os.to_s == 'windows' ? DEFAULT_WINDOWS_DEVICE : DEFAULT_LINUX_DEVICE
|
49
52
|
}.merge opts
|
50
53
|
|
51
54
|
super Rudy::Disks::RTYPE, opts # Rudy::Metadata#initialize
|
@@ -68,8 +71,8 @@ module Rudy
|
|
68
71
|
@mounted = (@mounted == "true") unless @mounted.is_a?(TrueClass)
|
69
72
|
end
|
70
73
|
|
71
|
-
def to_s(
|
72
|
-
self.name
|
74
|
+
def to_s(*args)
|
75
|
+
[self.name.bright, self.volid, self.size, self.fstype].join '; '
|
73
76
|
end
|
74
77
|
|
75
78
|
def name
|
@@ -83,7 +86,7 @@ module Rudy
|
|
83
86
|
end
|
84
87
|
|
85
88
|
def create(size=nil, zone=nil, snapshot=nil)
|
86
|
-
raise DuplicateRecord, self.name if exists?
|
89
|
+
raise DuplicateRecord, self.name if exists? && !@@global.force
|
87
90
|
vol = Rudy::AWS::EC2::Volumes.create(size || @size, zone || @zone, snapshot)
|
88
91
|
#vol = Rudy::AWS::EC2::Volumes.list(:available).first # debugging
|
89
92
|
@volid, @raw = vol.awsid, true
|
@@ -77,16 +77,55 @@ module Rudy
|
|
77
77
|
|
78
78
|
def postprocess
|
79
79
|
@position &&= @position.to_s.rjust(2, '0')
|
80
|
+
@os &&= @os.to_sym
|
80
81
|
end
|
81
82
|
|
82
83
|
def to_s(*args)
|
83
|
-
self.name
|
84
|
+
[self.name.bright, self.instid, self.dns_public].join '; '
|
84
85
|
end
|
85
86
|
|
87
|
+
def rbox
|
88
|
+
r = Rudy::Routines::Handlers::RyeTools.create_box self
|
89
|
+
end
|
90
|
+
|
91
|
+
def disks
|
92
|
+
Rudy::Disks.list
|
93
|
+
end
|
94
|
+
|
95
|
+
|
86
96
|
def get_instance
|
87
97
|
Rudy::AWS::EC2::Instances.get @instid
|
88
98
|
end
|
89
99
|
|
100
|
+
def get_console
|
101
|
+
raise "Instance not running" unless instance_running?
|
102
|
+
raw = Rudy::AWS::EC2::Instances.console @instid
|
103
|
+
console = Base64.decode64(raw)
|
104
|
+
# The linux console can include ANSI escape codes for color,
|
105
|
+
# clear screen etc... We strip them out to get rid of the
|
106
|
+
# clear specifically. Otherwise the display is messed!
|
107
|
+
console &&= console.noansi if console.respond_to? :noansi
|
108
|
+
console
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_password
|
112
|
+
unless windows?
|
113
|
+
raise "Password support is Windows only (this is #{@os})"
|
114
|
+
end
|
115
|
+
console = get_console
|
116
|
+
|
117
|
+
raise "Console output not yet available. Please wait." if console.nil?
|
118
|
+
|
119
|
+
unless console.match(/<Password>(.+)<\/Password>/m)
|
120
|
+
# /m, match multiple lines
|
121
|
+
raise "Password not yet available. Is this a custom AMI?"
|
122
|
+
end
|
123
|
+
|
124
|
+
encrtypted_text = ($1 || '').strip
|
125
|
+
k = Rye::Key.from_file root_keypairpath
|
126
|
+
k.decrypt encrtypted_text
|
127
|
+
end
|
128
|
+
|
90
129
|
def create
|
91
130
|
raise "#{name} is already running" if instance_running?
|
92
131
|
|
@@ -103,6 +142,10 @@ module Rudy
|
|
103
142
|
|
104
143
|
Rudy::Huxtable.ld "OPTS: #{opts.inspect}"
|
105
144
|
|
145
|
+
#@dns_public = @dns_private = nil
|
146
|
+
#inst = Rudy::AWS::EC2::Instances.list(:running).first
|
147
|
+
#@instid = inst.awsid
|
148
|
+
|
106
149
|
Rudy::AWS::EC2::Instances.create(opts) do |inst|
|
107
150
|
@instid = inst.awsid
|
108
151
|
@created = @started = Time.now
|
@@ -125,6 +168,7 @@ module Rudy
|
|
125
168
|
STDERR.puts ex.backtrace if Rudy.debug?
|
126
169
|
end
|
127
170
|
end
|
171
|
+
|
128
172
|
self.save
|
129
173
|
self
|
130
174
|
end
|
@@ -138,9 +182,15 @@ module Rudy
|
|
138
182
|
Rudy::AWS::EC2::Instances.restart(@instid) if instance_running?
|
139
183
|
end
|
140
184
|
|
185
|
+
def attached_volumes
|
186
|
+
volumes = []
|
187
|
+
return volumes if @instid.nil?
|
188
|
+
Rudy::AWS::EC2::Volumes.list_by_instance( @instid) || []
|
189
|
+
end
|
190
|
+
|
141
191
|
def refresh!(metadata=true)
|
142
192
|
## Updating the metadata isn't necessary
|
143
|
-
|
193
|
+
super() if metadata # update metadata
|
144
194
|
@instance = get_instance
|
145
195
|
if @instance.is_a?(Rudy::AWS::EC2::Instance)
|
146
196
|
@dns_public, @dns_private = @instance.dns_public, @instance.dns_private
|
@@ -161,6 +211,20 @@ module Rudy
|
|
161
211
|
d
|
162
212
|
end
|
163
213
|
|
214
|
+
def default_fstype
|
215
|
+
windows? ? Rudy::DEFAULT_WINDOWS_FS : Rudy::DEFAULT_LINUX_FS
|
216
|
+
end
|
217
|
+
|
218
|
+
def default_device
|
219
|
+
windows? ? Rudy::DEFAULT_WINDOWS_DEVICE : Rudy::DEFAULT_LINUX_DEVICE
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
def os?(v); @os.to_s == v.to_s; end
|
224
|
+
def windows?; os? 'windows'; end
|
225
|
+
def linux?; os? 'linux'; end
|
226
|
+
def solaris?; os? 'solaris'; end
|
227
|
+
|
164
228
|
def dns_public?; !@dns_public.nil? && !@dns_public.empty?; end
|
165
229
|
def dns_private?; !@dns_private.nil? && !@dns_private.empty?; end
|
166
230
|
|
data/lib/rudy/routines.rb
CHANGED
@@ -95,9 +95,10 @@ module Rudy
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def self.rescue(ret=nil, &bloc_party)
|
98
|
+
|
98
99
|
begin
|
99
100
|
ret = bloc_party.call
|
100
|
-
rescue NameError, ArgumentError, RuntimeError => ex
|
101
|
+
rescue NameError, ArgumentError, RuntimeError, Errno::ECONNREFUSED => ex
|
101
102
|
STDERR.puts " #{ex.class}: #{ex.message}".color(:red)
|
102
103
|
STDERR.puts ex.backtrace if Rudy.debug?
|
103
104
|
unless Rudy::Huxtable.global.parallel
|
data/lib/rudy/routines/base.rb
CHANGED
@@ -49,7 +49,10 @@ module Rudy; module Routines;
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Share one Rye::Box instance for localhost across all routines
|
52
|
-
|
52
|
+
unless defined?(@@lbox)
|
53
|
+
host, opts = @@global.localhost, { :user => Rudy.sysinfo.user }
|
54
|
+
@@lbox = Rudy::Routines::Handlers::RyeTools.create_box host, opts
|
55
|
+
end
|
53
56
|
|
54
57
|
disable_run if @@global.testrun
|
55
58
|
|
@@ -68,162 +71,6 @@ module Rudy; module Routines;
|
|
68
71
|
def raise_early_exceptions; raise "Please override"; end
|
69
72
|
def execute; raise "Please override"; end
|
70
73
|
|
71
|
-
# Create an instance of Rye::Box for +hostname+. +opts+ is
|
72
|
-
# an optional Hash of options. See Rye::Box.initialize
|
73
|
-
#
|
74
|
-
# This method should be used throughout the Rudy::Routines
|
75
|
-
# namespace rather than creating instances manually b/c it
|
76
|
-
# applies some fancy pants defaults like command hooks.
|
77
|
-
def create_rye_box(hostname, opts={})
|
78
|
-
ld [:hostname, hostname, opts, caller[0]]
|
79
|
-
opts = {
|
80
|
-
:info => (@@global.verbose >= 3), # rudy -vvv
|
81
|
-
:debug => false,
|
82
|
-
:user => Rudy.sysinfo.user
|
83
|
-
}.merge opts
|
84
|
-
|
85
|
-
box = Rye::Box.new hostname, opts
|
86
|
-
|
87
|
-
|
88
|
-
# We define hooks so we can still print each command and its output
|
89
|
-
# when running the command blocks. NOTE: We only print this in
|
90
|
-
# verbosity mode.
|
91
|
-
if @@global.verbose > 0 && !@@global.parallel
|
92
|
-
# This block gets called for every command method call.
|
93
|
-
box.pre_command_hook do |cmd, user, host, nickname|
|
94
|
-
print_command user, nickname, cmd
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
if @@global.verbose > 1
|
99
|
-
# And this one gets called after each command method call.
|
100
|
-
box.post_command_hook do |ret|
|
101
|
-
print_response ret
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
box.exception_hook(Rye::CommandError, &rbox_exception_handler)
|
106
|
-
box.exception_hook(Exception, &rbox_exception_handler)
|
107
|
-
|
108
|
-
## It'd better for unknown commands to be handled elsewhere
|
109
|
-
## because it doesn't make sense to retry a method that doesn't exist
|
110
|
-
##box.exception_hook(Rye::CommandNotFound, &rbox_exception_handler)
|
111
|
-
|
112
|
-
box
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# Create an instance of Rye::Set from a list of +hostnames+.
|
118
|
-
# +hostnames+ can contain hostnames or Rudy::Machine objects.
|
119
|
-
# +opts+ is an optional Hash of options. See Rye::Box.initialize
|
120
|
-
#
|
121
|
-
# NOTE: Windows machines are skipped and not added to the set.
|
122
|
-
def create_rye_set(hostnames, opts={})
|
123
|
-
hostnames ||= []
|
124
|
-
|
125
|
-
opts = {
|
126
|
-
:user => (current_machine_user).to_s,
|
127
|
-
:parallel => @@global.parallel
|
128
|
-
}.merge(opts)
|
129
|
-
set = Rye::Set.new current_machine_group, opts
|
130
|
-
|
131
|
-
opts.delete(:parallel) # Not used by Rye::Box.new
|
132
|
-
|
133
|
-
hostnames.each do |m|
|
134
|
-
# This is a short-circuit for Windows instances. We don't support
|
135
|
-
# disks for windows yet and there's no SSH so routines are out of
|
136
|
-
# the picture too.
|
137
|
-
next if (m.os || '').to_s == 'win32'
|
138
|
-
|
139
|
-
if m.is_a?(Rudy::Machine)
|
140
|
-
m.refresh! if m.dns_public.nil? || m.dns_public.empty?
|
141
|
-
if m.dns_public.nil? || m.dns_public.empty?
|
142
|
-
ld "Cannot find public DNS for #{m.name} (continuing...)"
|
143
|
-
##next
|
144
|
-
end
|
145
|
-
ld [:dns_public, m.dns_public, m.instid]
|
146
|
-
rbox = create_rye_box(m.dns_public, opts)
|
147
|
-
rbox.stash = m # Store the machine instance in the stash
|
148
|
-
rbox.nickname = m.name
|
149
|
-
else
|
150
|
-
# Otherwise we assume it's a hostname
|
151
|
-
rbox = create_rye_box(m)
|
152
|
-
end
|
153
|
-
rbox.add_key user_keypairpath(opts[:user])
|
154
|
-
set.add_box rbox
|
155
|
-
end
|
156
|
-
|
157
|
-
ld "Machines Set: %s" % [set.empty? ? '[empty]' : set.inspect]
|
158
|
-
|
159
|
-
set
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
# Returns a formatted string for printing command info
|
166
|
-
def print_command(user, host, cmd)
|
167
|
-
#return if @@global.parallel
|
168
|
-
cmd ||= ""
|
169
|
-
cmd, user = cmd.to_s, user.to_s
|
170
|
-
prompt = user == "root" ? "#" : "$"
|
171
|
-
li ("%s@%s%s %s" % [user, host, prompt, cmd.bright])
|
172
|
-
end
|
173
|
-
|
174
|
-
def print_response(rap)
|
175
|
-
# Non zero exit codes raise exceptions so
|
176
|
-
# the erorrs have already been handled.
|
177
|
-
return if rap.exit_code != 0
|
178
|
-
|
179
|
-
if @@global.parallel
|
180
|
-
cmd, user = cmd.to_s, user.to_s
|
181
|
-
prompt = user == "root" ? "#" : "$"
|
182
|
-
li "%s@%s%s %s%s%s" % [rap.box.user, rap.box.nickname, prompt, rap.cmd.bright, $/, rap.stdout.inspect]
|
183
|
-
unless rap.stderr.empty?
|
184
|
-
le "#{rap.box.nickname}: " << rap.stderr.join("#{rap.box.nickname}: ")
|
185
|
-
end
|
186
|
-
else
|
187
|
-
li ' ' << rap.stdout.join("#{$/} ") if !rap.stdout.empty?
|
188
|
-
colour = rap.exit_code != 0 ? :red : :normal
|
189
|
-
unless rap.stderr.empty?
|
190
|
-
le (" STDERR " << '-'*38).color(colour).bright
|
191
|
-
le " " << rap.stderr.join("#{$/} ").color(colour)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
private
|
197
|
-
|
198
|
-
def rbox_exception_handler
|
199
|
-
Proc.new do |ex, cmd, user, host, nickname|
|
200
|
-
print_exception(user, host, cmd, nickname, ex)
|
201
|
-
unless @@global.parallel
|
202
|
-
choice = Annoy.get_user_input('(S)kip (R)etry (F)orce (A)bort: ', nil, 3600) || ''
|
203
|
-
if choice.match(/\AS/i)
|
204
|
-
:skip
|
205
|
-
elsif choice.match(/\AR/i)
|
206
|
-
:retry # Tells Rye::Box#run_command to retry
|
207
|
-
elsif choice.match(/\AF/i)
|
208
|
-
@@global.force = true
|
209
|
-
:retry
|
210
|
-
else
|
211
|
-
exit 12
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def print_exception(user, host, cmd, nickname, ex)
|
218
|
-
prefix = @@global.parallel ? "#{nickname}: #{cmd}: " : ""
|
219
|
-
if ex.is_a?(Rye::CommandError)
|
220
|
-
le prefix << ex.message.color(:red)
|
221
|
-
else
|
222
|
-
le prefix << "#{ex.class}: #{ex.message}".color(:red)
|
223
|
-
end
|
224
|
-
le *ex.backtrace if @@global.verbose > 2
|
225
|
-
end
|
226
|
-
|
227
74
|
end
|
228
75
|
|
229
76
|
end; end;
|
@@ -12,11 +12,14 @@ module Rudy; module Routines; module Handlers;
|
|
12
12
|
print_response(ret)
|
13
13
|
rescue IOError => ex
|
14
14
|
STDERR.puts " Connection Error (#{ex.message})".color(:red)
|
15
|
-
choice = Annoy.get_user_input('(S)kip (A)bort: ', nil, 3600) || ''
|
15
|
+
choice = Annoy.get_user_input('(S)kip (R)etry (F)orce (A)bort: ', nil, 3600) || ''
|
16
16
|
if choice.match(/\AS/i)
|
17
17
|
return
|
18
|
-
|
19
|
-
|
18
|
+
elsif choice.match(/\AR/i)
|
19
|
+
retry
|
20
|
+
elsif choice.match(/\AF/i)
|
21
|
+
@@global.force = true
|
22
|
+
retry
|
20
23
|
else
|
21
24
|
exit 12
|
22
25
|
end
|