Revision bac5ffc3 lib/rapi/resources.py
b/lib/rapi/resources.py | ||
---|---|---|
31 | 31 |
import ganeti.cli |
32 | 32 |
|
33 | 33 |
from ganeti import constants |
34 |
from ganeti import luxi |
|
34 | 35 |
from ganeti import utils |
35 | 36 |
from ganeti.rapi import httperror |
36 | 37 |
|
... | ... | |
39 | 40 |
_CONNECTOR = {} |
40 | 41 |
|
41 | 42 |
|
42 |
def BuildUriList(names, uri_format):
|
|
43 |
def BuildUriList(ids, uri_format, uri_fields=("name", "uri")):
|
|
43 | 44 |
"""Builds a URI list as used by index resources. |
44 | 45 |
|
45 | 46 |
Args: |
46 |
- names: List of names as strings
|
|
47 |
- ids: List of ids as strings
|
|
47 | 48 |
- uri_format: Format to be applied for URI |
49 |
- uri_fields: Optional parameter for field ids |
|
48 | 50 |
|
49 | 51 |
""" |
50 |
def _MapName(name): |
|
51 |
return { "name": name, "uri": uri_format % name, } |
|
52 |
(field_id, field_uri) = uri_fields |
|
53 |
|
|
54 |
def _MapId(m_id): |
|
55 |
return { field_id: m_id, field_uri: uri_format % m_id, } |
|
52 | 56 |
|
53 | 57 |
# Make sure the result is sorted, makes it nicer to look at and simplifies |
54 | 58 |
# unittests. |
55 |
names.sort()
|
|
59 |
ids.sort()
|
|
56 | 60 |
|
57 |
return map(_MapName, names)
|
|
61 |
return map(_MapId, ids)
|
|
58 | 62 |
|
59 | 63 |
|
60 | 64 |
def ExtractField(sequence, index): |
... | ... | |
523 | 527 |
return [row[0] for row in diagnose_data if row[1]] |
524 | 528 |
|
525 | 529 |
|
530 |
class R_2_jobs(R_Generic): |
|
531 |
"""/2/jobs resource. |
|
532 |
|
|
533 |
""" |
|
534 |
DOC_URI = "/2/jobs" |
|
535 |
|
|
536 |
def GET(self): |
|
537 |
"""Returns a dictionary of jobs. |
|
538 |
|
|
539 |
Returns: |
|
540 |
A dictionary with jobs id and uri. |
|
541 |
|
|
542 |
""" |
|
543 |
fields = ["id"] |
|
544 |
# Convert the list of lists to the list of ids |
|
545 |
result = [job_id for [job_id] in luxi.Client().QueryJobs(None, fields)] |
|
546 |
return BuildUriList(result, "/2/jobs/%s", uri_fields=("id", "uri")) |
|
547 |
|
|
548 |
|
|
549 |
class R_2_jobs_id(R_Generic): |
|
550 |
"""/2/jobs/[job_id] resource. |
|
551 |
|
|
552 |
""" |
|
553 |
DOC_URI = "/2/jobs/[job_id]" |
|
554 |
|
|
555 |
def GET(self): |
|
556 |
"""Returns a job status. |
|
557 |
|
|
558 |
Returns: |
|
559 |
A dictionary with job parameters. |
|
560 |
|
|
561 |
The result includes: |
|
562 |
id - job ID as a number |
|
563 |
status - current job status as a string |
|
564 |
ops - involved OpCodes as a list of dictionaries for each opcodes in |
|
565 |
the job |
|
566 |
opstatus - OpCodes status as a list |
|
567 |
opresult - OpCodes results as a list of lists |
|
568 |
|
|
569 |
""" |
|
570 |
fields = ["id", "ops", "status", "opstatus", "opresult"] |
|
571 |
job_id = self.items[0] |
|
572 |
result = luxi.Client().QueryJobs([job_id,], fields)[0] |
|
573 |
return MapFields(fields, result) |
|
574 |
|
|
575 |
|
|
526 | 576 |
_CONNECTOR.update({ |
527 | 577 |
"/": R_root, |
528 | 578 |
|
... | ... | |
540 | 590 |
re.compile(r'^/instances/([\w\._-]+)/tags$'): R_instances_name_tags, |
541 | 591 |
|
542 | 592 |
"/os": R_os, |
593 |
|
|
594 |
"/2/jobs": R_2_jobs, |
|
595 |
re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): R_2_jobs_id, |
|
543 | 596 |
}) |
Also available in: Unified diff