rudy 0.4.0 → 0.6.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 +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
-