solutious-rudy 0.8.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/CHANGES.txt +55 -14
  2. data/README.rdoc +26 -34
  3. data/Rudyfile +27 -32
  4. data/bin/rudy +47 -27
  5. data/bin/rudy-ec2 +2 -16
  6. data/bin/rudy-s3 +0 -10
  7. data/bin/rudy-sdb +11 -12
  8. data/lib/rudy.rb +49 -89
  9. data/lib/rudy/aws.rb +2 -43
  10. data/lib/rudy/aws/ec2.rb +57 -20
  11. data/lib/rudy/aws/ec2/address.rb +10 -11
  12. data/lib/rudy/aws/ec2/group.rb +10 -9
  13. data/lib/rudy/aws/ec2/image.rb +8 -8
  14. data/lib/rudy/aws/ec2/instance.rb +15 -16
  15. data/lib/rudy/aws/ec2/keypair.rb +14 -19
  16. data/lib/rudy/aws/ec2/snapshot.rb +16 -9
  17. data/lib/rudy/aws/ec2/volume.rb +37 -24
  18. data/lib/rudy/aws/ec2/zone.rb +5 -4
  19. data/lib/rudy/aws/s3.rb +2 -1
  20. data/lib/rudy/aws/sdb.rb +35 -86
  21. data/lib/rudy/backups.rb +24 -0
  22. data/lib/rudy/cli.rb +5 -131
  23. data/lib/rudy/cli/aws/ec2/addresses.rb +19 -27
  24. data/lib/rudy/cli/aws/ec2/candy.rb +32 -7
  25. data/lib/rudy/cli/aws/ec2/groups.rb +9 -13
  26. data/lib/rudy/cli/aws/ec2/images.rb +5 -133
  27. data/lib/rudy/cli/aws/ec2/instances.rb +25 -25
  28. data/lib/rudy/cli/aws/ec2/keypairs.rb +7 -11
  29. data/lib/rudy/cli/aws/ec2/snapshots.rb +5 -9
  30. data/lib/rudy/cli/aws/ec2/volumes.rb +22 -23
  31. data/lib/rudy/cli/aws/ec2/zones.rb +2 -3
  32. data/lib/rudy/cli/aws/sdb/domains.rb +5 -6
  33. data/lib/rudy/cli/aws/sdb/objects.rb +33 -0
  34. data/lib/rudy/cli/aws/sdb/select.rb +23 -0
  35. data/lib/rudy/cli/backups.rb +38 -0
  36. data/lib/rudy/cli/base.rb +98 -0
  37. data/lib/rudy/cli/candy.rb +1 -2
  38. data/lib/rudy/cli/config.rb +7 -4
  39. data/lib/rudy/cli/disks.rb +6 -8
  40. data/lib/rudy/cli/execbase.rb +53 -0
  41. data/lib/rudy/cli/machines.rb +14 -18
  42. data/lib/rudy/cli/metadata.rb +24 -10
  43. data/lib/rudy/cli/routines.rb +31 -5
  44. data/lib/rudy/config.rb +17 -22
  45. data/lib/rudy/config/objects.rb +44 -30
  46. data/lib/rudy/disks.rb +25 -0
  47. data/lib/rudy/exceptions.rb +95 -0
  48. data/lib/rudy/global.rb +46 -23
  49. data/lib/rudy/guidelines.rb +3 -2
  50. data/lib/rudy/huxtable.rb +66 -57
  51. data/lib/rudy/machines.rb +41 -263
  52. data/lib/rudy/metadata.rb +212 -38
  53. data/lib/rudy/metadata/backup.rb +123 -78
  54. data/lib/rudy/metadata/disk.rb +152 -170
  55. data/lib/rudy/metadata/machine.rb +179 -0
  56. data/lib/rudy/mixins.rb +2 -1
  57. data/lib/rudy/mixins/hash.rb +3 -1
  58. data/lib/rudy/mixins/symbol.rb +8 -0
  59. data/lib/rudy/routines.rb +127 -344
  60. data/lib/rudy/routines/base.rb +226 -0
  61. data/lib/rudy/routines/handlers/base.rb +48 -0
  62. data/lib/rudy/routines/handlers/depends.rb +49 -0
  63. data/lib/rudy/routines/handlers/disks.rb +239 -0
  64. data/lib/rudy/routines/handlers/group.rb +42 -0
  65. data/lib/rudy/routines/handlers/host.rb +72 -0
  66. data/lib/rudy/routines/handlers/keypair.rb +70 -0
  67. data/lib/rudy/routines/handlers/machines.rb +15 -0
  68. data/lib/rudy/routines/handlers/script.rb +85 -0
  69. data/lib/rudy/routines/handlers/user.rb +41 -0
  70. data/lib/rudy/routines/passthrough.rb +19 -23
  71. data/lib/rudy/routines/reboot.rb +82 -51
  72. data/lib/rudy/routines/shutdown.rb +61 -14
  73. data/lib/rudy/routines/startup.rb +111 -17
  74. data/lib/rudy/utils.rb +12 -59
  75. data/rudy.gemspec +85 -25
  76. data/tryouts/01_mixins/01_hash_tryouts.rb +20 -0
  77. data/tryouts/10_require_time/10_rudy_tryouts.rb +33 -0
  78. data/tryouts/10_require_time/15_global_tryouts.rb +58 -0
  79. data/tryouts/12_config/10_load_config_tryouts.rb +43 -0
  80. data/tryouts/12_config/20_defaults_tryouts.rb +16 -0
  81. data/tryouts/12_config/30_accounts_tryouts.rb +17 -0
  82. data/tryouts/12_config/40_machines_tryouts.rb +53 -0
  83. data/tryouts/12_config/50_commands_tryouts.rb +17 -0
  84. data/tryouts/12_config/60_routines_tryouts.rb +16 -0
  85. data/tryouts/15_huxtable/10_huxtable_tryouts.rb +47 -0
  86. data/tryouts/15_huxtable/20_user_tryouts.rb +47 -0
  87. data/tryouts/20_simpledb/10_domains_tryouts.rb +36 -0
  88. data/tryouts/20_simpledb/20_objects_tryouts.rb +56 -0
  89. data/tryouts/25_ec2/10_keypairs_tryouts.rb +54 -0
  90. data/tryouts/25_ec2/20_groups_tryouts.rb +56 -0
  91. data/tryouts/25_ec2/21_groups_authorize_address_tryouts.rb +53 -0
  92. data/tryouts/25_ec2/22_groups_authorize_account_tryouts.rb +54 -0
  93. data/tryouts/25_ec2/30_addresses_tryouts.rb +42 -0
  94. data/tryouts/25_ec2/40_volumes_tryouts.rb +53 -0
  95. data/tryouts/25_ec2/50_snapshots_tryouts.rb +75 -0
  96. data/tryouts/26_ec2_instances/10_instance_tryouts.rb +107 -0
  97. data/tryouts/26_ec2_instances/50_images_tryouts.rb +7 -0
  98. data/tryouts/30_metadata/10_include_tryouts.rb +45 -0
  99. data/tryouts/30_metadata/13_object_tryouts.rb +19 -0
  100. data/tryouts/30_metadata/50_disk_tryouts.rb +115 -0
  101. data/tryouts/30_metadata/51_disk_digest_tryouts.rb +24 -0
  102. data/tryouts/30_metadata/53_disk_list_tryouts.rb +35 -0
  103. data/tryouts/30_metadata/56_disk_volume_tryouts.rb +68 -0
  104. data/tryouts/30_metadata/60_backup_tryouts.rb +101 -0
  105. data/tryouts/30_metadata/63_backup_list_tryouts.rb +38 -0
  106. data/tryouts/30_metadata/64_backup_disk_tryouts.rb +65 -0
  107. data/tryouts/30_metadata/66_backup_snapshot_tryouts.rb +76 -0
  108. data/tryouts/30_metadata/70_machine_tryouts.rb +85 -0
  109. data/tryouts/30_metadata/73_machine_list_tryouts.rb +58 -0
  110. data/tryouts/30_metadata/76_machine_instance_tryouts.rb +64 -0
  111. data/tryouts/30_metadata/77_machines_tryouts.rb +45 -0
  112. data/tryouts/40_routines/10_keypair_handler_tryouts.rb +52 -0
  113. data/tryouts/40_routines/11_group_handler_tryouts.rb +36 -0
  114. data/tryouts/80_cli/10_rudyec2_tryouts.rb +8 -0
  115. data/tryouts/80_cli/60_rudy_tryouts.rb +41 -0
  116. data/tryouts/failer +6 -0
  117. data/tryouts/misc/console_tryout.rb +91 -0
  118. data/tryouts/misc/disks_tryout.rb +48 -0
  119. data/tryouts/misc/drydock_tryout.rb +48 -0
  120. data/tryouts/misc/nested_methods.rb +103 -0
  121. data/tryouts/misc/session_tryout.rb +46 -0
  122. data/tryouts/misc/tryouts.rb +33 -0
  123. data/tryouts/misc/usage_tryout.rb +23 -0
  124. metadata +119 -31
  125. data/bin/ird +0 -153
  126. data/lib/rudy/metadata/backups.rb +0 -67
  127. data/lib/rudy/metadata/debug.rb +0 -38
  128. data/lib/rudy/metadata/disks.rb +0 -67
  129. data/lib/rudy/metadata/objectbase.rb +0 -108
  130. data/lib/rudy/routines/helper.rb +0 -76
  131. data/lib/rudy/routines/helpers/dependshelper.rb +0 -34
  132. data/lib/rudy/routines/helpers/diskhelper.rb +0 -403
  133. data/lib/rudy/routines/helpers/scripthelper.rb +0 -197
  134. data/lib/rudy/routines/helpers/userhelper.rb +0 -37
  135. data/support/rudy-ec2-startup +0 -200
