rudy 0.8.5 → 0.9.0

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 (132) hide show
  1. data/CHANGES.txt +110 -18
  2. data/README.rdoc +40 -44
  3. data/Rudyfile +35 -50
  4. data/bin/rudy +88 -57
  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 +59 -91
  9. data/lib/rudy/aws.rb +4 -45
  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 +18 -19
  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 +39 -26
  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 +45 -20
  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 +104 -0
  37. data/lib/rudy/cli/candy.rb +1 -2
  38. data/lib/rudy/cli/config.rb +20 -7
  39. data/lib/rudy/cli/disks.rb +7 -9
  40. data/lib/rudy/cli/execbase.rb +56 -0
  41. data/lib/rudy/cli/machines.rb +242 -45
  42. data/lib/rudy/cli/metadata.rb +24 -10
  43. data/lib/rudy/cli/networks.rb +34 -0
  44. data/lib/rudy/cli/routines.rb +32 -6
  45. data/lib/rudy/cli/status.rb +60 -0
  46. data/lib/rudy/config.rb +55 -32
  47. data/lib/rudy/config/objects.rb +44 -30
  48. data/lib/rudy/disks.rb +25 -0
  49. data/lib/rudy/exceptions.rb +99 -0
  50. data/lib/rudy/global.rb +67 -28
  51. data/lib/rudy/guidelines.rb +3 -2
  52. data/lib/rudy/huxtable.rb +67 -58
  53. data/lib/rudy/machines.rb +41 -263
  54. data/lib/rudy/metadata.rb +212 -38
  55. data/lib/rudy/metadata/backup.rb +123 -78
  56. data/lib/rudy/metadata/disk.rb +153 -170
  57. data/lib/rudy/metadata/machine.rb +179 -0
  58. data/lib/rudy/mixins.rb +2 -1
  59. data/lib/rudy/mixins/hash.rb +3 -1
  60. data/lib/rudy/mixins/symbol.rb +8 -0
  61. data/lib/rudy/routines.rb +127 -344
  62. data/lib/rudy/routines/base.rb +229 -0
  63. data/lib/rudy/routines/handlers/base.rb +48 -0
  64. data/lib/rudy/routines/handlers/depends.rb +49 -0
  65. data/lib/rudy/routines/handlers/disks.rb +249 -0
  66. data/lib/rudy/routines/handlers/group.rb +44 -0
  67. data/lib/rudy/routines/handlers/host.rb +70 -0
  68. data/lib/rudy/routines/handlers/keypair.rb +70 -0
  69. data/lib/rudy/routines/handlers/machines.rb +15 -0
  70. data/lib/rudy/routines/handlers/script.rb +85 -0
  71. data/lib/rudy/routines/handlers/user.rb +45 -0
  72. data/lib/rudy/routines/passthrough.rb +19 -23
  73. data/lib/rudy/routines/reboot.rb +98 -50
  74. data/lib/rudy/routines/shutdown.rb +65 -14
  75. data/lib/rudy/routines/startup.rb +112 -17
  76. data/lib/rudy/utils.rb +35 -68
  77. data/rudy.gemspec +82 -25
  78. data/tryouts/01_mixins/01_hash_tryouts.rb +20 -0
  79. data/tryouts/10_require_time/10_rudy_tryouts.rb +33 -0
  80. data/tryouts/10_require_time/15_global_tryouts.rb +58 -0
  81. data/tryouts/12_config/10_load_config_tryouts.rb +43 -0
  82. data/tryouts/12_config/20_defaults_tryouts.rb +16 -0
  83. data/tryouts/12_config/30_accounts_tryouts.rb +17 -0
  84. data/tryouts/12_config/40_machines_tryouts.rb +53 -0
  85. data/tryouts/12_config/50_commands_tryouts.rb +17 -0
  86. data/tryouts/12_config/60_routines_tryouts.rb +16 -0
  87. data/tryouts/15_huxtable/10_huxtable_tryouts.rb +47 -0
  88. data/tryouts/15_huxtable/20_user_tryouts.rb +47 -0
  89. data/tryouts/20_simpledb/10_domains_tryouts.rb +36 -0
  90. data/tryouts/20_simpledb/20_objects_tryouts.rb +56 -0
  91. data/tryouts/25_ec2/10_keypairs_tryouts.rb +54 -0
  92. data/tryouts/25_ec2/20_groups_tryouts.rb +56 -0
  93. data/tryouts/25_ec2/21_groups_authorize_address_tryouts.rb +53 -0
  94. data/tryouts/25_ec2/22_groups_authorize_account_tryouts.rb +54 -0
  95. data/tryouts/25_ec2/30_addresses_tryouts.rb +42 -0
  96. data/tryouts/25_ec2/40_volumes_tryouts.rb +53 -0
  97. data/tryouts/25_ec2/50_snapshots_tryouts.rb +75 -0
  98. data/tryouts/26_ec2_instances/10_instance_tryouts.rb +107 -0
  99. data/tryouts/26_ec2_instances/50_images_tryouts.rb +7 -0
  100. data/tryouts/30_metadata/10_include_tryouts.rb +45 -0
  101. data/tryouts/30_metadata/13_object_tryouts.rb +19 -0
  102. data/tryouts/30_metadata/50_disk_tryouts.rb +115 -0
  103. data/tryouts/30_metadata/51_disk_digest_tryouts.rb +24 -0
  104. data/tryouts/30_metadata/53_disk_list_tryouts.rb +35 -0
  105. data/tryouts/30_metadata/56_disk_volume_tryouts.rb +68 -0
  106. data/tryouts/30_metadata/60_backup_tryouts.rb +101 -0
  107. data/tryouts/30_metadata/63_backup_list_tryouts.rb +38 -0
  108. data/tryouts/30_metadata/64_backup_disk_tryouts.rb +65 -0
  109. data/tryouts/30_metadata/66_backup_snapshot_tryouts.rb +76 -0
  110. data/tryouts/30_metadata/70_machine_tryouts.rb +85 -0
  111. data/tryouts/30_metadata/73_machine_list_tryouts.rb +58 -0
  112. data/tryouts/30_metadata/76_machine_instance_tryouts.rb +64 -0
  113. data/tryouts/30_metadata/77_machines_tryouts.rb +45 -0
  114. data/tryouts/40_routines/10_keypair_handler_tryouts.rb +52 -0
  115. data/tryouts/40_routines/11_group_handler_tryouts.rb +36 -0
  116. data/tryouts/80_cli/10_rudyec2_tryouts.rb +8 -0
  117. data/tryouts/80_cli/60_rudy_tryouts.rb +41 -0
  118. data/tryouts/exploration/console.rb +91 -0
  119. data/tryouts/exploration/machine.rb +23 -0
  120. data/tryouts/failer +6 -0
  121. metadata +116 -32
  122. data/bin/ird +0 -153
  123. data/lib/rudy/metadata/backups.rb +0 -67
  124. data/lib/rudy/metadata/debug.rb +0 -38
  125. data/lib/rudy/metadata/disks.rb +0 -67
  126. data/lib/rudy/metadata/objectbase.rb +0 -108
  127. data/lib/rudy/routines/helper.rb +0 -76
  128. data/lib/rudy/routines/helpers/dependshelper.rb +0 -34
  129. data/lib/rudy/routines/helpers/diskhelper.rb +0 -403
  130. data/lib/rudy/routines/helpers/scripthelper.rb +0 -197
  131. data/lib/rudy/routines/helpers/userhelper.rb +0 -37
  132. data/support/rudy-ec2-startup +0 -200
