Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib2.py @ 3d103742

History | View | Annotate | Download (13 kB)

1 10b207d4 Oleksiy Mishchenko
#
2 10b207d4 Oleksiy Mishchenko
#
3 10b207d4 Oleksiy Mishchenko
4 10b207d4 Oleksiy Mishchenko
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 10b207d4 Oleksiy Mishchenko
#
6 10b207d4 Oleksiy Mishchenko
# This program is free software; you can redistribute it and/or modify
7 10b207d4 Oleksiy Mishchenko
# it under the terms of the GNU General Public License as published by
8 10b207d4 Oleksiy Mishchenko
# the Free Software Foundation; either version 2 of the License, or
9 10b207d4 Oleksiy Mishchenko
# (at your option) any later version.
10 10b207d4 Oleksiy Mishchenko
#
11 10b207d4 Oleksiy Mishchenko
# This program is distributed in the hope that it will be useful, but
12 10b207d4 Oleksiy Mishchenko
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 10b207d4 Oleksiy Mishchenko
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 10b207d4 Oleksiy Mishchenko
# General Public License for more details.
15 10b207d4 Oleksiy Mishchenko
#
16 10b207d4 Oleksiy Mishchenko
# You should have received a copy of the GNU General Public License
17 10b207d4 Oleksiy Mishchenko
# along with this program; if not, write to the Free Software
18 10b207d4 Oleksiy Mishchenko
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 10b207d4 Oleksiy Mishchenko
# 02110-1301, USA.
20 10b207d4 Oleksiy Mishchenko
21 10b207d4 Oleksiy Mishchenko
22 10b207d4 Oleksiy Mishchenko
"""Remote API version 2 baserlib.library.
23 10b207d4 Oleksiy Mishchenko

24 10b207d4 Oleksiy Mishchenko
"""
25 10b207d4 Oleksiy Mishchenko
26 10b207d4 Oleksiy Mishchenko
import ganeti.opcodes
27 15fd9fd5 Oleksiy Mishchenko
from ganeti import http
28 10b207d4 Oleksiy Mishchenko
from ganeti import luxi
29 15fd9fd5 Oleksiy Mishchenko
from ganeti import constants
30 38206f3c Iustin Pop
from ganeti.rapi import baserlib
31 10b207d4 Oleksiy Mishchenko
32 4e5a68f8 Oleksiy Mishchenko
33 9031ee8e Iustin Pop
I_FIELDS = ["name", "admin_state", "os",
34 9031ee8e Iustin Pop
            "pnode", "snodes",
35 9031ee8e Iustin Pop
            "disk_template",
36 9031ee8e Iustin Pop
            "nic.ips", "nic.macs", "nic.bridges",
37 9031ee8e Iustin Pop
            "disk.sizes",
38 9031ee8e Iustin Pop
            "beparams",
39 9031ee8e Iustin Pop
            "oper_state", "oper_ram", "status",
40 9031ee8e Iustin Pop
            "tags"]
41 9031ee8e Iustin Pop
42 9031ee8e Iustin Pop
N_FIELDS = ["name", "offline", "master_candidate",
43 9031ee8e Iustin Pop
            "dtotal", "dfree",
44 4e5a68f8 Oleksiy Mishchenko
            "mtotal", "mnode", "mfree",
45 4e5a68f8 Oleksiy Mishchenko
            "pinst_cnt", "sinst_cnt", "tags"]
46 4e5a68f8 Oleksiy Mishchenko
47 4e5a68f8 Oleksiy Mishchenko
48 4e5a68f8 Oleksiy Mishchenko
class R_version(baserlib.R_Generic):
49 4e5a68f8 Oleksiy Mishchenko
  """/version resource.
50 4e5a68f8 Oleksiy Mishchenko

51 4e5a68f8 Oleksiy Mishchenko
  This resource should be used to determine the remote API version and
52 4e5a68f8 Oleksiy Mishchenko
  to adapt clients accordingly.
53 4e5a68f8 Oleksiy Mishchenko

54 4e5a68f8 Oleksiy Mishchenko
  """
55 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/version"
56 4e5a68f8 Oleksiy Mishchenko
57 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
58 4e5a68f8 Oleksiy Mishchenko
    """Returns the remote API version.
59 4e5a68f8 Oleksiy Mishchenko

60 4e5a68f8 Oleksiy Mishchenko
    """
61 4e5a68f8 Oleksiy Mishchenko
    return constants.RAPI_VERSION
62 4e5a68f8 Oleksiy Mishchenko
63 4e5a68f8 Oleksiy Mishchenko
64 4e5a68f8 Oleksiy Mishchenko
class R_2_info(baserlib.R_Generic):
65 4e5a68f8 Oleksiy Mishchenko
  """Cluster info.
66 4e5a68f8 Oleksiy Mishchenko

67 4e5a68f8 Oleksiy Mishchenko
  """
