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 (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
+