@@ -0,0 +1,42 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module Group
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ##Rudy::Routines.add_handler :machines, self
8
+
9
+
10
+ def raise_early_exceptions(name=nil)
11
+
12
+ end
13
+
14
+ def create(name=nil)
15
+ name ||= current_group_name
16
+ return if exists? name
17
+ li "Creating group: #{name}"
18
+ Rudy::AWS::EC2::Groups.create name
19
+ end
20
+
21
+ def authorize(name=nil, addresses=nil, ports=nil)
22
+ name ||= current_group_name
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)
27
+ end
28
+
29
+ def exists?(name=nil)
30
+ name ||= current_group_name
31
+ Rudy::AWS::EC2::Groups.exists? name
32
+ end
33
+
34
+ def destroy(name=nil)
35
+ name ||= current_group_name
36
+ return unless exists? name
37
+ li "Destroying group: #{name}"
38
+ Rudy::AWS::EC2::Groups.destroy name
39
+ end
40
+
41
+ end
42
+ end; end; end
@@ -0,0 +1,72 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module Host
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ## NOTE: This handler doesn't use Rudy::Routines.add_handler
8
+
9
+ def is_running?(rset)
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
16
+ inst && inst.running?
17
+ }
18
+ end
19
+ end
20
+
21
+ # Add instance info to machine and save it. This is really important
22
+ # for the initial startup so the metadata is updated right away. But
23
+ # it's also important to call here because if a routine was executed
24
+ # and an unexpected exception occurs before this update is executed
25
+ # the machine metadata won't contain the DNS information. Calling it
26
+ # here ensure that the metadata is always up-to-date.
27
+ # Each Rye:Box instance has a Rudy::Machine instance in its stash so
28
+ # self.stash.update == machine.update
29
+ def update_dns(rset)
30
+ raise NoMachines if rset.boxes.empty?
31
+ rset.batch do
32
+ self.stash.refresh!
33
+ self.host = self.stash.dns_public
34
+ end
35
+ end
36
+
37
+ def is_available?(rset, port=22)
38
+ 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)
45
+ }
46
+ end
47
+ end
48
+ end
49
+
50
+ def set_hostname(rset)
51
+ raise NoMachines if rset.boxes.empty?
52
+ original_user = rset.user
53
+ rset.add_key user_keypairpath('root')
54
+ rset.switch_user 'root'
55
+ # Set the hostname if specified in the machines config.
56
+ # :rudy -> change to Rudy's machine name
57
+ # :default -> leave the hostname as it is
58
+ # Anything else other than nil -> change to that value
59
+ # NOTE: This will set hostname every time a routine is
60
+ # run so we may want to make this an explicit action.
61
+ type = current_machine_hostname || :rudy
62
+ rset.batch(type) do |hn|
63
+ if hn != :default
64
+ hn = self.stash.name if hn == :rudy
65
+ self.quietly { hostname(hn) }
66
+ end
67
+ end
68
+ rset.switch_user original_user
69
+ end
70
+
71
+ end
72
+ end; end; end
@@ -0,0 +1,70 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module Keypair
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ##Rudy::Routines.add_handler :machines, self
8
+
9
+
10
+ def raise_early_exceptions(name=:root)
11
+ keyname = user_keypairname name
12
+ kp_file = pkey name
13
+ if registered? keyname
14
+ # This means no keypair file can be found
15
+ raise PrivateKeyNotFound, keyname if kp_file.nil?
16
+ # This means we found a keypair in the config but we cannot find the private key file.
17
+ raise PrivateKeyNotFound, kp_file if !File.exists?(kp_file)
18
+ else
19
+ raise PrivateKeyFileExists, kp_file if File.exists?(kp_file)
20
+ end
21
+ end
22
+
23
+ def create(name=:root)
24
+ keyname = user_keypairname name
25
+ kp_file = pkey name
26
+ kp = nil
27
+ if registered? keyname
28
+ raise PrivateKeyNotFound, keyname if kp_file.nil?
29
+ raise PrivateKeyNotFound, kp_file if !File.exists?(kp_file)
30
+ else
31
+ raise PrivateKeyFileExists, kp_file if File.exists?(kp_file)
32
+ li "Creating keypair: #{keyname}"
33
+ kp = Rudy::AWS::EC2::Keypairs.create(keyname)
34
+ li "Saving #{kp_file}"
35
+ Rudy::Utils.write_to_file(kp_file, kp.private_key, 'w', 0600)
36
+ end
37
+ kp
38
+ end
39
+
40
+ def unregister(name=:root)
41
+ keyname = user_keypairname name
42
+ raise "Keypair not registered: #{keyname}" unless registered?(name)
43
+ Rudy::AWS::EC2::Keypairs.destroy keyname
44
+ end
45
+
46
+ def delete_pkey(name=:root)
47
+ kp_file = pkey name
48
+ raise PrivateKeyNotFound, kp_file unless pkey?(name)
49
+ File.unlink kp_file
50
+ end
51
+
52
+ def exists?(name=:root)
53
+ registered?(name) && pkey?(name)
54
+ end
55
+
56
+ def registered?(name=:root)
57
+ keyname = user_keypairname name
58
+ Rudy::AWS::EC2::Keypairs.exists?( keyname) rescue false
59
+ end
60
+
61
+ def pkey(name=:root)
62
+ user_keypairpath name
63
+ end
64
+
65
+ def pkey?(name=:root)
66
+ File.exists? pkey(name)
67
+ end
68
+
69
+ end
70
+ end; end; end
@@ -0,0 +1,15 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module Machines
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ##Rudy::Routines.add_handler :machines, self
8
+
9
+
10
+ def raise_early_exceptions
11
+ end
12
+
13
+
14
+ end
15
+ end; end; end
@@ -0,0 +1,85 @@
1
+
2
+
3
+ module Rudy; module Routines; module Handlers;
4
+ module Script
5
+ include Rudy::Routines::Handlers::Base
6
+ extend self
7
+
8
+ Rudy::Routines.add_handler :local, self
9
+ Rudy::Routines.add_handler :remote, self
10
+
11
+ Rudy::Routines.add_handler :xlocal, self
12
+ Rudy::Routines.add_handler :xremote, self
13
+
14
+ def raise_early_exceptions(type, batch, rset, lbox, argv=nil)
15
+
16
+ end
17
+
18
+ def execute(type, batch, rset, lbox, argv=nil)
19
+ if type.to_s =~ /\Ax/
20
+ # do nothing
21
+
22
+ # It's important this stay a regex rather than a literal comparison
23
+ elsif type.to_s =~ /local/
24
+ lbox.cd Dir.pwd
25
+ batch = { lbox.user => batch } if batch.is_a?(Proc)
26
+ execute_command(batch, lbox, argv)
27
+ else
28
+ batch = { rset.user => batch } if batch.is_a?(Proc)
29
+ raise NoMachines if rset.boxes.empty?
30
+ execute_command(batch, rset, argv)
31
+ end
32
+ end
33
+
34
+
35
+ private
36
+
37
+ # * +batch+ a single routine hash (startup, shutdown, etc...)
38
+ # * +robj+ an instance of Rye::Set or Rye::Box
39
+ # * +argv+ command line args
40
+ def execute_command(batch, robj, argv=nil)
41
+
42
+ original_user = robj.user
43
+ original_dir = robj.current_working_directory
44
+
45
+ batch.each_pair do |user, proc|
46
+
47
+ # The error doesn't apply to the local Rye::Box instance
48
+ if robj.is_a?(Rye::Set) && !File.exists?(user_keypairpath(user) || '')
49
+ le "Cannot find key for #{user}: #{user_keypairpath(user)}"
50
+ end
51
+
52
+ if user.to_s != robj.user
53
+ begin
54
+ ld "Switching user to: #{user} (was: #{robj.user})"
55
+ ld "(key: #{user_keypairpath(user)})"
56
+
57
+ robj.add_key user_keypairpath(user)
58
+ robj.switch_user user
59
+
60
+ rescue Net::SSH::AuthenticationFailed, Net::SSH::HostKeyMismatch => ex
61
+ STDERR.puts "Error connecting: #{ex.message}".color(:red)
62
+ STDERR.puts "Skipping user #{user}".color(:red)
63
+ next
64
+ end
65
+ end
66
+
67
+ ### EXECUTE THE COMMANDS BLOCK
68
+ begin
69
+ robj.batch(argv, &proc)
70
+ ensure
71
+ robj.enable_safe_mode # In case it was disabled
72
+ robj.switch_user original_user # Return to the user it was provided with
73
+ robj.cd # reset to home dir
74
+ robj.cd original_dir # return to previous directory
75
+ end
76
+
77
+ end
78
+
79
+
80
+
81
+
82
+ end
83
+ end
84
+
85
+ end;end;end
@@ -0,0 +1,41 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module User
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ Rudy::Routines.add_handler :adduser, self
8
+ Rudy::Routines.add_handler :authorize, self
9
+
10
+ def raise_early_exceptions(type, user, rset, lbox, argv=nil)
11
+
12
+ end
13
+
14
+ def execute(type, user, rset, lbox, argv=nil)
15
+ raise NoMachines if rset.boxes.empty?
16
+ send(type, user, rset)
17
+ end
18
+
19
+ def adduser(user, robj)
20
+
21
+ # On Solaris, the user's home directory needs to be specified
22
+ # explicitly so we do it for linux too for fun.
23
+ homedir = robj.guess_user_home(user.to_s)
24
+ args = [:m, :d, homedir, :s, '/bin/bash', user.to_s]
25
+
26
+ # NOTE: We'll may to use platform specific code here.
27
+ # Linux has adduser and useradd commands:
28
+ # adduser can prompt for info which we don't want.
29
+ # useradd does not prompt (on Debian/Ubuntu at least).
30
+ # We need to specify bash b/c the default is /bin/sh
31
+ robj.useradd(args)
32
+ end
33
+
34
+ def authorize(user, robj)
35
+ robj.authorize_keys_remote(user.to_s)
36
+ end
37
+
38
+
39
+ end
40
+
41
+ end; end; end
@@ -1,36 +1,32 @@
1
1
 