@@ -0,0 +1,44 @@
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
+ 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)
29
+ end
30
+
31
+ def exists?(name=nil)
32
+ name ||= current_group_name
33
+ Rudy::AWS::EC2::Groups.exists? name
34
+ end
35
+
36
+ def destroy(name=nil)
37
+ name ||= current_group_name
38
+ return unless exists? name
39
+ li "Destroying group: #{name}"
40
+ Rudy::AWS::EC2::Groups.destroy name
41
+ end
42
+
43
+ end
44
+ end; end; end
@@ -0,0 +1,70 @@
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.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
15
+ inst && inst.running?
16
+ }
17
+ end
18
+ end
19
+
20
+ # Add instance info to machine and save it. This is really important
21
+ # for the initial startup so the metadata is updated right away. But
22
+ # it's also important to call here because if a routine was executed
23
+ # and an unexpected exception occurs before this update is executed
24
+ # the machine metadata won't contain the DNS information. Calling it
25
+ # here ensure that the metadata is always up-to-date.
26
+ # Each Rye:Box instance has a Rudy::Machine instance in its stash so
27
+ # rbox.stash.refresh! == machine.refresh!
28
+ def update_dns(rset)
29
+ raise NoMachines if rset.boxes.empty?
30
+ rset.boxes.each do |rbox|
31
+ rbox.stash.refresh!
32
+ rbox.host = rbox.stash.dns_public
33
+ end
34
+ end
35
+
36
+ def is_available?(rset, port=22)
37
+ raise NoMachines if rset.boxes.empty?
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)
43
+ }
44
+ end
45
+ end
46
+ end
47
+
48
+ def set_hostname(rset)
49
+ raise NoMachines if rset.boxes.empty?
50
+ original_user = rset.user
51
+ rset.switch_user 'root'
52
+ rset.add_key user_keypairpath('root')
53
+ # Set the hostname if specified in the machines config.
54
+ # :rudy -> change to Rudy's machine name
55
+ # :default -> leave the hostname as it is
56
+ # Anything else other than nil -> change to that value
57
+ # NOTE: This will set hostname every time a routine is
58
+ # run so we may want to make this an explicit action.
59
+ type = current_machine_hostname || :rudy
60
+ rset.batch(type) do |hn|
61
+ if hn != :default
62
+ hn = self.stash.name if hn == :rudy
63
+ self.quietly { hostname(hn) }
64
+ end
65
+ end
66
+ rset.switch_user original_user
67
+ end
68
+
69
+ end
70
+ 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/ # (e.g. xremote, xlocal)
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,45 @@
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
+
25
+ # When more than one machine is running, this will be an Array
26
+ homedir = homedir.first if homedir.kind_of?(Array)
27
+
28
+ args = [:m, :d, homedir, :s, '/bin/bash', user.to_s]
29
+
30
+ # NOTE: We'll may to use platform specific code here.
31
+ # Linux has adduser and useradd commands:
32
+ # adduser can prompt for info which we don't want.
33
+ # useradd does not prompt (on Debian/Ubuntu at least).
34
+ # We need to specify bash b/c the default is /bin/sh
35
+ robj.useradd(args)
36
+ end
37
+
38
+ def authorize(user, robj)
39
+ robj.authorize_keys_remote(user.to_s)
40
+ end
41
+
42
+
43
+ end
44
+
45
+ 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,121 @@
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 ||= {}
14
+ @machines = Rudy::Machines.list
15
+ @@rset = create_rye_set @machines unless defined?(@@rset)
8
16
  end