68 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/info"
69 4e5a68f8 Oleksiy Mishchenko
70 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
71 4e5a68f8 Oleksiy Mishchenko
    """Returns cluster information.
72 4e5a68f8 Oleksiy Mishchenko

73 4e5a68f8 Oleksiy Mishchenko
    Example::
74 4e5a68f8 Oleksiy Mishchenko

75 4e5a68f8 Oleksiy Mishchenko
      {
76 4e5a68f8 Oleksiy Mishchenko
        "config_version": 3,
77 4e5a68f8 Oleksiy Mishchenko
        "name": "cluster1.example.com",
78 4e5a68f8 Oleksiy Mishchenko
        "software_version": "1.2.4",
79 4e5a68f8 Oleksiy Mishchenko
        "os_api_version": 5,
80 4e5a68f8 Oleksiy Mishchenko
        "export_version": 0,
81 4e5a68f8 Oleksiy Mishchenko
        "master": "node1.example.com",
82 4e5a68f8 Oleksiy Mishchenko
        "architecture": [
83 4e5a68f8 Oleksiy Mishchenko
          "64bit",
84 4e5a68f8 Oleksiy Mishchenko
          "x86_64"
85 4e5a68f8 Oleksiy Mishchenko
        ],
86 4e5a68f8 Oleksiy Mishchenko
        "hypervisor_type": "xen-pvm",
87 4e5a68f8 Oleksiy Mishchenko
        "protocol_version": 12
88 4e5a68f8 Oleksiy Mishchenko
      }
89 4e5a68f8 Oleksiy Mishchenko

90 4e5a68f8 Oleksiy Mishchenko
    """
91 9031ee8e Iustin Pop
    client = luxi.Client()
92 9031ee8e Iustin Pop
    return client.QueryClusterInfo()
93 4e5a68f8 Oleksiy Mishchenko
94 4e5a68f8 Oleksiy Mishchenko
95 4e5a68f8 Oleksiy Mishchenko
class R_2_os(baserlib.R_Generic):
96 4e5a68f8 Oleksiy Mishchenko
  """/2/os resource.
97 4e5a68f8 Oleksiy Mishchenko

98 4e5a68f8 Oleksiy Mishchenko
  """
99 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/os"
100 4e5a68f8 Oleksiy Mishchenko
101 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
102 4e5a68f8 Oleksiy Mishchenko
    """Return a list of all OSes.
103 4e5a68f8 Oleksiy Mishchenko

104 4e5a68f8 Oleksiy Mishchenko
    Can return error 500 in case of a problem.
105 4e5a68f8 Oleksiy Mishchenko

106 4e5a68f8 Oleksiy Mishchenko
    Example: ["debian-etch"]
107 4e5a68f8 Oleksiy Mishchenko

108 4e5a68f8 Oleksiy Mishchenko
    """
109 4e5a68f8 Oleksiy Mishchenko
    op = ganeti.opcodes.OpDiagnoseOS(output_fields=["name", "valid"],
110 4e5a68f8 Oleksiy Mishchenko
                                     names=[])
111 4e5a68f8 Oleksiy Mishchenko
    diagnose_data = ganeti.cli.SubmitOpCode(op)
112 4e5a68f8 Oleksiy Mishchenko
113 4e5a68f8 Oleksiy Mishchenko
    if not isinstance(diagnose_data, list):
114 4e5a68f8 Oleksiy Mishchenko
      raise http.HttpInternalServerError(message="Can't get OS list")
115 4e5a68f8 Oleksiy Mishchenko
116 4e5a68f8 Oleksiy Mishchenko
    return [row[0] for row in diagnose_data if row[1]]
117 51ee2f49 Oleksiy Mishchenko
118 10b207d4 Oleksiy Mishchenko
119 10b207d4 Oleksiy Mishchenko
class R_2_jobs(baserlib.R_Generic):
120 10b207d4 Oleksiy Mishchenko
  """/2/jobs resource.
121 10b207d4 Oleksiy Mishchenko

122 10b207d4 Oleksiy Mishchenko
  """
123 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/jobs"
124 10b207d4 Oleksiy Mishchenko
125 10b207d4 Oleksiy Mishchenko
  def GET(self):
126 10b207d4 Oleksiy Mishchenko
    """Returns a dictionary of jobs.
127 10b207d4 Oleksiy Mishchenko

128 c41eea6e Iustin Pop
    @return: a dictionary with jobs id and uri.
129 38206f3c Iustin Pop

130 10b207d4 Oleksiy Mishchenko
    """