2
-
3
2
  module Rudy; module Routines;
4
3
  class Passthrough < Rudy::Routines::Base
5
4
 
6
5
  def init(*args)
7
- @routine = fetch_routine_config(@cmdname)
6
+ @machines = Rudy::Machines.list || []
7
+ @@rset = create_rye_set @machines unless defined?(@@rset)
8
8
  end
9
9
 
10
- # * +each_mach+ is an optional block which is executed between
11
- # disk creation and the after scripts. The will receives two
12
- # arguments: instances of Rudy::Machine and Rye::Box.
13
- def execute(&each_mach)
14
- routine_separator(@cmdname)
15
- machines = []
16
- generic_machine_runner(:list) do |machine,rbox|
17
- puts $/ #, "[routine: #{@cmdname}]"
18
- machines << machine
19
- end
20
- machines
10
+ def execute
11
+ ld "Executing routine: #{@name}"
12
+ return @machines unless run?
13
+ Rudy::Routines::Handlers::Depends.execute_all @before
14
+ Rudy::Routines.runner(@routine, @@rset, @@lbox, @argv)
15
+ Rudy::Routines::Handlers::Depends.execute_all @after
16
+ @machines
21
17
  end
22
-
18
+
23
19
  # Called by generic_machine_runner
24
20
  def raise_early_exceptions