9
17
 
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 = {}
18
- 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
- }
18
+ # Startup routines run in the following order:
19
+ # * before_local (if present)
20
+ # * before_remote (if present)
21
+ # * Reboot instances
22
+ # * Set hostname
23
+ # * before dependencies
24
+ # * all other actions
25
+ # * after dependencies
26
+ def execute
27
+ ld "Executing routine: #{@name}"
28
+ ld "[this is a generic routine]" if @routine.empty?
29
29
 
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)
30
+ if run?
31
+ Rudy::Routines.rescue {
32
+ Rudy::Routines::Handlers::Group.authorize rescue nil
43
33
  }
44
34
 
45
- # NOTE: THIS IS INCOMPLETE
46
-
47
- sleep 1 # Avoid IOError: closed stream on SSH
48
-
35
+ if @routine.has_key? :before_local
36
+ handler = Rudy::Routines.get_handler :local
37
+ Rudy::Routines.rescue {
38
+ handler.execute(:local, @routine.delete(:before_local), nil, @@lbox, @argv)
39
+ }
40
+ end
49
41
 
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
42
+ if @routine.has_key? :before_remote
43
+ handler = Rudy::Routines.get_handler :remote
44
+ Rudy::Routines.rescue {
45
+ handler.execute(:remote, @routine.delete(:before_remote), @@rset, @@lbox, @argv)
46
+ }
57
47
  end
