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,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
+