solutious-rudy 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/CHANGES.txt +28 -5
  2. data/README.rdoc +1 -1
  3. data/Rudyfile +51 -19
  4. data/bin/ird +153 -0
  5. data/bin/rudy +18 -23
  6. data/bin/rudy-ec2 +5 -10
  7. data/bin/rudy-s3 +1 -3
  8. data/bin/rudy-sdb +0 -2
  9. data/examples/README.md +10 -0
  10. data/examples/debian-sinatra-passenger/commands.rb +19 -0
  11. data/examples/debian-sinatra-passenger/machines.rb +32 -0
  12. data/examples/debian-sinatra-passenger/routines.rb +30 -0
  13. data/examples/debian-sinatra-thin/commands.rb +17 -0
  14. data/examples/debian-sinatra-thin/machines.rb +35 -0
  15. data/examples/debian-sinatra-thin/routines.rb +72 -0
  16. data/lib/rudy.rb +8 -17
  17. data/lib/rudy/aws.rb +1 -2
  18. data/lib/rudy/aws/ec2/address.rb +0 -1
  19. data/lib/rudy/aws/ec2/snapshot.rb +11 -0
  20. data/lib/rudy/aws/s3.rb +6 -3
  21. data/lib/rudy/cli.rb +12 -2
  22. data/lib/rudy/cli/aws/ec2/candy.rb +19 -48
  23. data/lib/rudy/cli/aws/ec2/images.rb +109 -122
  24. data/lib/rudy/cli/aws/s3/buckets.rb +1 -2
  25. data/lib/rudy/cli/config.rb +13 -0
  26. data/lib/rudy/cli/disks.rb +24 -1
  27. data/lib/rudy/cli/routines.rb +10 -11
  28. data/lib/rudy/config.rb +6 -9
  29. data/lib/rudy/config/objects.rb +4 -0
  30. data/lib/rudy/global.rb +4 -5
  31. data/lib/rudy/huxtable.rb +23 -8
  32. data/lib/rudy/machines.rb +11 -4
  33. data/lib/rudy/metadata.rb +8 -94
  34. data/lib/rudy/metadata/backup.rb +113 -0
  35. data/lib/rudy/metadata/backups.rb +65 -0
  36. data/lib/rudy/{disks.rb → metadata/disk.rb} +36 -69
  37. data/lib/rudy/metadata/disks.rb +67 -0
  38. data/lib/rudy/metadata/objectbase.rb +104 -0
  39. data/lib/rudy/mixins.rb +2 -0
  40. data/lib/rudy/routines.rb +173 -88
  41. data/lib/rudy/routines/helpers/dependshelper.rb +34 -0
  42. data/lib/rudy/routines/helpers/diskhelper.rb +174 -5
  43. data/lib/rudy/routines/helpers/scmhelper.rb +2 -2
  44. data/lib/rudy/routines/helpers/scripthelper.rb +11 -4
  45. data/lib/rudy/routines/passthrough.rb +3 -1
  46. data/lib/rudy/routines/reboot.rb +75 -0
  47. data/lib/rudy/routines/startup.rb +3 -3
  48. data/lib/rudy/scm/git.rb +17 -17
  49. data/lib/rudy/scm/svn.rb +46 -5
  50. data/lib/rudy/utils.rb +3 -2
  51. data/rudy.gemspec +24 -46
  52. data/test/30_sdb_metadata/10_disks_test.rb +5 -5
  53. metadata +35 -67
  54. data/lib/annoy.rb +0 -298
  55. data/lib/console.rb +0 -404
  56. data/lib/escape.rb +0 -305
  57. data/lib/rudy/backup.rb +0 -135
  58. data/lib/storable.rb +0 -292
  59. data/lib/sysinfo.rb +0 -285
  60. data/lib/tryouts.rb +0 -33
  61. data/vendor/highline-1.5.1/CHANGELOG +0 -222
  62. data/vendor/highline-1.5.1/INSTALL +0 -35
  63. data/vendor/highline-1.5.1/LICENSE +0 -7
  64. data/vendor/highline-1.5.1/README +0 -63
  65. data/vendor/highline-1.5.1/Rakefile +0 -82
  66. data/vendor/highline-1.5.1/TODO +0 -6
  67. data/vendor/highline-1.5.1/examples/ansi_colors.rb +0 -38
  68. data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +0 -18
  69. data/vendor/highline-1.5.1/examples/basic_usage.rb +0 -75
  70. data/vendor/highline-1.5.1/examples/color_scheme.rb +0 -32
  71. data/vendor/highline-1.5.1/examples/limit.rb +0 -12
  72. data/vendor/highline-1.5.1/examples/menus.rb +0 -65
  73. data/vendor/highline-1.5.1/examples/overwrite.rb +0 -19
  74. data/vendor/highline-1.5.1/examples/page_and_wrap.rb +0 -322
  75. data/vendor/highline-1.5.1/examples/password.rb +0 -7
  76. data/vendor/highline-1.5.1/examples/trapping_eof.rb +0 -22
  77. data/vendor/highline-1.5.1/examples/using_readline.rb +0 -17
  78. data/vendor/highline-1.5.1/lib/highline.rb +0 -758
  79. data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +0 -120
  80. data/vendor/highline-1.5.1/lib/highline/compatibility.rb +0 -17
  81. data/vendor/highline-1.5.1/lib/highline/import.rb +0 -43
  82. data/vendor/highline-1.5.1/lib/highline/menu.rb +0 -395
  83. data/vendor/highline-1.5.1/lib/highline/question.rb +0 -463
  84. data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +0 -193
  85. data/vendor/highline-1.5.1/setup.rb +0 -1360
  86. data/vendor/highline-1.5.1/test/tc_color_scheme.rb +0 -56
  87. data/vendor/highline-1.5.1/test/tc_highline.rb +0 -823
  88. data/vendor/highline-1.5.1/test/tc_import.rb +0 -54
  89. data/vendor/highline-1.5.1/test/tc_menu.rb +0 -429
  90. data/vendor/highline-1.5.1/test/ts_all.rb +0 -15