131 10b207d4 Oleksiy Mishchenko
    fields = ["id"]
132 10b207d4 Oleksiy Mishchenko
    # Convert the list of lists to the list of ids
133 10b207d4 Oleksiy Mishchenko
    result = [job_id for [job_id] in luxi.Client().QueryJobs(None, fields)]
134 9031ee8e Iustin Pop
    return baserlib.BuildUriList(result, "/2/jobs/%s",
135 9031ee8e Iustin Pop
                                 uri_fields=("id", "uri"))
136 10b207d4 Oleksiy Mishchenko
137 10b207d4 Oleksiy Mishchenko
138 10b207d4 Oleksiy Mishchenko
class R_2_jobs_id(baserlib.R_Generic):
139 10b207d4 Oleksiy Mishchenko
  """/2/jobs/[job_id] resource.
140 10b207d4 Oleksiy Mishchenko

141 10b207d4 Oleksiy Mishchenko
  """
142 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/jobs/[job_id]"
143 10b207d4 Oleksiy Mishchenko
144 10b207d4 Oleksiy Mishchenko
  def GET(self):
145 10b207d4 Oleksiy Mishchenko
    """Returns a job status.
146 10b207d4 Oleksiy Mishchenko

147 c41eea6e Iustin Pop
    @return: a dictionary with job parameters.
148 c41eea6e Iustin Pop
        The result includes:
149 c41eea6e Iustin Pop
            - id: job ID as a number
150 c41eea6e Iustin Pop
            - status: current job status as a string
151 c41eea6e Iustin Pop
            - ops: involved OpCodes as a list of dictionaries for each
152 c41eea6e Iustin Pop
              opcodes in the job
153 c41eea6e Iustin Pop
            - opstatus: OpCodes status as a list
154 c41eea6e Iustin Pop
            - opresult: OpCodes results as a list of lists
155 38206f3c Iustin Pop

156 10b207d4 Oleksiy Mishchenko
    """
157 10b207d4 Oleksiy Mishchenko
    fields = ["id", "ops", "status", "opstatus", "opresult"]
158 10b207d4 Oleksiy Mishchenko
    job_id = self.items[0]
159 38206f3c Iustin Pop
    result = luxi.Client().QueryJobs([job_id, ], fields)[0]
160 10b207d4 Oleksiy Mishchenko
    return baserlib.MapFields(fields, result)
161 10b207d4 Oleksiy Mishchenko
162 c7f5f338 Oleksiy Mishchenko
  def DELETE(self):
163 c7f5f338 Oleksiy Mishchenko
    """Cancel not-yet-started job.
164 c7f5f338 Oleksiy Mishchenko

165 c7f5f338 Oleksiy Mishchenko
    """
166 c7f5f338 Oleksiy Mishchenko
    job_id = self.items[0]
167 c7f5f338 Oleksiy Mishchenko
    result = luxi.Client().CancelJob(job_id)
168 c7f5f338 Oleksiy Mishchenko
    return result
169 c7f5f338 Oleksiy Mishchenko
170 10b207d4 Oleksiy Mishchenko
171 10b207d4 Oleksiy Mishchenko
class R_2_nodes(baserlib.R_Generic):
172 10b207d4 Oleksiy Mishchenko
  """/2/nodes resource.
173 10b207d4 Oleksiy Mishchenko

174 10b207d4 Oleksiy Mishchenko
  """
175 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/nodes"
176 38206f3c Iustin Pop
177 10b207d4 Oleksiy Mishchenko
  def GET(self):
