rudy 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|