Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib2.py @ 0105bad3

History | View | Annotate | Download (13.2 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 a5b9d725 Iustin Pop
            "beparams", "hvparams",
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 0105bad3 Iustin Pop
            "pinst_cnt", "sinst_cnt", "tags",
46 0105bad3 Iustin Pop
            "ctotal", "cnodes", "csockets",
47 0105bad3 Iustin Pop
            ]
48 4e5a68f8 Oleksiy Mishchenko
49 4e5a68f8 Oleksiy Mishchenko
50 4e5a68f8 Oleksiy Mishchenko
class R_version(baserlib.R_Generic):
51 4e5a68f8 Oleksiy Mishchenko
  """/version resource.
52 4e5a68f8 Oleksiy Mishchenko

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

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

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

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

75 4e5a68f8 Oleksiy Mishchenko
    Example::
76 4e5a68f8 Oleksiy Mishchenko

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

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

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

106 4e5a68f8 Oleksiy Mishchenko
    Can return error 500 in case of a problem.
107 4e5a68f8 Oleksiy Mishchenko

108 4e5a68f8 Oleksiy Mishchenko
    Example: ["debian-etch"]
109 4e5a68f8 Oleksiy Mishchenko

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

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

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

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

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

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

158 10b207d4 Oleksiy Mishchenko
    """
159 ee69c97f Iustin Pop
    fields = ["id", "ops", "status", "summary",
160 ee69c97f Iustin Pop
              "opstatus", "opresult", "oplog",
161 ee69c97f Iustin Pop
              "received_ts", "start_ts", "end_ts",
162 ee69c97f Iustin Pop
              ]
163 10b207d4 Oleksiy Mishchenko
    job_id = self.items[0]
164 38206f3c Iustin Pop
    result = luxi.Client().QueryJobs([job_id, ], fields)[0]
165 ee69c97f Iustin Pop
    if result is None:
166 ee69c97f Iustin Pop
      raise http.HttpNotFound()
167 10b207d4 Oleksiy Mishchenko
    return baserlib.MapFields(fields, result)
168 10b207d4 Oleksiy Mishchenko
169 c7f5f338 Oleksiy Mishchenko
  def DELETE(self):
170 c7f5f338 Oleksiy Mishchenko
    """Cancel not-yet-started job.
171 c7f5f338 Oleksiy Mishchenko

172 c7f5f338 Oleksiy Mishchenko
    """
173 c7f5f338 Oleksiy Mishchenko
    job_id = self.items[0]
174 c7f5f338 Oleksiy Mishchenko
    result = luxi.Client().CancelJob(job_id)
175 c7f5f338 Oleksiy Mishchenko
    return result
176 c7f5f338 Oleksiy Mishchenko
177 10b207d4 Oleksiy Mishchenko
178 10b207d4 Oleksiy Mishchenko
class R_2_nodes(baserlib.R_Generic):
179 10b207d4 Oleksiy Mishchenko
  """/2/nodes resource.
180 10b207d4 Oleksiy Mishchenko

181 10b207d4 Oleksiy Mishchenko
  """
182 10b207d4 Oleksiy Mishchenko
  DOC_URI = "/2/nodes"
183 38206f3c Iustin Pop
184 10b207d4 Oleksiy Mishchenko
  def GET(self):
185 10b207d4 Oleksiy Mishchenko
    """Returns a list of all nodes.
186 38206f3c Iustin Pop

187 c41eea6e Iustin Pop
    Example::
188 10b207d4 Oleksiy Mishchenko

189 c41eea6e Iustin Pop
      [
190 10b207d4 Oleksiy Mishchenko
        {
191 10b207d4 Oleksiy Mishchenko
          "id": "node1.example.com",
192 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node1.example.com"
193 10b207d4 Oleksiy Mishchenko
        },
194 10b207d4 Oleksiy Mishchenko
        {
195 10b207d4 Oleksiy Mishchenko
          "id": "node2.example.com",
196 10b207d4 Oleksiy Mishchenko
          "uri": "\/instances\/node2.example.com"
197 c41eea6e Iustin Pop
        }
198 c41eea6e Iustin Pop
      ]
199 10b207d4 Oleksiy Mishchenko

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

204 c41eea6e Iustin Pop
    Example::
205 c41eea6e Iustin Pop

206 c41eea6e Iustin Pop
      [
207 10b207d4 Oleksiy Mishchenko
        {
208 10b207d4 Oleksiy Mishchenko
          "pinst_cnt": 1,
209 10b207d4 Oleksiy Mishchenko
          "mfree": 31280,
210 10b207d4 Oleksiy Mishchenko
          "mtotal": 32763,
211 10b207d4 Oleksiy Mishchenko
          "name": "www.example.com",
212 10b207d4 Oleksiy Mishchenko
          "tags": [],
213 10b207d4 Oleksiy Mishchenko
          "mnode": 512,
214 10b207d4 Oleksiy Mishchenko
          "dtotal": 5246208,
215 10b207d4 Oleksiy Mishchenko
          "sinst_cnt": 2,
216 9031ee8e Iustin Pop
          "dfree": 5171712,
217 9031ee8e Iustin Pop
          "offline": false
218 10b207d4 Oleksiy Mishchenko
        },
219 10b207d4 Oleksiy Mishchenko
        ...
220 c41eea6e Iustin Pop
      ]
221 c41eea6e Iustin Pop

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

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

240 028c6b76 Oleksiy Mishchenko
  """