25
- raise Rudy::Error, "No routine name" unless @cmdname
26
- raise NoRoutine, @cmdname unless @routine
27
- # TODO: enable this for EC2 groups only
28
- #raise Rudy::PrivateKeyNotFound, root_keypairpath unless has_keypair?(:root)
29
- raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
30
- ##rmach = Rudy::Machines.new
31
- ##if !@@global.offline && !rmach.running?
32
- ## raise MachineGroupNotRunning, current_machine_group
33
- ##end
21
+ raise Rudy::Error, "No routine name" unless @name
22
+ raise NoRoutine, @name unless @routine
23
+ ##raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
24
+ # Call raise_early_exceptions for each handler used in the routine
25
+ @routine.each_pair do |action,definition|
26
+ raise NoHandler, action unless Rudy::Routines.has_handler?(action)
27
+ handler = Rudy::Routines.get_handler action
28
+ handler.raise_early_exceptions(action, definition, @@rset, @@lbox, @argv)
29
+ end
34
30
  end
35
31
 
36
32
  end
@@ -3,73 +3,104 @@
3
3
  module Rudy; module Routines;
4
4
  class Reboot < Rudy::Routines::Base
5
5
 
6
+ Rudy::Routines.add_routine :reboot, self
7
+
8
+ @@allowed_actions = [:before, :disks, :adduser, :authorize,
9
+ :before_local, :before_remote,
10
+ :local, :remote, :after]
11
+
6
12
  def init(*args)
