ruby-manta 1.1.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.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +722 -0
- data/example.rb +78 -0
- data/lib/ruby-manta.rb +925 -0
- data/lib/version.rb +3 -0
- data/ruby-manta.gemspec +27 -0
- data/tests/test_ruby-manta.rb +653 -0
- metadata +80 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 5526525955be143def0033e1f1e72e5a57fe3aef
|
|
4
|
+
data.tar.gz: b4d4c6a1d8976375027b705e1484419cb4a5daf7
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 931e4b54947627df97a45131e712d10bc641138800d17b6c9fd57c1c137646816cb0709807289284aab9682b841bcb50db70ad58b2a4d31ac89dc27b0dfc4c1a
|
|
7
|
+
data.tar.gz: 2211861bc3ce04d358aeeb530ec7382e06de454b662f424e64ead06f2bc38c64159fd2fc674bab40534eeb4f753eea52ce209481d4cd179b9d12193e13d168c2
|
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
The MIT License (MIT) Copyright (c) 2012 Joyent
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
ruby-manta
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
What's ruby-manta?
|
|
7
|
+
------------------
|
|
8
|
+
|
|
9
|
+
ruby-manta is a client for communicating with Manta. Manta is a RESTful service,
|
|
10
|
+
so ruby-manta is effectively an HTTP(S) wrapper which handles required HTTP
|
|
11
|
+
headers and performs some sanity checks. ruby-manta seeks to expose all of
|
|
12
|
+
Manta's features in a thin low-abstraction client.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
What's Manta?
|
|
17
|
+
-------------
|
|
18
|
+
|
|
19
|
+
Manta is a RESTful replicated object store with a directory structure,
|
|
20
|
+
emphasizing Consistency and Partition Tolerance (C & P) in Brewer's CAP,
|
|
21
|
+
which differs from the usual Dynamo-derivative choice of Availability and
|
|
22
|
+
Partition Tolerance (A & P). This makes reasoning about Manta simpler (reads
|
|
23
|
+
after writes will _always_ return the newest version), and it supports CAS
|
|
24
|
+
semantics, but it also means that HTTP 500s may temporarily be returned for
|
|
25
|
+
some objects on rare occasion.
|
|
26
|
+
|
|
27
|
+
Manta also provides a map-reduce service operating over objects stored in
|
|
28
|
+
Manta. The most notable feature here is that map and reduce phases operate
|
|
29
|
+
fully within a UNIX environment. Standard utilities, language environments
|
|
30
|
+
(e.g. node.js, Python, Ruby, Perl), precompiled binaries (e.g. LuxRender,
|
|
31
|
+
BLAST, Postgres, your own custom binaries) and anything you can run in a
|
|
32
|
+
standard UNIX environment can be used.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Streaming Large Objects
|
|
37
|
+
-----------------------
|
|
38
|
+
|
|
39
|
+
One important limitation of ruby-manta is that it is not designed to handle
|
|
40
|
+
large objects. Specifically, when used to upload or download a large object,
|
|
41
|
+
that entire object will be loaded into Ruby's heap. If you're trying to move
|
|
42
|
+
multi-gigabyte objects using a sub-gigabyte VPS or zone, that won't work.
|
|
43
|
+
This leads to the following observations:
|
|
44
|
+
|
|
45
|
+
* don't upload or download large objects using ruby-manta
|
|
46
|
+
* if you must move large objects, consider compressing them first
|
|
47
|
+
* if they're still large, consider using node-manta instead.
|
|
48
|
+
|
|
49
|
+
Unlike ruby-manta, node-manta (the Node.js API for Manta) streams, so object
|
|
50
|
+
size is not a limitation. If you intend to work with large objects, use
|
|
51
|
+
node-manta instead. An slight alternative is to use node-manta for uploading
|
|
52
|
+
and downloading objects, and ruby-manta for everything else.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Example
|
|
57
|
+
-------
|
|
58
|
+
|
|
59
|
+
If you're like the author, examples are worth reams of explanation. Here,
|
|
60
|
+
hurried friend, is an example demonstrating some of ruby-manta's usage:
|
|
61
|
+
|
|
62
|
+
````` ruby
|
|
63
|
+
require 'ruby-manta'
|
|
64
|
+
|
|
65
|
+
# You'll need to provide these four environment variables to run this
|
|
66
|
+
# example. E.g.:
|
|
67
|
+
# USER=john KEY=~/.ssh/john HOST=https://us-east.manta.joyent.com DIR=. \
|
|
68
|
+
# ruby example.rb
|
|
69
|
+
host = ENV['HOST']
|
|
70
|
+
user = ENV['USER']
|
|
71
|
+
priv_key = ENV['KEY' ]
|
|
72
|
+
upload_dir = ENV['DIR' ]
|
|
73
|
+
|
|
74
|
+
# Read in private key, create a MantaClient instance. MantaClient is
|
|
75
|
+
# thread-safe and provides persistent connections with pooling, so you'll
|
|
76
|
+
# only ever need a single instance of this in a program.
|
|
77
|
+
priv_key_data = File.read(priv_key)
|
|
78
|
+
client = MantaClient.new(host, user, priv_key_data,
|
|
79
|
+
:disable_ssl_verification => true)
|
|
80
|
+
|
|
81
|
+
# Create an directory in Manta solely for this example run.
|
|
82
|
+
dir_path = '/' + user + '/stor/ruby-manta-example'
|
|
83
|
+
client.put_directory(dir_path)
|
|
84
|
+
|
|
85
|
+
# Upload files in a local directory to the Manta directory.
|
|
86
|
+
file_paths = Dir[upload_dir + '/*'].select { |p| File.file? p }
|
|
87
|
+
file_paths.each do |file_path|
|
|
88
|
+
file_name = File.basename(file_path)
|
|
89
|
+
# Be careful about binary files and file encodings in Ruby 1.9. If you don't
|
|
90
|
+
# use ASCII-8BIT (forced by 'rb' below), expect timeouts while PUTing an
|
|
91
|
+
# object.
|
|
92
|
+
file_data = File.open(file_path, 'rb') { |f| f.read }
|
|
93
|
+
client.put_object(dir_path + '/' + file_name, file_data)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# This example job runs the wc UNIX command on every object for the
|
|
97
|
+
# map phase, then uses awk during reduce to sum up the three numbers each wc
|
|
98
|
+
# returned.
|
|
99
|
+
job_details = {
|
|
100
|
+
:name => 'total word count',
|
|
101
|
+
:phases => [ {
|
|
102
|
+
:exec => 'wc'
|
|
103
|
+
}, {
|
|
104
|
+
:type => 'reduce',
|
|
105
|
+
:exec => "awk '{ l += $1; w += $2; c += $3 } END { print l, w, c }'"
|
|
106
|
+
} ]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Create the job, then add the objects the job should operate on.
|
|
110
|
+
job_path, _ = client.create_job(job_details)
|
|
111
|
+
|
|
112
|
+
entries, _ = client.list_directory(dir_path)
|
|
113
|
+
obj_paths = entries.select { |e| e['type'] == 'object' }.
|
|
114
|
+
map { |e| dir_path + '/' + e['name'] }
|
|
115
|
+
|
|
116
|
+
client.add_job_keys(job_path, obj_paths)
|
|
117
|
+
|
|
118
|
+
# Tell Manta we're done adding objects to the job. Manta doesn't need this
|
|
119
|
+
# to start running a job -- you can see map results without it, for
|
|
120
|
+
# example -- but reduce phases in particular depend on all mapping
|
|
121
|
+
# finishing.
|
|
122
|
+
client.end_job_input(job_path)
|
|
123
|
+
|
|
124
|
+
# Poll until Manta finishes the job.
|
|
125
|
+
begin
|
|
126
|
+
sleep 1
|
|
127
|
+
job, _ = client.get_job(job_path)
|
|
128
|
+
end while job['state'] != 'done'
|
|
129
|
+
|
|
130
|
+
# We know in this case there will be only one result. Fetch it and
|
|
131
|
+
# display it.
|
|
132
|
+
results, _ = client.get_job_output(job_path)
|
|
133
|
+
data, _ = client.get_object(results[0])
|
|
134
|
+
puts data
|
|
135
|
+
|
|
136
|
+
# Clean up; remove objects and directory.
|
|
137
|
+
obj_paths.each do |obj_path|
|
|
138
|
+
client.delete_object(obj_path)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
client.delete_directory(dir_path)
|
|
142
|
+
`````
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
NB: there's no catching of exceptions above! Real production code should
|
|
146
|
+
be prepared for the exceptional -- see "a note on semantics" below.
|
|
147
|
+
|
|
148
|
+
If you see a PEM pass phrase request, that's because you're using an
|
|
149
|
+
encrypted private key. In production on a server, you'd presumably use an
|
|
150
|
+
unencrypted key.
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
Installation
|
|
155
|
+
------------
|
|
156
|
+
|
|
157
|
+
If you're one of the chaps using Ruby 1.9.*, life is easy:
|
|
158
|
+
|
|
159
|
+
gem install ruby-manta-1.0.1.gem
|
|
160
|
+
|
|
161
|
+
Done.
|
|
162
|
+
|
|
163
|
+
Ruby 1.8.7 was end-of-life'd on June, 2013. As a result, ruby-manta no longer
|
|
164
|
+
supports it either.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
Public and Private spaces
|
|
169
|
+
-------------------------
|
|
170
|
+
|
|
171
|
+
ruby-manta operates with Manta paths. An example of a path is:
|
|
172
|
+
|
|
173
|
+
/john/stor/image.png
|
|
174
|
+
|
|
175
|
+
This object, image.png, belongs to the user "john". It's in his private space,
|
|
176
|
+
"stor". But what if John wants to let the ~~unwashed hoi poll~~general public to
|
|
177
|
+
see his image.png? In this case there is also the "public" space:
|
|
178
|
+
|
|
179
|
+
/john/public/image.png
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
Signed URLs
|
|
184
|
+
-----------
|
|
185
|
+
|
|
186
|
+
Objects put in the public space are accessible by everyone. Objects in the
|
|
187
|
+
private space are only accessible by individuals authenticated and authorized
|
|
188
|
+
by Manta. Manta also supports temporary signed URLs that allow unauthenticated
|
|
189
|
+
individuals to operate on private objects, until the link expires. See
|
|
190
|
+
gen_signed_url() below for the details.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
Map/Reduce Jobs
|
|
195
|
+
---------------
|
|
196
|
+
|
|
197
|
+
Alas, this is beyond the scope of this document. Please refer to Manta's
|
|
198
|
+
documentation for details on how to construct a job. ruby-manta passes job
|
|
199
|
+
details directly to Manta, so what you see is what you'll get.
|
|
200
|
+
|
|
201
|
+
Short summary: create a job, add paths to objects the job should operate on,
|
|
202
|
+
then close the job. Poll until Manta tells you the job is finished, then peek
|
|
203
|
+
at the resulting objects.
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
The API
|
|
208
|
+
=======
|
|
209
|
+
|
|
210
|
+
A note on sematics
|
|
211
|
+
------------------
|
|
212
|
+
|
|
213
|
+
All methods throw exceptions upon failure. If a method doesn't throw, the
|
|
214
|
+
returned results are valid. The most common category of failure you'll see
|
|
215
|
+
inherit from the MantaClient::MantaClientError class. If you feed ruby-manta
|
|
216
|
+
an argument it doesn't like, it'll throw ArgumentError. You might also see
|
|
217
|
+
Errno::ECONNREFUSED and HTTPClient::TimeoutError exceptions from the underlying
|
|
218
|
+
HTTPClient class.
|
|
219
|
+
|
|
220
|
+
Most methods take paths to Manta objects or jobs. Object (or directory) paths
|
|
221
|
+
are typically of the forms:
|
|
222
|
+
|
|
223
|
+
/<user>/stor/<directory>*/<object>
|
|
224
|
+
/<user>/public/<directory>*/<object>
|
|
225
|
+
/<user>/jobs/.../stor/...
|
|
226
|
+
|
|
227
|
+
The last one is a path for an intermediate or final object generated by a job.
|
|
228
|
+
Job paths are simpler:
|
|
229
|
+
|
|
230
|
+
/<user>/jobs/<job UUID>
|
|
231
|
+
|
|
232
|
+
MantaClient methods perform some basic sanity checks to prevent you from
|
|
233
|
+
using malformed paths, or mixing object/directory paths and job paths.
|
|
234
|
+
ArgumentError exceptions are immediately thrown if a bad path is provided,
|
|
235
|
+
otherwise you'll likely receive a MantaClient::ResourceNotFound exception
|
|
236
|
+
(inherits from MantaClient::MantaClientError) after the call fails in Manta.
|
|
237
|
+
|
|
238
|
+
All method calls, except for get_signed_url(), can take an optional :attempts.
|
|
239
|
+
By default they use the :attempts from the constructor (which default to three
|
|
240
|
+
tries), but the number of times a Manta call is attempted upon certain failures
|
|
241
|
+
can be overridden on an individual basis.
|
|
242
|
+
|
|
243
|
+
Lastly, recall that due to Manta's semantics you may see 500 errors on occasion.
|
|
244
|
+
When that happens, try again after a minute or three.
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
Conditional requests
|
|
249
|
+
--------------------
|
|
250
|
+
|
|
251
|
+
Operations on objects support conditional requests. Pass in as an optional
|
|
252
|
+
argument :if_modified_since, :if_unmodified_since, :if_match, or :if_none_match
|
|
253
|
+
to the method. For example, to conditionally get an object with etag
|
|
254
|
+
"e346dce6-22f3-4ed5-8191-6b059b3684de":
|
|
255
|
+
|
|
256
|
+
````` ruby
|
|
257
|
+
|
|
258
|
+
client.get_object(path, :if_match => 'e346dce6-22f3-4ed5-8191-6b059b3684de')
|
|
259
|
+
`````
|
|
260
|
+
|
|
261
|
+
You can get the Etag or Last-Modified from the headers returned by most
|
|
262
|
+
methods.
|
|
263
|
+
|
|
264
|
+
The methods follow the RFC2616 semantics in the following manner: where 304
|
|
265
|
+
would return instead of data, a nil returns instead. Where 412 would occur,
|
|
266
|
+
a MantaClient::PreconditionFailed is thrown.
|
|
267
|
+
|
|
268
|
+
Conditional requests allow many good things, so you're advised to use them
|
|
269
|
+
where applicable. You can conditionally download an object only if it has
|
|
270
|
+
changed, update an object with CAS semantics, create snaplinks correctly in the
|
|
271
|
+
face of concurrent updates, and so forth.
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
Cross-origin resource sharing
|
|
276
|
+
-----------------------------
|
|
277
|
+
|
|
278
|
+
Browsers do not allow cross-domain requests due to the same-origin policy.
|
|
279
|
+
Cross-Origin Resource Sharing (CORS) headers provide a mechanism by which a
|
|
280
|
+
browser can safely loosen this policy.
|
|
281
|
+
|
|
282
|
+
ruby-manta and Manta support all headers specified by the W3C working draft,
|
|
283
|
+
by passing in optional arguments to put_object() or put_directory():
|
|
284
|
+
|
|
285
|
+
:access_control_allow_credentials, :access_control_allow_headers,
|
|
286
|
+
:access_control_allow_methods, :access_control_allow_origin,
|
|
287
|
+
:access_control_expose_headers, :access_control_max_age
|
|
288
|
+
|
|
289
|
+
You can also pass in :origin to most object- and directory-related methods.
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
initialize(manta_host, user, priv_key, _options_)
|
|
294
|
+
-------------------------------------------------
|
|
295
|
+
|
|
296
|
+
Construct a new MantaClient instance.
|
|
297
|
+
|
|
298
|
+
priv_key_data is data read directly from an SSH private key (i.e. RFC 4716
|
|
299
|
+
format). The method can also accept several optional args: :connect_timeout,
|
|
300
|
+
:send_timeout, :receive_timeout, :disable_ssl_verification and :attempts.
|
|
301
|
+
The timeouts are in seconds, and :attempts determines the default number of
|
|
302
|
+
attempts each method will make upon receiving recoverable errors.
|
|
303
|
+
|
|
304
|
+
Will throw an exception if given a key whose format it doesn't understand.
|
|
305
|
+
|
|
306
|
+
MantaClient is thread-safe (in theory, anyway), and uses an HTTP client that
|
|
307
|
+
pools connections. You should only need to initialize a single MantaClient
|
|
308
|
+
object per process.
|
|
309
|
+
|
|
310
|
+
Example:
|
|
311
|
+
|
|
312
|
+
````` ruby
|
|
313
|
+
|
|
314
|
+
priv_key_data = File.read('/home/john/.ssh/john')
|
|
315
|
+
client = MantaClient.new('https://manta.joyentcloud.com', 'john',
|
|
316
|
+
priv_key_data, :disable_ssl_verification => true)
|
|
317
|
+
`````
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
put_object(object path, file data, _options_)
|
|
322
|
+
---------------------------------------------
|
|
323
|
+
|
|
324
|
+
Uploads object data to Manta to the given path, along with a computed MD5
|
|
325
|
+
hash.
|
|
326
|
+
|
|
327
|
+
The path must be a valid object path. Data can be any sequence of octets.
|
|
328
|
+
The HTTP Content-Type stored on Manta can be set with an optional
|
|
329
|
+
:content_type argument; the default is application/octet-stream. The
|
|
330
|
+
number of distributed replicates of an object stored in Manta can be set
|
|
331
|
+
with an optional :durability_level; the default is 2. Supports CORS optional
|
|
332
|
+
arguments.
|
|
333
|
+
|
|
334
|
+
Returns true along with received HTTP headers.
|
|
335
|
+
|
|
336
|
+
Examples:
|
|
337
|
+
|
|
338
|
+
````` ruby
|
|
339
|
+
|
|
340
|
+
obj_path, headers = client.put_object('/john/stor/area51_map.png',
|
|
341
|
+
binary_file_data,
|
|
342
|
+
:content_type => 'image/png',
|
|
343
|
+
:durability_level => 1,
|
|
344
|
+
:if_unmodified_since => Time.now - 300,
|
|
345
|
+
:access_control_allow_origin => 'http://example.com')
|
|
346
|
+
|
|
347
|
+
obj_path, _ = client.put_object('/john/public/pass.txt', 'illuminati 4evah')
|
|
348
|
+
`````
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
get_object(object path, _options_)
|
|
353
|
+
----------------------------------
|
|
354
|
+
|
|
355
|
+
Get an object from Manta at a given path, and checks it's uncorrupted.
|
|
356
|
+
|
|
357
|
+
The object path must point at an actual Manta object. :head => true can
|
|
358
|
+
optionally be passed in to do a HEAD instead of a GET.
|
|
359
|
+
|
|
360
|
+
Returns the retrieved data along with received HTTP headers.
|
|
361
|
+
|
|
362
|
+
Examples:
|
|
363
|
+
|
|
364
|
+
````` ruby
|
|
365
|
+
|
|
366
|
+
_, headers = client.get_object('/john/stor/area51_map.png',
|
|
367
|
+
:head => true,
|
|
368
|
+
:origin => 'https://illuminati.org')
|
|
369
|
+
|
|
370
|
+
file_data, headers = client.get_object('/john/stor/area51_map.png')
|
|
371
|
+
`````
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
delete_object(object path, _options_)
|
|
376
|
+
-------------------------------------
|
|
377
|
+
|
|
378
|
+
Deletes an object off Manta at a given path.
|
|
379
|
+
|
|
380
|
+
The object path must point at an actual object.
|
|
381
|
+
|
|
382
|
+
Returns true along with received HTTP headers.
|
|
383
|
+
|
|
384
|
+
Examples:
|
|
385
|
+
|
|
386
|
+
````` ruby
|
|
387
|
+
|
|
388
|
+
client.delete_object('/john/stor/area51_map.png')
|
|
389
|
+
|
|
390
|
+
_, headers = client.delete_object('/john/public/pass.txt')
|
|
391
|
+
`````
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
put_directory(dir path, _options_)
|
|
396
|
+
----------------------------------
|
|
397
|
+
|
|
398
|
+
Creates a directory on Manta at a given path. Supports CORS optional arguments.
|
|
399
|
+
|
|
400
|
+
Returns true along with received HTTP headers.
|
|
401
|
+
|
|
402
|
+
Example:
|
|
403
|
+
|
|
404
|
+
````` ruby
|
|
405
|
+
|
|
406
|
+
client.put_directory('/john/stor/plans-world-domination')
|
|
407
|
+
|
|
408
|
+
client.put_directory('/john/public/honeypot',
|
|
409
|
+
:access_control_allow_methods => 'GET, PUT, DELETE',
|
|
410
|
+
:access_control_allow_origin => '*')
|
|
411
|
+
`````
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
list_directory(dir_path, _options_)
|
|
416
|
+
-----------------------------------
|
|
417
|
+
|
|
418
|
+
Gets a lexicographically sorted directory listing on Manta at a given path,
|
|
419
|
+
|
|
420
|
+
The path must be a valid directory path and point at an actual directory.
|
|
421
|
+
:limit optionally changes the maximum number of entries; the default is 1000.
|
|
422
|
+
If given :marker, an object name in the directory, returned directory entries
|
|
423
|
+
will begin from that point. :head => true can optionally be passed in to do a
|
|
424
|
+
HEAD instead of a GET.
|
|
425
|
+
|
|
426
|
+
Returns an array of hash objects, each object representing a directory
|
|
427
|
+
entry. Also returns the received HTTP headers.
|
|
428
|
+
|
|
429
|
+
Examples:
|
|
430
|
+
|
|
431
|
+
````` ruby
|
|
432
|
+
|
|
433
|
+
dir_entries, _ = client.list_directory('/john/stor/plans-world-domination',
|
|
434
|
+
:limit => 50,
|
|
435
|
+
:marker => 'take_over_pentagon.txt')
|
|
436
|
+
|
|
437
|
+
_, headers = client.list_directory('/john/stor/plans-world-domination',
|
|
438
|
+
:head => true)
|
|
439
|
+
`````
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
delete_directory(dir_path, _options_)
|
|
444
|
+
-------------------------------------
|
|
445
|
+
|
|
446
|
+
Removes a directory from Manta at a given path.
|
|
447
|
+
|
|
448
|
+
The path must be a valid directory path, and point at an actual directory.
|
|
449
|
+
The directory must be empty.
|
|
450
|
+
|
|
451
|
+
Returns true along with received HTTP headers.
|
|
452
|
+
|
|
453
|
+
Example:
|
|
454
|
+
|
|
455
|
+
````` ruby
|
|
456
|
+
|
|
457
|
+
client.delete_directory('/john/stor/plans-world-domination')
|
|
458
|
+
`````
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
put_snaplink(orig_path, link_path, _options_)
|
|
463
|
+
-----------------------------------------
|
|
464
|
+
|
|
465
|
+
Creates a snaplink from on object in Manta at a given path to a different path.
|
|
466
|
+
This effectively creates another reference to the same object. Since objects
|
|
467
|
+
are immutable, PUTting over that object reduces the refcount on the object;
|
|
468
|
+
other references (i.e. snaplinks) continue to see the original version.
|
|
469
|
+
|
|
470
|
+
Both paths should be valid object paths. orig_path should point at an existing
|
|
471
|
+
object.
|
|
472
|
+
|
|
473
|
+
Returns true along with received HTTP headers.
|
|
474
|
+
|
|
475
|
+
Example:
|
|
476
|
+
|
|
477
|
+
````` ruby
|
|
478
|
+
|
|
479
|
+
client.put_snaplink('/john/stor/character_assassination.txt',
|
|
480
|
+
'/john/public/media_consultation.txt')
|
|
481
|
+
`````
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
create_job(job_description, _options_)
|
|
486
|
+
--------------------------------------
|
|
487
|
+
|
|
488
|
+
Creates a job in Manta.
|
|
489
|
+
|
|
490
|
+
The job must be a hash, containing at minimum a :phases key. See README.md
|
|
491
|
+
or the Manta docs to see the format and options for setting up a job on
|
|
492
|
+
Manta; this method effectively just converts the job hash to JSON and sends
|
|
493
|
+
to the Manta service.
|
|
494
|
+
|
|
495
|
+
Returns the path for the new job, along with received HTTP headers.
|
|
496
|
+
|
|
497
|
+
Example:
|
|
498
|
+
|
|
499
|
+
````` ruby
|
|
500
|
+
|
|
501
|
+
job_desc = { :phases => [{ :exec => 'grep skynet' }] }
|
|
502
|
+
job_path, _ = client.create_job(job_desc)
|
|
503
|
+
`````
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
get_job(job_path, _options_)
|
|
508
|
+
----------------------------
|
|
509
|
+
|
|
510
|
+
Gets various information about a job in Manta at a given job path.
|
|
511
|
+
|
|
512
|
+
The path must point at an actual job. :head => true can optionally be passed
|
|
513
|
+
in to do a HEAD instead of a GET.
|
|
514
|
+
|
|
515
|
+
Returns a hash with job information, along with received HTTP headers.
|
|
516
|
+
|
|
517
|
+
Example:
|
|
518
|
+
|
|
519
|
+
````` ruby
|
|
520
|
+
|
|
521
|
+
job_path = '/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7'
|
|
522
|
+
job_info, _ = client.get_job(job_path)
|
|
523
|
+
`````
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
get_job_errors(job_path, _options_)
|
|
528
|
+
-----------------------------------
|
|
529
|
+
|
|
530
|
+
Gets errors that occured during the execution of a job in Manta at a given
|
|
531
|
+
job path.
|
|
532
|
+
|
|
533
|
+
The must point at an actual job. :head => true can optionally be passed in to
|
|
534
|
+
do a HEAD instead of a GET.
|
|
535
|
+
|
|
536
|
+
Returns an array of hashes, each hash containing information about an
|
|
537
|
+
error; this information is best-effort by Manta, so it may not be complete.
|
|
538
|
+
Also returns received HTTP headers.
|
|
539
|
+
|
|
540
|
+
Examples:
|
|
541
|
+
|
|
542
|
+
````` ruby
|
|
543
|
+
|
|
544
|
+
job_path = '/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7'
|
|
545
|
+
job_errors, _ = client.get_job_errors(job_path)
|
|
546
|
+
|
|
547
|
+
_, headers = client.get_job_errors(job_path, :head => true)
|
|
548
|
+
`````
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
cancel_job(job_path, _options_)
|
|
553
|
+
-------------------------------
|
|
554
|
+
|
|
555
|
+
Cancels a running job in Manta at a given path.
|
|
556
|
+
|
|
557
|
+
The job path must point at an actual job.
|
|
558
|
+
|
|
559
|
+
Returns true along with received HTTP headers.
|
|
560
|
+
|
|
561
|
+
Example:
|
|
562
|
+
|
|
563
|
+
````` ruby
|
|
564
|
+
|
|
565
|
+
client.cancel_job('/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7')
|
|
566
|
+
`````
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
add_job_keys(job_path, object_keys, _options_)
|
|
571
|
+
----------------------------------------------
|
|
572
|
+
|
|
573
|
+
Adds objects for a running job in Manta to process.
|
|
574
|
+
|
|
575
|
+
The job_path must point at an actual running job. The obj_paths must be an
|
|
576
|
+
array of object paths pointing at actual objects.
|
|
577
|
+
|
|
578
|
+
Returns true, along with received HTTP headers.
|
|
579
|
+
|
|
580
|
+
Example:
|
|
581
|
+
|
|
582
|
+
````` ruby
|
|
583
|
+
|
|
584
|
+
client.add_job_keys('/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7',
|
|
585
|
+
['/john/stor/skynet_plans.txt',
|
|
586
|
+
'/john/stor/the_matrix.txt'])
|
|
587
|
+
`````
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
end_job_input(job_path, _options_)
|
|
592
|
+
----------------------------------
|
|
593
|
+
|
|
594
|
+
Inform Manta that no more objects will be added for processing by a job,
|
|
595
|
+
and that the job should finish all phases and terminate.
|
|
596
|
+
|
|
597
|
+
The job path must point at an actual running job.
|
|
598
|
+
|
|
599
|
+
Returns true, along with received HTTP headers.
|
|
600
|
+
|
|
601
|
+
Example:
|
|
602
|
+
|
|
603
|
+
````` ruby
|
|
604
|
+
|
|
605
|
+
client.end_job_input('/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7')
|
|
606
|
+
`````
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
get_job_input(job_path, _options_)
|
|
612
|
+
----------------------------------
|
|
613
|
+
|
|
614
|
+
Get a list of objects that have been given to a Manta job for processing.
|
|
615
|
+
|
|
616
|
+
The job path must point at an actual running job.
|
|
617
|
+
|
|
618
|
+
Returns an array of object paths, along with received HTTP headers.
|
|
619
|
+
|
|
620
|
+
Example:
|
|
621
|
+
|
|
622
|
+
````` ruby
|
|
623
|
+
|
|
624
|
+
job_path = '/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7'
|
|
625
|
+
obj_paths, _ = client.get_job_input(job_path)
|
|
626
|
+
`````
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
get_job_output(job_path, _options_)
|
|
631
|
+
-----------------------------------
|
|
632
|
+
|
|
633
|
+
Get a list of objects that contain the intermediate and/or final results of a
|
|
634
|
+
running Manta job.
|
|
635
|
+
|
|
636
|
+
The job_path must point at an actual running job.
|
|
637
|
+
|
|
638
|
+
Returns an array of object paths, along with received HTTP headers.
|
|
639
|
+
|
|
640
|
+
Example:
|
|
641
|
+
|
|
642
|
+
````` ruby
|
|
643
|
+
|
|
644
|
+
job_path = '/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7'
|
|
645
|
+
obj_paths, _ = client.get_job_output(job_path)
|
|
646
|
+
`````
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
get_job_failures(job_path, _options_)
|
|
651
|
+
-------------------------------------
|
|
652
|
+
|
|
653
|
+
Get a list of objects that had failures during processing in a Manta job.
|
|
654
|
+
|
|
655
|
+
The job path must point at an actual running job.
|
|
656
|
+
|
|
657
|
+
Returns an array of object paths, along with received HTTP headers.
|
|
658
|
+
|
|
659
|
+
Example:
|
|
660
|
+
|
|
661
|
+
````` ruby
|
|
662
|
+
|
|
663
|
+
job_path = '/john/jobs/80e481c4-8567-47e7-bdba-f0c5705af1c7'
|
|
664
|
+
obj_failures, _ = client.get_job_failures(job_path)
|
|
665
|
+
`````
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
list_jobs(state, _options_)
|
|
670
|
+
---------------------------
|
|
671
|
+
|
|
672
|
+
Get a list of Manta jobs.
|
|
673
|
+
|
|
674
|
+
The state indicates which kind of jobs to return. :running is for jobs
|
|
675
|
+
that are currently processing, :done and :all should be obvious. Be careful
|
|
676
|
+
of the latter two if you've run a lot of jobs -- the list could be quite
|
|
677
|
+
long.
|
|
678
|
+
|
|
679
|
+
Returns an array of hashes, each hash containing some information about a job.
|
|
680
|
+
Also returns received HTTP headers.
|
|
681
|
+
|
|
682
|
+
Example:
|
|
683
|
+
|
|
684
|
+
````` ruby
|
|
685
|
+
|
|
686
|
+
running_jobs, _ = client.list_jobs(:running)
|
|
687
|
+
`````
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
gen_signed_url(expiry_date, http_method, path, _query_args_)
|
|
692
|
+
----------------------------------------------------------
|
|
693
|
+
|
|
694
|
+
Generates a signed URL which can be used by unauthenticated users to
|
|
695
|
+
make a request to Manta at the given path. This is typically used to GET
|
|
696
|
+
an object.
|
|
697
|
+
|
|
698
|
+
expires is a Time object or integer representing time after epoch; this
|
|
699
|
+
determines how long the signed URL will be valid for. The method is the HTTP
|
|
700
|
+
method (:get, :put, :post, :delete) the signed URL is allowed to be used
|
|
701
|
+
for. The path must be a valid object (or directory?) path. Lastly, the
|
|
702
|
+
optional args is an array containing pairs of query args that will be
|
|
703
|
+
appended at the end of the URL.
|
|
704
|
+
|
|
705
|
+
The returned URL is signed, and can be used either over HTTP or HTTPS until
|
|
706
|
+
it reaches the expiry date.
|
|
707
|
+
|
|
708
|
+
Example:
|
|
709
|
+
|
|
710
|
+
````` ruby
|
|
711
|
+
|
|
712
|
+
url = client.gen_signed_url(Time.now + 5000, :get, '/john/stor/pass.txt')
|
|
713
|
+
`````
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
License
|
|
718
|
+
=======
|
|
719
|
+
|
|
720
|
+
(c) 2012 Joyent, licensed under MIT. See LICENSE for details, you legal geek
|
|
721
|
+
you.
|
|
722
|
+
|