solutious-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 (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,226 @@
1
+
2
+ module Rudy; module Routines;
3
+ class Base
4
+ include Rudy::Huxtable
5
+
6
+ @@run = true
7
+
8
+ def self.run?; @@run; end
9
+ def self.disable_run; @@run = false; end
10
+ def self.enable_run; @@run = true; end
11
+
12
+ def run?; @@run; end
13
+ def disable_run; @@run = false; end
14
+ def enable_run; @@run = true; end
15
+
16
+ # An Array Rudy::Machines objects that will be processed
17
+ attr_reader :machines
18
+
19
+ # * +name+ The name of the command specified on the command line
20
+ # * +option+ A Hash or OpenStruct of named command line options.
21
+ # If it's a Hash it will be converted to an OpenStruct.
22
+ # * +argv+ An Array of arguments
23
+ #
24
+ # +option+ and +argv+ are made available to the routine block.
25
+ #
26
+ # routines do
27
+ # magic do |options,argv|
28
+ # ...
29
+ # end
30
+ # end
31
+ #
32
+ def initialize(name=nil, option={}, argv=[], *args)
33
+ name ||= (self.class.to_s.split(/::/)).last.downcase
34
+ option = OpenStruct.new(option) if option.is_a? Hash
35
+ @name, @option, @argv = name.to_sym, option, argv
36
+ a, s, r = @@global.accesskey, @@global.secretkey, @@global.region
37
+ @@sdb ||= Rudy::AWS::SDB.new(a, s, r)
38
+
39
+ # Grab the routines configuration for this routine name
40
+ # e.g. startup, sysupdate, installdeps
41
+ @routine = fetch_routine_config @name
42
+
43
+ ld "Routine: #{@routine.inspect}"
44
+
45
+ if @routine
46
+ # Removes the dependencies from the routines hash.
47
+ # We run these separately from the other actions.
48
+ @before, @after = @routine.delete(:before), @routine.delete(:after)
49
+ end
50
+
51
+ # Share one Rye::Box instance for localhost across all routines
52
+ @@lbox = create_rye_box @@global.localhost unless defined?(@@lbox)
53
+
54
+ disable_run if @@global.testrun
55
+
56
+ # We create these frozen globals for the benefit of
57
+ # the local and remote routine blocks.
58
+ $global = @@global.dup.freeze unless $global
59
+ $option = option.dup.freeze unless $option
60
+
61
+ ## TODO: get the machine config for just the current machine group. This
62
+ ## probably requires Caesars to be aware of which nodes are structural.
63
+ ##$config = fetch_machine_config unless $config
64
+
65
+ init(*args) if respond_to? :init
66
+ end
67
+
68
+ def raise_early_exceptions; raise "Please override"; end
69
+ def execute; raise "Please override"; end
70
+
71
+ # Create an instance of Rye::Box for +hostname+. +opts+ is
72
+ # an optional Hash of options. See Rye::Box.initialize
73
+ #
74
+ # This method should be used throughout the Rudy::Routines
75
+ # namespace rather than creating instances manually b/c it
76
+ # applies some fancy pants defaults like command hooks.
77
+ def create_rye_box(hostname, opts={})
78
+ ld [:hostname, hostname, opts, caller[0]]
79
+ opts = {
80
+ :info => (@@global.verbose >= 3), # rudy -vvv
81
+ :debug => false,
82
+ :user => Rudy.sysinfo.user
83
+ }.merge opts
84
+
85
+ box = Rye::Box.new hostname, opts
86
+
87
+
88
+ # We define hooks so we can still print each command and its output
89
+ # when running the command blocks. NOTE: We only print this in
90
+ # verbosity mode.
91
+ if @@global.verbose > 0
92
+ # This block gets called for every command method call.
93
+ box.pre_command_hook do |cmd, user, host, nickname|
94
+ print_command user, nickname, cmd
95
+ end
96
+ end
97
+
98
+ if @@global.verbose > 1
99
+ # And this one gets called after each command method call.
100
+ box.post_command_hook do |ret|
101
+ print_response ret
102
+ end
103
+ end
104
+
105
+ box.exception_hook(Rye::CommandError, &rbox_exception_handler)
106
+ box.exception_hook(Exception, &rbox_exception_handler)
107
+
108
+ ## It'd better for unknown commands to be handled elsewhere
109
+ ## because it doesn't make sense to retry a method that doesn't exist
110
+ ##box.exception_hook(Rye::CommandNotFound, &rbox_exception_handler)
111
+
112
+ box
113
+ end
114
+
115
+
116
+
117
+ # Create an instance of Rye::Set from a list of +hostnames+.
118
+ # +hostnames+ can contain hostnames or Rudy::Machine objects.
119
+ # +opts+ is an optional Hash of options. See Rye::Box.initialize
120
+ #
121
+ # NOTE: Windows machines are skipped and not added to the set.
122
+ def create_rye_set(hostnames, opts={})
123
+ hostnames ||= []
124
+
125
+ opts = {
126
+ :user => (current_machine_user).to_s,
127
+ :parallel => @@global.parallel
128
+ }.merge(opts)
129
+ set = Rye::Set.new current_machine_group, opts
130
+
131
+ opts.delete(:parallel) # Not used by Rye::Box.new
132
+
133
+ hostnames.each do |m|
134
+ # This is a short-circuit for Windows instances. We don't support
135
+ # disks for windows yet and there's no SSH so routines are out of
136
+ # the picture too.
137
+ next if (m.os || '').to_s == 'win32'
138
+
139
+ if m.is_a?(Rudy::Machine)
140
+ m.refresh! if m.dns_public.nil? || m.dns_public.empty?
141
+ if m.dns_public.nil? || m.dns_public.empty?
142
+ ld "Cannot find public DNS for #{m.name} (continuing...)"
143
+ ##next
144
+ end
145
+ ld [:dns_public, m.dns_public, m.instid]
146
+ rbox = create_rye_box(m.dns_public, opts)
147
+ rbox.stash = m # Store the machine instance in the stash
148
+ rbox.nickname = m.name
149
+ else
150
+ # Otherwise we assume it's a hostname
151
+ rbox = create_rye_box(m)
152
+ end
153
+ rbox.add_key user_keypairpath(opts[:user])
154
+ set.add_box rbox
155
+ end
156
+
157
+ ld "Machines Set: %s" % [set.empty? ? '[empty]' : set.inspect]
158
+
159
+ set
160
+ end
161
+
162
+
163
+
164
+
165
+ # Returns a formatted string for printing command info
166
+ def print_command(user, host, cmd)
167
+ #return if @@global.parallel
168
+ cmd ||= ""
169
+ cmd, user = cmd.to_s, user.to_s
170
+ prompt = user == "root" ? "#" : "$"
171
+ li ("%s@%s%s %s" % [user, host, prompt, cmd.bright])
172
+ end
173
+
174
+ def print_response(rap)
175
+ # Non zero exit codes raise exceptions so
176
+ # the erorrs have already been handled.
177
+ return if rap.exit_code != 0
178
+
179
+ if @@global.parallel
180
+ cmd, user = cmd.to_s, user.to_s
181
+ prompt = user == "root" ? "#" : "$"
182
+ li "%s@%s%s %s%s%s" % [rap.box.user, rap.box.nickname, prompt, rap.cmd.bright, $/, rap.stdout.inspect]
183
+ unless rap.stderr.empty?
184
+ le "#{rap.box.nickname}: " << rap.stderr.join("#{rap.box.nickname}: ")
185
+ end
186
+ else
187
+ li ' ' << rap.stdout.join("#{$/} ") if !rap.stdout.empty?
188
+ colour = rap.exit_code != 0 ? :red : :normal
189
+ unless rap.stderr.empty?
190
+ le (" STDERR " << '-'*38).color(colour).bright
191
+ le " " << rap.stderr.join("#{$/} ").color(colour)
192
+ end
193
+ end
194
+ end
195
+
196
+ private
197
+
198
+ def rbox_exception_handler
199
+ Proc.new do |ex, cmd, user, host, nickname|
200
+ print_exception(user, host, cmd, nickname, ex)
201
+ unless @@global.parallel
202
+ choice = Annoy.get_user_input('(S)kip (R)etry (A)bort: ', nil, 3600) || ''
203
+ if choice.match(/\AS/i)
204
+ :skip
205
+ elsif choice.match(/\AR/i)
206
+ :retry # Tells Rye::Box#run_command to retry
207
+ else
208
+ exit 12
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ def print_exception(user, host, cmd, nickname, ex)
215
+ prefix = @@global.parallel ? "#{nickname}: #{cmd}: " : ""
216
+ if ex.is_a?(Rye::CommandError)
217
+ le prefix << ex.message.color(:red)
218
+ else
219
+ le prefix << "#{ex.class}: #{ex.message}".color(:red)
220
+ end
221
+ le *ex.backtrace
222
+ end
223
+
224
+ end
225
+
226
+ end; end;
@@ -0,0 +1,48 @@
1
+
2
+
3
+ module Rudy; module Routines; module Handlers;
4
+ module Base
5
+ include Rudy::Huxtable
6
+
7
+ def trap_rbox_errors(ret=nil, &command)
8
+ begin
9
+ ret = command.call if command
10
+ return unless ret.is_a?(Rye::Rap)
11
+ puts ' ' << ret.stdout.join("#{$/} ") if !ret.stdout.empty?
12
+ print_response(ret)
13
+ rescue IOError => ex
14
+ STDERR.puts " Connection Error (#{ex.message})".color(:red)
15
+ choice = Annoy.get_user_input('(S)kip (A)bort: ', nil, 3600) || ''
16
+ if choice.match(/\AS/i)
17
+ return
18
+ #elsif choice.match(/\AR/i)
19
+ # retry
20
+ else
21
+ exit 12
22
+ end
23
+ end
24
+
25
+ ret
26
+ end
27
+
28
+ def keep_going?
29
+ Annoy.pose_question(" Keep going?\a ", /yes|y|ya|sure|you bet!/i, STDERR)
30
+ end
31
+
32
+
33
+ private
34
+ def print_response(rap)
35
+ colour = rap.exit_code != 0 ? :red : :normal
36
+ [:stderr].each do |sumpin|
37
+ next if rap.send(sumpin).empty?
38
+ STDERR.puts
39
+ STDERR.puts((" #{sumpin.to_s.upcase} " << '-'*38).color(colour).bright)
40
+ STDERR.puts " " << rap.send(sumpin).join("#{$/} ").color(colour)
41
+ end
42
+ STDERR.puts " Exit code: #{rap.exit_code}".color(colour) if rap.exit_code != 0
43
+ end
44
+
45
+ end
46
+
47
+ end; end; end
48
+
@@ -0,0 +1,49 @@
1
+
2
+ module Rudy; module Routines; module Handlers;
3
+ module Depends
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ## NOTE: Dependencies don't use Rudy::Routines.add_handler but we
8
+ ## define them ehere anyway so raise_early_exceptions passes.
9
+ Rudy::Routines.add_handler :before, self
10
+ Rudy::Routines.add_handler :after, self
11
+
12
+ def raise_early_exceptions(type, depends, rset, lbox, argv=nil)
13
+ unless depends.kind_of? Array
14
+ raise Rudy::Error, "#{type} must be a kind of Array (#{depends.class})"
15
+ end
16
+ raise Rudy::Routines::EmptyDepends, type if depends.nil? || depends.empty?
17
+ depends.flatten.compact.each do |name|
18
+ raise Rudy::Routines::NoRoutine, name unless valid_routine?(name)
19
+ end
20
+ end
21
+
22
+ # A simple wrapper for executing a routine.
23
+ #
24
+ # * +routine_name+ should be a Symbol representing a routine
25
+ # available to the current machine group.
26
+ #
27
+ # This method finds the handler for the given routine,
28
+ # creates an instance, calls raise_early_exceptions,
29
+ # and finally executes the routine.
30
+ def execute(routine_name)
31
+ routine_obj = Rudy::Routines.get_routine routine_name
32
+ ld "Executing dependency: #{routine_name} (#{routine_obj})"
33
+ routine = routine_obj.new routine_name
34
+ routine.raise_early_exceptions
35
+ routine.execute
36
+ end
37
+
38
+ # Calls execute for each routine name in +depends+ (an Array).
39
+ # Does nothing if given an empty Array or nil.
40
+ def execute_all(depends)
41
+ return if depends.nil? || depends.empty?
42
+ depends = depends.flatten.compact
43
+ ld "Found depenencies: #{depends.join(', ')}"
44
+ depends.each { |routine| execute(routine) }
45
+ end
46
+
47
+ end
48
+
49
+ end; end; end
@@ -0,0 +1,239 @@
1
+
2
+ module Rudy::Routines::Handlers;
3
+ module Disks
4
+ include Rudy::Routines::Handlers::Base
5
+ extend self
6
+
7
+ ACTIONS = [:create, :destroy, :archive, :mount, :restore,
8
+ :attach, :detach, :mount, :umount].freeze
9
+
10
+ Rudy::Routines.add_handler :disks, self
11
+
12
+ def raise_early_exceptions(type, batch, rset, lbox, argv=nil)
13
+
14
+ end
15
+
16
+ def disks?(routine)
17
+ (routine.kind_of?(Hash) && routine.disks &&
18
+ routine.disks.kind_of?(Hash) && !routine.disks.empty?) ? true : false
19
+ end
20
+
21
+ def paths(routine)
22
+ return nil unless disks?(routine)
23
+ routine.disks.values.collect { |d| d.keys }.flatten
24
+ end
25
+
26
+
27
+ def execute(type, routine, rset, lbox, argv=nil)
28
+ original_user = rset.user
29
+ rset.add_key user_keypairpath('root')
30
+ rset.switch_user 'root'
31
+
32
+ # We need to add mkfs since it's not enabled by default.
33
+ # We prepend the command with rudy_ so we can delete it.
34
+ Rye::Cmd.add_command(:rudy_mkfs, 'mkfs')
35
+
36
+ routine.each_pair do |action, disks|
37
+ unless respond_to?(action.to_sym)
38
+ Rudy::Huxtable.le %Q(DiskHelper: unknown action "#{action}")
39
+ next
40
+ end
41
+ # A quick hack to take advantage of the threading in Rye::Set.
42
+ # The action method does not run in the context of a Rye::Box
43
+ # object so we need to send rset as an argument.
44
+ rset.batch do
45
+ disks.each_pair do |path, props|
46
+ # self contains the current instance of Rye::Box.
47
+ disk = Rudy::Disk.new(self.stash.position, path, props)
48
+ Rudy::Routines::Handlers::Disks.send(action, self, disk)
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ Rye::Cmd.remove_command(:rudy_mkfs)
55
+
56
+ rset.switch_user original_user
57
+ end
58
+
59
+
60
+ def create(rbox, disk)
61
+ if disk.exists?
62
+ puts "Disk found: #{disk.name}"
63
+ disk.refresh!
64
+ end
65
+
66
+ unless @@global.force
67
+ raise Rudy::Disks::AlreadyAttached, disk.name if disk.volume_attached?
68
+ end
69
+
70
+ unless disk.volume_exists?
71
+ msg = "Creating volume... "
72
+ disk.create
73
+ Rudy::Utils.waiter(2, 60, STDOUT, msg) {
74
+ disk.volume_available?
75
+ }
76
+ end
77
+
78
+ attach rbox, disk unless disk.volume_attached?
79
+ format rbox, disk if disk.raw?
80
+ mount rbox, disk unless disk.mounted?
81
+
82
+ disk.save :replace
83
+ end
84
+
85
+
86
+
87
+ def detach(rbox, disk)
88
+
89
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
90
+ disk.refresh!
91
+
92
+ raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
93
+
94
+ umount rbox, disk if disk.mounted?
95
+ raise Rudy::Disks::InUse, disk.name if disk.mounted?
96
+
97
+ msg = "Detaching #{disk.volid}..."
98
+ disk.volume_detach
99
+ Rudy::Utils.waiter(2, 60, STDOUT, msg) {
100
+ disk.volume_available?
101
+ }
102
+
103
+ end
104
+
105
+ def attach(rbox, disk)
106
+
107
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
108
+ disk.refresh!
109
+
110
+ raise Rudy::Disks::AlreadyAttached, disk.name if disk.volume_attached?
111
+
112
+ msg = "Attaching #{disk.volid} to #{rbox.stash.instid}... "
113
+ disk.volume_attach(rbox.stash.instid)
114
+ Rudy::Utils.waiter(2, 10, STDOUT, msg) {
115
+ disk.volume_attached?
116
+ }
117
+
118
+ end
119
+
120
+ def mount(rbox, disk)
121
+
122
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
123
+ disk.refresh!
124
+ attach rbox, disk unless disk.volume_attached?
125
+
126
+ unless @@global.force
127
+ raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
128
+ raise Rudy::Disks::NotFormatted, disk.name if disk.raw?
129
+ raise Rudy::Disks::AlreadyMounted, disk.name if disk.mounted?
130
+ end
131
+
132
+ rbox.mkdir(:p, disk.path)
133
+
134
+ puts "Mounting at #{disk.path}... "
135
+
136
+ rbox.mount(:t, disk.fstype, disk.device, disk.path)
137
+ disk.mounted = true
138
+ disk.save :replace
139
+ sleep 1
140
+ end
141
+
142
+
143
+ def umount(rbox, disk)
144
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
145
+ disk.refresh!
146
+
147
+ raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
148
+ raise Rudy::Disks::NotMounted, disk.name if !disk.mounted?
149
+
150
+ puts "Unmounting #{disk.path}... "
151
+ rbox.umount(disk.path)
152
+ disk.mounted = false
153
+ disk.save :replace
154
+ sleep 2
155
+ end
156
+ alias_method :unmount, :umount
157
+
158
+ def format(rbox, disk)
159
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
160
+ disk.refresh!
161
+
162
+ attach rbox, disk unless disk.volume_attached?
163
+
164
+ raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
165
+
166
+ unless @@global.force
167
+ raise Rudy::Disks::AlreadyFormatted, disk.name if !disk.raw?
168
+ end
169
+
170
+ disk.fstype = 'ext3' if disk.fstype.nil? || disk.fstype.empty?
171
+
172
+ puts "Creating #{disk.fstype} filesystem for #{disk.device}... "
173
+ rbox.rudy_mkfs(:t, disk.fstype, :F, disk.device)
174
+ disk.raw = false
175
+ disk.save :replace
176
+ end
177
+
178
+ def destroy(rbox, disk)
179
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
180
+ disk.refresh!
181
+
182
+ umount rbox, disk if disk.mounted?
183
+ detach rbox, disk if disk.volume_attached?
184
+
185
+ unless @@global.force
186
+ raise Rudy::Disks::InUse, disk.name if disk.volume_attached?
187
+ end
188
+
189
+ puts "Destroying #{disk.name}"
190
+ disk.destroy
191
+ end
192
+
193
+ def archive(rbox, disk)
194
+ raise Rudy::Metadata::UnknownObject, disk.name unless disk.exists?
195
+ disk.refresh!
196
+
197
+ raise Rudy::Disks::NotAttached, disk.name if !disk.volume_attached?
198
+
199
+ back = disk.archive
200
+ puts "Created backup: #{back.name}"
201
+ end
202
+
203
+ def restore(rbox, disk)
204
+
205
+ if disk.exists?
206
+ puts "Disk found: #{disk.name}"
207
+ disk.refresh!
208
+ end
209
+
210
+ unless @@global.force
211
+ raise Rudy::Disks::AlreadyAttached, disk.name if disk.volume_attached?
212
+ end
213
+
214
+ latest_backup = disk.backups.last
215
+ disk.size, disk.fstype = latest_backup.size, latest_backup.fstype
216
+
217
+ puts "Backup found: #{latest_backup.name}"
218
+
219
+ unless disk.volume_exists?
220
+ msg = "Creating volume... "
221
+ disk.create latest_backup.size, latest_backup.zone, latest_backup.snapid
222
+ Rudy::Utils.waiter(2, 60, STDOUT, msg) {
223
+ disk.volume_available?
224
+ }
225
+
226
+ end
227
+ disk.raw = false
228
+
229
+ attach rbox, disk unless disk.volume_attached?
230
+ #format rbox, disk if disk.raw?
231
+ mount rbox, disk unless disk.mounted?
232
+
233
+ disk.save :replace
234
+
235
+ end
236
+
237
+
238
+ end
239
+ end