@@ -1,6 +1,4 @@
1
-
2
-
3
- module Rudy
1
+ module Rudy::MetaData
4
2
  class Disk < Storable
5
3
  include Rudy::MetaData::ObjectBase
6
4
 
@@ -28,6 +26,8 @@ class Disk < Storable
28
26
  field :fstype
29
27
  field :mounted
30
28
 
29
+ field :created
30
+
31
31
  def init(path=nil, size=nil, device=nil, position=nil)
32
32
  @path, @size, @device = path, size, device
33
33
  @rtype = 'disk'
@@ -37,6 +37,11 @@ class Disk < Storable
37
37
  @role = @@global.role
38
38
  @position = position || @@global.position
39
39
  @mounted = false
40
+
41
+ now = Time.now.utc
42
+ datetime = Backup.format_timestamp(now).split(Rudy::DELIM)
43
+ @created = now.to_i
44
+
40
45
  postprocess
41
46
  end
42
47
 
@@ -45,15 +50,14 @@ class Disk < Storable
45
50
  @mounted = true if @mounted == "true"
46
51
  end
47
52
 
48
- def liner_note
49
- info = @awsid && !@awsid.empty? ? @awsid : 'no volume'
50
- "%s %s" % [self.name.bright, info]
51
- end
52
-
53
53
  def to_s(with_titles=true)
54
54
  update
55
55
  mtd = @mounted == true ? "mounted" : @status
56
- "%s; %3sGB; %s; %s" % [liner_note, @size, @device, mtd]
56
+ if @size && @device
57
+ "%s; %3sGB; %s; %s" % [liner_note, @size, @device, mtd]
58
+ else
59
+ liner_note
60
+ end
57
61
  end
58
62
 
59
63
  def inspect
@@ -74,17 +78,35 @@ class Disk < Storable
74
78
  super("disk", @zone, @environment, @role, @position, *dirs)
75
79
  end
76
80
 
