rudy 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/CHANGES.txt +54 -30
  2. data/README.rdoc +100 -12
  3. data/Rakefile +103 -8
  4. data/Rudyfile +119 -0
  5. data/bin/ird +175 -0
  6. data/bin/rudy +259 -156
  7. data/bin/rudy-ec2 +228 -95
  8. data/bin/rudy-s3 +76 -0
  9. data/bin/rudy-sdb +67 -0
  10. data/lib/annoy.rb +270 -0
  11. data/lib/console.rb +30 -9
  12. data/lib/escape.rb +305 -0
  13. data/lib/rudy.rb +151 -182
  14. data/lib/rudy/aws.rb +56 -49
  15. data/lib/rudy/aws/ec2.rb +47 -292
  16. data/lib/rudy/aws/ec2/address.rb +157 -0
  17. data/lib/rudy/aws/ec2/group.rb +301 -0
  18. data/lib/rudy/aws/ec2/image.rb +168 -0
  19. data/lib/rudy/aws/ec2/instance.rb +434 -0
  20. data/lib/rudy/aws/ec2/keypair.rb +104 -0
  21. data/lib/rudy/aws/ec2/snapshot.rb +98 -0
  22. data/lib/rudy/aws/ec2/volume.rb +230 -0
  23. data/lib/rudy/aws/ec2/zone.rb +77 -0
  24. data/lib/rudy/aws/s3.rb +54 -0
  25. data/lib/rudy/aws/sdb.rb +298 -0
  26. data/lib/rudy/aws/sdb/error.rb +46 -0
  27. data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
  28. data/lib/rudy/cli.rb +157 -0
  29. data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
  30. data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
  31. data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
  32. data/lib/rudy/cli/aws/ec2/images.rb +196 -0
  33. data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
  34. data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
  35. data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
  36. data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
  37. data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
  38. data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
  39. data/lib/rudy/cli/aws/s3/store.rb +22 -0
  40. data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
  41. data/lib/rudy/cli/candy.rb +8 -0
  42. data/lib/rudy/{command → cli}/config.rb +34 -24
  43. data/lib/rudy/cli/disks.rb +35 -0
  44. data/lib/rudy/cli/machines.rb +94 -0
  45. data/lib/rudy/cli/routines.rb +57 -0
  46. data/lib/rudy/config.rb +77 -72
  47. data/lib/rudy/config/objects.rb +29 -0
  48. data/lib/rudy/disks.rb +248 -0
  49. data/lib/rudy/global.rb +121 -0
  50. data/lib/rudy/huxtable.rb +340 -0
  51. data/lib/rudy/machines.rb +245 -0
  52. data/lib/rudy/metadata.rb +123 -13
  53. data/lib/rudy/routines.rb +47 -0
  54. data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
  55. data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
  56. data/lib/rudy/routines/release.rb +34 -0
  57. data/lib/rudy/routines/shutdown.rb +57 -0
  58. data/lib/rudy/routines/startup.rb +58 -0
  59. data/lib/rudy/scm/svn.rb +1 -1
  60. data/lib/rudy/utils.rb +322 -4
  61. data/lib/storable.rb +26 -17
  62. data/lib/sysinfo.rb +274 -0
  63. data/lib/tryouts.rb +6 -13
  64. data/rudy.gemspec +128 -42
  65. data/support/randomize-root-password +45 -0
  66. data/support/rudy-ec2-startup +9 -9
  67. data/support/update-ec2-ami-tools +20 -0
  68. data/test/05_config/00_setup_test.rb +20 -0
  69. data/test/05_config/30_machines_test.rb +69 -0
  70. data/test/20_sdb/00_setup_test.rb +16 -0
  71. data/test/20_sdb/10_domains_test.rb +115 -0
  72. data/test/25_ec2/00_setup_test.rb +29 -0
  73. data/test/25_ec2/10_keypairs_test.rb +41 -0
  74. data/test/25_ec2/20_groups_test.rb +131 -0
  75. data/test/25_ec2/30_addresses_test.rb +38 -0
  76. data/test/25_ec2/40_volumes_test.rb +49 -0
  77. data/test/25_ec2/50_snapshots_test.rb +74 -0
  78. data/test/26_ec2_instances/00_setup_test.rb +28 -0
  79. data/test/26_ec2_instances/10_instances_test.rb +83 -0
  80. data/test/26_ec2_instances/50_images_test.rb +13 -0
  81. data/test/30_sdb_metadata/00_setup_test.rb +21 -0
  82. data/test/30_sdb_metadata/10_disks_test.rb +109 -0
  83. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  84. data/test/coverage.txt +51 -0
  85. data/test/helper.rb +36 -0
  86. data/vendor/highline-1.5.1/CHANGELOG +222 -0
  87. data/vendor/highline-1.5.1/INSTALL +35 -0
  88. data/vendor/highline-1.5.1/LICENSE +7 -0
  89. data/vendor/highline-1.5.1/README +63 -0
  90. data/vendor/highline-1.5.1/Rakefile +82 -0
  91. data/vendor/highline-1.5.1/TODO +6 -0
  92. data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
  93. data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
  94. data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
  95. data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
  96. data/vendor/highline-1.5.1/examples/limit.rb +12 -0
  97. data/vendor/highline-1.5.1/examples/menus.rb +65 -0
  98. data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
  99. data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
  100. data/vendor/highline-1.5.1/examples/password.rb +7 -0
  101. data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
  102. data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
  103. data/vendor/highline-1.5.1/lib/highline.rb +758 -0
  104. data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
  105. data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
  106. data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
  107. data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
  108. data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
  109. data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
  110. data/vendor/highline-1.5.1/setup.rb +1360 -0
  111. data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
  112. data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
  113. data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
  114. data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
  115. data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
  116. metadata +141 -38
  117. data/lib/aws_sdb.rb +0 -3
  118. data/lib/aws_sdb/error.rb +0 -42
  119. data/lib/aws_sdb/service.rb +0 -215
  120. data/lib/rudy/aws/simpledb.rb +0 -53
  121. data/lib/rudy/command/addresses.rb +0 -46
  122. data/lib/rudy/command/backups.rb +0 -175
  123. data/lib/rudy/command/base.rb +0 -841
  124. data/lib/rudy/command/deploy.rb +0 -12
  125. data/lib/rudy/command/disks.rb +0 -213
  126. data/lib/rudy/command/environment.rb +0 -73
  127. data/lib/rudy/command/groups.rb +0 -61
  128. data/lib/rudy/command/images.rb +0 -91
  129. data/lib/rudy/command/instances.rb +0 -85
  130. data/lib/rudy/command/machines.rb +0 -161
  131. data/lib/rudy/command/metadata.rb +0 -41
  132. data/lib/rudy/command/release.rb +0 -174
  133. data/lib/rudy/command/volumes.rb +0 -66
  134. data/lib/rudy/metadata/disk.rb +0 -138
  135. data/tryouts/console_tryout.rb +0 -91
