solutious-rudy 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/CHANGES.txt +8 -9
  2. data/README.rdoc +48 -7
  3. data/Rakefile +102 -7
  4. data/Rudyfile +28 -0
  5. data/bin/ird +162 -0
  6. data/bin/rudy +287 -93
  7. data/lib/annoy.rb +227 -0
  8. data/lib/aws_sdb/service.rb +1 -1
  9. data/lib/console.rb +20 -4
  10. data/lib/escape.rb +305 -0
  11. data/lib/rudy.rb +265 -125
  12. data/lib/rudy/aws.rb +61 -26
  13. data/lib/rudy/aws/ec2.rb +20 -296
  14. data/lib/rudy/aws/ec2/address.rb +121 -0
  15. data/lib/rudy/aws/ec2/group.rb +241 -0
  16. data/lib/rudy/aws/ec2/image.rb +46 -0
  17. data/lib/rudy/aws/ec2/instance.rb +407 -0
  18. data/lib/rudy/aws/ec2/keypair.rb +92 -0
  19. data/lib/rudy/aws/ec2/snapshot.rb +87 -0
  20. data/lib/rudy/aws/ec2/volume.rb +234 -0
  21. data/lib/rudy/aws/simpledb.rb +33 -15
  22. data/lib/rudy/cli.rb +142 -0
  23. data/lib/rudy/cli/addresses.rb +85 -0
  24. data/lib/rudy/cli/backups.rb +175 -0
  25. data/lib/rudy/{command → cli}/config.rb +18 -13
  26. data/lib/rudy/cli/deploy.rb +12 -0
  27. data/lib/rudy/cli/disks.rb +125 -0
  28. data/lib/rudy/cli/domains.rb +17 -0
  29. data/lib/rudy/cli/groups.rb +77 -0
  30. data/lib/rudy/{command → cli}/images.rb +18 -6
  31. data/lib/rudy/cli/instances.rb +142 -0
  32. data/lib/rudy/cli/keypairs.rb +47 -0
  33. data/lib/rudy/cli/manager.rb +51 -0
  34. data/lib/rudy/{command → cli}/release.rb +10 -10
  35. data/lib/rudy/cli/routines.rb +80 -0
  36. data/lib/rudy/cli/volumes.rb +121 -0
  37. data/lib/rudy/command/addresses.rb +62 -39
  38. data/lib/rudy/command/backups.rb +60 -170
  39. data/lib/rudy/command/disks-old.rb +322 -0
  40. data/lib/rudy/command/disks.rb +5 -209
  41. data/lib/rudy/command/domains.rb +34 -0
  42. data/lib/rudy/command/groups.rb +105 -48
  43. data/lib/rudy/command/instances.rb +263 -70
  44. data/lib/rudy/command/keypairs.rb +149 -0
  45. data/lib/rudy/command/manager.rb +65 -0
  46. data/lib/rudy/command/volumes.rb +110 -49
  47. data/lib/rudy/config.rb +90 -70
  48. data/lib/rudy/config/objects.rb +67 -0
  49. data/lib/rudy/huxtable.rb +253 -0
  50. data/lib/rudy/metadata/backup.rb +23 -48
  51. data/lib/rudy/metadata/disk.rb +79 -68
  52. data/lib/rudy/metadata/machine.rb +34 -0
  53. data/lib/rudy/routines.rb +54 -0
  54. data/lib/rudy/routines/disk_handler.rb +190 -0
  55. data/lib/rudy/routines/release.rb +15 -0
  56. data/lib/rudy/routines/script_runner.rb +65 -0
  57. data/lib/rudy/routines/shutdown.rb +42 -0
  58. data/lib/rudy/routines/startup.rb +48 -0
  59. data/lib/rudy/utils.rb +57 -2
  60. data/lib/storable.rb +11 -5
  61. data/lib/sysinfo.rb +274 -0
  62. data/rudy.gemspec +84 -20
  63. data/support/randomize-root-password +45 -0
  64. data/support/rudy-ec2-startup +5 -5
  65. data/support/update-ec2-ami-tools +20 -0
  66. data/test/05_config/00_setup_test.rb +24 -0
  67. data/test/05_config/30_machines_test.rb +69 -0
  68. data/test/20_sdb/00_setup_test.rb +31 -0
  69. data/test/20_sdb/10_domains_test.rb +113 -0
  70. data/test/25_ec2/00_setup_test.rb +34 -0
  71. data/test/25_ec2/10_keypairs_test.rb +33 -0
  72. data/test/25_ec2/20_groups_test.rb +139 -0
  73. data/test/25_ec2/30_addresses_test.rb +35 -0
  74. data/test/25_ec2/40_volumes_test.rb +46 -0
  75. data/test/25_ec2/50_snapshots_test.rb +69 -0
  76. data/test/26_ec2_instances/00_setup_test.rb +33 -0
  77. data/test/26_ec2_instances/10_instances_test.rb +81 -0
  78. data/test/26_ec2_instances/50_images_test.rb +13 -0
  79. data/test/30_sdb_metadata/00_setup_test.rb +28 -0
  80. data/test/30_sdb_metadata/10_disks_test.rb +99 -0
  81. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  82. data/test/50_commands/00_setup_test.rb +11 -0
  83. data/test/50_commands/10_keypairs_test.rb +79 -0
  84. data/test/50_commands/20_groups_test.rb +77 -0
  85. data/test/50_commands/40_volumes_test.rb +55 -0
  86. data/test/50_commands/50_instances_test.rb +110 -0
  87. data/test/coverage.txt +51 -0
  88. data/test/helper.rb +35 -0
  89. data/tryouts/disks.rb +55 -0
  90. data/tryouts/nested_methods.rb +36 -0
  91. data/tryouts/session_tryout.rb +48 -0
  92. metadata +94 -25
  93. data/bin/rudy-ec2 +0 -108
  94. data/lib/rudy/command/base.rb +0 -839
  95. data/lib/rudy/command/deploy.rb +0 -12
  96. data/lib/rudy/command/environment.rb +0 -74
  97. data/lib/rudy/command/machines.rb +0 -170
  98. data/lib/rudy/command/metadata.rb +0 -41
  99. data/lib/rudy/metadata.rb +0 -26