77
-
78
-
79
- def create(snapshot=nil)
80
- raise "#{name} is already running" if exists?
81
- vol = @rvol.create(@size, @zone, snapshot)
81
+ def create(size=nil, zone=nil, snapshot=nil)
82
+ raise "#{name} already exists" if exists?
83
+ vol = @rvol.create(size || @size, zone || @zone, snapshot)
82
84
  @awsid = vol.awsid
83
85
  @raw = true
84
86
  self.save
85
87
  self
86
88
  end
87
89
 
90
+ def backup
91
+ raise "No volume to backup" unless @awsid
92
+ bup = Rudy::MetaData::Backup.new(@awsid, @path, @position)
93
+ bup.size = @size || 1
94
+ bup.fstype = @fstype || 'ext3'
95
+ bup.create
96
+ end
97
+
98
+ def list_backups
99
+ rback = Rudy::Backups.new
100
+ props = {
101
+ :environment => @environment,
102
+ :role => @role,
103
+ :zone => @zone,
104
+ :region => @region,
105
+ :position => @position
106
+ }
107
+ rback.list([], [], props)
108
+ end
109
+
88
110
  def attach(instid)
89
111
  raise "No volume id" unless exists?
90
112
  vol = @rvol.attach(@awsid, instid, @device)
@@ -150,61 +172,6 @@ class Disk < Storable
150
172
  @rvol.send(state, @awsid) rescue false # deleting?, available?, etc...
151
173
  end
152
174
  end
153
- end
154
-
155
- class Disks
156
- include Rudy::MetaData
157
-
158
-
159
- def create(&each_mach)
160
-
161
- end
162
-
163
-
164
- def destroy(&each_mach)
165
- #raise MachineGroupNotRunning, current_machine_group unless running?
166
- #raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
167
- list do |disk|
168
- puts "Destroying #{disk.name}"
169
- disk.destroy
170
- end
171
- end
172
-
173
- def list(more=[], less=[], &each_disk)
174
- disks = list_as_hash(&each_disk)
175
- disks &&= disks.values
176
- disks
177
- end
178
-
179
- def list_as_hash(more=[], less=[], &each_disk)
180
- query = to_select([:rtype, 'disk'], less)
181
- list = @sdb.select(query) || {}
182
- disks = {}
183
- list.each_pair do |n,d|
184
- disks[n] = Rudy::Disk.from_hash(d)
185
- end
186
- disks.each_pair { |n,disk| each_disk.call(disk) } if each_disk
187
- disks = nil if disks.empty?
188
- disks
189
- end
190
-
191
- def get(rname=nil)
192
- dhash = @sdb.get(Rudy::DOMAIN, rname)
193
- return nil if dhash.nil? || dhash.empty?
194
- d = Rudy::Disk.from_hash(dhash)
195
- d.update if d
196
- d
197
- end
198
-
199
-
200
- def running?
201
- !list.nil?
202
- # TODO: add logic that checks whether the instances are running.
203
- end
204
-
205
-
206
-
207
175
 
208
176
  end
209
177
  end
