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.
- data/CHANGES.txt +54 -30
- data/README.rdoc +100 -12
- data/Rakefile +103 -8
- data/Rudyfile +119 -0
- data/bin/ird +175 -0
- data/bin/rudy +259 -156
- data/bin/rudy-ec2 +228 -95
- data/bin/rudy-s3 +76 -0
- data/bin/rudy-sdb +67 -0
- data/lib/annoy.rb +270 -0
- data/lib/console.rb +30 -9
- data/lib/escape.rb +305 -0
- data/lib/rudy.rb +151 -182
- data/lib/rudy/aws.rb +56 -49
- data/lib/rudy/aws/ec2.rb +47 -292
- data/lib/rudy/aws/ec2/address.rb +157 -0
- data/lib/rudy/aws/ec2/group.rb +301 -0
- data/lib/rudy/aws/ec2/image.rb +168 -0
- data/lib/rudy/aws/ec2/instance.rb +434 -0
- data/lib/rudy/aws/ec2/keypair.rb +104 -0
- data/lib/rudy/aws/ec2/snapshot.rb +98 -0
- data/lib/rudy/aws/ec2/volume.rb +230 -0
- data/lib/rudy/aws/ec2/zone.rb +77 -0
- data/lib/rudy/aws/s3.rb +54 -0
- data/lib/rudy/aws/sdb.rb +298 -0
- data/lib/rudy/aws/sdb/error.rb +46 -0
- data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
- data/lib/rudy/cli.rb +157 -0
- data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
- data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
- data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
- data/lib/rudy/cli/aws/ec2/images.rb +196 -0
- data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
- data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
- data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
- data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
- data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
- data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
- data/lib/rudy/cli/aws/s3/store.rb +22 -0
- data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
- data/lib/rudy/cli/candy.rb +8 -0
- data/lib/rudy/{command → cli}/config.rb +34 -24
- data/lib/rudy/cli/disks.rb +35 -0
- data/lib/rudy/cli/machines.rb +94 -0
- data/lib/rudy/cli/routines.rb +57 -0
- data/lib/rudy/config.rb +77 -72
- data/lib/rudy/config/objects.rb +29 -0
- data/lib/rudy/disks.rb +248 -0
- data/lib/rudy/global.rb +121 -0
- data/lib/rudy/huxtable.rb +340 -0
- data/lib/rudy/machines.rb +245 -0
- data/lib/rudy/metadata.rb +123 -13
- data/lib/rudy/routines.rb +47 -0
- data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
- data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
- data/lib/rudy/routines/release.rb +34 -0
- data/lib/rudy/routines/shutdown.rb +57 -0
- data/lib/rudy/routines/startup.rb +58 -0
- data/lib/rudy/scm/svn.rb +1 -1
- data/lib/rudy/utils.rb +322 -4
- data/lib/storable.rb +26 -17
- data/lib/sysinfo.rb +274 -0
- data/lib/tryouts.rb +6 -13
- data/rudy.gemspec +128 -42
- data/support/randomize-root-password +45 -0
- data/support/rudy-ec2-startup +9 -9
- data/support/update-ec2-ami-tools +20 -0
- data/test/05_config/00_setup_test.rb +20 -0
- data/test/05_config/30_machines_test.rb +69 -0
- data/test/20_sdb/00_setup_test.rb +16 -0
- data/test/20_sdb/10_domains_test.rb +115 -0
- data/test/25_ec2/00_setup_test.rb +29 -0
- data/test/25_ec2/10_keypairs_test.rb +41 -0
- data/test/25_ec2/20_groups_test.rb +131 -0
- data/test/25_ec2/30_addresses_test.rb +38 -0
- data/test/25_ec2/40_volumes_test.rb +49 -0
- data/test/25_ec2/50_snapshots_test.rb +74 -0
- data/test/26_ec2_instances/00_setup_test.rb +28 -0
- data/test/26_ec2_instances/10_instances_test.rb +83 -0
- data/test/26_ec2_instances/50_images_test.rb +13 -0
- data/test/30_sdb_metadata/00_setup_test.rb +21 -0
- data/test/30_sdb_metadata/10_disks_test.rb +109 -0
- data/test/30_sdb_metadata/20_backups_test.rb +102 -0
- data/test/coverage.txt +51 -0
- data/test/helper.rb +36 -0
- data/vendor/highline-1.5.1/CHANGELOG +222 -0
- data/vendor/highline-1.5.1/INSTALL +35 -0
- data/vendor/highline-1.5.1/LICENSE +7 -0
- data/vendor/highline-1.5.1/README +63 -0
- data/vendor/highline-1.5.1/Rakefile +82 -0
- data/vendor/highline-1.5.1/TODO +6 -0
- data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
- data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
- data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
- data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
- data/vendor/highline-1.5.1/examples/limit.rb +12 -0
- data/vendor/highline-1.5.1/examples/menus.rb +65 -0
- data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
- data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
- data/vendor/highline-1.5.1/examples/password.rb +7 -0
- data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
- data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline.rb +758 -0
- data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
- data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
- data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
- data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
- data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
- data/vendor/highline-1.5.1/setup.rb +1360 -0
- data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
- data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
- data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
- data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
- data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
- metadata +141 -38
- data/lib/aws_sdb.rb +0 -3
- data/lib/aws_sdb/error.rb +0 -42
- data/lib/aws_sdb/service.rb +0 -215
- data/lib/rudy/aws/simpledb.rb +0 -53
- data/lib/rudy/command/addresses.rb +0 -46
- data/lib/rudy/command/backups.rb +0 -175
- data/lib/rudy/command/base.rb +0 -841
- data/lib/rudy/command/deploy.rb +0 -12
- data/lib/rudy/command/disks.rb +0 -213
- data/lib/rudy/command/environment.rb +0 -73
- data/lib/rudy/command/groups.rb +0 -61
- data/lib/rudy/command/images.rb +0 -91
- data/lib/rudy/command/instances.rb +0 -85
- data/lib/rudy/command/machines.rb +0 -161
- data/lib/rudy/command/metadata.rb +0 -41
- data/lib/rudy/command/release.rb +0 -174
- data/lib/rudy/command/volumes.rb +0 -66
- data/lib/rudy/metadata/disk.rb +0 -138
- data/tryouts/console_tryout.rb +0 -91
data/lib/rudy/aws/sdb.rb
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
|
2
|
+
require 'time'
|
3
|
+
require 'cgi'
|
4
|
+
require 'uri'
|
5
|
+
require 'net/http'
|
6
|
+
require 'base64'
|
7
|
+
require 'openssl'
|
8
|
+
require 'rexml/document'
|
9
|
+
require 'rexml/xpath'
|
10
|
+
|
11
|
+
module Rudy
|
12
|
+
module AWS
|
13
|
+
class SDB
|
14
|
+
class NoAccessKey < RuntimeError; end
|
15
|
+
class NoSecretKey < RuntimeError; end
|
16
|
+
|
17
|
+
require 'rudy/aws/sdb/error'
|
18
|
+
|
19
|
+
def initialize(access_key=nil, secret_key=nil, region=nil, debug=nil)
|
20
|
+
raise NoAccessKey if access_key.nil? || access_key.empty?
|
21
|
+
raise NoSecretKey if secret_key.nil? || secret_key.empty?
|
22
|
+
|
23
|
+
url ||= 'http://sdb.amazonaws.com'
|
24
|
+
# There is a bug with passing :server to EC2::Base.new so
|
25
|
+
# we'll use the environment variable for now.
|
26
|
+
#if region && Rudy::AWS.valid_region?(region)
|
27
|
+
# "#{region}.sdb.amazonaws.com"
|
28
|
+
#end
|
29
|
+
|
30
|
+
@access_key_id = access_key || ENV['AWS_ACCESS_KEY']
|
31
|
+
@secret_access_key = secret_key || ENV['AWS_SECRET_KEY']
|
32
|
+
@base_url = url
|
33
|
+
@debug = debug || StringIO.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def list_domains(max = nil, token = nil)
|
37
|
+
params = { 'Action' => 'ListDomains' }
|
38
|
+
params['NextToken'] =
|
39
|
+
token unless token.nil? || token.empty?
|
40
|
+
params['MaxNumberOfDomains'] =
|
41
|
+
max.to_s unless max.nil? || max.to_i == 0
|
42
|
+
doc = call(:get, params)
|
43
|
+
results = []
|
44
|
+
REXML::XPath.each(doc, '//DomainName/text()') do |domain|
|
45
|
+
results << domain.to_s
|
46
|
+
end
|
47
|
+
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
48
|
+
results
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_domain(domain)
|
52
|
+
call(:post, { 'Action' => 'CreateDomain', 'DomainName'=> domain.to_s })
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy_domain(domain)
|
57
|
+
call(
|
58
|
+
:delete,
|
59
|
+
{ 'Action' => 'DeleteDomain', 'DomainName' => domain.to_s }
|
60
|
+
)
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Takes a zipped Array or Hash of criteria.
|
66
|
+
# Returns a string suitable for a SimpleDB Select
|
67
|
+
def self.generate_select(*args)
|
68
|
+
fields, domain, args = *args
|
69
|
+
q = args.is_a?(Hash) ? args : Hash[*args.flatten]
|
70
|
+
query = []
|
71
|
+
q.each do |n,v|
|
72
|
+
query << "#{Rudy::AWS.escape n}='#{Rudy::AWS.escape v}'"
|
73
|
+
end
|
74
|
+
"select * from #{domain} where " << query.join(' and ')
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Takes a zipped Array or Hash of criteria.
|
79
|
+
# Returns a string suitable for a SimpleDB Query
|
80
|
+
def self.generate_query(*args)
|
81
|
+
q = args.first.is_a?(Hash)? args.first : Hash[*args.flatten]
|
82
|
+
query = []
|
83
|
+
q.each do |n,v|
|
84
|
+
query << "['#{Rudy::AWS.escape n}'='#{Rudy::AWS.escape v}']"
|
85
|
+
end
|
86
|
+
query.join(" intersection ")
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def select(select, token = nil)
|
91
|
+
params = {
|
92
|
+
'Action' => 'Select',
|
93
|
+
'SelectExpression' => select,
|
94
|
+
}
|
95
|
+
params['NextToken'] =
|
96
|
+
token unless token.nil? || token.empty?
|
97
|
+
|
98
|
+
doc = call(:get, params)
|
99
|
+
results = []
|
100
|
+
REXML::XPath.each(doc, "//Item") do |item|
|
101
|
+
name = REXML::XPath.first(item, './Name/text()').to_s
|
102
|
+
|
103
|
+
attributes = {'Name' => name}
|
104
|
+
REXML::XPath.each(item, "./Attribute") do |attr|
|
105
|
+
key = REXML::XPath.first(attr, './Name/text()').to_s
|
106
|
+
value = REXML::XPath.first(attr, './Value/text()').to_s
|
107
|
+
( attributes[key] ||= [] ) << value
|
108
|
+
end
|
109
|
+
results << attributes
|
110
|
+
end
|
111
|
+
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
112
|
+
|
113
|
+
hash_results = {}
|
114
|
+
results.each do |item|
|
115
|
+
hash_results[item.delete('Name')] = item
|
116
|
+
end
|
117
|
+
|
118
|
+
hash_results.empty? ? nil : hash_results
|
119
|
+
end
|
120
|
+
|
121
|
+
# <QueryResult><ItemName>in-c2ffrw</ItemName><ItemName>in-72yagt</ItemName><ItemName>in-52j8gj</ItemName>
|
122
|
+
def query(domain, query, max = nil, token = nil)
|
123
|
+
params = {
|
124
|
+
'Action' => 'Query',
|
125
|
+
'QueryExpression' => query,
|
126
|
+
'DomainName' => domain.to_s
|
127
|
+
}
|
128
|
+
params['NextToken'] =
|
129
|
+
token unless token.nil? || token.empty?
|
130
|
+
params['MaxNumberOfItems'] =
|
131
|
+
max.to_s unless max.nil? || max.to_i == 0
|
132
|
+
|
133
|
+
|
134
|
+
doc = call(:get, params)
|
135
|
+
results = []
|
136
|
+
REXML::XPath.each(doc, '//ItemName/text()') do |item|
|
137
|
+
results << item.to_s
|
138
|
+
end
|
139
|
+
|
140
|
+
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
141
|
+
results.empty? ? nil : results
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
# <QueryWithAttributesResult><Item><Name>in-c2ffrw</Name><Attribute><Name>code</Name><Value>in-c2ffrw</Value></Attribute><Attribute><Name>date_created</Name><Value>2008-10-31</Value></Attribute></Item><Item>
|
148
|
+
def query_with_attributes(domain, query, max = nil, token = nil)
|
149
|
+
params = {
|
150
|
+
'Action' => 'QueryWithAttributes',
|
151
|
+
'QueryExpression' => query,
|
152
|
+
'DomainName' => domain.to_s
|
153
|
+
}
|
154
|
+
params['NextToken'] =
|
155
|
+
token unless token.nil? || token.empty?
|
156
|
+
params['MaxNumberOfItems'] =
|
157
|
+
max.to_s unless max.nil? || max.to_i == 0
|
158
|
+
|
159
|
+
doc = call(:get, params)
|
160
|
+
results = []
|
161
|
+
REXML::XPath.each(doc, "//Item") do |item|
|
162
|
+
name = REXML::XPath.first(item, './Name/text()').to_s
|
163
|
+
|
164
|
+
attributes = {'Name' => name}
|
165
|
+
REXML::XPath.each(item, "./Attribute") do |attr|
|
166
|
+
key = REXML::XPath.first(attr, './Name/text()').to_s
|
167
|
+
value = REXML::XPath.first(attr, './Value/text()').to_s
|
168
|
+
( attributes[key] ||= [] ) << value
|
169
|
+
end
|
170
|
+
results << attributes
|
171
|
+
end
|
172
|
+
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
173
|
+
|
174
|
+
hash_results = {}
|
175
|
+
results.each do |item|
|
176
|
+
hash_results[item.delete('Name')] = item
|
177
|
+
end
|
178
|
+
|
179
|
+
hash_results
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
def put_attributes(domain, item, attributes, replace = true)
|
185
|
+
replace = true if replace == :replace
|
186
|
+
params = {
|
187
|
+
'Action' => 'PutAttributes',
|
188
|
+
'DomainName' => domain.to_s,
|
189
|
+
'ItemName' => item.to_s
|
190
|
+
}
|
191
|
+
count = 0
|
192
|
+
|
193
|
+
attributes.each do | key, values |
|
194
|
+
([]<<values).flatten.each do |value|
|
195
|
+
params["Attribute.#{count}.Name"] = key.to_s
|
196
|
+
params["Attribute.#{count}.Value"] = value.to_s
|
197
|
+
params["Attribute.#{count}.Replace"] = replace
|
198
|
+
count += 1
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
call(:put, params)
|
203
|
+
|
204
|
+
true
|
205
|
+
end
|
206
|
+
alias :put :put_attributes
|
207
|
+
|
208
|
+
def get_attributes(domain, item)
|
209
|
+
doc = call(
|
210
|
+
:get,
|
211
|
+
{
|
212
|
+
'Action' => 'GetAttributes',
|
213
|
+
'DomainName' => domain.to_s,
|
214
|
+
'ItemName' => item.to_s
|
215
|
+
}
|
216
|
+
)
|
217
|
+
attributes = {}
|
218
|
+
REXML::XPath.each(doc, "//Attribute") do |attr|
|
219
|
+
key = REXML::XPath.first(attr, './Name/text()').to_s
|
220
|
+
value = REXML::XPath.first(attr, './Value/text()').to_s
|
221
|
+
( attributes[key] ||= [] ) << value
|
222
|
+
end
|
223
|
+
attributes = nil if attributes.empty?
|
224
|
+
attributes
|
225
|
+
end
|
226
|
+
alias :get :get_attributes
|
227
|
+
|
228
|
+
|
229
|
+
def delete_attributes(domain, item)
|
230
|
+
call(
|
231
|
+
:delete,
|
232
|
+
{
|
233
|
+
'Action' => 'DeleteAttributes',
|
234
|
+
'DomainName' => domain.to_s,
|
235
|
+
'ItemName' => item.to_s
|
236
|
+
}
|
237
|
+
)
|
238
|
+
true
|
239
|
+
end
|
240
|
+
alias :destroy :delete_attributes
|
241
|
+
|
242
|
+
|
243
|
+
|
244
|
+
protected
|
245
|
+
|
246
|
+
def call(method, params)
|
247
|
+
params.merge!( {
|
248
|
+
'Version' => '2007-11-07',
|
249
|
+
'SignatureVersion' => '1',
|
250
|
+
'AWSAccessKeyId' => @access_key_id,
|
251
|
+
'Timestamp' => Time.now.gmtime.iso8601
|
252
|
+
}
|
253
|
+
)
|
254
|
+
data = ''
|
255
|
+
query = []
|
256
|
+
|
257
|
+
params.keys.sort_by { |k| k.upcase }.each do |key|
|
258
|
+
data << "#{key}#{params[key].to_s}"
|
259
|
+
query << "#{key}=#{CGI::escape(params[key].to_s)}"
|
260
|
+
end
|
261
|
+
|
262
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
263
|
+
hmac = OpenSSL::HMAC.digest(digest, @secret_access_key, data)
|
264
|
+
signature = Base64.encode64(hmac).strip
|
265
|
+
query << "Signature=#{CGI::escape(signature)}"
|
266
|
+
query = query.join('&')
|
267
|
+
url = "#{@base_url}?#{query}"
|
268
|
+
uri = URI.parse(url)
|
269
|
+
@debug.puts("#{url}") if @debug
|
270
|
+
|
271
|
+
response =
|
272
|
+
Net::HTTP.new(uri.host, uri.port).send_request(method, uri.request_uri)
|
273
|
+
@debug.puts("#{response.code}\n#{response.body}") if @debug
|
274
|
+
raise(ConnectionError.new(response)) unless (200..400).include?(
|
275
|
+
response.code.to_i
|
276
|
+
)
|
277
|
+
|
278
|
+
doc = REXML::Document.new(response.body)
|
279
|
+
error = doc.get_elements('*/Errors/Error')[0]
|
280
|
+
raise(
|
281
|
+
Module.class_eval(
|
282
|
+
"AwsSdb::#{error.get_elements('Code')[0].text}Error"
|
283
|
+
).new(
|
284
|
+
error.get_elements('Message')[0].text,
|
285
|
+
doc.get_elements('*/RequestID')[0].text
|
286
|
+
)
|
287
|
+
) unless error.nil?
|
288
|
+
|
289
|
+
doc
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
require 'aws_sdb/error'
|
297
|
+
require 'aws_sdb/service'
|
298
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Rudy
|
2
|
+
module AWS
|
3
|
+
class SDB
|
4
|
+
|
5
|
+
class Error < RuntimeError ; end
|
6
|
+
|
7
|
+
class RequestError < Error
|
8
|
+
attr_reader :request_id
|
9
|
+
|
10
|
+
def initialize(message, request_id=nil)
|
11
|
+
super(message)
|
12
|
+
@request_id = request_id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class InvalidDomainNameError < RequestError ; end
|
17
|
+
class InvalidParameterValueError < RequestError ; end
|
18
|
+
class InvalidNextTokenError < RequestError ; end
|
19
|
+
class InvalidNumberPredicatesError < RequestError ; end
|
20
|
+
class InvalidNumberValueTestsError < RequestError ; end
|
21
|
+
class InvalidQueryExpressionError < RequestError ; end
|
22
|
+
class MissingParameterError < RequestError ; end
|
23
|
+
class NoSuchDomainError < RequestError ; end
|
24
|
+
class NumberDomainsExceededError < RequestError ; end
|
25
|
+
class NumberDomainAttributesExceededError < RequestError ; end
|
26
|
+
class NumberDomainBytesExceededError < RequestError ; end
|
27
|
+
class NumberItemAttributesExceededError < RequestError ; end
|
28
|
+
class RequestTimeoutError < RequestError ; end
|
29
|
+
|
30
|
+
class FeatureDeprecatedError < RequestError ; end
|
31
|
+
|
32
|
+
class ConnectionError < Error
|
33
|
+
attr_reader :response
|
34
|
+
|
35
|
+
def initialize(response)
|
36
|
+
super(
|
37
|
+
"#{response.code} \
|
38
|
+
#{response.message if response.respond_to?(:message)}"
|
39
|
+
)
|
40
|
+
@response = response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -4,10 +4,7 @@ require 'date'
|
|
4
4
|
module Rudy
|
5
5
|
module MetaData
|
6
6
|
class Backup < Storable
|
7
|
-
include Rudy::
|
8
|
-
extend Rudy::MetaData::ObjectBase
|
9
|
-
|
10
|
-
@@rtype = "back"
|
7
|
+
include Rudy::AWS
|
11
8
|
|
12
9
|
field :rtype
|
13
10
|
field :awsid
|
@@ -32,15 +29,12 @@ module Rudy
|
|
32
29
|
@zone = DEFAULT_ZONE
|
33
30
|
@region = DEFAULT_REGION
|
34
31
|
@position = "01"
|
35
|
-
@rtype =
|
36
|
-
|
37
|
-
|
38
|
-
def rtype
|
39
|
-
@@rtype
|
32
|
+
@rtype = Backup.rtype
|
33
|
+
time_stamp # initialize time to right now
|
40
34
|
end
|
41
35
|
|
42
36
|
def self.rtype
|
43
|
-
|
37
|
+
'back'
|
44
38
|
end
|
45
39
|
|
46
40
|
|
@@ -50,13 +44,14 @@ module Rudy
|
|
50
44
|
end
|
51
45
|
|
52
46
|
def valid?
|
53
|
-
@zone
|
47
|
+
#puts(@zone, @environment, @role, @position, @path, @date, @time, @second)
|
48
|
+
(@zone && @environment && @role && @position && @path && @date && @time && @second)
|
54
49
|
end
|
55
50
|
|
56
51
|
def time_stamp
|
57
52
|
#return [@date, @time] if @date && @time
|
58
53
|
now = Time.now.utc
|
59
|
-
datetime = Backup.format_timestamp(now).split(
|
54
|
+
datetime = Backup.format_timestamp(now).split(Rudy::DELIM)
|
60
55
|
@unixtime = now.to_i
|
61
56
|
@date, @time, @second = datetime
|
62
57
|
end
|
@@ -71,7 +66,7 @@ module Rudy
|
|
71
66
|
def to_query(more=[], remove=[])
|
72
67
|
criteria = [:rtype, :zone, :environment, :role, :position, :path, :date, :time, :second, *more]
|
73
68
|
criteria -= [*remove].flatten
|
74
|
-
query = "select * from #{
|
69
|
+
query = "select * from #{Rudy::DOMAIN} where unixtime > '0' "
|
75
70
|
criteria.each do |n|
|
76
71
|
query << "and #{n} = '#{self.send(n.to_sym)}'"
|
77
72
|
end
|
@@ -93,7 +88,7 @@ module Rudy
|
|
93
88
|
# 20090224-1813-36
|
94
89
|
def Backup.format_timestamp(dat)
|
95
90
|
mon, day, hour, min, sec = [dat.mon, dat.day, dat.hour, dat.min, dat.sec].collect { |v| v.to_s.rjust(2, "0") }
|
96
|
-
[dat.year, mon, day,
|
91
|
+
[dat.year, mon, day, Rudy::DELIM, hour, min, Rudy::DELIM, sec].join
|
97
92
|
end
|
98
93
|
|
99
94
|
# Times are converted to UTC
|
@@ -104,54 +99,34 @@ module Rudy
|
|
104
99
|
dirs = pat.split sep if pat
|
105
100
|
dirs.shift while dirs && (dirs[0].nil? || dirs[0].empty?)
|
106
101
|
timestamp = Backup.format_timestamp(dat.utc)
|
107
|
-
[
|
102
|
+
[rtype, zon, env, rol, pos, dirs, timestamp].flatten.join(Rudy::DELIM)
|
108
103
|
end
|
109
104
|
|
110
|
-
|
111
|
-
def Backup.for_disk(sdb, disk, max=50)
|
112
|
-
list = Backup.list(sdb, disk.zone, disk.environment, disk.role, disk.position, disk.path) || []
|
113
|
-
list[0..(max-1)]
|
114
|
-
end
|
115
105
|
|
116
|
-
def Backup.get(sdb, name)
|
117
|
-
object = sdb.get_attributes(RUDY_DOMAIN, name)
|
118
|
-
raise "Object #{name} does not exist!" unless object.has_key?(:attributes) && !object[:attributes].empty?
|
119
|
-
self.from_hash(object[:attributes])
|
120
|
-
end
|
121
106
|
|
122
|
-
|
123
|
-
|
107
|
+
|
108
|
+
def to_select
|
109
|
+
|
124
110
|
end
|
125
111
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
query << " and zone = '#{zon}'" if zon
|
130
|
-
query << " and environment = '#{env}'" if env
|
131
|
-
query << " and role = '#{rol}'" if rol
|
132
|
-
query << " and position = '#{pos}'" if pos
|
133
|
-
query << " and path = '#{path}'" if path
|
134
|
-
query << " and date = '#{date}'" if date
|
135
|
-
query << " and unixtime != '0' order by unixtime desc"
|
136
|
-
list = []
|
137
|
-
sdb.select(query).each do |obj|
|
138
|
-
list << self.from_hash(obj)
|
139
|
-
end
|
140
|
-
list
|
112
|
+
def save
|
113
|
+
@@sdb.store(Rudy::DOMAIN, name, self.to_hash, :replace) # Always returns nil
|
114
|
+
true
|
141
115
|
end
|
142
116
|
|
143
|
-
def
|
144
|
-
|
145
|
-
|
146
|
-
true # wtf: RightAws::SimpleDB doesn't tell us whether it succeeds. We'll assume!
|
117
|
+
def destroy
|
118
|
+
@@sdb.destroy(Rudy::DOMAIN, name)
|
119
|
+
true
|
147
120
|
end
|
148
121
|
|
149
|
-
|
122
|
+
def refresh
|
123
|
+
h = @@sdb.get(Rudy::DOMAIN, name) || {}
|
124
|
+
from_hash(h)
|
125
|
+
end
|
150
126
|
|
151
|
-
def Backup.
|
152
|
-
|
153
|
-
|
154
|
-
!sdb.select(query).empty?
|
127
|
+
def Backup.get(dname)
|
128
|
+
h = @@sdb.get(Rudy::DOMAIN, dname) || {}
|
129
|
+
from_hash(h)
|
155
130
|
end
|
156
131
|
|
157
132
|
end
|