ruby-manta 1.1.0

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