210
-
@@ -0,0 +1,67 @@
1
+
2
+
3
+ module Rudy
4
+ class Disks
5
+ include Rudy::MetaData
6
+
7
+
8
+ def init
9
+ @rback = Rudy::Backups.new
10
+ end
11
+
12
+ #def create(&each_mach)
13
+
14
+ #end
15
+
16
+
17
+ def destroy(&each_mach)
18
+ #raise MachineGroupNotRunning, current_machine_group unless running?
19
+ #raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
20
+ list do |disk|
21
+ puts "Destroying #{disk.name}"
22
+ disk.destroy
23
+ end
24
+ end
25
+
26
+ def backups
27
+ @rback.list()
28
+ end
29
+
30
+ def list(more=[], less=[], &each_disk)
31
+ disks = list_as_hash(&each_disk)
32
+ disks &&= disks.values
33
+ disks
34
+ end
35
+
36
+ def list_as_hash(more=[], less=[], &each_disk)
37
+ query = to_select([:rtype, 'disk'], less)
38
+ list = @sdb.select(query) || {}
39
+ disks = {}
40
+ list.each_pair do |n,d|
41
+ disks[n] = Rudy::MetaData::Disk.from_hash(d)
42
+ end
43
+ disks.each_pair { |n,disk| each_disk.call(disk) } if each_disk
44
+ disks = nil if disks.empty?
45
+ disks
46
+ end
47
+
48
+ def get(rname=nil)
49
+ dhash = @sdb.get(Rudy::DOMAIN, rname)
50
+ return nil if dhash.nil? || dhash.empty?
51
+ d = Rudy::MetaData::Disk.from_hash(dhash)
52
+ d.update if d
53
+ d
54
+ end
55
+
56
+
57
+ def running?
58
+ !list.nil?
59
+ # TODO: add logic that checks whether the instances are running.
60
+ end
61
+
62
+
63
+
64
+
65
+ end
66
+ end
67
+
@@ -0,0 +1,104 @@
1
+
2
+
3
+ module Rudy
4
+ module MetaData
5
+ module ObjectBase
6
+ include Rudy::Huxtable
7
+
8
+ def initialize(*args)
9
+ a, s, r = @@global.accesskey, @@global.secretkey, @@global.region
10
+ @sdb = Rudy::AWS::SDB.new(a, s, r)
11
+ @ec2inst = Rudy::AWS::EC2::Instances.new(a, s, r)
12
+ @rvol = Rudy::AWS::EC2::Volumes.new(a, s, r)
13
+ @radd = Rudy::AWS::EC2::Addresses.new(a, s, r)
14
+ @rsnap = Rudy::AWS::EC2::Snapshots.new(a, s, r)
15
+ init(*args)
16
+ end
17
+
18
+ def init(*args); raise "Must override init"; end
19
+
20
+ def valid?; raise "#{self.class} must override 'valid?'"; end
21
+
22
+ def to_query(more=[], less=[])
23
+ Rudy::AWS::SDB.generate_query build_criteria(more, less)
24
+ end
25
+
26
+ def to_select(more=[], less=[])
27
+ Rudy::AWS::SDB.generate_select ['*'], Rudy::DOMAIN, build_criteria(more, less)
28
+ end
29
+
30
+ def name(identifier, zon, env, rol, pos, *other)
31
+ pos = pos.to_s.rjust 2, '0'
32
+ [identifier, zon, env, rol, pos, *other].flatten.compact.join(Rudy::DELIM)
33
+ end
34
+
35
+ def save(replace=true)
36
+ replace = true if replace.nil?
37
+ @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
38
+ @sdb.put(Rudy::DOMAIN, name, self.to_hash, replace) # Always returns nil
39
+ true
40
+ end
41
+
42
+ def destroy
43
+ @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
44
+ @sdb.destroy(Rudy::DOMAIN, name)
45
+ true
46
+ end
47
+
48
+ def refresh
49
+ @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
50
+ h = @sdb.get(Rudy::DOMAIN, name) || {}
51
+ from_hash(h)
52
+ end
53
+
54
+ def ==(other)
55
+ return false unless other.is_a?(self.class)
56
+ self.name == other.name
57
+ end
58
+
59
+ # A generic default
60
+ def to_s
61
+ str = ""
62
+ field_names.each do |key|
63
+ str << sprintf(" %22s: %s#{$/}", key, self.send(key.to_sym))
64
+ end
65
+ str
66
+ end
67
+
68
+ def liner_note
69
+ info = @awsid && !@awsid.empty? ? @awsid : "[no aws object]"
70
+ "%s %s" % [self.name.bright, info]
71
+ end
72
+
73
+ def inspect
74
+ lines = []
75
+ lines << liner_note
76
+ field_names.each do |key|
77
+ next unless self.respond_to?(key)
78
+ val = self.send(key)
79
+ lines << sprintf(" %22s: %s", key, (val.is_a?(Array) ? val.join(', ') : val))
80
+ end
81
+ lines.join($/)
82
+ end
83
+
84
+ protected
85
+
86
+ # Builds a zipped Array from a list of criteria.
87
+ # The list of criteria is made up of metadata object attributes.
88
+ # The list is constructed by taking the adding +more+, and
89
+ # subtracting +less+ from <tt>:rtype, :region, :zone, :environment, :role, :position</tt>
90
+ #
91
+ # Returns [[:rtype, value], [:zone, value], ...]
92
+ def build_criteria(more=[], less=[])
93
+ criteria = [:rtype, :region, :zone, :environment, :role, :position, *more].compact
94
+ criteria -= [*less].flatten.uniq.compact
95
+ values = criteria.collect do |n|
96
+ self.send(n.to_sym)
97
+ end
98
+ criteria.zip(values)
99
+ end
100
+
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,2 @@
1
+
2
+ require "rudy/mixins/hash"
@@ -32,45 +32,78 @@ module Rudy
32
32
  end