7
- @routine = fetch_routine_config(:reboot)
13
+ @routine ||= {}
8
14
  end
9
15
 
10
- # * +each_mach+ is an optional block which is executed between
11
- # disk creation and the after scripts. The will receives two
12
- # arguments: instances of Rudy::Machine and Rye::Box.
13
- def execute(&each_mach)
14
- routine_separator(:reboot)
15
- unless @routine
16
- STDERR.puts "[this is a generic reboot routine]"
17
- @routine = {}
16
+ # Startup routines run in the following order:
17
+ # * before_local (if present)
18
+ # * before_remote (if present)
19
+ # * Reboot instances
20
+ # * Set hostname
21
+ # * before dependencies
22
+ # * all other actions
23
+ # * after dependencies
24
+ def execute
25
+ ld "Executing routine: #{@name}"
26
+ ld "[this is a generic routine]" if @routine.empty?
27
+
28
+
29
+ # If this is a testrun we won't create new instances
30
+ # we'll just grab the list of machines in this group.
31
+ # NOTE: Expect errors if there are no machines.
32
+ @machines = run? ? Rudy::Machines.restart : Rudy::Machines.list
33
+ @@rset = create_rye_set @machines unless defined?(@@rset)
34
+
35
+ if run?
36
+ if @routine.has_key? :before_local
37
+ handler = Rudy::Routines.get_handler :local
38
+ Rudy::Routines.rescue {
39
+ handler.execute(:local, @routine.delete(:before_local), nil, @@lbox, @argv)
40
+ }
41
+ end
42
+
43
+ if @routine.has_key? :before_remote
44
+ handler = Rudy::Routines.get_handler :remote
45
+ Rudy::Routines.rescue {
46
+ handler.execute(:remote, @routine.delete(:before_remote), @@rset, @@lbox, @argv)
47
+ }
48
+ end
18
49
  end