178 10b207d4 Oleksiy Mishchenko
    """Returns a list of all nodes.
179 38206f3c Iustin Pop

180 c41eea6e Iustin Pop
    Example::
181 10b207d4 Oleksiy Mishchenko

182 c41eea6e Iustin Pop
      [
183 10b207d4 Oleksiy Mishchenko
        {
184 10b207d4 Oleksiy Mishchenko
          "id": "node1.example.com",
185 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node1.example.com"
186 10b207d4 Oleksiy Mishchenko
        },
187 10b207d4 Oleksiy Mishchenko
        {
188 10b207d4 Oleksiy Mishchenko
          "id": "node2.example.com",
189 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node2.example.com"
190 c41eea6e Iustin Pop
        }
191 c41eea6e Iustin Pop
      ]
192 10b207d4 Oleksiy Mishchenko

193 38206f3c Iustin Pop
    If the optional 'bulk' argument is provided and set to 'true'
194 10b207d4 Oleksiy Mishchenko
    value (i.e '?bulk=1'), the output contains detailed
195 10b207d4 Oleksiy Mishchenko
    information about nodes as a list.
196 10b207d4 Oleksiy Mishchenko

197 c41eea6e Iustin Pop
    Example::
198 c41eea6e Iustin Pop

199 c41eea6e Iustin Pop
      [
200 10b207d4 Oleksiy Mishchenko
        {
201 10b207d4 Oleksiy Mishchenko
          "pinst_cnt": 1,
202 10b207d4 Oleksiy Mishchenko
          "mfree": 31280,
203 10b207d4 Oleksiy Mishchenko
          "mtotal": 32763,
204 10b207d4 Oleksiy Mishchenko
          "name": "www.example.com",
205 10b207d4 Oleksiy Mishchenko
          "tags": [],
206 10b207d4 Oleksiy Mishchenko
          "mnode": 512,
207 10b207d4 Oleksiy Mishchenko
          "dtotal": 5246208,
208 10b207d4 Oleksiy Mishchenko
          "sinst_cnt": 2,
209 9031ee8e Iustin Pop
          "dfree": 5171712,
210 9031ee8e Iustin Pop
          "offline": false
211 10b207d4 Oleksiy Mishchenko
        },
212 10b207d4 Oleksiy Mishchenko
        ...
213 c41eea6e Iustin Pop
      ]
214 c41eea6e Iustin Pop

215 c41eea6e Iustin Pop
    @return: a dictionary with 'name' and 'uri' keys for each of them
216 10b207d4 Oleksiy Mishchenko

217 10b207d4 Oleksiy Mishchenko
    """
218 a0dcf7c2 Oleksiy Mishchenko
    client = luxi.Client()
219 38206f3c Iustin Pop
220 3d103742 Iustin Pop
    if self.useBulk():
221 9031ee8e Iustin Pop
      bulkdata = client.QueryNodes([], N_FIELDS, False)
222 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, N_FIELDS)
223 9031ee8e Iustin Pop
    else:
224 9031ee8e Iustin Pop
      nodesdata = client.QueryNodes([], ["name"], False)
225 9031ee8e Iustin Pop
      nodeslist = [row[0] for row in nodesdata]
226 9031ee8e Iustin Pop
      return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
227 9031ee8e Iustin Pop
                                   uri_fields=("id", "uri"))
228 441e7cfd Oleksiy Mishchenko
229 441e7cfd Oleksiy Mishchenko
230 4e5a68f8 Oleksiy Mishchenko
class R_2_nodes_name(baserlib.R_Generic):
231 4e5a68f8 Oleksiy Mishchenko
  """/2/nodes/[node_name] resources.
232 028c6b76 Oleksiy Mishchenko

233 028c6b76 Oleksiy Mishchenko
  """
234 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/nodes/[node_name]"
235 4e5a68f8 Oleksiy Mishchenko
236 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
237 4e5a68f8 Oleksiy Mishchenko
    """Send information about a node.
238 4e5a68f8 Oleksiy Mishchenko

239 4e5a68f8 Oleksiy Mishchenko
    """
240 4e5a68f8 Oleksiy Mishchenko
    node_name = self.items[0]
241 9031ee8e Iustin Pop
    client = luxi.Client()
242 9031ee8e Iustin Pop
    result = client.QueryNodes(names=[node_name], fields=N_FIELDS,
243 3d103742 Iustin Pop
                               use_locking=self.useLocking())
244 4e5a68f8 Oleksiy Mishchenko
245 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(N_FIELDS, result[0])
246 028c6b76 Oleksiy Mishchenko
247 028c6b76 Oleksiy Mishchenko
248 441e7cfd Oleksiy Mishchenko
class R_2_instances(baserlib.R_Generic):
249 441e7cfd Oleksiy Mishchenko
  """/2/instances resource.
250 441e7cfd Oleksiy Mishchenko

251 441e7cfd Oleksiy Mishchenko
  """
252 441e7cfd Oleksiy Mishchenko
  DOC_URI = "/2/instances"
253 441e7cfd Oleksiy Mishchenko
254 441e7cfd Oleksiy Mishchenko
  def GET(self):
