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,209 +1,178 @@
1
1
 
2
- #
3
- # No Ruby 1.9.1 support. Only 1.8.x for now :[
4
- unless RUBY_VERSION < "1.9"
5
- puts "Sorry! We're using the right_aws gem and it doesn't support Ruby 1.9 (md5 error)."
6
- exit 1
2
+ unless defined?(RUDY_HOME)
3
+ RUDY_HOME = File.join(File.dirname(__FILE__), '..')
4
+ RUDY_LIB = File.join(File.dirname(__FILE__), '..', 'lib')
7
5
  end
8
6
 
9
7
 
10
- begin
11
- require 'digest/md5'
12
- require 'right_aws'
13
- require 'stringio'
14
- require 'ostruct'
15
- require 'yaml'
16
- require 'socket'
17
- require 'tempfile'
8
+ require 'digest/md5'
9
+ require 'stringio'
10
+ require 'ostruct'
11
+ require 'yaml'
12
+ require 'socket'
13
+ require 'timeout'
14
+ require 'tempfile'
18
15
 
19
- require 'console'
20
- require 'storable'
16
+ require 'storable'
17
+ require 'console'
18
+ require 'sysinfo'
19
+ require 'annoy'
21
20
 
22
- require 'net/ssh'
23
- require 'net/ssh/gateway'
24
- require 'net/ssh/multi'
25
- require 'net/scp'
26
-
27
- rescue LoadError => ex
28
- puts "Problem requiring: #{ex.message}"
29
- exit 1
30
- end
21
+ require 'rye'
31
22
 
23
+ require 'net/ssh'
24
+ require 'net/scp'
25
+ require 'net/ssh/multi'
26
+ require 'net/ssh/gateway'
32
27
 
33
28
 
34
- module Rudy #:nodoc:
35
- RUDY_DOMAIN = "rudy_state"
36
- RUDY_DELIM = '-'
29
+ require 'logger'
30
+
31
+ # = Rudy
32
+ #
33
+ # == About
34
+ #
35
+ # Rudy is a development and deployment tool for the Amazon Elastic Compute Cloud
36
+ # (EC2). See README.rdoc for more information.
37
+ #
38
+ # == Status: Alpha
39
+ #
40
+ # The current release (0.6) is not ready for general production use. Use it for
41
+ # exploring EC2 and operating your development / ad-hoc instances. We've put in
42
+ # a lot of effort to make sure Rudy plays safe, but it's possible we missed
43
+ # something. That's why we consider it alpha code.
44
+ #
45
+ # To get started right away, try:
46
+ #
47
+ # $ rudy -h
48
+ # $ rudy show-commands
49
+ #
50
+ # Also:
51
+ #
52
+ # $ rudy-ec2 -h
53
+ # $ rudy-ec2 show-commands
54
+ #
55
+ # And if you're feeling particularly saucey, try Rudy's REPL interface:
56
+ #
57
+ # $ ird
58
+ #
59
+ #
60
+ #
61
+ module Rudy
62
+ extend self
37
63
 
38
- RUDY_CONFIG_DIR = File.join(ENV['HOME'] || ENV['USERPROFILE'], '.rudy')
39
- RUDY_CONFIG_FILE = File.join(RUDY_CONFIG_DIR, 'config')
64
+ module VERSION #:nodoc:
65
+ unless defined?(MAJOR)
66
+ MAJOR = 0.freeze
67
+ MINOR = 6.freeze
68
+ TINY = 0.freeze
69
+ end
70
+ def self.to_s; [MAJOR, MINOR, TINY].join('.'); end
71
+ def self.to_f; self.to_s.to_f; end
72
+ end
40
73
 
41
- DEFAULT_REGION = 'us-east-1'
42
- DEFAULT_ZONE = 'us-east-1b'
43
- DEFAULT_ENVIRONMENT = 'stage'
44
- DEFAULT_ROLE = 'app'
45
- DEFAULT_POSITION = '01'
74
+ unless defined?(Rudy::DOMAIN) # We can assume all constants are defined
75
+ # SimpleDB accepts dashes in the domain name on creation and with the query syntax.
76
+ # However, with select syntax it says: "The specified query expression syntax is not valid"
77
+ DOMAIN = "rudy_state".freeze
78
+ DELIM = '-'.freeze
46
79
 
47
- DEFAULT_USER = 'rudy'
80
+ CONFIG_DIR = File.join(ENV['HOME'] || ENV['USERPROFILE'], '.rudy').freeze
81
+ CONFIG_FILE = File.join(Rudy::CONFIG_DIR, 'config').freeze
82
+
83
+ DEFAULT_REGION = 'us-east-1'.freeze
84
+ DEFAULT_ZONE = 'us-east-1b'.freeze
85
+ DEFAULT_ENVIRONMENT = 'stage'.freeze
86
+ DEFAULT_ROLE = 'app'.freeze
87
+ DEFAULT_POSITION = '01'.freeze
88
+
89
+ DEFAULT_USER = 'rudy'.freeze
90
+
91
+ DEFAULT_EC2_HOST = "ec2.amazonaws.com"
92
+ DEFAULT_EC2_PORT = 443
93
+
94
+ MAX_INSTANCES = 3.freeze
95
+
96
+ SUPPORTED_SCM_NAMES = [:svn, :git].freeze
48
97
 