241 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/nodes/[node_name]"
242 4e5a68f8 Oleksiy Mishchenko
243 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
244 4e5a68f8 Oleksiy Mishchenko
    """Send information about a node.
245 4e5a68f8 Oleksiy Mishchenko

246 4e5a68f8 Oleksiy Mishchenko
    """
247 4e5a68f8 Oleksiy Mishchenko
    node_name = self.items[0]
248 9031ee8e Iustin Pop
    client = luxi.Client()
249 9031ee8e Iustin Pop
    result = client.QueryNodes(names=[node_name], fields=N_FIELDS,
250 3d103742 Iustin Pop
                               use_locking=self.useLocking())
251 4e5a68f8 Oleksiy Mishchenko
252 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(N_FIELDS, result[0])
253 028c6b76 Oleksiy Mishchenko
254 028c6b76 Oleksiy Mishchenko
255 441e7cfd Oleksiy Mishchenko
class R_2_instances(baserlib.R_Generic):
256 441e7cfd Oleksiy Mishchenko
  """/2/instances resource.
257 441e7cfd Oleksiy Mishchenko

258 441e7cfd Oleksiy Mishchenko
  """
259 441e7cfd Oleksiy Mishchenko
  DOC_URI = "/2/instances"
260 441e7cfd Oleksiy Mishchenko
261 441e7cfd Oleksiy Mishchenko
  def GET(self):
262 441e7cfd Oleksiy Mishchenko
    """Returns a list of all available instances.
263 441e7cfd Oleksiy Mishchenko

264 441e7cfd Oleksiy Mishchenko

265 c41eea6e Iustin Pop
    Example::
266 c41eea6e Iustin Pop

267 c41eea6e Iustin Pop
      [
268 441e7cfd Oleksiy Mishchenko
        {
269 441e7cfd Oleksiy Mishchenko
          "name": "web.example.com",
270 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/web.example.com"
271 441e7cfd Oleksiy Mishchenko
        },
272 441e7cfd Oleksiy Mishchenko
        {
273 441e7cfd Oleksiy Mishchenko
          "name": "mail.example.com",
274 441e7cfd Oleksiy Mishchenko
          "uri": "\/instances\/mail.example.com"
275 c41eea6e Iustin Pop
        }
276 c41eea6e Iustin Pop
      ]
277 441e7cfd Oleksiy Mishchenko

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

282 c41eea6e Iustin Pop
    Example::
283 c41eea6e Iustin Pop

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

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

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

324 c41eea6e Iustin Pop
    @returns: a job id
325 2f7635f4 Oleksiy Mishchenko

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

362 028c6b76 Oleksiy Mishchenko
  """
363 4e5a68f8 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]"
364 4e5a68f8 Oleksiy Mishchenko
365 4e5a68f8 Oleksiy Mishchenko
  def GET(self):
366 4e5a68f8 Oleksiy Mishchenko
    """Send information about an instance.
367 4e5a68f8 Oleksiy Mishchenko

368 4e5a68f8 Oleksiy Mishchenko
    """
369 9031ee8e Iustin Pop
    client = luxi.Client()
370 4e5a68f8 Oleksiy Mishchenko
    instance_name = self.items[0]
371 9031ee8e Iustin Pop
    result = client.QueryInstances(names=[instance_name], fields=I_FIELDS,
372 3d103742 Iustin Pop
                                   use_locking=self.useLocking())
373 4e5a68f8 Oleksiy Mishchenko
374 4e5a68f8 Oleksiy Mishchenko
    return baserlib.MapFields(I_FIELDS, result[0])
