solutious-rudy 0.9.0 → 0.9.1

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.
Files changed (48) hide show
  1. data/CHANGES.txt +61 -4
  2. data/README.rdoc +91 -53
  3. data/Rakefile +0 -92
  4. data/Rudyfile +15 -25
  5. data/bin/rudy +52 -41
  6. data/examples/gem-test.rb +92 -0
  7. data/lib/rudy.rb +15 -7
  8. data/lib/rudy/aws.rb +2 -2
  9. data/lib/rudy/aws/ec2.rb +2 -2
  10. data/lib/rudy/aws/ec2/instance.rb +3 -3
  11. data/lib/rudy/aws/ec2/volume.rb +4 -4
  12. data/lib/rudy/cli/aws/ec2/candy.rb +13 -13
  13. data/lib/rudy/cli/base.rb +10 -4
  14. data/lib/rudy/cli/config.rb +13 -3
  15. data/lib/rudy/cli/disks.rb +1 -1
  16. data/lib/rudy/cli/execbase.rb +5 -2
  17. data/lib/rudy/cli/machines.rb +231 -30
  18. data/lib/rudy/cli/networks.rb +34 -0
  19. data/lib/rudy/cli/routines.rb +1 -1
  20. data/lib/rudy/cli/status.rb +60 -0
  21. data/lib/rudy/config.rb +42 -14
  22. data/lib/rudy/exceptions.rb +5 -1
  23. data/lib/rudy/global.rb +29 -13
  24. data/lib/rudy/huxtable.rb +2 -2
  25. data/lib/rudy/machines.rb +2 -2
  26. data/lib/rudy/metadata/disk.rb +2 -1
  27. data/lib/rudy/routines.rb +3 -3
  28. data/lib/rudy/routines/base.rb +7 -4
  29. data/lib/rudy/routines/handlers/disks.rb +16 -6
  30. data/lib/rudy/routines/handlers/group.rb +5 -3
  31. data/lib/rudy/routines/handlers/host.rb +14 -16
  32. data/lib/rudy/routines/handlers/script.rb +2 -2
  33. data/lib/rudy/routines/handlers/user.rb +4 -0
  34. data/lib/rudy/routines/reboot.rb +26 -9
  35. data/lib/rudy/routines/shutdown.rb +4 -0
  36. data/lib/rudy/routines/startup.rb +3 -2
  37. data/lib/rudy/utils.rb +23 -9
  38. data/rudy.gemspec +10 -29
  39. data/tryouts/10_require_time/10_rudy_tryouts.rb +1 -1
  40. data/tryouts/{misc/console_tryout.rb → exploration/console.rb} +0 -0
  41. data/tryouts/{misc/usage_tryout.rb → exploration/machine.rb} +0 -0
  42. data/tryouts/failer +1 -1
  43. metadata +8 -70
  44. data/tryouts/misc/disks_tryout.rb +0 -48
  45. data/tryouts/misc/drydock_tryout.rb +0 -48
  46. data/tryouts/misc/nested_methods.rb +0 -103
  47. data/tryouts/misc/session_tryout.rb +0 -46
  48. data/tryouts/misc/tryouts.rb +0 -33