49
- SUPPORTED_SCM_NAMES = [:svn, :git]
98
+ ID_MAP = {
99
+ :instance => 'i',
100
+ :disk => 'disk',
101
+ :backup => 'back',
102
+ :machine => 'm',
103
+ :volume => 'vol',
104
+ :snapshot => 'snap',
105
+ :kernel => 'aki',
106
+ :image => 'ami',
107
+ :ram => 'ari',
108
+ :log => 'log',
109
+ :key => 'key',
110
+ :awspk => 'pk',
111
+ :awscert => 'cert',
112
+ :reservation => 'r',
113
+ :dns_public => 'ec2',
114
+ :dns_private => 'domU',
115
+ }.freeze
116
+
117
+ @@quiet = false
118
+ @@debug = false
119
+ @@sysinfo = SystemInfo.new.freeze
120
+
121
+ end
50
122
 
51
- module VERSION #:nodoc:
52
- MAJOR = 0.freeze unless defined? MAJOR
53
- MINOR = 4.freeze unless defined? MINOR
54
- TINY = 0.freeze unless defined? TINY
55
- def self.to_s
56
- [MAJOR, MINOR, TINY].join('.')
57
- end
58
- def self.to_f
59
- self.to_s.to_f
123
+ def Rudy.debug?; @@debug == true; end
124
+ def Rudy.quiet?; @@quiet == true; end
125
+ def Rudy.enable_debug; @@debug = true; end
126
+ def Rudy.enable_quiet; @@quiet = true; end
127
+ def Rudy.disable_debug; @@debug = false; end
128
+ def Rudy.disable_quiet; @@quiet = false; end
129
+
130
+ def Rudy.sysinfo; @@sysinfo; end
131
+ def sysinfo; @@sysinfo; end
132
+
133
+ class Error < RuntimeError
134
+ def initialize(obj); @obj = obj; end
135
+ def message; "#{self.class}: #{@obj}"; end
136
+ end
137
+ class InsecureKeyPermissions < Rudy::Error
138
+ def message
139
+ lines = ["Insecure file permissions for #{@obj}"]
140
+ lines << "Try: chmod 600 #{@obj}"
141
+ lines.join($/)
60
142
  end
61
143
  end
62
-
63
- # Determine if we're running directly on EC2 or
64
- # "some other machine". We do this by checking if
65
- # the file /etc/ec2/instance-id exists. This
66
- # file is written by /etc/init.d/rudy-ec2-startup.
67
- # NOTE: Is there a way to know definitively that this is EC2?
68
- # We could make a request to the metadata IP addresses.
69
- def self.in_situ?
70
- File.exists?('/etc/ec2/instance-id')
144
+ class NoConfig < Rudy::Error
145
+ def message; "No AWS credentials. Check your configs!"; end
71
146
  end
72
- end
73
-
74
- require 'rudy/aws'
75
- require 'rudy/config'
76
- require 'rudy/metadata'
77
- require 'rudy/utils'
78
- require 'rudy/command/base'
79
-
80
- # Require Command, MetaData, and SCM classes
81
- begin
82
- # TODO: Use autoload
83
- Dir.glob(File.join(RUDY_LIB, 'rudy', '{command,metadata,scm}', "*.rb")).each do |path|
84
- require path
147
+ class ServiceUnavailable < Rudy::Error
148
+ def message; "#{@obj} is not available. Check your internets!"; end
85
149
  end
86
- rescue LoadError => ex
87
- puts "Error: #{ex.message}"
88
- exit 1
89
- end
90
-
91
-
92
- # Capture STDOUT or STDERR to prevent it from being printed.
93
- #
94
- # capture(:stdout) do
95
- # ...
96
- # end
97
- #
98
- def capture(stream)
99
- #raise "We can only capture STDOUT or STDERR" unless stream == :stdout || stream == :stderr
100
-
101
- # I'm using this to trap the annoying right_aws "peer certificate" warning.
102
- # TODO: discover source of annoying right_aws warning and give it a hiding.
103
- begin
104
- stream = stream.to_s
105
- eval "$#{stream} = StringIO.new"
106
- yield
107
- result = eval("$#{stream}").read
108
- ensure
109
- eval("$#{stream} = #{stream.upcase}")
150
+ class MachineGroupAlreadyRunning < Rudy::Error
151
+ def message; "Machine group #{@obj} is already running."; end
110
152
  end