33
33
 
34
34
  # * +machine_action+ a method on Rudy::Machines, one of: create, destroy, list
35
- # * +skipcheck+ Skip checking if machine is up and SSH is available (default: false)
36
- # * +routine_action+ is an optional block which represents the action
37
- # for a specific routine. For example, a startup routine will start
38
- # an EC2 instance. Arguments: instances of Rudy::Machine and Rye::Box.
39
- def generic_machine_runner(machine_action, skipcheck=false, &routine_action)
40
- rmach = Rudy::Machines.new
41
- raise "No routine supplied" unless @routine
35
+ # * +routine+ Override +routine+ with another routine (default: nil)
36
+ # * +skip_check+ Don't check that the machine is up and SSH is available (default: false)
37
+ # * +skip_header+ Don't print machine header (default: false)
38
+ # * +routine_action+ is an optional block which will be executed for each
39
+ # machine between the disk routine and after blocks. The block receives
40
+ # two argument: an instance of Rudy::Machine and one of Rye::Box.
41
+ def generic_machine_runner(machine_action, routine=nil, skip_check=false, skip_header=false, &routine_action)
42
+ if @@global.offline
43
+ rmach = Rudy::Machines::Offline.new
44
+ skip_check = true
45
+ remote_user = Rudy.sysinfo.user
46
+ else
47
+ rmach = Rudy::Machines.new
48
+ remote_user = 'root'
49
+ end
50
+
51
+ routine ||= @routine
52
+ raise "No routine supplied" unless routine
42
53
  raise "No machine action supplied" unless machine_action
43
54
  unless rmach.respond_to?(machine_action)
44
55
  raise "Unknown machine action #{machine_action}"
45
56
  end
46
57
 
58
+ # Declare a couple vars so they're available outide the block
59
+ before_dependencies = after_dependencies = nil
60
+ enjoy_every_sandwich {
61
+ # This gets and removes the dependencies from the routines hash.
62
+ if Rudy::Routines::DependsHelper.has_depends?(:before, routine)
63
+ before_dependencies = Rudy::Routines::DependsHelper.get(:before, routine)
64
+ end
65
+
66
+ # We grab the after ones now too, so we don't fool the ScriptHelper
67
+ # later on in this routine (after keyword is used for scripts too)
68
+ if Rudy::Routines::DependsHelper.has_depends?(:after, routine)
69
+ after_dependencies = Rudy::Routines::DependsHelper.get(:after, routine)
70
+ end
71
+
72
+ # This calls generic_machine_runner for every dependent before routine.
73
+ execute_dependency(before_dependencies, skip_check, skip_header)
74
+ }
75
+
76
+
47
77
  lbox = Rye::Box.new('localhost')
48
78
  sconf = fetch_script_config
49
79
 
80
+ enjoy_every_sandwich {
81
+ if Rudy::Routines::ScriptHelper.before_local?(routine) # before_local
82
+ # Runs "before_local" scripts of routines config.
83
+ puts task_separator("LOCAL SHELL")
84
+ Rudy::Routines::ScriptHelper.before_local(routine, sconf, lbox)
85
+ end
86
+ }
50
87
 