@@ -0,0 +1,60 @@
1
+
2
+
3
+ module Rudy
4
+ module CLI
5
+ class Status < Rudy::CLI::CommandBase
6
+
7
+ def status
8
+ process_region @@global.region
9
+ oregions = Rudy::AWS::VALID_REGIONS - [@@global.region.to_sym]
10
+ if @option.all
11
+ oregions.each do |region|
12
+ Rudy::AWS::EC2.connect @@global.accesskey, @@global.secretkey, region
13
+ process_region region
14
+ end
15
+ else
16
+ puts $/, "Other regions: " << oregions.join(', ')
17
+ end
18
+ end
19
+
20
+
21
+ private
22
+ def process_region(region)
23
+ puts " Region: %s %30s".att(:reverse) % [region, '']
24
+ puts " Instances".bright
25
+ istatus = @option.all ? :any : :running
26
+ (Rudy::AWS::EC2::Instances.list(istatus) || []).collect do |inst|
27
+ puts " %s (%s): %s; %s; %s" % [inst.awsid, inst.state, inst.dns_public || '[no dns]', inst.size, inst.created]
28
+ end
29
+
30
+ puts " Volumes".bright
31
+ (Rudy::AWS::EC2::Volumes.list || []).collect do |vol|
32
+ puts " %s (%s): %sGB; %s" % [vol.awsid, vol.instid || vol.status, vol.size, vol.created]
33
+ end
34
+
35
+ puts " Snapshots".bright
36
+ (Rudy::AWS::EC2::Snapshots.list || []).collect do |snap|
37
+ puts " %s: %s; %s" % [snap.awsid, snap.volid, snap.created]
38
+ end
39
+
40
+ puts " Addresses".bright
41
+ (Rudy::AWS::EC2::Addresses.list || []).collect do |o|
42
+ puts " %s (%s)" % [o.ipaddress, o.instid || 'available']
43
+ end
44
+
45
+ puts " Groups".bright
46
+ puts (Rudy::AWS::EC2::Groups.list || []).collect { |o| " #{o.name}" }
47
+
48
+ puts " Keypairs".bright
49
+ puts (Rudy::AWS::EC2::Keypairs.list || []).collect { |o| " #{o.name}" }
50
+
51
+ puts " Images".bright
52
+ (Rudy::AWS::EC2::Images.list('self') || []).collect do |o|
53
+ puts " %s: %s; %s; %s" % [o.awsid, o.location, o.arch, o.visibility]
54
+ end
55
+ puts
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -44,6 +44,30 @@ module Rudy
44
44
  @defaults = Rudy::Config::Defaults.new if @defaults.nil?
45
45
  end
46
46
 
47
+ # Looks for a loads configuration files from standard locations.
48
+ # ./.rudy/config
49
+ # ~/.rudy/config
50
+ #
51
+ # ~/.rudy/*.rb
52
+ # ./Rudyfile
53
+ # ./machines.rb, ./routines.rb, ./commands.rb
54
+ # ./config/rudy/*.rb
55
+ # ./.rudy/*.rb
56
+ # /etc/rudy/*.rb
57
+ #
58
+ # When multuple files are found, the configuration is NOT OVERRIDDEN,
59
+ # it's ADDED or APPENDED depending on context. This means you can split
60
+ # configuration across as many files as you please.
61
+ #
62
+ # There are five sections: accounts, defaults, machines, commands and routines.
63
+ #
64
+ # By convention, accounts go in ./.rudy/config or ~/.rudy/config
65
+ # machines, commands, routines, and defaults configuration go in ./Rudyfile or
66
+ # into separate files in ./.rudy or ./config/rudy (machines.rb, commands.rb, ...)
67
+ #
68
+ # If +adhoc_path+ is supplied (e.g. rudy -C config/file/path routines), this method
69
+ # will look for ~/.rudy/config or ./.rudy/config but none of the other default file
70
+ # locations other than the supplied path. If it's an Array, all paths will be loaded.
47
71
  def look_and_load(adhoc_path=nil)
48
72
  cwd = Dir.pwd
49
73
  cwd_path = File.join(cwd, '.rudy', 'config')
@@ -52,24 +76,28 @@ module Rudy
52
76
  # The "core" config file can have any or all configuration
53
77
  # but it should generally only contain the access identifiers
54
78
  # and defaults. That's why we only load one of them.
55
- core_config_paths = [adhoc_path, cwd_path, Rudy::CONFIG_FILE]
79
+ core_config_paths = [cwd_path, Rudy::CONFIG_FILE]
56
80
  core_config_paths.each do |path|
57
81
  next unless path && File.exists?(path)
58
82
  @paths << path
59
83
  break
60
84
  end
61
85
 
62
- # self.keys returns the current config types (machines, routines, etc...)
63
- typelist = self.keys.collect { |g| "#{g}.rb" }.join(',')
86
+ if adhoc_path.nil?
87
+ # self.keys returns the current config types (machines, routines, etc...)
88
+ typelist = self.keys.collect { |g| "#{g}.rb" }.join(',')
64
89
 