255 441e7cfd Oleksiy Mishchenko
    """Returns a list of all available instances.
256 441e7cfd Oleksiy Mishchenko

257 441e7cfd Oleksiy Mishchenko

258 c41eea6e Iustin Pop
    Example::
259 c41eea6e Iustin Pop

260 c41eea6e Iustin Pop
      [
261 441e7cfd Oleksiy Mishchenko
        {
262 441e7cfd Oleksiy Mishchenko
          "name": "web.example.com",
263 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/web.example.com"
264 441e7cfd Oleksiy Mishchenko
        },
265 441e7cfd Oleksiy Mishchenko
        {
266 441e7cfd Oleksiy Mishchenko
          "name": "mail.example.com",
267 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/mail.example.com"
268 c41eea6e Iustin Pop
        }
269 c41eea6e Iustin Pop
      ]
270 441e7cfd Oleksiy Mishchenko

271 441e7cfd Oleksiy Mishchenko
    If the optional 'bulk' argument is provided and set to 'true'
272 441e7cfd Oleksiy Mishchenko
    value (i.e '?bulk=1'), the output contains detailed
273 441e7cfd Oleksiy Mishchenko
    information about instances as a list.
274 441e7cfd Oleksiy Mishchenko

275 c41eea6e Iustin Pop
    Example::
276 c41eea6e Iustin Pop

277 c41eea6e Iustin Pop
      [
278 441e7cfd Oleksiy Mishchenko
        {
279 441e7cfd Oleksiy Mishchenko
           "status": "running",
280 441e7cfd Oleksiy Mishchenko
           "bridge": "xen-br0",
281 441e7cfd Oleksiy Mishchenko
           "name": "web.example.com",
282 441e7cfd Oleksiy Mishchenko
           "tags": ["tag1", "tag2"],
283 441e7cfd Oleksiy Mishchenko
           "admin_ram": 512,
284 441e7cfd Oleksiy Mishchenko
           "sda_size": 20480,
285 441e7cfd Oleksiy Mishchenko
           "pnode": "node1.example.com",
286 441e7cfd Oleksiy Mishchenko
           "mac": "01:23:45:67:89:01",
287 441e7cfd Oleksiy Mishchenko
           "sdb_size": 4096,
288 441e7cfd Oleksiy Mishchenko
           "snodes": ["node2.example.com"],
289 441e7cfd Oleksiy Mishchenko
           "disk_template": "drbd",
290 441e7cfd Oleksiy Mishchenko
           "ip": null,
291 441e7cfd Oleksiy Mishchenko
           "admin_state": true,
292 441e7cfd Oleksiy Mishchenko
           "os": "debian-etch",
293 441e7cfd Oleksiy Mishchenko
           "vcpus": 2,
294 441e7cfd Oleksiy Mishchenko
           "oper_state": true
295 441e7cfd Oleksiy Mishchenko
        },
296 441e7cfd Oleksiy Mishchenko
        ...
297 c41eea6e Iustin Pop
      ]
298 c41eea6e Iustin Pop

299 c41eea6e Iustin Pop
    @returns: a dictionary with 'name' and 'uri' keys for each of them.
300 441e7cfd Oleksiy Mishchenko

301 441e7cfd Oleksiy Mishchenko
    """
302 a0dcf7c2 Oleksiy Mishchenko
    client = luxi.Client()
303 441e7cfd Oleksiy Mishchenko
304 3d103742 Iustin Pop
    use_locking = self.useLocking()
305 3d103742 Iustin Pop
    if self.useBulk():
306 3d103742 Iustin Pop
      bulkdata = client.QueryInstances([], I_FIELDS, use_locking)
307 a0dcf7c2 Oleksiy Mishchenko
      return baserlib.MapBulkFields(bulkdata, I_FIELDS)
308 441e7cfd Oleksiy Mishchenko
    else:
309 3d103742 Iustin Pop
      instancesdata = client.QueryInstances([], ["name"], use_locking)
310 9031ee8e Iustin Pop
      instanceslist = [row[0] for row in instancesdata]
311 441e7cfd Oleksiy Mishchenko
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
312 441e7cfd Oleksiy Mishchenko
                                   uri_fields=("id", "uri"))
313 441e7cfd Oleksiy Mishchenko
314 21f04e5e Oleksiy Mishchenko
  def POST(self):
315 2f7635f4 Oleksiy Mishchenko
    """Create an instance.
316 2f7635f4 Oleksiy Mishchenko

317 c41eea6e Iustin Pop
    @returns: a job id
318 2f7635f4 Oleksiy Mishchenko

319 2f7635f4 Oleksiy Mishchenko
    """
320 212fa3a7 Oleksiy Mishchenko
    opts = self.req.request_post_data
321 2f7635f4 Oleksiy Mishchenko
322 d50b3059 Oleksiy Mishchenko
    beparams = baserlib.MakeParamsDict(opts, constants.BES_PARAMETERS)
323 d50b3059 Oleksiy Mishchenko
    hvparams = baserlib.MakeParamsDict(opts, constants.HVS_PARAMETERS)
