Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / rlib2.py @ 212fa3a7

History | View | Annotate | Download (7.8 kB)

1
#
2
#
3

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

    
21

    
22
"""Remote API version 2 baserlib.library.
23

24
"""
25

    
26
import ganeti.opcodes
27
from ganeti import http
28
from ganeti import luxi
29
from ganeti import constants
30
from ganeti.rapi import baserlib
31

    
32
from ganeti.rapi.rlib1 import I_FIELDS, N_FIELDS
33

    
34

    
35
class R_2_jobs(baserlib.R_Generic):
36
  """/2/jobs resource.
37

38
  """
39
  DOC_URI = "/2/jobs"
40

    
41
  def GET(self):
42
    """Returns a dictionary of jobs.
43

44
    Returns:
45
      A dictionary with jobs id and uri.
46

47
    """
48
    fields = ["id"]
49
    # Convert the list of lists to the list of ids
50
    result = [job_id for [job_id] in luxi.Client().QueryJobs(None, fields)]
51
    return baserlib.BuildUriList(result, "/2/jobs/%s", uri_fields=("id", "uri"))
52

    
53

    
54
class R_2_jobs_id(baserlib.R_Generic):
55
  """/2/jobs/[job_id] resource.
56

57
  """
58
  DOC_URI = "/2/jobs/[job_id]"
59

    
60
  def GET(self):
61
    """Returns a job status.
62

63
    Returns:
64
      A dictionary with job parameters.
65

66
    The result includes:
67
      id - job ID as a number
68
      status - current job status as a string
69
      ops - involved OpCodes as a list of dictionaries for each opcodes in
70
        the job
71
      opstatus - OpCodes status as a list
72
      opresult - OpCodes results as a list of lists
73

74
    """
75
    fields = ["id", "ops", "status", "opstatus", "opresult"]
76
    job_id = self.items[0]
77
    result = luxi.Client().QueryJobs([job_id, ], fields)[0]
78
    return baserlib.MapFields(fields, result)
79

    
80

    
81
class R_2_nodes(baserlib.R_Generic):
82
  """/2/nodes resource.
83

84
  """
85
  DOC_URI = "/2/nodes"
86

    
87
  def GET(self):
88
    """Returns a list of all nodes.
89

90
    Returns:
91
      A dictionary with 'name' and 'uri' keys for each of them.
92

93
    Example: [
94
        {
95
          "id": "node1.example.com",
96
          "uri": "\/instances\/node1.example.com"
97
        },
98
        {
99
          "id": "node2.example.com",
100
          "uri": "\/instances\/node2.example.com"
101
        }]
102

103
    If the optional 'bulk' argument is provided and set to 'true'
104
    value (i.e '?bulk=1'), the output contains detailed
105
    information about nodes as a list.
106

107
    Example: [
108
        {
109
          "pinst_cnt": 1,
110
          "mfree": 31280,
111
          "mtotal": 32763,
112
          "name": "www.example.com",
113
          "tags": [],
114
          "mnode": 512,
115
          "dtotal": 5246208,
116
          "sinst_cnt": 2,
117
          "dfree": 5171712
118
        },
119
        ...
120
    ]
121

122
    """
123
    op = ganeti.opcodes.OpQueryNodes(output_fields=["name"], names=[])
124
    nodeslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
125

    
126
    if 'bulk' in self.queryargs:
127
      op = ganeti.opcodes.OpQueryNodes(output_fields=N_FIELDS,
128
                                       names=nodeslist)
129
      result = ganeti.cli.SubmitOpCode(op)
130
      return baserlib.MapBulkFields(result, N_FIELDS)
131

    
132
    return baserlib.BuildUriList(nodeslist, "/2/nodes/%s",
133
                                 uri_fields=("id", "uri"))
134

    
135

    
136
class R_2_instances(baserlib.R_Generic):
137
  """/2/instances resource.
138

139
  """
140
  DOC_URI = "/2/instances"
141

    
142
  def GET(self):