65
- # Rudy then looks for the rest of the config in these locations
66
- @paths += Dir.glob(File.join(Rudy.sysinfo.home, '.rudy', '*.rb')) || []
67
- @paths += Dir.glob(File.join(cwd, 'Rudyfile')) || []
68
- @paths += Dir.glob(File.join(cwd, 'config', 'rudy', '*.rb')) || []
69
- @paths += Dir.glob(File.join(cwd, '.rudy', '*.rb')) || []
70
- @paths += Dir.glob(File.join(cwd, "{#{typelist}}")) || []
71
- @paths += Dir.glob(File.join('/etc', 'rudy', '*.rb')) || []
72
- @paths &&= @paths.uniq
90
+ # Rudy then looks for the rest of the config in these locations
91
+ @paths += Dir.glob(File.join(Rudy.sysinfo.home, '.rudy', '*.rb')) || []
92
+ @paths += Dir.glob(File.join(cwd, 'Rudyfile')) || []
93
+ @paths += Dir.glob(File.join(cwd, 'config', 'rudy', '*.rb')) || []
94
+ @paths += Dir.glob(File.join(cwd, '.rudy', '*.rb')) || []
95
+ @paths += Dir.glob(File.join(cwd, "{#{typelist}}")) || []
96
+ @paths += Dir.glob(File.join('/etc', 'rudy', '*.rb')) || []
97
+ @paths &&= @paths.uniq
98
+ else
99
+ @paths += [adhoc_path].flatten
100
+ end
73
101
 
74
102
  refresh
75
103
  end
@@ -88,9 +116,9 @@ module Rudy
88
116
  accounts { # Account Access Indentifiers
89
117
  aws { # amazon web services
90
118
  name "Rudy Default"
91
- accountnum "012345678912"
92
- accesskey "ACCESSACCESS"
93
- secretkey "SECRETSECRET"
119
+ accountnum ""
120
+ accesskey ""
121
+ secretkey ""
94
122
  pkey "~/path/2/pk-xxxx.pem"
95
123
  cert "~/path/2/cert-xxxx.pem"
96
124
  }
@@ -48,7 +48,11 @@ module Rudy
48
48
  def message; "Machine #{@obj} is not running."; end
49
49
  end
50
50
  class NoMachines < Rudy::Error;
51
- def message; "Specified remote machine(s) not running"; end
51
+ def message
52
+ msg = "No machines running "
53
+ msg << "in #{@obj}" if @obj
54
+ msg
55
+ end
52
56
  end
53
57
  class MachineGroupNotDefined < Rudy::Error
54
58
  def message; "#{@obj} is not defined in machines config."; end
@@ -22,7 +22,7 @@ module Rudy
22
22
  field :verbose
23
23
  field :format
24
24
  field :print_header
25
- field :yes
25
+ field :auto
26
26
  field :force
27
27
 
28
28
  field :accesskey
@@ -57,6 +57,7 @@ module Rudy
57
57
  end
58
58
 
59
59
  def apply_config(config)
60
+
60
61
  return unless config.is_a?(Rudy::Config)
61
62
  clear_system_defaults # temporarily unapply default values
62
63
 
@@ -70,9 +71,12 @@ module Rudy
70
71
  # WARNING: Don't add bucket either or any machines configuration param
71
72
  # TODO: investigate removing this apply_config method
72
73
  %w[region zone environment role position
73
- localhost nocolor quiet yes force parallel].each do |name|
74
+ localhost nocolor quiet auto force parallel].each do |name|
74
75
  curval, defval = self.send(name), config.defaults.send(name)
75
- self.send("#{name}=", defval) if curval.nil? && !defval.nil?
76
+ if curval.nil? && !defval.nil?
77
+ # Don't use the accessors. These are defaults so no Region magic.
78
+ self.instance_variable_set("@#{name}", defval)
79
+ end
76
80
  end
77
81
  end
78
82
 
@@ -85,17 +89,22 @@ module Rudy
85
89
  postprocess
86
90
  end
87
91
 
88
- def zone=(z)
89
- @zone = z.to_sym
90
- @region = @zone.to_s.gsub(/[a-z]$/, '').to_sym
91
- end
92
-
93
92
  def update(ghash={})
94
93
  ghash = ghash.marshal_dump if ghash.is_a?(OpenStruct)
95
94
  ghash.each_pair { |n,v| self.send("#{n}=", v) }
96
95
  postprocess
97
96
  end
98
97
 
98
+ def zone=(z)
99
+ @zone = z
100
+ @region = @zone.to_s.gsub(/[a-z]$/, '').to_sym
101
+ end
102
+
103
+ def region=(r)
104
+ @region = r
105
+ @zone = "#{@region}b".to_sym
106
+ end
107
+
99
108
  def to_s(*args)
100
109
  super()
101
110
  end
@@ -112,7 +121,8 @@ module Rudy
112
121
  @position &&= @position.to_s.rjust(2, '0')
113
122
  @format &&= @format.to_sym rescue nil