324 2f7635f4 Oleksiy Mishchenko
325 2f7635f4 Oleksiy Mishchenko
    op = ganeti.opcodes.OpCreateInstance(
326 2f7635f4 Oleksiy Mishchenko
        instance_name=opts.get('name'),
327 2f7635f4 Oleksiy Mishchenko
        disk_size=opts.get('size', 20 * 1024),
328 2f7635f4 Oleksiy Mishchenko
        swap_size=opts.get('swap', 4 * 1024),
329 2f7635f4 Oleksiy Mishchenko
        disk_template=opts.get('disk_template', None),
330 2f7635f4 Oleksiy Mishchenko
        mode=constants.INSTANCE_CREATE,
331 2f7635f4 Oleksiy Mishchenko
        os_type=opts.get('os'),
332 2f7635f4 Oleksiy Mishchenko
        pnode=opts.get('pnode'),
333 2f7635f4 Oleksiy Mishchenko
        snode=opts.get('snode'),
334 2f7635f4 Oleksiy Mishchenko
        ip=opts.get('ip', 'none'),
335 2f7635f4 Oleksiy Mishchenko
        bridge=opts.get('bridge', None),
336 2f7635f4 Oleksiy Mishchenko
        start=opts.get('start', True),
337 2f7635f4 Oleksiy Mishchenko
        ip_check=opts.get('ip_check', True),
338 2f7635f4 Oleksiy Mishchenko
        wait_for_sync=opts.get('wait_for_sync', True),
339 2f7635f4 Oleksiy Mishchenko
        mac=opts.get('mac', 'auto'),
340 2f7635f4 Oleksiy Mishchenko
        hypervisor=opts.get('hypervisor', None),
341 d50b3059 Oleksiy Mishchenko
        hvparams=hvparams,
342 2f7635f4 Oleksiy Mishchenko
        beparams=beparams,
343 2f7635f4 Oleksiy Mishchenko
        iallocator=opts.get('iallocator', None),
344 2f7635f4 Oleksiy Mishchenko
        file_storage_dir=opts.get('file_storage_dir', None),
345 2f7635f4 Oleksiy Mishchenko
        file_driver=opts.get('file_driver', 'loop'),
346 2f7635f4 Oleksiy Mishchenko
        )
347 2f7635f4 Oleksiy Mishchenko
348 2f7635f4 Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
349 2f7635f4 Oleksiy Mishchenko
    return job_id
350 2f7635f4 Oleksiy Mishchenko
351 441e7cfd Oleksiy Mishchenko
352 4e5a68f8 Oleksiy Mishchenko
class R_2_instances_name(baserlib.R_Generic):
353 4e5a68f8 Oleksiy Mishchenko
  """/2/instances/[instance_name] resources.
354 028c6b76 Oleksiy Mishchenko

355 028c6b76 Oleksiy Mishchenko
  """
356 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]"
357 4e5a68f8 Oleksiy Mishchenko
358 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
359 4e5a68f8 Oleksiy Mishchenko
    """Send information about an instance.
360 4e5a68f8 Oleksiy Mishchenko

361 4e5a68f8 Oleksiy Mishchenko
    """
362 9031ee8e Iustin Pop
    client = luxi.Client()
363 4e5a68f8 Oleksiy Mishchenko
    instance_name = self.items[0]
364 9031ee8e Iustin Pop
    result = client.QueryInstances(names=[instance_name], fields=I_FIELDS,
365 3d103742 Iustin Pop
                                   use_locking=self.useLocking())
366 4e5a68f8 Oleksiy Mishchenko
367 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(I_FIELDS, result[0])
368 028c6b76 Oleksiy Mishchenko
369 028c6b76 Oleksiy Mishchenko
370 2276aa29 Oleksiy Mishchenko
class R_2_instances_name_reboot(baserlib.R_Generic):
371 2276aa29 Oleksiy Mishchenko
  """/2/instances/[instance_name]/reboot resource.
372 2276aa29 Oleksiy Mishchenko

373 2276aa29 Oleksiy Mishchenko
  Implements an instance reboot.
374 2276aa29 Oleksiy Mishchenko

375 2276aa29 Oleksiy Mishchenko
  """
376 2276aa29 Oleksiy Mishchenko
377 2276aa29 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/reboot"
378 2276aa29 Oleksiy Mishchenko
379 21f04e5e Oleksiy Mishchenko
  def POST(self):
380 2276aa29 Oleksiy Mishchenko
    """Reboot an instance.
381 2276aa29 Oleksiy Mishchenko

382 0c55c24b Oleksiy Mishchenko
    The URI takes type=[hard|soft|full] and
383 0c55c24b Oleksiy Mishchenko
    ignore_secondaries=[False|True] parameters.
384 0c55c24b Oleksiy Mishchenko

385 2276aa29 Oleksiy Mishchenko
    """
386 2276aa29 Oleksiy Mishchenko
    instance_name = self.items[0]
387 0c55c24b Oleksiy Mishchenko
    reboot_type = self.queryargs.get('type',
388 0c55c24b Oleksiy Mishchenko
                                     [constants.INSTANCE_REBOOT_HARD])[0]