375 028c6b76 Oleksiy Mishchenko
376 028c6b76 Oleksiy Mishchenko
377 2276aa29 Oleksiy Mishchenko
class R_2_instances_name_reboot(baserlib.R_Generic):
378 2276aa29 Oleksiy Mishchenko
  """/2/instances/[instance_name]/reboot resource.
379 2276aa29 Oleksiy Mishchenko

380 2276aa29 Oleksiy Mishchenko
  Implements an instance reboot.
381 2276aa29 Oleksiy Mishchenko

382 2276aa29 Oleksiy Mishchenko
  """
383 2276aa29 Oleksiy Mishchenko
384 2276aa29 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/reboot"
385 2276aa29 Oleksiy Mishchenko
386 21f04e5e Oleksiy Mishchenko
  def POST(self):
387 2276aa29 Oleksiy Mishchenko
    """Reboot an instance.
388 2276aa29 Oleksiy Mishchenko

389 0c55c24b Oleksiy Mishchenko
    The URI takes type=[hard|soft|full] and
390 0c55c24b Oleksiy Mishchenko
    ignore_secondaries=[False|True] parameters.
391 0c55c24b Oleksiy Mishchenko

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

411 0c55c24b Oleksiy Mishchenko
  Implements an instance startup.
412 0c55c24b Oleksiy Mishchenko

413 0c55c24b Oleksiy Mishchenko
  """
414 0c55c24b Oleksiy Mishchenko
415 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/startup"
416 0c55c24b Oleksiy Mishchenko
417 21f04e5e Oleksiy Mishchenko
  def PUT(self):
418 0c55c24b Oleksiy Mishchenko
    """Startup an instance.
419 0c55c24b Oleksiy Mishchenko

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

423 0c55c24b Oleksiy Mishchenko
    """
424 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
425 0c55c24b Oleksiy Mishchenko
    force_startup = bool(self.queryargs.get('force', [False])[0])
426 0c55c24b Oleksiy Mishchenko
    op = ganeti.opcodes.OpStartupInstance(instance_name=instance_name,
427 0c55c24b Oleksiy Mishchenko
                                          force=force_startup)
428 0c55c24b Oleksiy Mishchenko
429 0c55c24b Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
430 0c55c24b Oleksiy Mishchenko
431 0c55c24b Oleksiy Mishchenko
    return job_id
432 0c55c24b Oleksiy Mishchenko
433 0c55c24b Oleksiy Mishchenko
434 0c55c24b Oleksiy Mishchenko
class R_2_instances_name_shutdown(baserlib.R_Generic):
435 0c55c24b Oleksiy Mishchenko
  """/2/instances/[instance_name]/shutdown resource.
436 0c55c24b Oleksiy Mishchenko

437 0c55c24b Oleksiy Mishchenko
  Implements an instance shutdown.
438 0c55c24b Oleksiy Mishchenko

439 0c55c24b Oleksiy Mishchenko
  """
440 0c55c24b Oleksiy Mishchenko
441 0c55c24b Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/shutdown"
442 0c55c24b Oleksiy Mishchenko
443 21f04e5e Oleksiy Mishchenko
  def PUT(self):
444 0c55c24b Oleksiy Mishchenko
    """Shutdown an instance.
445 0c55c24b Oleksiy Mishchenko

446 0c55c24b Oleksiy Mishchenko
    """
447 0c55c24b Oleksiy Mishchenko
    instance_name = self.items[0]
448 0c55c24b Oleksiy Mishchenko
    op = ganeti.opcodes.OpShutdownInstance(instance_name=instance_name)
449 0c55c24b Oleksiy Mishchenko
450 0c55c24b Oleksiy Mishchenko
    job_id = ganeti.cli.SendJob([op])
451 0c55c24b Oleksiy Mishchenko
452 0c55c24b Oleksiy Mishchenko
    return job_id
453 0c55c24b Oleksiy Mishchenko
454 0c55c24b Oleksiy Mishchenko
455 18cb43a2 Oleksiy Mishchenko
class _R_Tags(baserlib.R_Generic):
456 18cb43a2 Oleksiy Mishchenko
  """ Quasiclass for tagging resources
457 441e7cfd Oleksiy Mishchenko

458 18cb43a2 Oleksiy Mishchenko
  Manages tags. Inheriting this class you suppose to define DOC_URI and
459 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL for it.
460 441e7cfd Oleksiy Mishchenko

461 441e7cfd Oleksiy Mishchenko
  """
462 18cb43a2 Oleksiy Mishchenko
463 18cb43a2 Oleksiy Mishchenko
  def __init__(self, items, queryargs, req):
464 18cb43a2 Oleksiy Mishchenko
    """A tag resource constructor.
465 18cb43a2 Oleksiy Mishchenko

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

468 18cb43a2 Oleksiy Mishchenko
    """