114
123
  @quiet ? Rudy.enable_quiet : Rudy.disable_quiet
115
- @yes ? Rudy.enable_yes : Rudy.disable_yes
124
+ @auto ? Rudy.enable_auto : Rudy.disable_auto
125
+
116
126
  end
117
127
 
118
128
  def apply_environment_variables
@@ -125,12 +135,18 @@ module Rudy
125
135
 
126
136
  # Apply defaults for parameters that must have values
127
137
  def apply_system_defaults
128
- @region ||= Rudy::DEFAULT_REGION
129
- @zone ||= Rudy::DEFAULT_ZONE
138
+ if @region.nil? && @zone.nil?
139
+ @region, @zone = Rudy::DEFAULT_REGION, Rudy::DEFAULT_ZONE
140
+ elsif @region.nil?
141
+ @region = @zone.to_s.gsub(/[a-z]$/, '').to_sym
142
+ elsif @zone.nil?
143
+ @zone = "#{@region}b".to_sym
144
+ end
145
+
130
146
  @environment ||= Rudy::DEFAULT_ENVIRONMENT
131
147
  @role ||= Rudy::DEFAULT_ROLE
132
148
  @localhost ||= Rudy.sysinfo.hostname || 'localhost'
133
- @yes = false if @yes.nil?
149
+ @auto = false if @auto.nil?
134
150
  end
135
151
 
136
152
  # Unapply defaults for parameters that must have values.
@@ -143,7 +159,7 @@ module Rudy
143
159
  @environment = nil if @environment == Rudy::DEFAULT_ENVIRONMENT
144
160
  @role = nil if @role == Rudy::DEFAULT_ROLE
145
161
  @localhost = nil if @localhost == (Rudy.sysinfo.hostname || 'localhost')
146
- @yes = nil if @yes == false
162
+ @auto = nil if @auto == false
147
163
  end
148
164
 
149
165
  end
@@ -190,7 +190,7 @@ module Rudy
190
190
  end
191
191
 
192
192
  def current_machine_user
193
- @@global.user || fetch_machine_param(:user) || Rudy.sysinfo.user
193
+ @@global.user || fetch_machine_param(:user) || @@config.defaults.user || Rudy.sysinfo.user
194
194
  end
195
195
 
196
196
  def current_machine_bucket
@@ -253,7 +253,7 @@ module Rudy
253
253
  raise NoRoutinesConfig unless @@config.routines
254
254
  raise NoGlobal unless @@global
255
255
 
256
- action = action.to_s.tr('-', '_')
256
+ action = action.to_s.tr('-:', '_')
257
257
 
258
258
  zon, env, rol = @@global.zone, @@global.environment, @@global.role
259
259
 
@@ -38,9 +38,9 @@ module Rudy
38
38
  end
39
39
 
40
40
  # Returns an Array of newly created Rudy::Machine objects
41
- def create(size=1)
41
+ def create(size=nil)
42
42
  if Rudy::Huxtable.global.position.nil?
43
- size ||= current_machine_count.to_i
43
+ size ||= current_machine_count.to_i || 1
44
44
  group = Array.new(size) do |i|
45
45
  m = Rudy::Machine.new(i + 1)
46
46
  m.create
@@ -69,7 +69,7 @@ module Rudy
69
69
  end
70
70
 
71
71
  def to_s(with_titles=true)
72
- "%s; %s" % [self.name, self.to_hash.inspect]
72
+ self.name
73
73
  end
74
74
 
75
75
  def name
@@ -96,6 +96,7 @@ module Rudy
96
96
  back = Rudy::Backup.new @position, @path, self.descriptors
97
97
  back.create
98
98
  back.size, back.fstype = @size, @fstype
99
+ back.save :replace
99
100
  back
100
101
  end
101
102
 
@@ -97,10 +97,10 @@ module Rudy
97
97
  def self.rescue(ret=nil, &bloc_party)
98
98
  begin
99
99
  ret = bloc_party.call
100
- rescue => ex
100
+ rescue NameError, ArgumentError, RuntimeError => ex
101
+ STDERR.puts " #{ex.class}: #{ex.message}".color(:red)
102
+ STDERR.puts ex.backtrace if Rudy.debug?
101
103
  unless Rudy::Huxtable.global.parallel
102
- STDERR.puts " #{ex.class}: #{ex.message}".color(:red)
103
- STDERR.puts ex.backtrace if Rudy.debug?
104
104
  choice = Annoy.get_user_input('(S)kip (A)bort: ', nil, 3600) || ''