@@ -1,12 +0,0 @@
1
-
2
-
3
-
4
-
5
- module Rudy
6
- module Command
7
- class Deploy < Rudy::Command::Base
8
-
9
- end
10
- end
11
- end
12
-
@@ -1,213 +0,0 @@
1
-
2
-
3
- module Rudy
4
- module Command
5
- class Disks < Rudy::Command::Base
6
-
7
- def disk
8
- criteria = [@global.zone]
9
- criteria += [@global.environment, @global.role] unless @option.all
10
- Rudy::MetaData::Disk.list(@sdb, *criteria).each do |disk|
11
- backups = Rudy::MetaData::Backup.for_disk(@sdb, disk, 2)
12
- print_disk(disk, backups)
13
- end
14
- end
15
-
16
- def create_disk_valid?
17
- raise "No filesystem path specified" unless @option.path
18
- raise "No size specified" unless @option.size
19
- @instances = @ec2.instances.list(machine_group)
20
- raise "There are no instances running in #{machine_group}" if !@instances || @instances.empty?
21
- true
22
- end
23
-
24
- def create_disk
25
- puts "Creating #{@option.path} for #{machine_group}"
26
- switch_user("root")
27
- exit unless are_you_sure?(2)
28
- machine = @instances.values.first # NOTE: DANGER! Should handle position.
29
-
30
- disk = Rudy::MetaData::Disk.new
31
- [:region, :zone, :environment, :role, :position].each do |n|
32
- disk.send("#{n}=", @global.send(n)) if @global.send(n)
33
- end
34
- [:path, :device, :size].each do |n|
35
- disk.send("#{n}=", @option.send(n)) if @option.send(n)
36
- end
37
-
38
- raise "Not enough info was provided to define a disk (#{disk.name})" unless disk.valid?
39
- raise "The device #{disk.device} is already in use on that machine" if Rudy::MetaData::Disk.is_defined?(@sdb, disk)
40
- # TODO: Check disk path
41
- puts "Creating disk metadata for #{disk.name}"
42
-
43
-
44
-
45
- puts "Creating volume... (#{disk.size}GB in #{@global.zone})"
46
- volume = @ec2.volumes.create(@global.zone, disk.size)
47
- sleep 3
48
-
49
- disk.awsid = volume[:aws_id]
50
- disk.raw_volume = true # This value is not saved.
51
- Rudy::MetaData::Disk.save(@sdb, disk)
52
-
53
- execute_attach_disk(disk, machine)
54
-
55
- print_disk(disk)
56
- end
57
-
58
-
59
- def destroy_disk_valid?
60
- raise "No disk specified" if argv.empty?
61
-
62
- if @argv.diskname =~ /^disk-/
63
- @disk = Rudy::MetaData::Disk.get(@sdb, @argv.diskname)
64
- else
65
- disk = Rudy::MetaData::Disk.new
66
- [:zone, :environment, :role, :position].each do |n|
67
- disk.send("#{n}=", @global.send(n)) if @global.send(n)
68
- end
69
- disk.path = @argv.diskname
70
- @disk = Rudy::MetaData::Disk.get(@sdb, disk.name)
71
- end
72
-
73
- raise "No such disk: #{@argv.diskname}" unless @disk
74
- raise "The disk is in another machine environment" unless @global.environment.to_s == @disk.environment.to_s
75
- raise "The disk is in another machine role" unless @global.role.to_s == @disk.role.to_s
76
- @instances = @ec2.instances.list(machine_group)
77
- true
78
- end
79
-
80
- def destroy_disk
81
- puts "Destroying #{@disk.name} and #{@disk.awsid}"
82
- switch_user("root")
83
- exit unless are_you_sure?(5)
84
-
85
- machine = @instances.values.first # NOTE: DANGER! Should handle position.
86
-
87
- execute_unattach_disk(@disk, machine)
88
- execute_destroy_disk(@disk, machine)
89
-
90
- puts "Done."
91
- end
92
-
93
- def attach_disk_valid?
94
- destroy_disk_valid?
95
- raise "There are no instances running in #{machine_group}" if !@instances || @instances.empty?
96
- true
97
- end
98
-
99
- def attach_disk
100
- puts "Attaching #{name}"
101
- switch_user("root")
102
- are_you_sure?(4)
103
-
104
- machine = @instances.values.first # AK! Assumes single machine
105
-
106
- execute_attach_disk(@disk, machine)
107
-
108
- puts
109
- ssh_command machine[:dns_name], keypairpath, @global.user, "df -h" # Display current mounts
110
- puts
111
-
112
- puts "Done!"
113
- end
114
-
115
-
116
-
117
-
118
- def unattach_disk_valid?
119
- destroy_disk_valid?
120
- true
121
- end
122
-
123
- def unattach_disk
124
- puts "Unattaching #{@disk.name} from #{machine_group}"
125
- switch_user("root")
126
- are_you_sure?(4)
127
-
128
- machine = @instances.values.first
129
-
130
- execute_unattach_disk(@disk, machine)
131
-
132
- puts "Done!"
133
- end
134
-
135
-
136
-
137
- def execute_unattach_disk(disk, machine)
138
- begin
139
-
140
- if machine
141
- puts "Unmounting #{disk.path}...".att(:bright)
142
- ssh_command machine[:dns_name], keypairpath, global.user, "umount #{disk.path}"
143
- sleep 1
144
- end
145
-
146
- if @ec2.volumes.attached?(disk.awsid)
147
- puts "Unattaching #{disk.awsid}".att(:bright)
148
- @ec2.volumes.detach(disk.awsid)
149
- sleep 5
150
- end
151
-
152
- rescue => ex
153
- puts "Error while unattaching volume #{disk.awsid}: #{ex.message}"
154
- puts ex.backtrace if Drydock.debug?
155
- end
156
- end
157
-
158
- def execute_destroy_disk(disk, machine)
159
- begin
160
-
161
- if disk
162
-
163
- if disk.awsid && @ec2.volumes.available?(disk.awsid)
164
- puts "Destroying #{disk.path} (#{disk.awsid})".att(:bright)
165
- @ec2.volumes.destroy(disk.awsid)
166
- end
167
-
168
- end
169
-
170
- rescue => ex
171
- puts "Error while destroying volume #{disk.awsid}: #{ex.message}"
172
- puts ex.backtrace if Drydock.debug?
173
- ensure
174
- puts "Deleteing metadata for #{disk.name}".att(:bright)
175
- Rudy::MetaData::Disk.destroy(@sdb, disk)
176
- end
177
- end
178
-
179
- def execute_attach_disk(disk, machine)
180
- begin
181
- unless @ec2.instances.attached_volume?(machine[:aws_instance_id], disk.device)
182
- puts "Attaching #{disk.awsid} to #{machine[:aws_instance_id]}".att(:bright)
183
- @ec2.volumes.attach(machine[:aws_instance_id], disk.awsid, disk.device)
184
- sleep 3
185
- end
186
-
187
- if disk.raw_volume
188
- puts "Creating the filesystem (mkfs.ext3 -F #{disk.device})".att(:bright)
189
- ssh_command machine[:dns_name], keypairpath, @global.user, "mkfs.ext3 -F #{disk.device}"
190
- sleep 1
191
- end
192
-
193
- puts "Mounting #{disk.path} to #{disk.device}".att(:bright)
194
- ssh_command machine[:dns_name], keypairpath, @global.user, "mkdir -p #{disk.path} && mount -t ext3 #{disk.device} #{disk.path}"
195
-
196
- sleep 1
197
- rescue => ex
198
- puts "There was an error attaching #{disk.name}: #{ex.message}"
199
- puts ex.backtrace if Drydock.debug?
200
- end
201
- end
202
-
203
- end
204
- end
205
- end
206
-
207
-
208
- __END__
209
-
210
-
211
-
212
-
213
-
@@ -1,73 +0,0 @@
1
-
2
-
3
-
4
- module Rudy
5
- module Command
6
- class Environment < Rudy::Command::Base
7
-
8
- #---
9
- # TODO: http://net-ssh.rubyforge.org/ssh/v1/chapter-4.html
10
- #+++
11
-
12
-
13
- def connect
14
- check_keys
15
- machine = find_current_machine
16
- if @argv.cmd
17
- cmd = @argv.cmd.is_a?(Array) ? @argv.cmd.join(' ') : @argv.cmd
18
- else
19
- cmd = false
20
- end
21
-
22
- puts ssh_command(machine[:dns_name], keypairpath, @global.user, cmd, @option.print)
23
-
24
- end
25
-
26
- def copy_valid?
27
- check_keys
28
- raise "No path specified (rudy copy FROM-PATH [FROM-PATH ...] TO-PATH)" unless argv.size >= 2
29
- true
30
- end
31
-
32
- # +paths+ an array of paths to copy. The last element is the "to" path.
33
- def copy
34
- machine = find_current_machine
35
-
36
- paths = @argv
37
- dest_path = paths.pop
38
-
39
- if @option.print
40
- scp_command machine[:dns_name], keypairpath, @global.user, paths, dest_path, @option.remote, false, @option.print
41
- return
42
- end
43
-
44
- @option.remote = true if @alias == 'download'
45
- @option.remote = false if @alias == 'upload'
46
-
47
- if @alias == 'scp' || @alias == 'copy'
48
- @alias = 'download' if @option.remote
49
- @alias = 'upload' unless @option.remote
50
- end
51
-
52
- scp do |scp|
53
- transfers = paths.collect { |path|
54
- scp.send(@alias, path, dest_path) do |ch, name, sent, total|
55
- #TODO: Nice printing in place
56
- #puts "#{name}: #{sent}/#{total}"
57
- end
58
-
59
- }
60
- transfers.each { |trans| trans.wait }
61
- end
62
- end
63
-
64
-
65
-
66
-
67
- end
68
- end
69
- end
70
-
71
- __END__
72
-
73
-
@@ -1,61 +0,0 @@
1
-
2
-
3
-
4
- module Rudy
5
- module Command
6
- class Groups < Rudy::Command::Base
7
-
8
- def groups(name=@argv.first)
9
- name = machine_group if name.nil? && !@option.all
10
- @ec2.groups.list(name).each do |grp|
11
- print_group grp
12
- end
13
- end
14
-
15
- def create_groups(name=@argv.first)
16
- name ||= machine_group
17
- puts "Creating group #{name}"
18
- raise "The group #{name} already exists" if @ec2.groups.exists?(name)
19
-
20
- @ec2.groups.create(name)
21
-
22
- modify_groups name
23
- end
24
-
25
- def modify_groups(name=@argv.first)
26
- name ||= machine_group
27
- raise "The group #{name} does not exist" unless @ec2.groups.exists?(name)
28
-
29
- @option.addresses ||= [Rudy::Utils::external_ip_address]
30
- @option.ports ||= [22,80,443]
31
- @option.protocols ||= ["tcp"]
32
-
33
- # Make sure the IP addresses have ranges
34
- @option.addresses.collect! { |ip| (ip.match /\/\d+/) ? ip : "#{ip}/32" }
35
-
36
- @option.protocols.each do |protocol|
37
- puts "Adding ports #{@option.ports.join(',')} (#{protocol}) for #{@option.addresses.join(', ')}"
38
- @option.addresses.each do |address|
39
- @option.ports.each do |port|
40
- @ec2.groups.modify(name, port, port, protocol, address)
41
- end
42
- end
43
- end
44
-
45
- groups name
46
- end
47
-
48
- def destroy_groups(name=@argv.first)
49
- name ||= machine_group
50
- puts "Destroying group #{name}"
51
- name = machine_group if name.nil?
52
- raise "The group #{name} does not exist" unless @ec2.groups.exists?(name)
53
- exit unless are_you_sure?
54
-
55
- @ec2.groups.destroy(name)
56
-
57
- end
58
- end
59
- end
60
- end
61
-
@@ -1,91 +0,0 @@
1
-
2
-
3
- module Rudy
4
- module Command
5
- class Images < Rudy::Command::Base
6
-
7
-
8
- def images
9
- @ec2.images.list.each do |img|
10
- print_image img
11
- end
12
- end
13
-
14
- def create_images_valid?
15
- puts "Make sure the machine is clean. I don't want archive no crud!"
16
- exit unless are_you_sure?
17
- true
18
- end
19
-
20
-
21
- def prepare_images
22
- # TODO: Avail hooks for clean an instance
23
- # Clean off Rudy specific crap.
24
- end
25
-
26
-
27
- def create_images
28
-
29
- switch_user("root")
30
-
31
- puts "TODO: clean transient rudy crap off of instance before making image!!!"
32
- # ~/.rudy, /etc/motd, history -c, /etc/hosts, /var/log/rudy*
33
- exit
34
-
35
- raise "No EC2 .pem keys provided" unless has_pem_keys?
36
- raise "No SSH key provided for #{keypairname}!" unless has_keypair?(keypairname)
37
- raise "SSH key provided but cannot be found! (#{keypairpath})" unless File.exists?(keypairpath)
38
-
39
- machine_list = @ec2.instances.list(machine_group)
40
- machine = machine_list.values.first # NOTE: Only one machine per group, for now...
41
-
42
- raise "There's no machine running in #{machine_group}" unless machine
43
- raise "The primary machine in #{machine_group} is not in a running state" unless machine[:aws_state] == 'running'
44
-
45
- puts "The new image will be based on #{machine_group}_01"
46
-
47
- @option.account ||= @global.account_num
48
-
49
- unless @global.account
50
- puts "Enter your 12 digit Amazon account number:"
51
- @global.account = gets.chomp
52
- end
53
-
54
- unless @option.image_name
55
- puts "Enter the image name:"
56
- @option.image_name = gets.chomp
57
- end
58
-
59
- unless @option.bucket_name
60
- puts "Enter the S3 bucket that will store the image:"
61
- @option.bucket_name = gets.chomp
62
- end
63
-
64
- scp_command machine[:dns_name], keypairpath, @global.user, @global.cert, "/mnt/"
65
- scp_command machine[:dns_name], keypairpath, @global.user, @global.privatekey, "/mnt/"
66
-
67
- ssh_command machine[:dns_name], keypairpath, @global.user, "ec2-bundle-vol -r i386 -p #{@option.image_name} -k /mnt/pk-*pem -c /mnt/cert*pem -u #{@option.account}"
68
- ssh_command machine[:dns_name], keypairpath, @global.user, "ec2-upload-bundle -b #{@option.bucket_name} -m /tmp/#{@option.image_name}.manifest.xml -a #{@global.accesskey} -s #{@global.secretkey}"
69
-
70
- @ec2.images.register("#{@option.bucket_name}/#{@option.image_name}.manifest.xml")
71
- end
72
-
73
- def deregister
74
- ami = @argv.first
75
- raise "You must supply an AMI ID (ami-XXXXXXX)" unless ami
76
- puts "Deregistering AMI: #{ami}"
77
-
78
- are_you_sure?
79
-
80
- if @ec2.images.deregister(ami)
81
- puts "Done!"
82
- else
83
- puts "There was an unknown problem!"
84
- end
85
-
86
- end
87
-
88
- end
89
- end
90
- end
91
-