19
- machines = []
20
- generic_machine_runner(:list) do |machine,rbox|
21
- puts $/, "Rebooting...", $/
22
- rbox.disconnect unless rbox.nil?
23
- machine.restart
24
- sleep 4
25
- msg = preliminary_separator("Checking if instance is running...")
26
- Rudy::Utils.waiter(3, 120, STDOUT, msg, 0) {
27
- machine.running?
28
- }
29
50
 
30
- # Add instance info to machine and save it. This is really important
31
- # for the initial startup so the metadata is updated right away. But
32
- # it's also important to call here because if a routine was executed
33
- # and an unexpected exception occurs before this update is executed
34
- # the machine metadata won't contain the DNS information. Calling it
35
- # here ensure that the metadata is always up-to-date.
36
- machine.update
37
-
38
- sleep 4
39
-
40
- msg = preliminary_separator("Waiting for SSH daemon...")
41
- Rudy::Utils.waiter(3, 120, STDOUT, msg, 0) {
42
- Rudy::Utils.service_available?(machine.dns_public, 22)
43
- }
44
-
45
- # NOTE: THIS IS INCOMPLETE
46
-
47
- sleep 1 # Avoid IOError: closed stream on SSH
48
-
51
+ Rudy::Routines.rescue {
52
+ if !Rudy::Routines::Handlers::Host.is_running? @@rset
53
+ a = @@rset.boxes.select { |box| !box.stash.running? }
54
+ raise GroupNotRunning, a
55
+ end
56
+ }
57
+
58
+ # This is important b/c the machines will not
59
+ # have DNS info until after they are running.
60
+ Rudy::Routines.rescue { Rudy::Routines::Handlers::Host.update_dns @@rset }
49
61
 