105
105
  if choice.match(/\AS/i)
106
106
  # do nothing
@@ -38,7 +38,7 @@ module Rudy; module Routines;
38
38
 
39
39
  # Grab the routines configuration for this routine name
40
40
  # e.g. startup, sysupdate, installdeps
41
- @routine = fetch_routine_config @name
41
+ @routine = fetch_routine_config @name rescue {}
42
42
 
43
43
  ld "Routine: #{@routine.inspect}"
44
44
 
@@ -88,7 +88,7 @@ module Rudy; module Routines;
88
88
  # We define hooks so we can still print each command and its output
89
89
  # when running the command blocks. NOTE: We only print this in
90
90
  # verbosity mode.
91
- if @@global.verbose > 0
91
+ if @@global.verbose > 0 && !@@global.parallel
92
92
  # This block gets called for every command method call.
93
93
  box.pre_command_hook do |cmd, user, host, nickname|
94
94
  print_command user, nickname, cmd
@@ -199,11 +199,14 @@ module Rudy; module Routines;
199
199
  Proc.new do |ex, cmd, user, host, nickname|
200
200
  print_exception(user, host, cmd, nickname, ex)
201
201
  unless @@global.parallel
202
- choice = Annoy.get_user_input('(S)kip (R)etry (A)bort: ', nil, 3600) || ''
202
+ choice = Annoy.get_user_input('(S)kip (R)etry (F)orce (A)bort: ', nil, 3600) || ''
203
203
  if choice.match(/\AS/i)
204
204
  :skip
205
205
  elsif choice.match(/\AR/i)
206
206
  :retry # Tells Rye::Box#run_command to retry
207
+ elsif choice.match(/\AF/i)
208
+ @@global.force = true
209
+ :retry
207
210
  else
208
211
  exit 12
209
212
  end
@@ -218,7 +221,7 @@ module Rudy; module Routines;
218
221
  else
219
222
  le prefix << "#{ex.class}: #{ex.message}".color(:red)
220
223
  end
221
- le *ex.backtrace
224
+ le *ex.backtrace if @@global.verbose > 2
222
225
  end
223
226
 
224
227
  end
@@ -13,11 +13,19 @@ module Rudy::Routines::Handlers;
13
13
 
14
14
  end
15
15
 
16
- def disks?(routine)
16
+ def any?(routine)
17
17
  (routine.kind_of?(Hash) && routine.disks &&
18
18
  routine.disks.kind_of?(Hash) && !routine.disks.empty?) ? true : false
19
19
  end
20
20
 
21
+ # Create mount?, create?, umount? etc... methods
22
+ ACTIONS.each do |action|
23
+ define_method "#{action}?" do |routine|
24
+ return false unless any? routine
25
+ routine.disks.member? action
26
+ end
27
+ end
28
+
21
29
  def paths(routine)
22
30
  return nil unless disks?(routine)
23
31
  routine.disks.values.collect { |d| d.keys }.flatten
@@ -145,7 +153,9 @@ module Rudy::Routines::Handlers;
145
153
  disk.refresh!
146
154
 
147
155
  raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
148
- raise Rudy::Disks::NotMounted, disk.name if !disk.mounted?
156
+ if @@global.force
157
+ raise Rudy::Disks::NotMounted, disk.name if !disk.mounted?
158
+ end
149
159
 
150
160
  puts "Unmounting #{disk.path}... "
151
161
  rbox.umount(disk.path)
@@ -201,7 +211,7 @@ module Rudy::Routines::Handlers;
201
211
  end
202
212
 
203
213
  def restore(rbox, disk)
204
-
214
+
205
215
  if disk.exists?
206
216
  puts "Disk found: #{disk.name}"
207
217
  disk.refresh!
@@ -212,6 +222,7 @@ module Rudy::Routines::Handlers;
212
222
  end
213
223
 
214
224
  latest_backup = disk.backups.last
225
+ latest_backup.fstype = 'ext3' if latest_backup.fstype.nil? || latest_backup.fstype.empty?
215
226
  disk.size, disk.fstype = latest_backup.size, latest_backup.fstype
216
227
 
217
228
  puts "Backup found: #{latest_backup.name}"
@@ -222,12 +233,11 @@ module Rudy::Routines::Handlers;
222
233
  Rudy::Utils.waiter(2, 60, STDOUT, msg) {
223
234
  disk.volume_available?
224
235
  }