@@ -0,0 +1,51 @@
1
+
2
+
3
+ module Rudy
4
+ module CLI
5
+ class Manager < Rudy::CLI::Base
6
+
7
+
8
+ # Print Rudy's metadata to STDOUT
9
+ def metadata
10
+ group_metadata.each_pair do |n,h|
11
+ puts n.bright
12
+ puts h.inspect, ""
13
+ end
14
+ end
15
+
16
+ def destroy_metadata_valid?
17
+ false
18
+ end
19
+
20
+ def destroy_metadata
21
+ @sdb.domains.destroy(RUDY_DOMAIN)
22
+ end
23
+
24
+ # TODO: WHERE TO CREATE DOMAIN???????????????????????????
25
+
26
+ def create_domain
27
+ puts "Creating SimpleDB Domain called #{RUDY_DOMAIN}".bright
28
+ rmanager = Rudy::Manager.new(:config => @config, :global => @global)
29
+ rmanager.create_domain(RUDY_DOMAIN)
30
+ doms = rmanager.domains || []
31
+ puts "Domains: #{doms.join(", ")}"
32
+ end
33
+
34
+ def info
35
+ puts "Rudy Manager".bright
36
+ rmanager = Rudy::Manager.new(:config => @config, :global => @global)
37
+ doms = rmanager.domains
38
+ puts "Domains: #{doms.join(", ")}"
39
+ end
40
+
41
+ private
42
+ def check_environment
43
+ raise "No Amazon keys provided!" unless has_keys?
44
+ raise "No SSH keypairs provided!" unless has_keypair?
45
+ true
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
3
  module Rudy
4
- module Command
5
- class Release < Rudy::Command::Base
4
+ module CLI
5
+ class Release < Rudy::CLI::Base
6
6
 
7
7
 
8
8
 
@@ -61,7 +61,7 @@ module Rudy
61
61
  end
62
62
 
63
63
  def rerelease
64
- puts "Updating release from working copy".att(:bright)
64
+ puts "Updating release from working copy".bright
65
65
 
66
66
  tag, revision = @scm.local_info
67
67
  puts "tag: #{tag}"
@@ -71,7 +71,7 @@ module Rudy
71
71
 
72
72
  if @scm
73
73
 
74
- puts "Running SCM command".att(:bright)
74
+ puts "Running SCM command".bright
75
75
  ssh do |session|
76
76
  cmd = "svn #{@scm_params[:command]}"