58
-
59
- machines << machine
60
48
  end
61
- machines
49
+
50
+ Rudy::Routines.rescue {
51
+ if Rudy::Routines::Handlers::Disks.mount? @routine
52
+ fake = Hash[:umount => @routine.disks[:mount]]
53
+ Rudy::Routines::Handlers::Disks.execute :umount, fake, @@rset, @@lbox, @argv
54
+ end
55
+ }
56
+
57
+ li "Rebooting #{current_group_name}..."
58
+ @machines.each { |m| m.restart } if run?
59
+
60
+ 15.times { print '.'; Kernel.sleep 2 }; puts $/ # Wait for 30 seconds
61
+
62
+ Rudy::Routines.rescue {
63
+ if !Rudy::Routines::Handlers::Host.is_running? @@rset
64
+ a = @@rset.boxes.select { |box| !box.stash.instance_running? }
65
+ raise GroupNotRunning, a
66
+ end
67
+ }
68
+
69
+ # This is important b/c the machines will not
70
+ # have DNS info until after they are running.
71
+ Rudy::Routines.rescue { Rudy::Routines::Handlers::Host.update_dns @@rset }
72
+
73
+ Rudy::Routines.rescue {
74
+ if !Rudy::Routines::Handlers::Host.is_available? @@rset
75
+ a = @@rset.boxes.select { |box| !box.stash.instance_available? }
76
+ raise GroupNotAvailable, a
77
+ end
78
+ }
79
+ Rudy::Routines.rescue {
80
+ Rudy::Routines::Handlers::Host.set_hostname @@rset
81
+ }
82
+
83
+ if run?
84
+ # This is the meat of the sandwich
85
+ Rudy::Routines.runner @routine, @@rset, @@lbox, @argv
86
+
87
+ Rudy::Routines.rescue {
88
+ Rudy::Routines::Handlers::Depends.execute_all @after
89
+ }
90
+ end
91
+
92
+ @machines
62
93
  end
63
94
 
64
95
  # Called by generic_machine_runner
65
96
  def raise_early_exceptions
66
- rmach = Rudy::Machines.new
97
+ raise NoMachinesConfig unless @@config.machines
67
98
  # There's no keypair check here because Rudy::Machines will attempt
68
99
  # to create one.
69
100
  raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
70
- raise MachineGroupNotRunning, current_machine_group unless rmach.running?
101
+
102
+ # If this is a test run we don't care if the group is running
103
+ if run?
104
+ raise MachineGroupNotRunning, current_machine_group unless Rudy::Machines.running?
105
+ end
106
+
107
+ if @routine
108
+ bad = @routine.keys - @@allowed_actions
109
+ raise UnsupportedActions.new(@name, bad) unless bad.empty?
110
+ end
111
+
112
+ if @machines
113
+ down = @@rset.boxes.select { |box| !box.stash.instance_running? }
114
+ raise GroupNotAvailable, down unless down.empty?
115
+ end
116
+
71
117
  end
72
118
 
73
119
  end
74
120
 
75
- end; end
121
+ end; end
122
+
123
+