"""
-import re
-
import ganeti.opcodes
-
-from ganeti import constants
+from ganeti import http
from ganeti import luxi
+from ganeti import constants
+from ganeti.rapi import baserlib
-from ganeti.rapi import baserlib
+from ganeti.rapi.rlib1 import I_FIELDS, N_FIELDS
class R_2_jobs(baserlib.R_Generic):
Returns:
A dictionary with jobs id and uri.
-
+
"""
fields = ["id"]
# Convert the list of lists to the list of ids
def GET(self):
"""Returns a job status.
- Returns:
+ Returns:
A dictionary with job parameters.
The result includes:
id - job ID as a number
status - current job status as a string
- ops - involved OpCodes as a list of dictionaries for each opcodes in
+ ops - involved OpCodes as a list of dictionaries for each opcodes in
the job
opstatus - OpCodes status as a list
opresult - OpCodes results as a list of lists
-
+
"""
fields = ["id", "ops", "status", "opstatus", "opresult"]
job_id = self.items[0]
- result = luxi.Client().QueryJobs([job_id,], fields)[0]
+ result = luxi.Client().QueryJobs([job_id, ], fields)[0]
return baserlib.MapFields(fields, result)
"""
DOC_URI = "/2/nodes"
-
- def _GetDetails(self, nodeslist):
- """Returns detailed instance data for bulk output.
-
- Args:
- instance: A list of nodes names.
-
- Returns:
- A list of nodes properties
- """
- fields = ["name","dtotal", "dfree",
- "mtotal", "mnode", "mfree",
- "pinst_cnt", "sinst_cnt", "tags"]
-
- op = ganeti.opcodes.OpQueryNodes(output_fields=fields,
- names=nodeslist)
- result = ganeti.cli.SubmitOpCode(op)
-
- nodes_details = []
- for node in result:
- mapped = baserlib.MapFields(fields, node)
- nodes_details.append(mapped)
- return nodes_details
-
def GET(self):
"""Returns a list of all nodes.
-
+
Returns:
A dictionary with 'name' and 'uri' keys for each of them.
"uri": "\/instances\/node2.example.com"
}]
- If the optional 'bulk' argument is provided and set to 'true'
+ If the optional 'bulk' argument is provided and set to 'true'
value (i.e '?bulk=1'), the output contains detailed
information about nodes as a list.
"""
op = ganeti.opcodes.OpQueryNodes(output_fields=["name"], names=[])
nodeslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
-
+
if 'bulk' in self.queryargs:
- return self._GetDetails(nodeslist)
+ op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
+ names=nodeslist)
+ result = ganeti.cli.SubmitOpCode(op)
+ return baserlib.MapBulkFields(result, N_FIELDS)
+
+ return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
+ uri_fields=("id", "uri"))
+
- return baserlib.BuildUriList(nodeslist, "/nodes/%s", uri_fields=("id", "uri"))
+class R_2_instances(baserlib.R_Generic):
+ """/2/instances resource.
+
+ """
+ DOC_URI = "/2/instances"
+
+ def GET(self):
+ """Returns a list of all available instances.
+
+ Returns:
+ A dictionary with 'name' and 'uri' keys for each of them.
+
+ Example: [
+ {
+ "name": "web.example.com",
+ "uri": "\/instances\/web.example.com"
+ },
+ {
+ "name": "mail.example.com",
+ "uri": "\/instances\/mail.example.com"
+ }]
+
+ If the optional 'bulk' argument is provided and set to 'true'
+ value (i.e '?bulk=1'), the output contains detailed
+ information about instances as a list.
+
+ Example: [
+ {
+ "status": "running",
+ "bridge": "xen-br0",
+ "name": "web.example.com",
+ "tags": ["tag1", "tag2"],
+ "admin_ram": 512,
+ "sda_size": 20480,
+ "pnode": "node1.example.com",
+ "mac": "01:23:45:67:89:01",
+ "sdb_size": 4096,
+ "snodes": ["node2.example.com"],
+ "disk_template": "drbd",
+ "ip": null,
+ "admin_state": true,
+ "os": "debian-etch",
+ "vcpus": 2,
+ "oper_state": true
+ },
+ ...
+ ]
+
+ """
+ op = ganeti.opcodes.OpQueryInstances(output_fields=["name"], names=[])
+ instanceslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
+
+ if 'bulk' in self.queryargs:
+ op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
+ names=instanceslist)
+ result = ganeti.cli.SubmitOpCode(op)
+ return baserlib.MapBulkFields(result, I_FIELDS)
+
+
+ else:
+ return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
+ uri_fields=("id", "uri"))
+
+ def PUT(self):
+ """Create an instance.
+
+ Returns:
+ A job id.
+
+ """
+ opts = self.req.request_post_data
+
+ # beparams
+ mem = opts.get('mem', None)
+ vcpus = opts.get('vcpus', None)
+ auto_balance = opts.get('auto_balance', None)
+
+ beparams = {}
+
+ for key, const in [(mem, constants.BE_MEMORY),
+ (vcpus, constants.BE_VCPUS),
+ (auto_balance, constants.BE_AUTO_BALANCE)]:
+ if key is not None:
+ beparams[const] = key
+
+ op = ganeti.opcodes.OpCreateInstance(
+ instance_name=opts.get('name'),
+ disk_size=opts.get('size', 20 * 1024),
+ swap_size=opts.get('swap', 4 * 1024),
+ disk_template=opts.get('disk_template', None),
+ mode=constants.INSTANCE_CREATE,
+ os_type=opts.get('os'),
+ pnode=opts.get('pnode'),
+ snode=opts.get('snode'),
+ ip=opts.get('ip', 'none'),
+ bridge=opts.get('bridge', None),
+ start=opts.get('start', True),
+ ip_check=opts.get('ip_check', True),
+ wait_for_sync=opts.get('wait_for_sync', True),
+ mac=opts.get('mac', 'auto'),
+ hypervisor=opts.get('hypervisor', None),
+ hvparams=opts.get('hvparams', {}),
+ beparams=beparams,
+ iallocator=opts.get('iallocator', None),
+ file_storage_dir=opts.get('file_storage_dir', None),
+ file_driver=opts.get('file_driver', 'loop'),
+ )
+
+ job_id = ganeti.cli.SendJob([op])
+ return job_id
+
+
+class R_2_instances_name_reboot(baserlib.R_Generic):
+ """/2/instances/[instance_name]/reboot resource.
+
+ Implements an instance reboot.
+
+ """
+
+ DOC_URI = "/2/instances/[instance_name]/reboot"
+
+ def GET(self):
+ """Reboot an instance.
+
+ """
+ instance_name = self.items[0]
+ reboot_type = self.queryargs.get('reboot_type',
+ constants.INSTANCE_REBOOT_HARD)
+ ignore_secondaries = self.queryargs.get('ignore_secondaries', False)
+ op = ganeti.opcodes.OpRebootInstance(
+ instance_name=instance_name,
+ reboot_type=reboot_type,
+ ignore_secondaries=ignore_secondaries)
+
+ job_id = ganeti.cli.SendJob([op])
+
+ return job_id
+
+
+class R_2_instances_name_tags(baserlib.R_Generic):
+ """/2/instances/[instance_name]/tags resource.
+
+ Manages per-instance tags.
+
+ """
+ DOC_URI = "/2/instances/[instance_name]/tags"
+
+ def GET(self):
+ """Returns a list of instance tags.
+
+ Example: ["tag1", "tag2", "tag3"]
+
+ """
+ return baserlib._Tags_GET(constants.TAG_INSTANCE, name=self.items[0])
+
+ def POST(self):
+ """Add a set of tags to the instance.
+
+ The reqest as a list of strings should be POST to this URI. And you'll have
+ back a job id.
+
+ """
+ return baserlib._Tags_POST(constants.TAG_INSTANCE,
+ self.post_data, name=self.items[0])
+
+ def DELETE(self):
+ """Delete a tag.
+
+ In order to delete a set of tags from a instance, DELETE request should be
+ addressed to URI like: /2/instances/[instance_name]/tags?tag=[tag]&tag=[tag]
+
+ """
+ if 'tag' not in self.queryargs:
+ # no we not gonna delete all tags from an instance
+ raise http.HTTPNotImplemented()
+ return baserlib._Tags_DELETE(constants.TAG_INSTANCE,
+ self.queryargs['tag'],
+ name=self.items[0])