77
77
  puts "#{cmd}"
@@ -91,15 +91,15 @@ module Rudy
91
91
  # <li>Executes release routines</li>
92
92
  def release
93
93
  # TODO: store metadata about release with local username and hostname
94
- puts "Creating release from working copy".att(:bright)
94
+ puts "Creating release from working copy".bright
95
95
 
96
- exit unless are_you_sure?
96
+ exit unless Annoy.are_you_sure?(:low)
97
97
 
98
98
  tag = @scm.create_release(@global.local_user, @option.msg)
99
99
  puts "Done! (#{tag})"
100
100
 
101
101
  if @option.switch
102
- puts "Switching working copy to new tag".att(:bright)
102
+ puts "Switching working copy to new tag".bright
103
103
  @scm.switch_working_copy(tag)
104
104
  end
105
105
 
@@ -107,13 +107,13 @@ module Rudy
107
107
 
108
108
  switch_user("root")
109
109
 
110
- puts "Starting #{machine_group}".att(:bright)
110
+ puts "Starting #{machine_group}".bright
111
111
 
112
112
  instances = @ec2.instances.create(@option.image, machine_group.to_s, File.basename(keypairpath), machine_data.to_yaml, @global.zone)
113
113
  inst = instances.first
114
114
 
115
115
  if @option.address ||= machine_address
116
- puts "Associating #{@option.address} to #{inst[:aws_instance_id]}".att(:bright)
116
+ puts "Associating #{@option.address} to #{inst[:aws_instance_id]}".bright
117
117
  @ec2.addresses.associate(inst[:aws_instance_id], @option.address)
118
118
  end
119
119
 
@@ -127,7 +127,7 @@ module Rudy
127
127
 
128
128
  if @scm
129
129
 
130
- puts "Running SCM command".att(:bright)
130
+ puts "Running SCM command".bright
131
131
  ssh do |session|
132
132
  cmd = "svn #{@scm_params[:command]} #{tag} #{@scm_params[:path]}"
133
133
  puts "#{cmd}"
