rudy 0.9.1 → 0.9.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/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
|