469 18cb43a2 Oleksiy Mishchenko
    baserlib.R_Generic.__init__(self, items, queryargs, req)
470 18cb43a2 Oleksiy Mishchenko
471 18cb43a2 Oleksiy Mishchenko
    if self.TAG_LEVEL != constants.TAG_CLUSTER:
472 18cb43a2 Oleksiy Mishchenko
      self.name = items[0]
473 18cb43a2 Oleksiy Mishchenko
    else:
474 18cb43a2 Oleksiy Mishchenko
      self.name = ""
475 441e7cfd Oleksiy Mishchenko
476 441e7cfd Oleksiy Mishchenko
  def GET(self):
477 18cb43a2 Oleksiy Mishchenko
    """Returns a list of tags.
478 441e7cfd Oleksiy Mishchenko

479 441e7cfd Oleksiy Mishchenko
    Example: ["tag1", "tag2", "tag3"]
480 441e7cfd Oleksiy Mishchenko

481 441e7cfd Oleksiy Mishchenko
    """
482 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_GET(self.TAG_LEVEL, name=self.name)
483 441e7cfd Oleksiy Mishchenko
484 21f04e5e Oleksiy Mishchenko
  def PUT(self):
485 18cb43a2 Oleksiy Mishchenko
    """Add a set of tags.
486 441e7cfd Oleksiy Mishchenko

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

490 441e7cfd Oleksiy Mishchenko
    """
491 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_PUT(self.TAG_LEVEL,
492 18cb43a2 Oleksiy Mishchenko
                              self.req.request_post_data, name=self.name)
493 15fd9fd5 Oleksiy Mishchenko
494 15fd9fd5 Oleksiy Mishchenko
  def DELETE(self):
495 15fd9fd5 Oleksiy Mishchenko
    """Delete a tag.
496 15fd9fd5 Oleksiy Mishchenko

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

501 15fd9fd5 Oleksiy Mishchenko
    """
502 15fd9fd5 Oleksiy Mishchenko
    if 'tag' not in self.queryargs:
503 18cb43a2 Oleksiy Mishchenko
      # no we not gonna delete all tags
504 84f2756e Michael Hanselmann
      raise http.HttpNotImplemented()
505 18cb43a2 Oleksiy Mishchenko
    return baserlib._Tags_DELETE(self.TAG_LEVEL,
506 15fd9fd5 Oleksiy Mishchenko
                                 self.queryargs['tag'],
507 18cb43a2 Oleksiy Mishchenko
                                 name=self.name)
508 18cb43a2 Oleksiy Mishchenko
509 18cb43a2 Oleksiy Mishchenko
510 18cb43a2 Oleksiy Mishchenko
class R_2_instances_name_tags(_R_Tags):
511 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/[instance_name]/tags resource.
512 18cb43a2 Oleksiy Mishchenko

513 18cb43a2 Oleksiy Mishchenko
  Manages per-instance tags.
514 18cb43a2 Oleksiy Mishchenko

515 18cb43a2 Oleksiy Mishchenko
  """
516 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/instances/[instance_name]/tags"
517 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_INSTANCE
518 18cb43a2 Oleksiy Mishchenko
519 18cb43a2 Oleksiy Mishchenko
520 18cb43a2 Oleksiy Mishchenko
class R_2_nodes_name_tags(_R_Tags):
521 18cb43a2 Oleksiy Mishchenko
  """ /2/nodes/[node_name]/tags resource.
522 18cb43a2 Oleksiy Mishchenko

523 18cb43a2 Oleksiy Mishchenko
  Manages per-node tags.
524 18cb43a2 Oleksiy Mishchenko

525 18cb43a2 Oleksiy Mishchenko
  """
526 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/nodes/[node_name]/tags"
527 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_NODE
528 18cb43a2 Oleksiy Mishchenko
529 18cb43a2 Oleksiy Mishchenko
530 18cb43a2 Oleksiy Mishchenko
class R_2_tags(_R_Tags):
531 18cb43a2 Oleksiy Mishchenko
  """ /2/instances/tags resource.
532 18cb43a2 Oleksiy Mishchenko

533 18cb43a2 Oleksiy Mishchenko
  Manages cluster tags.
534 18cb43a2 Oleksiy Mishchenko

535 18cb43a2 Oleksiy Mishchenko
  """
536 18cb43a2 Oleksiy Mishchenko
  DOC_URI = "/2/tags"
537 18cb43a2 Oleksiy Mishchenko
  TAG_LEVEL = constants.TAG_CLUSTER