@@ -0,0 +1,80 @@
1
+
2
+ module Rudy
3
+ module CLI
4
+ class Routines < Rudy::CLI::Base
5
+
6
+
7
+
8
+ def startup_valid?
9
+ true
10
+ end
11
+ def startup
12
+ puts "Starting a machine group".bright
13
+ opts = {}
14
+ opts[:ami] = @option.image if @option.image
15
+ opts[:group] = @option.group if @option.group
16
+ #exit unless Annoy.are_you_sure?
17
+
18
+ rroutine = Rudy::Routines::Startup.new(:config => @config, :global => @global)
19
+ instances = rroutine.startup(opts)
20
+
21
+ puts "Done!"
22
+ end
23
+
24
+
25
+
26
+
27
+ def restart_valid?
28
+ shutdown_valid?
29
+ end
30
+ def restart
31
+ puts "Restarting #{machine_group}: #{@list.keys.join(', ')}".bright
32
+ switch_user("root")
33
+ exit unless Annoy.are_you_sure?(:medium)
34
+
35
+ @list.each do |id, inst|
36
+ execute_routines(@list.values, :restart, :before)
37
+ end
38
+
39
+ puts "Restarting instances: #{@list.keys.join(', ')}".bright
40
+ @ec2.instances.restart @list.keys
41
+ sleep 10 # Wait for state to change and SSH to shutdown
42
+
43
+ @list.keys.each do |id|
44
+ wait_for_machine(id)
45
+ end
46
+
47
+ execute_disk_routines(@list.values, :restart)
48
+
49
+ @list.each do |id, inst|
50
+ execute_routines(@list.values, :restart, :after)
51
+ end
52
+
53
+ puts "Done!"
54
+ end
55
+
56
+
57
+
58
+
59
+
60
+ def shutdown_valid?
61
+ raise "Cannot specify both instance ID and group name" if @argv.awsid && @option.group
62
+ raise "I will not help you ruin production!" if @global.environment == "prod" # TODO: use_caution?, locked?
63
+ true
64
+ end
65
+ def shutdown
66
+ puts "Shutting down a machine group".bright
67
+ opts = {}
68
+ opts[:group] = @option.group if @option.group
69
+ opts[:id] = @argv.awsid if @argv.awsid
70
+ opts[:id] &&= [opts[:id]].flatten
71
+
72
+ msg = opts[:id] ? "instances: #{opts[:id].join(', ')}" : (opts[:group] ? "group: #{opts[:group]}" : '')
73
+ puts "This command also affects the disks on these machines! (according to your routines config)"
74
+ #exit unless Annoy.are_you_sure?(:medium) # TODO: Check if instances are running before this
75
+
76
+ puts "TBD"
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,121 @@
1
+
2
+
3
+ module Rudy
4
+ module CLI
5
+ class Volumes < Rudy::CLI::Base
6
+
7
+
8
+ def destroy_volume_valid?
9
+ raise "You must supply a volume ID. See rudy volume -h" unless @argv.volid
10
+
11
+ @rvol = Rudy::Volumes.new(:config => @config, :global => @global)
12
+
13
+ @volume = @rvol.get(@argv.volid)
14
+
15
+ raise "Volume #{@argv.volid} does not exist" unless @volume
16
+
17
+ raise "Volume #{@argv.volid} is still in-use" if @volume.in_use?
18
+ raise "Volume #{@argv.volid} is still attached" if @volume.attached?
19
+
20
+ true
21
+ end
22
+
23
+ def destroy_volume
24
+ puts "Destroy Volume".bright, $/
25
+
26
+ puts "Destroying #{@volume.awsid}"
27
+ exit unless Annoy.are_you_sure?(:medium)
28
+
29
+ ret = @rvol.destroy(@volume.awsid)
30
+ raise "Failed" unless ret
31
+
32
+ vol = @rvol.get(@volume.awsid)
33
+
34
+ puts vol.to_s
35
+ end
36
+
37
+
38
+ def volume_create_valid?
39
+ raise "You must supply a volume size. See rudy volume -h" unless @option.size
40
+ raise "You have no zone configured. Check #{RUDY_CONFIG_FILE}." unless @global.zone
41
+ true
42
+ end
43
+ def volume_create
44
+ puts "Create Volume".bright
45
+
46
+ exit unless Annoy.are_you_sure?(:medium)
47
+
48
+ rvol = Rudy::Volumes.new(:config => @config, :global => @global)
49
+ vol = rvol.create(@option.size, @global.zone, @option.snapshot)
50
+
51
+ puts vol.to_s
52
+ end
53
+
54
+ def volume_attach_valid?
55
+ raise "You must supply a volume ID. See rudy volume -h" unless @argv.volid
56
+ raise "You must supply an instance ID. See rudy volume -h" unless @argv.instid
57
+
58
+ @rvol = Rudy::Volumes.new(:config => @config, :global => @global)
59
+ @rmach = Rudy::Instances.new(:config => @config, :global => @global)
60
+ raise "Volume #{@argv.volid} does not exist" unless @rvol.exists?(@argv.volid)
61
+ raise "Instance #{@argv.instid} does not exist" unless @rmach.exists?(@argv.instid)
62
+
63
+ true
64
+ end
65
+ def volume_attach
66
+ puts "Attach Volume".bright, $/
67
+
68
+ @option.device ||= "/dev/sdh"
69
+
70
+ puts "Attaching #{@argv.volid} to #{@argv.instid} on #{@option.device}"
71
+ exit unless Annoy.are_you_sure?(:low)
72
+
73
+ ret = @rvol.attach(@argv.volid, @argv.instid, @option.device)
74
+ raise "Attach failed" unless ret
75
+ volume = @rvol.get(@argv.volid)
76
+ puts volume.to_s
77
+ end
78
+
79
+ def volume_detach_valid?
80
+ raise "You must supply a volume ID. See rudy volume -h" unless @argv.volid
81
+
82
+ @rvol = Rudy::Volumes.new(:config => @config, :global => @global)
83
+
84
+ @volume = @rvol.get(@argv.volid)
85
+
86
+ raise "Volume #{@argv.volid} does not exist" unless @volume
87
+
88
+ #raise "Volume #{@argv.volid} is in use" unless @volume.in_use?
89
+ raise "Volume #{@argv.volid} is not attached" unless @volume.attached?
90
+
91
+ true
92
+ end
93
+ def volume_detach
94
+ puts "Detach Volume".bright, $/
95
+
96
+ puts "Detaching #{@volume.awsid} from #{@volume.instid}"
97
+ exit unless Annoy.are_you_sure?(:low)
98
+
99
+ ret = @rvol.detach(@volume.awsid)
100
+ raise "Detach failed" unless ret
101
+ volume = @rvol.get(@volume.awsid)
102
+ puts volume.to_s
103
+ end
104
+
105
+
106
+ def volume
107
+ puts "Volumes".bright, $/
108
+
109
+ rvol = Rudy::Volumes.new(:config => @config, :global => @global)
110
+ volumes = rvol.list || []
111
+ volumes.each do |volume|
112
+ puts '-'*60
113
+ puts volume.to_s
114
+ end
115
+ puts "No volumes" if volumes.empty?
116
+ end
117
+
118
+ end
119
+ end
120
+ end
121
+
@@ -1,46 +1,69 @@
1
1
 