143
    """Returns a list of all available instances.
144

145
    Returns:
146
       A dictionary with 'name' and 'uri' keys for each of them.
147

148
    Example: [
149
        {
150
          "name": "web.example.com",
151
          "uri": "\/instances\/web.example.com"
152
        },
153
        {
154
          "name": "mail.example.com",
155
          "uri": "\/instances\/mail.example.com"
156
        }]
157

158
    If the optional 'bulk' argument is provided and set to 'true'
159
    value (i.e '?bulk=1'), the output contains detailed
160
    information about instances as a list.
161

162
    Example: [
163
        {
164
           "status": "running",
165
           "bridge": "xen-br0",
166
           "name": "web.example.com",
167
           "tags": ["tag1", "tag2"],
168
           "admin_ram": 512,
169
           "sda_size": 20480,
170
           "pnode": "node1.example.com",
171
           "mac": "01:23:45:67:89:01",
172
           "sdb_size": 4096,
173
           "snodes": ["node2.example.com"],
174
           "disk_template": "drbd",
175
           "ip": null,
176
           "admin_state": true,
177
           "os": "debian-etch",
178
           "vcpus": 2,
179
           "oper_state": true
180
        },
181
        ...
182
    ]
183

184
    """
185
    op = ganeti.opcodes.OpQueryInstances(output_fields=["name"], names=[])
186
    instanceslist = baserlib.ExtractField(ganeti.cli.SubmitOpCode(op), 0)
187

    
188
    if 'bulk' in self.queryargs:
189
      op = ganeti.opcodes.OpQueryInstances(output_fields=I_FIELDS,
190
                                           names=instanceslist)
191
      result = ganeti.cli.SubmitOpCode(op)
192
      return baserlib.MapBulkFields(result, I_FIELDS)
193

    
194

    
195
    else:
196
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
197
                                   uri_fields=("id", "uri"))
198

    
199
  def PUT(self):
200
    """Create an instance.
201

202
    Returns:
203
      A job id.
204

205
    """
206
    opts = self.req.request_post_data
207

    
208
    # beparams
209
    mem = opts.get('mem', None)
210
    vcpus = opts.get('vcpus', None)
211
    auto_balance = opts.get('auto_balance', None)
212

    
213
    beparams = {}
214

    
215
    for key, const in [(mem, constants.BE_MEMORY),
216
                       (vcpus, constants.BE_VCPUS),
217
                       (auto_balance, constants.BE_AUTO_BALANCE)]:
218
      if key is not None:
219
        beparams[const] = key
220

    
221
    op = ganeti.opcodes.OpCreateInstance(
222
        instance_name=opts.get('name'),
223
        disk_size=opts.get('size', 20 * 1024),
224
        swap_size=opts.get('swap', 4 * 1024),
225
        disk_template=opts.get('disk_template', None),
226
        mode=constants.INSTANCE_CREATE,
227
        os_type=opts.get('os'),
228
        pnode=opts.get('pnode'),
229
        snode=opts.get('snode'),
230
        ip=opts.get('ip', 'none'),
231
        bridge=opts.get('bridge', None),
232
        start=opts.get('start', True),
233
        ip_check=opts.get('ip_check', True),
234
        wait_for_sync=opts.get('wait_for_sync', True),
235
        mac=opts.get('mac', 'auto'),
236
        hypervisor=opts.get('hypervisor', None),
237
        hvparams=opts.get('hvparams', {}),
238
        beparams=beparams,
239
        iallocator=opts.get('iallocator', None),
240
        file_storage_dir=opts.get('file_storage_dir', None),
241
        file_driver=opts.get('file_driver', 'loop'),
242
        )
243

    
244
    job_id = ganeti.cli.SendJob([op])
245
    return job_id
246

    
247

    
248
class R_2_instances_name_tags(baserlib.R_Generic):
249
  """/2/instances/[instance_name]/tags resource.
250

251
  Manages per-instance tags.
252

253
  """
254
  DOC_URI = "/2/instances/[instance_name]/tags"
255

    
256
  def GET(self):
257
    """Returns a list of instance tags.
258

259
    Example: ["tag1", "tag2", "tag3"]
260

261
    """
262
    return baserlib._Tags_GET(constants.TAG_INSTANCE, name=self.items[0])
263

    
264
  def POST(self):
265
    """Add a set of tags to the instance.
266

267
    The reqest as a list of strings should be POST to this URI. And you'll have
268
    back a job id.
269

270
    """
271
    return baserlib._Tags_POST(constants.TAG_INSTANCE,
272
                               self.post_data, name=self.items[0])
273

    
274
  def DELETE(self):
275
    """Delete a tag.
276

277
    In order to delete a set of tags from a instance, DELETE request should be
278
    addressed to URI like: /2/instances/[instance_name]/tags?tag=[tag]&tag=[tag]
279

280
    """
281
    if 'tag' not in self.queryargs:
282
      # no we not gonna delete all tags from an instance
283
      raise http.HTTPNotImplemented()
284
    return baserlib._Tags_DELETE(constants.TAG_INSTANCE,
285
                                 self.queryargs['tag'],
286
                                 name=self.items[0])