111
-
112
- result
113
- end
114
-
115
-
116
- def write_to_file(filename, content, type)
117
- type = (type == :append) ? 'a' : 'w'
118
- f = File.open(filename,type)
119
- f.puts content
120
- f.close
121
- end
122
-
123
- def are_you_sure?(len=3)
124
- if Drydock.debug?
125
- puts 'DEBUG: skipping "are you sure" check'
126
- return true
153
+ class MachineGroupNotRunning < Rudy::Error
154
+ def message; "Machine group #{@obj} is not running."; end
127
155
  end
128
-
129
- if STDIN.tty? # Only ask a question if there's a human
130
- challenge = strand len
131
- STDOUT.print "Are you sure? To continue type \"#{challenge}\": "
132
- STDOUT.flush
133
- if ((STDIN.gets || "").gsub(/["']/, '') =~ /^#{challenge}$/)
134
- true
135
- else
136
- puts "Nothing changed"
137
- exit 0
138
- end
139
- else
140
- true
156
+ class MachineGroupNotDefined < Rudy::Error
157
+ def message; "#{@obj} is not defined in machines config."; end
141
158
  end
142
- end
143
-
144
- #
145
- # Generates a string of random alphanumeric characters
146
- # These are used as IDs throughout the system
147
- def strand( len=8, safe=true )
148
- chars = ("a".."z").to_a + ("0".."9").to_a
149
- chars = [("a".."h").to_a, "j", "k", "m", "n", ("p".."z").to_a, ("2".."9").to_a].flatten if safe
150
- newpass = ""
151
- 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
152
- newpass
153
- end
154
-
155
- def sh(command, chdir=false, verbose=false)
156
- prevdir = Dir.pwd
157
- Dir.chdir chdir if chdir
158
- puts command if verbose
159
- system(command)
160
- Dir.chdir prevdir if chdir
161
- end
162
-
163
- def ssh_command(host, keypair, user, command=false, printonly=false, verbose=false)
164
- #puts "CONNECTING TO #{host}..."
165
- cmd = "ssh -q -i #{keypair} #{user}@#{host} "
166
- cmd += " '#{command}'" if command
167
- puts cmd if verbose
168
- return cmd if printonly
169
- # backticks returns STDOUT
170
- # exec replaces current process (it's just like running ssh)
171
- (command) ? `#{cmd}` : Kernel.exec(cmd)
172
- end
173
-
174
-
175
- def scp_command(host, keypair, user, paths, to_path, to_local=false, verbose=false, printonly=false)
176
-
177
- paths = [paths] unless paths.is_a?(Array)
178
- from_paths = ""
179
- if to_local
180
- paths.each do |path|
181
- from_paths << "#{user}@#{host}:#{path} "
182
- end
183
- puts "Copying FROM remote TO this machine", $/
184
-
185
- else
186
- to_path = "#{user}@#{host}:#{to_path}"
187
- from_paths = paths.join(' ')
188
- puts "Copying FROM this machine TO remote", $/
159
+ class PrivateKeyFileExists < Rudy::Error
160
+ def message; "Private key #{@obj} already exists."; end
161
+ end
162
+ class PrivateKeyNotFound < Rudy::Error
163
+ def message; "Private key file #{@obj} not found."; end
189
164
  end
190
-
191
-
192
- cmd = "scp -i #{keypair} #{from_paths} #{to_path}"
193
-
194
- puts "CONNECTING TO #{host}..."
195
- puts cmd if verbose
196
- printonly ? (puts cmd) : system(cmd)
197
165
  end
198
166
 
167
+ require 'rudy/utils' # The
168
+ require 'rudy/global' # order
169
+ require 'rudy/config' # of
170
+ require 'rudy/huxtable' # requires
171
+ require 'rudy/aws' # is
172
+ require 'rudy/metadata' # important
199
173
 
200
- # Returns +str+ with the average leading indentation removed.
201
- # Useful for keeping inline codeblocks spaced with code.
202
- def without_indent(str)
203
- lines = str.split($/)
204
- lspaces = (lines.inject(0) {|total,line| total += (line.scan(/^\s+/).first || '').size } / lines.size) + 1
205
- lines.collect { |line| line.gsub(/^\s{#{lspaces}}/, '') }.join($/)
206
- end
207
-
174
+ require 'rudy/machines'
175
+ require 'rudy/disks'
176
+ require 'rudy/routines'
208
177
 
209
178
 
@@ -1,68 +1,75 @@
1
1
 
2
2
 
3
-
3
+ require 'EC2' # What a
4
+ require 'aws_sdb' # motley
5
+ require 'aws/s3' # crew
4
6
 
5
7
  module Rudy
6
8
  module AWS
7
-
8
- module ObjectBase
9
- attr_accessor :aws
10
- def initialize(aws_connection)
11
- @aws = aws_connection
12
- end
13
- end
14
-
15
- class EC2
16
- @@logger = StringIO.new
17
-
18
- attr_reader :instances
19
- attr_reader :images
20
- attr_reader :addresses
21
- attr_reader :groups
22
- attr_reader :volumes
23
- attr_reader :snapshots
24
- attr_reader :aws
25
-
26
- def initialize(access_key, secret_key)
27
- @aws = RightAws::Ec2.new(access_key, secret_key, {:logger => Logger.new(@@logger)})
28
- @instances = Rudy::AWS::EC2::Instances.new(@aws)
29
- @images = Rudy::AWS::EC2::Images.new(@aws)
30
- @groups = Rudy::AWS::EC2::Groups.new(@aws)
31
- @addresses = Rudy::AWS::EC2::Addresses.new(@aws)
32
- @snapshots = Rudy::AWS::EC2::Snapshots.new(@aws)
33
- @volumes = Rudy::AWS::EC2::Volumes.new(@aws)
34
- end
9
+ extend self
35
10
 
36
- end
37
-
38
- class S3
39
- @@logger = StringIO.new
40
-
41
- attr_reader :aws
42
-
43
- def initialize(access_key, secret_key)
44
- @aws = RightAws::S3.new(access_key, secret_key, {:logger => Logger.new(@@logger)})
45
- end
11
+ unless defined?(Rudy::AWS::VALID_REGIONS)
12
+ VALID_REGIONS = ['eu-west-1', 'us-east-1'].freeze
46
13
  end
47
14
 
48
- class SimpleDB
49
- @@logger = StringIO.new
15
+ def valid_region?(r); VALID_REGIONS.member?(r.to_s || ''); end
50
16
 
51
- attr_reader :domains
52
- attr_reader :aws
17
+ # Modifies +str+ by removing <tt>[\0\n\r\032\\\\]</tt> and escaping <tt>[\'\"]</tt>
18
+ def escape(str)
19
+ str.to_s.tr("[\0\n\r\032\\\\]", '').gsub(/([\'\"])/, '\\1\\1')
20
+ end
21
+ def escape!(str)
22
+ str.to_s.tr!("[\0\n\r\032\\\\]", '').gsub!(/([\'\"])/, '\\1\\1')
23
+ end
53
24
 
54
- def initialize(access_key, secret_key)
55
- @aws = RightAws::SdbInterface.new(access_key, secret_key, {:logger => Logger.new(@@logger)})
56
- @aws2 = AwsSdb::Service.new(:access_key_id => access_key, :secret_access_key => secret_key, :logger => Logger.new(@@logger))
57
- @domains = Rudy::AWS::SimpleDB::Domains.new(@aws)
58
- end
25
+ module ObjectBase
26
+
27
+ protected
59
28
 
29
+ # Execute AWS requests safely. This will trap errors and return
30
+ # a default value (if specified).
31
+ # * +default+ A default response value
32
+ # * +request+ A block which contains the AWS request
33
+ # Returns the return value from the request is returned untouched
34
+ # or the default value on error or if the request returned nil.
35
+ def execute_request(default=nil, timeout=nil, &request)
36
+ timeout ||= 30
37
+ raise "No block provided" unless request
38
+ response = nil
39
+ begin
40
+ Timeout::timeout(timeout) do
41
+ response = request.call
42
+ end
43
+ # Raise the EC2 exceptions
44
+ rescue ::EC2::Error, ::EC2::InvalidInstanceIDMalformed => ex
45
+ raise Rudy::AWS::Error, ex.message
46
+
47
+ # NOTE: The InternalError is returned for non-existent volume IDs.
48
+ # It's probably a bug so we're ignoring it -- Dave.
49
+ rescue ::EC2::InternalError => ex
50
+ raise Rudy::AWS::Error, ex.message
51
+
52
+ rescue Timeout::Error => ex
53
+ STDERR.puts "Timeout (#{timeout}): #{ex.message}!"
54
+ rescue SocketError => ex
55
+ STDERR.puts "Socket Error. Check your Internets!"
56
+ STDERR.puts ex.message
57
+ STDERR.puts ex.backtrace
58
+ ensure
59
+ response ||= default
60
+ end
61
+ response
62
+ end
60
63
  end
61
64
 
62
- require 'rudy/aws/simpledb'
65
+ require 'rudy/aws/sdb'
63
66
  require 'rudy/aws/ec2'
64
67
  require 'rudy/aws/s3'
65
68
 
69
+ Rudy::Utils.require_glob(RUDY_LIB, 'rudy', 'aws', '{ec2,s3,sdb}', "*.rb")
70
+
71
+ class Error < ::EC2::Error; end
66
72
  end
67
73
 
68
74
  end
75
+