389 0c55c24b Oleksiy Mishchenko
    ignore_secondaries = bool(self.queryargs.get('ignore_secondaries',
390 0c55c24b Oleksiy Mishchenko
                                                 [False])[0])
391 2276aa29 Oleksiy Mishchenko
    op = ganeti.opcodes.OpRebootInstance(
392 2276aa29 Oleksiy Mishchenko
        instance_name=instance_name,
393 2276aa29 Oleksiy Mishchenko
        reboot_type=reboot_type,
394 2276aa29 Oleksiy Mishchenko
        ignore_secondaries=ignore_secondaries)
395 2276aa29 Oleksiy Mishchenko
396 2276aa29 Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
397 2276aa29 Oleksiy Mishchenko
398 2276aa29 Oleksiy Mishchenko
    return job_id
399 2276aa29 Oleksiy Mishchenko
400 2276aa29 Oleksiy Mishchenko
401 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_startup(baserlib.R_Generic):
402 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/startup resource.
403 0c55c24b Oleksiy Mishchenko

404 0c55c24b Oleksiy Mishchenko
  Implements an instance startup.
405 0c55c24b Oleksiy Mishchenko

406 0c55c24b Oleksiy Mishchenko
  """
407 0c55c24b Oleksiy Mishchenko
408 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/startup"
409 0c55c24b Oleksiy Mishchenko
410 21f04e5e Oleksiy Mishchenko
  def PUT(self):
411 0c55c24b Oleksiy Mishchenko
    """Startup an instance.
412 0c55c24b Oleksiy Mishchenko

413 c41eea6e Iustin Pop
    The URI takes force=[False|True] parameter to start the instance
414 c41eea6e Iustin Pop
    if even if secondary disks are failing.
415 0c55c24b Oleksiy Mishchenko

416 0c55c24b Oleksiy Mishchenko
    """
417 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
418 0c55c24b Oleksiy Mishchenko
    force_startup = bool(self.queryargs.get('force', [False])[0])
419 0c55c24b Oleksiy Mishchenko
    op = ganeti.opcodes.OpStartupInstance(instance_name=instance_name,
420 0c55c24b Oleksiy Mishchenko
                                          force=force_startup)
421 0c55c24b Oleksiy Mishchenko
422 0c55c24b Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
423 0c55c24b Oleksiy Mishchenko
424 0c55c24b Oleksiy Mishchenko
    return job_id
425 0c55c24b Oleksiy Mishchenko
426 0c55c24b Oleksiy Mishchenko
427 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_shutdown(baserlib.R_Generic):
428 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/shutdown resource.
429 0c55c24b Oleksiy Mishchenko

430 0c55c24b Oleksiy Mishchenko
  Implements an instance shutdown.
431 0c55c24b Oleksiy Mishchenko

432 0c55c24b Oleksiy Mishchenko
  """
433 0c55c24b Oleksiy Mishchenko
434 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/shutdown"
435 0c55c24b Oleksiy Mishchenko
436 21f04e5e Oleksiy Mishchenko
  def PUT(self):
437 0c55c24b Oleksiy Mishchenko
    """Shutdown an instance.
438 0c55c24b Oleksiy Mishchenko

439 0c55c24b Oleksiy Mishchenko
    """
440 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
441 0c55c24b Oleksiy Mishchenko
    op = ganeti.opcodes.OpShutdownInstance(instance_name=instance_name)
442 0c55c24b Oleksiy Mishchenko
443 0c55c24b Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
444 0c55c24b Oleksiy Mishchenko
445 0c55c24b Oleksiy Mishchenko
    return job_id
446 0c55c24b Oleksiy Mishchenko
447 0c55c24b Oleksiy Mishchenko
448 18cb43a2 Oleksiy Mishchenko
class _R_Tags(baserlib.R_Generic):
449 18cb43a2 Oleksiy Mishchenko
  """ Quasiclass for tagging resources
450 441e7cfd Oleksiy Mishchenko

451 18cb43a2 Oleksiy Mishchenko
  Manages tags. Inheriting this class you suppose to define DOC_URI and
452 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL for it.
453 441e7cfd Oleksiy Mishchenko

454 441e7cfd Oleksiy Mishchenko
  """
455 18cb43a2 Oleksiy Mishchenko
456 18cb43a2 Oleksiy Mishchenko
  def __init__(self, items, queryargs, req):
457 18cb43a2 Oleksiy Mishchenko
    """A tag resource constructor.
458 18cb43a2 Oleksiy Mishchenko

459 18cb43a2 Oleksiy Mishchenko
    We have to override the default to sort out cluster naming case.
460 18cb43a2 Oleksiy Mishchenko

461 18cb43a2 Oleksiy Mishchenko
    """