51
- if Rudy::Routines::ScriptHelper.before_local?(@routine) # before_local
52
- # Runs "before_local" scripts of routines config.
53
- puts task_separator("LOCAL SHELL")
54
- Rudy::Routines::ScriptHelper.before_local(@routine, sconf, lbox)
55
- end
56
-
57
- if Rudy::Routines::ScriptHelper.script_local?(@routine) # before_local
58
- # Runs "script_local" scripts of routines config.
59
- # NOTE: This is synonymous with before_local
60
- puts task_separator("LOCAL SHELL")
61
- Rudy::Routines::ScriptHelper.script_local(@routine, sconf, lbox)
62
- end
88
+ enjoy_every_sandwich {
89
+ if Rudy::Routines::ScriptHelper.script_local?(routine) # script_local
90
+ # Runs "script_local" scripts of routines config.
91
+ # NOTE: This is synonymous with before_local
92
+ puts task_separator("LOCAL SHELL")
93
+ Rudy::Routines::ScriptHelper.script_local(routine, sconf, lbox)
94
+ end
95
+ }
63
96
 
64
- unless has_remote_task?(@routine)
97
+ unless has_remote_task?(routine)
65
98
  puts "[no remote tasks]"
66
99
  return
67
100
  end
68
101
 
69
102
  # Execute the action (create, list, destroy, restart) & apply the block to each
70
103
  rmach.send(machine_action) do |machine|
71
- puts machine_separator(machine.name, machine.awsid)
104
+ puts machine_separator(machine.name, machine.awsid) unless skip_header
72
105
 
73
- unless skipcheck
106
+ unless skip_check
74
107
  msg = preliminary_separator("Checking if instance is running...")