50
- if Rudy::Routines::DiskHelper.disks?(@routine) # disk
51
- task_separator("DISKS")
52
- if rbox.ostype == "sunos"
53
- puts "Sorry, Solaris is not supported yet!"
54
- else
55
- Rudy::Routines::DiskHelper.execute(@routine, machine, rbox)
56
- end
62
+ Rudy::Routines.rescue {
63
+ if !Rudy::Routines::Handlers::Host.is_available? @@rset
64
+ a = @@rset.boxes.select { |box| !box.stash.available? }
65
+ raise GroupNotAvailable, a
57
66
  end
58
-
59
- machines << machine
67
+ }
68
+ Rudy::Routines.rescue {
69
+ Rudy::Routines::Handlers::Host.set_hostname @@rset
70
+ }
71
+
72
+ if run?
73
+ # This is the meat of the sandwich
74
+ Rudy::Routines.runner @routine, @@rset, @@lbox, @argv
75
+
76
+ Rudy::Routines.rescue {
77
+ Rudy::Routines::Handlers::Depends.execute_all @after
78
+ }
60
79
  end
61
- machines
80
+
81
+ @machines
62
82
  end
63
83
 
64
84
  # Called by generic_machine_runner
65
85
  def raise_early_exceptions
66
- rmach = Rudy::Machines.new
86
+ raise NoMachinesConfig unless @@config.machines
67
87
  # There's no keypair check here because Rudy::Machines will attempt
68
88
  # to create one.
69
89
  raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
70
- raise MachineGroupNotRunning, current_machine_group unless rmach.running?
90
+
91
+ # If this is a test run we don't care if the group is running
92
+ if run?
93
+ raise MachineGroupNotRunning, current_machine_group unless Rudy::Machines.running?
94
+ end
95
+
96
+ if @routine
97
+ bad = @routine.keys - @@allowed_actions
98
+ raise UnsupportedActions.new(@name, bad) unless bad.empty?
99
+ end
71
100
  end
72
101
 
73
102
  end
74
103
 
75
- end; end
104
+ end; end
105
+
106
+