462 18cb43a2 Oleksiy Mishchenko
    baserlib.R_Generic.__init__(self, items, queryargs, req)
463 18cb43a2 Oleksiy Mishchenko
464 18cb43a2 Oleksiy Mishchenko
    if self.TAG_LEVEL != constants.TAG_CLUSTER:
465 18cb43a2 Oleksiy Mishchenko
      self.name = items[0]
466 18cb43a2 Oleksiy Mishchenko
    else:
467 18cb43a2 Oleksiy Mishchenko
      self.name = ""
468 441e7cfd Oleksiy Mishchenko
469 441e7cfd Oleksiy Mishchenko
  def GET(self):
470 18cb43a2 Oleksiy Mishchenko
    """Returns a list of tags.
471 441e7cfd Oleksiy Mishchenko

472 441e7cfd Oleksiy Mishchenko
    Example: ["tag1", "tag2", "tag3"]
473 441e7cfd Oleksiy Mishchenko

474 441e7cfd Oleksiy Mishchenko
    """
475 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_GET(self.TAG_LEVEL, name=self.name)
476 441e7cfd Oleksiy Mishchenko
477 21f04e5e Oleksiy Mishchenko
  def PUT(self):
478 18cb43a2 Oleksiy Mishchenko
    """Add a set of tags.
479 441e7cfd Oleksiy Mishchenko

480 c41eea6e Iustin Pop
    The request as a list of strings should be PUT to this URI. And
481 c41eea6e Iustin Pop
    you'll have back a job id.
482 441e7cfd Oleksiy Mishchenko

483 441e7cfd Oleksiy Mishchenko
    """
484 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_PUT(self.TAG_LEVEL,
485 18cb43a2 Oleksiy Mishchenko
                              self.req.request_post_data, name=self.name)
486 15fd9fd5 Oleksiy Mishchenko
487 15fd9fd5 Oleksiy Mishchenko
  def DELETE(self):
488 15fd9fd5 Oleksiy Mishchenko
    """Delete a tag.
489 15fd9fd5 Oleksiy Mishchenko

490 18cb43a2 Oleksiy Mishchenko
    In order to delete a set of tags, the DELETE
491 c41eea6e Iustin Pop
    request should be addressed to URI like:
492 18cb43a2 Oleksiy Mishchenko
    /tags?tag=[tag]&tag=[tag]
493 15fd9fd5 Oleksiy Mishchenko

494 15fd9fd5 Oleksiy Mishchenko
    """
495 15fd9fd5 Oleksiy Mishchenko
    if 'tag' not in self.queryargs:
496 18cb43a2 Oleksiy Mishchenko
      # no we not gonna delete all tags
497 84f2756e Michael Hanselmann
      raise http.HttpNotImplemented()
498 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_DELETE(self.TAG_LEVEL,
499 15fd9fd5 Oleksiy Mishchenko
                                 self.queryargs['tag'],
500 18cb43a2 Oleksiy Mishchenko
                                 name=self.name)
501 18cb43a2 Oleksiy Mishchenko
502 18cb43a2 Oleksiy Mishchenko
503 18cb43a2 Oleksiy Mishchenko
class R_2_instances_name_tags(_R_Tags):
504 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/[instance_name]/tags resource.
505 18cb43a2 Oleksiy Mishchenko

506 18cb43a2 Oleksiy Mishchenko
  Manages per-instance tags.
507 18cb43a2 Oleksiy Mishchenko

508 18cb43a2 Oleksiy Mishchenko
  """
509 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/tags"
510 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_INSTANCE
511 18cb43a2 Oleksiy Mishchenko
512 18cb43a2 Oleksiy Mishchenko
513 18cb43a2 Oleksiy Mishchenko
class R_2_nodes_name_tags(_R_Tags):
514 18cb43a2 Oleksiy Mishchenko
  """ /2/nodes/[node_name]/tags resource.
515 18cb43a2 Oleksiy Mishchenko

516 18cb43a2 Oleksiy Mishchenko
  Manages per-node tags.
517 18cb43a2 Oleksiy Mishchenko

518 18cb43a2 Oleksiy Mishchenko
  """
519 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/nodes/[node_name]/tags"
520 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_NODE
521 18cb43a2 Oleksiy Mishchenko
522 18cb43a2 Oleksiy Mishchenko
523 18cb43a2 Oleksiy Mishchenko
class R_2_tags(_R_Tags):
524 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/tags resource.
525 18cb43a2 Oleksiy Mishchenko

526 18cb43a2 Oleksiy Mishchenko
  Manages cluster tags.
527 18cb43a2 Oleksiy Mishchenko

528 18cb43a2 Oleksiy Mishchenko
  """
529 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/tags"
530 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_CLUSTER