75
108
  Rudy::Utils.waiter(3, 120, STDOUT, msg, 0) {
76
109
  inst = machine.get_instance
@@ -80,7 +113,7 @@ module Rudy
80
113
  # Add instance info to machine and save it. This is really important
81
114
  # for the initial startup so the metadata is updated right away. But
82
115
  # it's also important to call here because if a routine was executed
83
- # and an unexpected exception occurrs before this update is executed
116
+ # and an unexpected exception occurs before this update is executed
84
117
  # the machine metadata won't contain the DNS information. Calling it
85
118
  # here ensure that the metadata is always up-to-date.
86
119
  machine.update
@@ -92,55 +125,70 @@ module Rudy
92
125
  end
93
126
 
94
127
  # TODO: trap rbox errors. We could get an authentication error.
95
- opts = { :keys => root_keypairpath, :user => 'root', :info => @@global.verbose > 0 }
128
+ opts = { :keys => root_keypairpath, :user => remote_user, :info => @@global.verbose > 0 }
96
129
  begin
97
130
  rbox = Rye::Box.new(machine.dns_public, opts)
98
131
  rbox.connect
99
132
  rescue Rye::NoHost => ex
100
-
133
+ STDERR.puts "No host: #{ex.message}"
101
134
  exit 65
102
135
  end
103
-
104
- # Set the hostname if specified in the machines config.
105
- # :rudy -> change to Rudy's machine name
106
- # :default -> leave the hostname as it is
107
- # Anything else other than nil -> change to that value
108
- # NOTE: This will set hostname every time a routine is
109
- # run so we may want to make this an explicit action.
110
- hn = current_machine_hostname || :rudy
111
- if hn != :default
112
- hn = machine.name if hn == :rudy
113
- print preliminary_separator("Setting hostame to #{hn}... ")
114
- rbox.hostname(hn)
115
- puts "done"
116
- end
117
136
 
118
- if Rudy::Routines::UserHelper.adduser?(@routine) # adduser
119
- puts task_separator("ADD USER")
120
- Rudy::Routines::UserHelper.adduser(@routine, machine, rbox)
137
+ unless skip_check
138
+ # Set the hostname if specified in the machines config.
139
+ # :rudy -> change to Rudy's machine name
140
+ # :default -> leave the hostname as it is
141
+ # Anything else other than nil -> change to that value
142
+ # NOTE: This will set hostname every time a routine is
143
+ # run so we may want to make this an explicit action.
144
+ enjoy_every_sandwich {
145
+ hn = current_machine_hostname || :rudy
146
+ if hn != :default
147
+ hn = machine.name if hn == :rudy
148
+ print preliminary_separator("Setting hostame to #{hn}... ")
149
+ rbox.hostname(hn)
150
+ puts "done"
151
+ end
152
+ }
121
153
  end
122
154
 
123
- if Rudy::Routines::UserHelper.authorize?(@routine) # authorize
124
- puts task_separator("AUTHORIZE USER")
125
- Rudy::Routines::UserHelper.authorize(@routine, machine, rbox)
126
- end
127
- #puts 1
128
- if Rudy::Routines::ScriptHelper.before?(@routine) # before
129
- puts task_separator("REMOTE SHELL")
130
- Rudy::Routines::ScriptHelper.before(@routine, sconf, machine, rbox)
131
- end
132
- #puts 2
133
- if Rudy::Routines::DiskHelper.disks?(@routine) # disk
134
- puts task_separator("DISKS")
135
- if rbox.ostype == "sunos"
136
- puts "Sorry, Solaris is not supported yet!"
137
- else
138
- Rudy::Routines::DiskHelper.execute(@routine, machine, rbox)
139
- end
140
- end
141
155
 
142
- # Startup, shutdown, release, deploy, etc...
143
- routine_action.call(machine, rbox) if routine_action
156
+ enjoy_every_sandwich {
157
+ if Rudy::Routines::UserHelper.adduser?(routine) # adduser
158
+ puts task_separator("ADD USER")
159
+ Rudy::Routines::UserHelper.adduser(routine, machine, rbox)
160
+ end
161
+ }
162
+
163
+ enjoy_every_sandwich {
164
+ if Rudy::Routines::UserHelper.authorize?(routine) # authorize
165
+ puts task_separator("AUTHORIZE USER")
166
+ Rudy::Routines::UserHelper.authorize(routine, machine, rbox)
167
+ end
168
+ }
169
+
170
+ enjoy_every_sandwich {
171
+ if Rudy::Routines::ScriptHelper.before?(routine) # before
172
+ puts task_separator("REMOTE SHELL")
173
+ Rudy::Routines::ScriptHelper.before(routine, sconf, machine, rbox)
174
+ end
175
+ }
176
+
177
+ enjoy_every_sandwich {
178
+ if Rudy::Routines::DiskHelper.disks?(routine) # disk
179
+ puts task_separator("DISKS")
180
+ if rbox.ostype == "sunos"
181
+ puts "Sorry, Solaris disks are not supported yet!"
182
+ else
183
+ Rudy::Routines::DiskHelper.execute(routine, machine, rbox)
184
+ end
185
+ end
186
+ }
187
+
188
+ enjoy_every_sandwich {
189
+ # Startup, shutdown, release, deploy, etc...
190
+ routine_action.call(machine, rbox) if routine_action
191
+ }
144
192
 
145
193
  # The "after" blocks are synonymous with "script" blocks.
146
194
  # For some routines, like startup, it makes sense to an
@@ -149,37 +197,60 @@ module Rudy
149
197
  # definition is the entire routine so we use "script".
150
198
  # NOTE: If both after and script are supplied they will
151
199
  # both be executed.
152
- if Rudy::Routines::ScriptHelper.script?(@routine) # script
153
- puts task_separator("REMOTE SHELL")
154
- # Runs "after" scripts of routines config
155
- Rudy::Routines::ScriptHelper.script(@routine, sconf, machine, rbox)
156
- end
200
+ enjoy_every_sandwich {
201
+ if Rudy::Routines::ScriptHelper.script?(routine) # script
202
+ puts task_separator("REMOTE SHELL")
203
+ # Runs "after" scripts of routines config
204
+ Rudy::Routines::ScriptHelper.script(routine, sconf, machine, rbox)
205
+ end
206
+ }
157
207
 
158
-
159
- if Rudy::Routines::ScriptHelper.after?(@routine) # after
160
- puts task_separator("REMOTE SHELL")
161
- # Runs "after" scripts of routines config
162
- Rudy::Routines::ScriptHelper.after(@routine, sconf, machine, rbox)
163
- end
164
-
165
- if Rudy::Routines::DiskHelper.disks?(@routine)
166
- # TODO: Print only the requested disks
167
- puts task_separator("INFO")
168
- puts "Filesystem on #{machine.name}:"
169
- puts " " << rbox.df(:h).join("#{$/} ")
170
- end
208
+ enjoy_every_sandwich {
209
+ if Rudy::Routines::ScriptHelper.after?(routine) # after
210
+ puts task_separator("REMOTE SHELL")
211
+ # Runs "after" scripts of routines config
212
+ Rudy::Routines::ScriptHelper.after(routine, sconf, machine, rbox)
213
+ end
214
+ }
171
215
 
172
216
  rbox.disconnect
173
217
  end
174
-
175
- if Rudy::Routines::ScriptHelper.after_local?(@routine) # after_local
176
- puts task_separator("LOCAL SHELL")
177
- # Runs "after_local" scripts of routines config
178
- Rudy::Routines::ScriptHelper.after_local(@routine, sconf, lbox)
218
+
219
+ enjoy_every_sandwich {
220
+ if Rudy::Routines::ScriptHelper.after_local?(routine) # after_local
221
+ puts task_separator("LOCAL SHELL")
222
+ # Runs "after_local" scripts of routines config
223
+ Rudy::Routines::ScriptHelper.after_local(routine, sconf, lbox)
224
+ end
225
+ }
226
+
227
+ # This calls generic_machine_runner for every dependent after routine
228
+ enjoy_every_sandwich {
229
+ execute_dependency(after_dependencies, skip_check, skip_header)
230
+ }
231
+
232
+ end
233
+
234
+ def execute_dependency(depends, skip_check, skip_header)
235
+ return unless depends
236
+ unless depends.empty?
237
+ depends.each_with_index do |d, index|
238
+ puts task_separator("DEPENDENCY: #{d}")
239
+ routine_dependency = fetch_routine_config(d)
240
+ unless routine_dependency
241
+ STDERR.puts " Unknown routine: #{d}".color(:red)
242
+ next
243
+ end
244
+ # NOTE: running routines here means they do not have their own
245
+ # payload and they must use the list action. I think this is ok
246
+ # though b/c there should only be a few routines with payloads
247
+ # (startup, shutdown, reboot)
248
+ generic_machine_runner(:list, routine_dependency, skip_check, skip_header)
249
+ end
179
250
  end
180
-
181
251
  end
182
252
 
253
+
183
254
  # Does the given +routine+ define any remote tasks?
184
255
  def has_remote_task?(routine)
185
256
  any = [Rudy::Routines::DiskHelper.disks?(routine),
@@ -187,7 +258,9 @@ module Rudy
187
258
  Rudy::Routines::ScriptHelper.after?(routine),
188
259
  Rudy::Routines::ScriptHelper.script?(routine),
189
260
  Rudy::Routines::UserHelper.authorize?(routine),
190
- Rudy::Routines::UserHelper.adduser?(routine)]
261
+ Rudy::Routines::UserHelper.adduser?(routine),
262
+ !@after_dependencies.nil?,
263
+ !@before_dependencies.nil?]
191
264
  # Throw away all false answers (and nil answers)
192
265
  any = any.compact.select { |success| success }
193
266
  !any.empty? # Returns true if any element contains true
@@ -220,9 +293,21 @@ module Rudy
220
293
  #puts '%-40s' % [name.bright]
221
294
  end
222
295
 
296
+ def enjoy_every_sandwich(&bloc_party)
297
+ begin
298
+ bloc_party.call
299
+ rescue => ex
300
+ STDERR.puts " Error: #{ex.message}".color(:red)
301
+ STDERR.puts ex.backtrace if Rudy.debug?
302
+ exit 12 unless keep_going?
303
+ end
304
+ end
305
+
306
+ def keep_going?
307
+ Annoy.pose_question(" Keep going?\a ", /yes|y|ya|sure|you bet!/i, STDERR)
308
+ end
223
309
 
224
310
  end
225
-
226
311
  end
227
312
  end
228
313