2
2
 
3
-
4
3
  module Rudy
5
- module Command
6
- class Addresses < Rudy::Command::Base
7
-
8
-
9
- def associate_addresses_valid?
10
- raise "You have not supplied an IP addresses" unless @argv.address
11
- raise "You did not supply an instance ID" unless @argv.instanceid
12
-
13
- @inst = @ec2.instances.get(@argv.instanceid)
14
- raise "Instance #{@inst[:aws_instance_id]} does not exist!" unless @inst
15
-
16
- raise "That's not an elastic IP you own!" unless @ec2.addresses.valid?(@argv.address)
17
- raise "#{@argv.address} is already associated!" if @ec2.addresses.associated?(@argv.address)
18
-
19
- true
20
- end
21
-
22
- def associate_addresses
23
- puts "Associating #{@argv.address} to #{@inst[:aws_groups]}: #{@inst[:dns_name]}"
24
- @ec2.addresses.associate(@inst[:aws_instance_id], @argv.address)
25
- puts "Done!"
26
- puts
27
-
28
- addresses
29
- end
30
-
31
- def addresses
32
- puts "Elastic IP mappings:"
33
- @ec2.addresses.list.each do |address|
34
- print "IP: #{address[:public_ip]} "
35
- if address[:instance_id]
36
- inst = @ec2.instances.get(address[:instance_id])
37
- puts "%s: %s %s" % [inst[:aws_groups], inst[:aws_instance_id], inst[:dns_name]]
38
- end
39
- end
40
- puts
41
- end
42
-
4
+ class Addresses
5
+ include Rudy::Huxtable
6
+
7
+ def create
8
+ address = @@ec2.addresses.create
9
+ raise ErrorCreatingAddress unless address.is_a?(Rudy::AWS::EC2::Address)
10
+ address
11
+ end
12
+
13
+ def destroy(address)
14
+ address = address
15
+ @@ec2.addresses.destroy(address)
16
+ end
17
+
18
+ def assign(address, instance)
19
+ raise "Not an instance object" unless instance.is_a?(Rudy::AWS::EC2::Instance)
20
+ raise "Address not available for this account" unless @@ec2.addresses.valid?(address)
21
+ @@ec2.addresses.associate(instance.awsid, address)
22
+ end
23
+
24
+
25
+ # Lists the addresses registered with Amazon
26
+ def list(n=nil, &each_object)
27
+ n = [n].flatten.compact
28
+ addresses = @@ec2.addresses.list(n)
29
+ addresses.each { |n,kp| each_object.call(kp) } if each_object
30
+ addresses || []
31
+ end
32
+
33
+ def get(n=nil)
34
+ raise "Address cannot be nil" if n.nil?
35
+ @@ec2.addresses.get(n)
43
36
  end
37
+
38
+ def associated?(n=nil)
39
+ raise "Address cannot be nil" if n.nil?
40
+ @@ec2.addresses.associated?(n)
41
+ end
42
+
43
+ def list_as_hash(n=nil, &each_object)
44
+ n &&= [n].flatten.compact
45
+ addresses = @@ec2.addresses.list_as_hash(n)
46
+ addresses.each_pair { |n,kp| each_object.call(kp) } if each_object
47
+ addresses || {}
48
+ end
49
+
50
+ def exists?(n=nil)
51
+ n ||= name(n)
52
+ @@ec2.addresses.exists?(n)
53
+ end
54
+
55
+ def any?(n=nil)
56
+ n ||= name(n)
57
+ @@ec2.addresses.any?
58
+ end
59
+
44
60
  end
61
+
45
62
  end
46
63
 