225
-
236
+ disk.raw = false
237
+ disk.save :replace
226
238
  end
227
- disk.raw = false
228
239
 
229
240
  attach rbox, disk unless disk.volume_attached?
230
- #format rbox, disk if disk.raw?
231
241
  mount rbox, disk unless disk.mounted?
232
242
 
233
243
  disk.save :replace
@@ -21,9 +21,11 @@ module Rudy; module Routines; module Handlers;
21
21
  def authorize(name=nil, addresses=nil, ports=nil)
22
22
  name ||= current_group_name
23
23
  addresses ||= [Rudy::Utils::external_ip_address]
24
- ports ||= [[22,22]]
25
- li "Authorizing group: #{addresses.inspect} (#{ports.inspect})"
26
- Rudy::AWS::EC2::Groups.authorize(name, addresses, ports)
24
+ if ports.nil?
25
+ ports = current_machine_os.to_s == 'win32' ? [[3389,3389]] : [[22,22]]
26
+ end
27
+ li "Authorizing ports #{ports.inspect} access for: #{addresses.join(', ')}"
28
+ Rudy::AWS::EC2::Groups.authorize(name, addresses, ports)
27
29
  end
28
30
 
29
31
  def exists?(name=nil)
@@ -8,11 +8,10 @@ module Rudy; module Routines; module Handlers;
8
8
 
9
9
  def is_running?(rset)
10
10
  raise NoMachines if rset.boxes.empty?
11
- rset.batch(rset.parallel) do |parallel|
12
- msg = "Starting #{self.nickname}..."
13
- output = parallel ? nil : Rudy::Huxtable.logger
14
- Rudy::Utils.waiter(3, 120, output, msg, 0) {
15
- inst = self.stash.get_instance
11
+ rset.boxes.each do |rbox|
12
+ msg = "Waiting for #{rbox.nickname} to boot..."
13
+ Rudy::Utils.waiter(3, 240, Rudy::Huxtable.logger, msg, 0) {
14
+ inst = rbox.stash.get_instance
16
15
  inst && inst.running?
17
16
  }
18
17
  end
@@ -25,23 +24,22 @@ module Rudy; module Routines; module Handlers;
25
24
  # the machine metadata won't contain the DNS information. Calling it
26
25
  # here ensure that the metadata is always up-to-date.
27
26
  # Each Rye:Box instance has a Rudy::Machine instance in its stash so
28
- # self.stash.update == machine.update
27
+ # rbox.stash.refresh! == machine.refresh!
29
28
  def update_dns(rset)
30
29
  raise NoMachines if rset.boxes.empty?
31
- rset.batch do
32
- self.stash.refresh!
33
- self.host = self.stash.dns_public
30
+ rset.boxes.each do |rbox|
31
+ rbox.stash.refresh!
32
+ rbox.host = rbox.stash.dns_public
34
33
  end
35
34
  end
36
35
 
37
36
  def is_available?(rset, port=22)
38
37
  raise NoMachines if rset.boxes.empty?
39
- rset.batch(rset.parallel, port) do |parallel,p|
40
- # Windows machines do not have an SSH daemon
41
- unless (self.stash.os || '').to_s == 'win32'
42
- msg = parallel ? nil : "Waiting for SSH on port #{p}..."
43
- Rudy::Utils.waiter(2, 30, STDOUT, msg, 0) {
44
- Rudy::Utils.service_available?(self.stash.dns_public, p)
38
+ rset.boxes.each do |rbox|
39
+ unless (rbox.stash.os || '').to_s == 'win32' # No SSH daemon in windows
40
+ msg = "Waiting for SSH (#{port}) on #{rbox.nickname} ..."
41
+ Rudy::Utils.waiter(2, 60, STDOUT, msg, 0) {
42
+ Rudy::Utils.service_available?(rbox.stash.dns_public, port)
45
43
  }
46
44
  end
47
45
  end
@@ -50,8 +48,8 @@ module Rudy; module Routines; module Handlers;
50
48
  def set_hostname(rset)
51
49
  raise NoMachines if rset.boxes.empty?
52
50
  original_user = rset.user
51
+ rset.switch_user 'root'
53
52
  rset.add_key user_keypairpath('root')
54
- rset.switch_user 'root'
55
53
  # Set the hostname if specified in the machines config.
56
54
  # :rudy -> change to Rudy's machine name
57
55
  # :default -> leave the hostname as it is