64
+
65
+ module Rudy
66
+ class Addresses
67
+ class ErrorCreatingAddress < RuntimeError; end
68
+ end
69
+ end
@@ -1,175 +1,65 @@
1
1
 
2
2
 
3
+ module Rudy
4
+ class Backups
5
+
6
+ end
7
+ end
3
8
 
4
9
 
5
- module Rudy
6
- module Command
7
- class Backups < Rudy::Command::Base
8
-
9
-
10
- def backup
11
- criteria = [@global.zone]
12
- criteria += [@global.environment, @global.role] unless @option.all
13
-
14
- Rudy::MetaData::Backup.list(@sdb, *criteria).each do |backup|
15
- puts "%s (%s)" % [backup.name, backup.awsid]
16
- end
17
- end
18
-
19
- # Check for backups pointing to snapshots that don't exist.
20
- def sync_backup
21
- unless argv.empty?
22
- puts "The disk you specified will be ignored."
23
- argv.clear
24
- end
25
-
26
- criteria = [@global.zone]
27
- criteria += [@global.environment, @global.role] unless @option.all
28
-
29
- puts "Looking for backup metadata with delinquent snapshots..."
30
- to_be_deleted = {} # snap-id => backup
31
- Rudy::MetaData::Backup.list(@sdb, *criteria).each do |backup|
32
- to_be_deleted[backup.awsid] = backup unless @ec2.snapshots.exists?(backup.awsid)
33
- end
34
-
35
- if to_be_deleted.empty?
36
- puts "All backups are in-sync with snapshots. Nothing to do."
37
- return
38
- end
39
-
40
- puts
41
- puts "These backup metadata will be deleted:"
42
- to_be_deleted.each do |snap_id, backup|
43
- puts "%s: %s" % [snap_id, backup.name]
44
- end
45
-
46
- puts
47
- are_you_sure?
48
-
49
- puts
50
- puts "Deleting..."
51
- to_be_deleted.each do |snap_id, backup|
52
- print " -> #{backup.name}... "
53
- @sdb.destroy(RUDY_DOMAIN, backup.name)
54
- puts "done"
55
- end
56
-
57
- puts "Done!"
58
- end
59
-
60
- def destroy_backup_valid?
61
- raise "No backup specified" if argv.empty?
62
- exit unless are_you_sure?(5)
63
- true
64
- end
65
-
66
- def destroy_backup
67
- name = @argv.first
68
- puts "Destroying #{name}"
69
- begin
70
- backup = Rudy::MetaData::Backup.get(@sdb, name)
71
- rescue => ex
72
- puts "Error deleteing backup: #{ex.message}"
73
- end
74
-
75
- return unless backup
76
-
77
- begin
78
- puts " -> deleting snapshot..."
79
- @ec2.snapshots.destroy(backup.awsid)
80
- rescue => ex
81
- puts "Error deleting snapshot: #{ex.message}."
82
- puts "Continuing..."
83
- ensure
84
- puts " -> deleting metadata..."
85
- @sdb.destroy(RUDY_DOMAIN, name)
86
- end
87
- puts "Done."
88
- end
89
-
90
- def create_backup
91
- diskname = @argv.first
92
-
93
- machine = find_current_machine
94
-
95
- disks = Rudy::MetaData::Disk.list(@sdb, machine[:aws_availability_zone], @global.environment, @global.role, @global.position)
96
- raise "The machine #{machine_name} does not have any disk metadata" if disks.empty?
97
-
98
- puts "Machine: #{machine_name}"
99
-
100
- if @option.snapshot
101
- raise "You must supply a diskname when using an existing snapshot" unless diskname
102
- raise "The snapshot #{@option.snapshot} does not exist" unless @ec2.snapshots.exists?(@option.snapshot)
103
- disk = Rudy::MetaData::Disk.get(@sdb, diskname)
104
-
105
- raise "The disk #{diskname} does not exist" unless disk
106
- backup = Rudy::MetaData::Backup.new
107
- backup.awsid = @option.snapshot
108
- backup.time_stamp
109
-
110
- # Populate machine infos
111
- [:zone, :environment, :role, :position].each do |n|
112
- backup.send("#{n}=", @global.send(n)) if @global.send(n)
113
- end
114
-
115
- # Populate disk infos
116
- [:path, :size].each do |n|
117
- backup.send("#{n}=", disk.send(n)) if disk.send(n)
118
- end
119
-
120
-
121
- Rudy::MetaData::Backup.save(@sdb, backup)
122
-
123
- puts backup.name
124
-
125
- else
126
- volumes = @ec2.instances.volumes(machine[:aws_instance_id])
127
- raise "The machine #{machine_name} does not have any volumes attached." if volumes.empty?
128
-
129
- puts "#{disks.size} Disk(s) defined with #{volumes.size} Volume(s) running"
130
-
131
- volumes.each do |volume|
132
- print "Volume #{volume[:aws_id]}... "
133
- disk = Rudy::MetaData::Disk.find_from_volume(@sdb, volume[:aws_id])
134
- backup = Rudy::MetaData::Backup.new
135
-
136
- # TODO: Look for the disk based on the machine
137
- raise "No disk associated to volume #{volume[:aws_id]}" unless disk
138
-
139
- backup.volume = volume[:aws_id]
140
-
141
- # Populate machine infos
142
- [:zone, :environment, :role, :position].each do |n|
143
- backup.send("#{n}=", @global.send(n)) if @global.send(n)
144
- end
145
-
146
- # Populate disk infos
147
- [:path, :size].each do |n|
148
- backup.send("#{n}=", disk.send(n)) if disk.send(n)
149
- end
150
-
151
- backup.time_stamp
152
-
153
- raise "There was a problem creating the backup metadata" unless backup.valid?
154
-
155
- snap = @ec2.snapshots.create(volume[:aws_id])
156
-
157
- if !snap || !snap.is_a?(Hash)
158
- puts "There was an unknown problem creating #{backup.name}. Continuing with the next volume..."
159
- next
160
- end
161
-
162
- backup.awsid = snap[:aws_id]
163
-
164
- Rudy::MetaData::Backup.save(@sdb, backup)
165
-
166
- puts backup.name
167
-
168
- end
169
- end
170
- end
171
-
172
-
173
- end
10
+ __END__
11
+
12
+
13
+ # From Rudy::MetaData::Backup
14
+
15
+ def Backup.for_disk(sdb, disk, max=50)
16
+ list = Backup.list(sdb, disk.zone, disk.environment, disk.role, disk.position, disk.path) || []
17
+ list[0..(max-1)]
18
+ end
19
+
20
+ def Backup.get(sdb, name)
21
+ object = sdb.get_attributes(RUDY_DOMAIN, name)
22
+ raise "Object #{name} does not exist!" unless object.has_key?(:attributes) && !object[:attributes].empty?
23
+ self.from_hash(object[:attributes])
24
+ end
25
+
26
+ def Backup.save(sdb, obj, replace = :replace)
27
+ sdb.store(RUDY_DOMAIN, obj.name, obj.to_hash, replace)
28
+ end
29
+
30
+ def Backup.list(sdb, zon, env=nil, rol=nil, pos=nil, path=nil, date=nil)
31
+ query = "select * from #{RUDY_DOMAIN} where "
32
+ query << "rtype = '#{rtype}' "
33
+ query << " and zone = '#{zon}'" if zon
34
+ query << " and environment = '#{env}'" if env
35
+ query << " and role = '#{rol}'" if rol
36
+ query << " and position = '#{pos}'" if pos
37
+ query << " and path = '#{path}'" if path
38
+ query << " and date = '#{date}'" if date
39
+ query << " and unixtime != '0' order by unixtime desc"
40
+ list = []
41
+ sdb.select(query).each do |obj|
42
+ list << self.from_hash(obj)
174
43
  end
175
- end
44
+ list
45
+ end
46
+
47
+ def Backup.find_most_recent(zon, env, rol, pos, path)
48
+ criteria = [zon, env, rol, pos, path]
49
+ (Rudy::MetaData::Backup.list(@sdb, *criteria) || []).first
50
+ end
51
+
52
+ def Backup.destroy(sdb, name)
53
+ back = Backup.get(sdb, name) # get raises an exception if the disk doesn't exist
54
+ sdb.destroy(RUDY_DOMAIN, name)
55
+ true # wtf: RightAws::SimpleDB doesn't tell us whether it succeeds. We'll assume!
56
+ end
57
+
58
+
59
+
60
+ def Backup.is_defined?(sdb, backup)
61
+ query = backup.to_query()
62
+ puts query
63
+ !sdb.select(query).empty?
64
+ end
65
+