Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ cdb08f44

History | View | Annotate | Download (15.6 kB)

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

24 a8083063 Iustin Pop
"""
25 a8083063 Iustin Pop
26 a8083063 Iustin Pop
# pylint: disable-msg=C0103
27 a8083063 Iustin Pop
28 a8083063 Iustin Pop
import os
29 81010134 Iustin Pop
import socket
30 81010134 Iustin Pop
import httplib
31 a8083063 Iustin Pop
32 81010134 Iustin Pop
import simplejson
33 a8083063 Iustin Pop
34 a8083063 Iustin Pop
from ganeti import logger
35 a8083063 Iustin Pop
from ganeti import utils
36 a8083063 Iustin Pop
from ganeti import errors
37 a8083063 Iustin Pop
from ganeti import constants
38 a8083063 Iustin Pop
from ganeti import objects
39 a8083063 Iustin Pop
from ganeti import ssconf
40 a8083063 Iustin Pop
41 a8083063 Iustin Pop
class NodeController:
42 a8083063 Iustin Pop
  """Node-handling class.
43 a8083063 Iustin Pop

44 a8083063 Iustin Pop
  For each node that we speak with, we create an instance of this
45 a8083063 Iustin Pop
  class, so that we have a safe place to store the details of this
46 a8083063 Iustin Pop
  individual call.
47 a8083063 Iustin Pop

48 a8083063 Iustin Pop
  """
49 a8083063 Iustin Pop
  def __init__(self, parent, node):
50 a8083063 Iustin Pop
    self.parent = parent
51 a8083063 Iustin Pop
    self.node = node
52 81010134 Iustin Pop
    self.failed = False
53 a8083063 Iustin Pop
54 81010134 Iustin Pop
    self.http_conn = hc = httplib.HTTPConnection(node, self.parent.port)
55 a8083063 Iustin Pop
    try:
56 81010134 Iustin Pop
      hc.connect()
57 81010134 Iustin Pop
      hc.putrequest('PUT', "/%s" % self.parent.procedure,
58 81010134 Iustin Pop
                    skip_accept_encoding=True)
59 81010134 Iustin Pop
      hc.putheader('Content-Length', str(len(parent.body)))
60 81010134 Iustin Pop
      hc.endheaders()
61 81010134 Iustin Pop
      hc.send(parent.body)
62 81010134 Iustin Pop
    except socket.error, err:
63 81010134 Iustin Pop
      logger.Error("Error connecting to %s: %s" % (node, str(err)))
64 81010134 Iustin Pop
      self.failed = True
65 81010134 Iustin Pop
66 81010134 Iustin Pop
  def get_response(self):
67 81010134 Iustin Pop
    """Try to process the response from the node.
68 a8083063 Iustin Pop

69 a8083063 Iustin Pop
    """
70 81010134 Iustin Pop
    if self.failed:
71 81010134 Iustin Pop
      # we already failed in connect
72 a8083063 Iustin Pop
      return False
73 81010134 Iustin Pop
    resp = self.http_conn.getresponse()
74 81010134 Iustin Pop
    if resp.status != 200:
75 a8083063 Iustin Pop
      return False
76 81010134 Iustin Pop
    try:
77 81010134 Iustin Pop
      length = int(resp.getheader('Content-Length', '0'))
78 81010134 Iustin Pop
    except ValueError:
79 81010134 Iustin Pop
      return False
80 81010134 Iustin Pop
    if not length:
81 81010134 Iustin Pop
      logger.Error("Zero-length reply from %s" % self.node)
82 81010134 Iustin Pop
      return False
83 81010134 Iustin Pop
    payload = resp.read(length)
84 81010134 Iustin Pop
    unload = simplejson.loads(payload)
85 81010134 Iustin Pop
    return unload
86 a8083063 Iustin Pop
87 a8083063 Iustin Pop
88 a8083063 Iustin Pop
class Client:
89 a8083063 Iustin Pop
  """RPC Client class.
90 a8083063 Iustin Pop

91 2f8598a5 Alexander Schreiber
  This class, given a (remote) method name, a list of parameters and a
92 a8083063 Iustin Pop
  list of nodes, will contact (in parallel) all nodes, and return a
93 a8083063 Iustin Pop
  dict of results (key: node name, value: result).
94 a8083063 Iustin Pop

95 a8083063 Iustin Pop
  One current bug is that generic failure is still signalled by
96 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
97 a8083063 Iustin Pop
  cause bugs.
98 a8083063 Iustin Pop

99 a8083063 Iustin Pop
  """
100 a8083063 Iustin Pop
  result_set = False
101 a8083063 Iustin Pop
  result = False
102 a8083063 Iustin Pop
  allresult = []
103 a8083063 Iustin Pop
104 a8083063 Iustin Pop
  def __init__(self, procedure, args):
105 a8083063 Iustin Pop
    ss = ssconf.SimpleStore()
106 a8083063 Iustin Pop
    self.port = ss.GetNodeDaemonPort()
107 a8083063 Iustin Pop
    self.nodepw = ss.GetNodeDaemonPassword()
108 a8083063 Iustin Pop
    self.nc = {}
109 a8083063 Iustin Pop
    self.results = {}
110 a8083063 Iustin Pop
    self.procedure = procedure
111 a8083063 Iustin Pop
    self.args = args
112 81010134 Iustin Pop
    self.body = simplejson.dumps(args)
113 a8083063 Iustin Pop
114 a8083063 Iustin Pop
  #--- generic connector -------------
115 a8083063 Iustin Pop
116 a8083063 Iustin Pop
  def connect_list(self, node_list):
117 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
118 a8083063 Iustin Pop

119 a8083063 Iustin Pop
    """
120 a8083063 Iustin Pop
    for node in node_list:
121 a8083063 Iustin Pop
      self.connect(node)
122 a8083063 Iustin Pop
123 a8083063 Iustin Pop
  def connect(self, connect_node):
124 a8083063 Iustin Pop
    """Add a node to the target list.
125 a8083063 Iustin Pop

126 a8083063 Iustin Pop
    """
127 a8083063 Iustin Pop
    self.nc[connect_node] = nc = NodeController(self, connect_node)
128 a8083063 Iustin Pop
129 a8083063 Iustin Pop
  def getresult(self):
130 a8083063 Iustin Pop
    """Return the results of the call.
131 a8083063 Iustin Pop

132 a8083063 Iustin Pop
    """
133 a8083063 Iustin Pop
    return self.results
134 a8083063 Iustin Pop
135 a8083063 Iustin Pop
  def run(self):
136 a8083063 Iustin Pop
    """Wrapper over reactor.run().
137 a8083063 Iustin Pop

138 a8083063 Iustin Pop
    This function simply calls reactor.run() if we have any requests
139 a8083063 Iustin Pop
    queued, otherwise it does nothing.
140 a8083063 Iustin Pop

141 a8083063 Iustin Pop
    """
142 81010134 Iustin Pop
    for node, nc in self.nc.items():
143 81010134 Iustin Pop
      self.results[node] = nc.get_response()
144 a8083063 Iustin Pop
145 a8083063 Iustin Pop
146 a8083063 Iustin Pop
def call_volume_list(node_list, vg_name):
147 a8083063 Iustin Pop
  """Gets the logical volumes present in a given volume group.
148 a8083063 Iustin Pop

149 a8083063 Iustin Pop
  This is a multi-node call.
150 a8083063 Iustin Pop

151 a8083063 Iustin Pop
  """
152 a8083063 Iustin Pop
  c = Client("volume_list", [vg_name])
153 a8083063 Iustin Pop
  c.connect_list(node_list)
154 a8083063 Iustin Pop
  c.run()
155 a8083063 Iustin Pop
  return c.getresult()
156 a8083063 Iustin Pop
157 a8083063 Iustin Pop
158 a8083063 Iustin Pop
def call_vg_list(node_list):
159 a8083063 Iustin Pop
  """Gets the volume group list.
160 a8083063 Iustin Pop

161 a8083063 Iustin Pop
  This is a multi-node call.
162 a8083063 Iustin Pop

163 a8083063 Iustin Pop
  """
164 a8083063 Iustin Pop
  c = Client("vg_list", [])
165 a8083063 Iustin Pop
  c.connect_list(node_list)
166 a8083063 Iustin Pop
  c.run()
167 a8083063 Iustin Pop
  return c.getresult()
168 a8083063 Iustin Pop
169 a8083063 Iustin Pop
170 a8083063 Iustin Pop
def call_bridges_exist(node, bridges_list):
171 a8083063 Iustin Pop
  """Checks if a node has all the bridges given.
172 a8083063 Iustin Pop

173 a8083063 Iustin Pop
  This method checks if all bridges given in the bridges_list are
174 a8083063 Iustin Pop
  present on the remote node, so that an instance that uses interfaces
175 a8083063 Iustin Pop
  on those bridges can be started.
176 a8083063 Iustin Pop

177 a8083063 Iustin Pop
  This is a single-node call.
178 a8083063 Iustin Pop

179 a8083063 Iustin Pop
  """
180 a8083063 Iustin Pop
  c = Client("bridges_exist", [bridges_list])
181 a8083063 Iustin Pop
  c.connect(node)
182 a8083063 Iustin Pop
  c.run()
183 a8083063 Iustin Pop
  return c.getresult().get(node, False)
184 a8083063 Iustin Pop
185 a8083063 Iustin Pop
186 a8083063 Iustin Pop
def call_instance_start(node, instance, extra_args):
187 2f8598a5 Alexander Schreiber
  """Starts an instance.
188 a8083063 Iustin Pop

189 a8083063 Iustin Pop
  This is a single-node call.
190 a8083063 Iustin Pop

191 a8083063 Iustin Pop
  """
192 319856a9 Michael Hanselmann
  c = Client("instance_start", [instance.ToDict(), extra_args])
193 a8083063 Iustin Pop
  c.connect(node)
194 a8083063 Iustin Pop
  c.run()
195 a8083063 Iustin Pop
  return c.getresult().get(node, False)
196 a8083063 Iustin Pop
197 a8083063 Iustin Pop
198 a8083063 Iustin Pop
def call_instance_shutdown(node, instance):
199 a8083063 Iustin Pop
  """Stops an instance.
200 a8083063 Iustin Pop

201 a8083063 Iustin Pop
  This is a single-node call.
202 a8083063 Iustin Pop

203 a8083063 Iustin Pop
  """
204 319856a9 Michael Hanselmann
  c = Client("instance_shutdown", [instance.ToDict()])
205 a8083063 Iustin Pop
  c.connect(node)
206 a8083063 Iustin Pop
  c.run()
207 a8083063 Iustin Pop
  return c.getresult().get(node, False)
208 a8083063 Iustin Pop
209 a8083063 Iustin Pop
210 007a2f3e Alexander Schreiber
def call_instance_reboot(node, instance, reboot_type, extra_args):
211 007a2f3e Alexander Schreiber
  """Reboots an instance.
212 007a2f3e Alexander Schreiber

213 007a2f3e Alexander Schreiber
  This is a single-node call.
214 007a2f3e Alexander Schreiber

215 007a2f3e Alexander Schreiber
  """
216 007a2f3e Alexander Schreiber
  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
217 007a2f3e Alexander Schreiber
  c.connect(node)
218 007a2f3e Alexander Schreiber
  c.run()
219 007a2f3e Alexander Schreiber
  return c.getresult().get(node, False)
220 007a2f3e Alexander Schreiber
221 007a2f3e Alexander Schreiber
222 a8083063 Iustin Pop
def call_instance_os_add(node, inst, osdev, swapdev):
223 a8083063 Iustin Pop
  """Installs an OS on the given instance.
224 a8083063 Iustin Pop

225 a8083063 Iustin Pop
  This is a single-node call.
226 a8083063 Iustin Pop

227 a8083063 Iustin Pop
  """
228 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev]
229 a8083063 Iustin Pop
  c = Client("instance_os_add", params)
230 a8083063 Iustin Pop
  c.connect(node)
231 a8083063 Iustin Pop
  c.run()
232 a8083063 Iustin Pop
  return c.getresult().get(node, False)
233 a8083063 Iustin Pop
234 a8083063 Iustin Pop
235 decd5f45 Iustin Pop
def call_instance_run_rename(node, inst, old_name, osdev, swapdev):
236 decd5f45 Iustin Pop
  """Run the OS rename script for an instance.
237 decd5f45 Iustin Pop

238 decd5f45 Iustin Pop
  This is a single-node call.
239 decd5f45 Iustin Pop

240 decd5f45 Iustin Pop
  """
241 319856a9 Michael Hanselmann
  params = [inst.ToDict(), old_name, osdev, swapdev]
242 decd5f45 Iustin Pop
  c = Client("instance_run_rename", params)
243 decd5f45 Iustin Pop
  c.connect(node)
244 decd5f45 Iustin Pop
  c.run()
245 decd5f45 Iustin Pop
  return c.getresult().get(node, False)
246 decd5f45 Iustin Pop
247 decd5f45 Iustin Pop
248 a8083063 Iustin Pop
def call_instance_info(node, instance):
249 a8083063 Iustin Pop
  """Returns information about a single instance.
250 a8083063 Iustin Pop

251 a8083063 Iustin Pop
  This is a single-node call.
252 a8083063 Iustin Pop

253 a8083063 Iustin Pop
  """
254 a8083063 Iustin Pop
  c = Client("instance_info", [instance])
255 a8083063 Iustin Pop
  c.connect(node)
256 a8083063 Iustin Pop
  c.run()
257 a8083063 Iustin Pop
  return c.getresult().get(node, False)
258 a8083063 Iustin Pop
259 a8083063 Iustin Pop
260 a8083063 Iustin Pop
def call_all_instances_info(node_list):
261 a8083063 Iustin Pop
  """Returns information about all instances on a given node.
262 a8083063 Iustin Pop

263 a8083063 Iustin Pop
  This is a single-node call.
264 a8083063 Iustin Pop

265 a8083063 Iustin Pop
  """
266 a8083063 Iustin Pop
  c = Client("all_instances_info", [])
267 a8083063 Iustin Pop
  c.connect_list(node_list)
268 a8083063 Iustin Pop
  c.run()
269 a8083063 Iustin Pop
  return c.getresult()
270 a8083063 Iustin Pop
271 a8083063 Iustin Pop
272 a8083063 Iustin Pop
def call_instance_list(node_list):
273 a8083063 Iustin Pop
  """Returns the list of running instances on a given node.
274 a8083063 Iustin Pop

275 a8083063 Iustin Pop
  This is a single-node call.
276 a8083063 Iustin Pop

277 a8083063 Iustin Pop
  """
278 a8083063 Iustin Pop
  c = Client("instance_list", [])
279 a8083063 Iustin Pop
  c.connect_list(node_list)
280 a8083063 Iustin Pop
  c.run()
281 a8083063 Iustin Pop
  return c.getresult()
282 a8083063 Iustin Pop
283 a8083063 Iustin Pop
284 16abfbc2 Alexander Schreiber
def call_node_tcp_ping(node, source, target, port, timeout, live_port_needed):
285 16abfbc2 Alexander Schreiber
  """Do a TcpPing on the remote node
286 16abfbc2 Alexander Schreiber

287 16abfbc2 Alexander Schreiber
  This is a single-node call.
288 16abfbc2 Alexander Schreiber
  """
289 16abfbc2 Alexander Schreiber
  c = Client("node_tcp_ping", [source, target, port, timeout,
290 16abfbc2 Alexander Schreiber
                               live_port_needed])
291 16abfbc2 Alexander Schreiber
  c.connect(node)
292 16abfbc2 Alexander Schreiber
  c.run()
293 16abfbc2 Alexander Schreiber
  return c.getresult().get(node, False)
294 16abfbc2 Alexander Schreiber
295 16abfbc2 Alexander Schreiber
296 a8083063 Iustin Pop
def call_node_info(node_list, vg_name):
297 a8083063 Iustin Pop
  """Return node information.
298 a8083063 Iustin Pop

299 a8083063 Iustin Pop
  This will return memory information and volume group size and free
300 a8083063 Iustin Pop
  space.
301 a8083063 Iustin Pop

302 a8083063 Iustin Pop
  This is a multi-node call.
303 a8083063 Iustin Pop

304 a8083063 Iustin Pop
  """
305 a8083063 Iustin Pop
  c = Client("node_info", [vg_name])
306 a8083063 Iustin Pop
  c.connect_list(node_list)
307 a8083063 Iustin Pop
  c.run()
308 a8083063 Iustin Pop
  retux = c.getresult()
309 a8083063 Iustin Pop
310 a8083063 Iustin Pop
  for node_name in retux:
311 a8083063 Iustin Pop
    ret = retux.get(node_name, False)
312 a8083063 Iustin Pop
    if type(ret) != dict:
313 a8083063 Iustin Pop
      logger.Error("could not connect to node %s" % (node_name))
314 a8083063 Iustin Pop
      ret = {}
315 a8083063 Iustin Pop
316 a8083063 Iustin Pop
    utils.CheckDict(ret,
317 a8083063 Iustin Pop
                    { 'memory_total' : '-',
318 a8083063 Iustin Pop
                      'memory_dom0' : '-',
319 a8083063 Iustin Pop
                      'memory_free' : '-',
320 a8083063 Iustin Pop
                      'vg_size' : 'node_unreachable',
321 a8083063 Iustin Pop
                      'vg_free' : '-' },
322 a8083063 Iustin Pop
                    "call_node_info",
323 a8083063 Iustin Pop
                    )
324 a8083063 Iustin Pop
  return retux
325 a8083063 Iustin Pop
326 a8083063 Iustin Pop
327 a8083063 Iustin Pop
def call_node_add(node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
328 a8083063 Iustin Pop
  """Add a node to the cluster.
329 a8083063 Iustin Pop

330 a8083063 Iustin Pop
  This is a single-node call.
331 a8083063 Iustin Pop

332 a8083063 Iustin Pop
  """
333 a8083063 Iustin Pop
  params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
334 a8083063 Iustin Pop
  c = Client("node_add", params)
335 a8083063 Iustin Pop
  c.connect(node)
336 a8083063 Iustin Pop
  c.run()
337 a8083063 Iustin Pop
  return c.getresult().get(node, False)
338 a8083063 Iustin Pop
339 a8083063 Iustin Pop
340 a8083063 Iustin Pop
def call_node_verify(node_list, checkdict):
341 a8083063 Iustin Pop
  """Request verification of given parameters.
342 a8083063 Iustin Pop

343 a8083063 Iustin Pop
  This is a multi-node call.
344 a8083063 Iustin Pop

345 a8083063 Iustin Pop
  """
346 a8083063 Iustin Pop
  c = Client("node_verify", [checkdict])
347 a8083063 Iustin Pop
  c.connect_list(node_list)
348 a8083063 Iustin Pop
  c.run()
349 a8083063 Iustin Pop
  return c.getresult()
350 a8083063 Iustin Pop
351 a8083063 Iustin Pop
352 a8083063 Iustin Pop
def call_node_start_master(node):
353 a8083063 Iustin Pop
  """Tells a node to activate itself as a master.
354 a8083063 Iustin Pop

355 a8083063 Iustin Pop
  This is a single-node call.
356 a8083063 Iustin Pop

357 a8083063 Iustin Pop
  """
358 a8083063 Iustin Pop
  c = Client("node_start_master", [])
359 a8083063 Iustin Pop
  c.connect(node)
360 a8083063 Iustin Pop
  c.run()
361 a8083063 Iustin Pop
  return c.getresult().get(node, False)
362 a8083063 Iustin Pop
363 a8083063 Iustin Pop
364 a8083063 Iustin Pop
def call_node_stop_master(node):
365 a8083063 Iustin Pop
  """Tells a node to demote itself from master status.
366 a8083063 Iustin Pop

367 a8083063 Iustin Pop
  This is a single-node call.
368 a8083063 Iustin Pop

369 a8083063 Iustin Pop
  """
370 a8083063 Iustin Pop
  c = Client("node_stop_master", [])
371 a8083063 Iustin Pop
  c.connect(node)
372 a8083063 Iustin Pop
  c.run()
373 a8083063 Iustin Pop
  return c.getresult().get(node, False)
374 a8083063 Iustin Pop
375 a8083063 Iustin Pop
376 a8083063 Iustin Pop
def call_version(node_list):
377 a8083063 Iustin Pop
  """Query node version.
378 a8083063 Iustin Pop

379 a8083063 Iustin Pop
  This is a multi-node call.
380 a8083063 Iustin Pop

381 a8083063 Iustin Pop
  """
382 a8083063 Iustin Pop
  c = Client("version", [])
383 a8083063 Iustin Pop
  c.connect_list(node_list)
384 a8083063 Iustin Pop
  c.run()
385 a8083063 Iustin Pop
  return c.getresult()
386 a8083063 Iustin Pop
387 a8083063 Iustin Pop
388 3f78eef2 Iustin Pop
def call_blockdev_create(node, bdev, size, owner, on_primary, info):
389 a8083063 Iustin Pop
  """Request creation of a given block device.
390 a8083063 Iustin Pop

391 a8083063 Iustin Pop
  This is a single-node call.
392 a8083063 Iustin Pop

393 a8083063 Iustin Pop
  """
394 3f78eef2 Iustin Pop
  params = [bdev.ToDict(), size, owner, on_primary, info]
395 a8083063 Iustin Pop
  c = Client("blockdev_create", params)
396 a8083063 Iustin Pop
  c.connect(node)
397 a8083063 Iustin Pop
  c.run()
398 a8083063 Iustin Pop
  return c.getresult().get(node, False)
399 a8083063 Iustin Pop
400 a8083063 Iustin Pop
401 a8083063 Iustin Pop
def call_blockdev_remove(node, bdev):
402 a8083063 Iustin Pop
  """Request removal of a given block device.
403 a8083063 Iustin Pop

404 a8083063 Iustin Pop
  This is a single-node call.
405 a8083063 Iustin Pop

406 a8083063 Iustin Pop
  """
407 319856a9 Michael Hanselmann
  c = Client("blockdev_remove", [bdev.ToDict()])
408 a8083063 Iustin Pop
  c.connect(node)
409 a8083063 Iustin Pop
  c.run()
410 a8083063 Iustin Pop
  return c.getresult().get(node, False)
411 a8083063 Iustin Pop
412 a8083063 Iustin Pop
413 f3e513ad Iustin Pop
def call_blockdev_rename(node, devlist):
414 f3e513ad Iustin Pop
  """Request rename of the given block devices.
415 f3e513ad Iustin Pop

416 f3e513ad Iustin Pop
  This is a single-node call.
417 f3e513ad Iustin Pop

418 f3e513ad Iustin Pop
  """
419 f3e513ad Iustin Pop
  params = [(d.ToDict(), uid) for d, uid in devlist]
420 f3e513ad Iustin Pop
  c = Client("blockdev_rename", params)
421 f3e513ad Iustin Pop
  c.connect(node)
422 f3e513ad Iustin Pop
  c.run()
423 f3e513ad Iustin Pop
  return c.getresult().get(node, False)
424 f3e513ad Iustin Pop
425 f3e513ad Iustin Pop
426 3f78eef2 Iustin Pop
def call_blockdev_assemble(node, disk, owner, on_primary):
427 a8083063 Iustin Pop
  """Request assembling of a given block device.
428 a8083063 Iustin Pop

429 a8083063 Iustin Pop
  This is a single-node call.
430 a8083063 Iustin Pop

431 a8083063 Iustin Pop
  """
432 3f78eef2 Iustin Pop
  params = [disk.ToDict(), owner, on_primary]
433 a8083063 Iustin Pop
  c = Client("blockdev_assemble", params)
434 a8083063 Iustin Pop
  c.connect(node)
435 a8083063 Iustin Pop
  c.run()
436 a8083063 Iustin Pop
  return c.getresult().get(node, False)
437 a8083063 Iustin Pop
438 a8083063 Iustin Pop
439 a8083063 Iustin Pop
def call_blockdev_shutdown(node, disk):
440 a8083063 Iustin Pop
  """Request shutdown of a given block device.
441 a8083063 Iustin Pop

442 a8083063 Iustin Pop
  This is a single-node call.
443 a8083063 Iustin Pop

444 a8083063 Iustin Pop
  """
445 319856a9 Michael Hanselmann
  c = Client("blockdev_shutdown", [disk.ToDict()])
446 a8083063 Iustin Pop
  c.connect(node)
447 a8083063 Iustin Pop
  c.run()
448 a8083063 Iustin Pop
  return c.getresult().get(node, False)
449 a8083063 Iustin Pop
450 a8083063 Iustin Pop
451 153d9724 Iustin Pop
def call_blockdev_addchildren(node, bdev, ndevs):
452 153d9724 Iustin Pop
  """Request adding a list of children to a (mirroring) device.
453 a8083063 Iustin Pop

454 a8083063 Iustin Pop
  This is a single-node call.
455 a8083063 Iustin Pop

456 a8083063 Iustin Pop
  """
457 153d9724 Iustin Pop
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
458 153d9724 Iustin Pop
  c = Client("blockdev_addchildren", params)
459 a8083063 Iustin Pop
  c.connect(node)
460 a8083063 Iustin Pop
  c.run()
461 a8083063 Iustin Pop
  return c.getresult().get(node, False)
462 a8083063 Iustin Pop
463 a8083063 Iustin Pop
464 153d9724 Iustin Pop
def call_blockdev_removechildren(node, bdev, ndevs):
465 153d9724 Iustin Pop
  """Request removing a list of children from a (mirroring) device.
466 a8083063 Iustin Pop

467 a8083063 Iustin Pop
  This is a single-node call.
468 a8083063 Iustin Pop

469 a8083063 Iustin Pop
  """
470 153d9724 Iustin Pop
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
471 153d9724 Iustin Pop
  c = Client("blockdev_removechildren", params)
472 a8083063 Iustin Pop
  c.connect(node)
473 a8083063 Iustin Pop
  c.run()
474 a8083063 Iustin Pop
  return c.getresult().get(node, False)
475 a8083063 Iustin Pop
476 a8083063 Iustin Pop
477 a8083063 Iustin Pop
def call_blockdev_getmirrorstatus(node, disks):
478 a8083063 Iustin Pop
  """Request status of a (mirroring) device.
479 a8083063 Iustin Pop

480 a8083063 Iustin Pop
  This is a single-node call.
481 a8083063 Iustin Pop

482 a8083063 Iustin Pop
  """
483 319856a9 Michael Hanselmann
  params = [dsk.ToDict() for dsk in disks]
484 a8083063 Iustin Pop
  c = Client("blockdev_getmirrorstatus", params)
485 a8083063 Iustin Pop
  c.connect(node)
486 a8083063 Iustin Pop
  c.run()
487 a8083063 Iustin Pop
  return c.getresult().get(node, False)
488 a8083063 Iustin Pop
489 a8083063 Iustin Pop
490 a8083063 Iustin Pop
def call_blockdev_find(node, disk):
491 a8083063 Iustin Pop
  """Request identification of a given block device.
492 a8083063 Iustin Pop

493 a8083063 Iustin Pop
  This is a single-node call.
494 a8083063 Iustin Pop

495 a8083063 Iustin Pop
  """
496 319856a9 Michael Hanselmann
  c = Client("blockdev_find", [disk.ToDict()])
497 a8083063 Iustin Pop
  c.connect(node)
498 a8083063 Iustin Pop
  c.run()
499 a8083063 Iustin Pop
  return c.getresult().get(node, False)
500 a8083063 Iustin Pop
501 a8083063 Iustin Pop
502 a8083063 Iustin Pop
def call_upload_file(node_list, file_name):
503 a8083063 Iustin Pop
  """Upload a file.
504 a8083063 Iustin Pop

505 a8083063 Iustin Pop
  The node will refuse the operation in case the file is not on the
506 a8083063 Iustin Pop
  approved file list.
507 a8083063 Iustin Pop

508 a8083063 Iustin Pop
  This is a multi-node call.
509 a8083063 Iustin Pop

510 a8083063 Iustin Pop
  """
511 a8083063 Iustin Pop
  fh = file(file_name)
512 a8083063 Iustin Pop
  try:
513 a8083063 Iustin Pop
    data = fh.read()
514 a8083063 Iustin Pop
  finally:
515 a8083063 Iustin Pop
    fh.close()
516 a8083063 Iustin Pop
  st = os.stat(file_name)
517 a8083063 Iustin Pop
  params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
518 a8083063 Iustin Pop
            st.st_atime, st.st_mtime]
519 a8083063 Iustin Pop
  c = Client("upload_file", params)
520 a8083063 Iustin Pop
  c.connect_list(node_list)
521 a8083063 Iustin Pop
  c.run()
522 a8083063 Iustin Pop
  return c.getresult()
523 a8083063 Iustin Pop
524 a8083063 Iustin Pop
525 a8083063 Iustin Pop
def call_os_diagnose(node_list):
526 a8083063 Iustin Pop
  """Request a diagnose of OS definitions.
527 a8083063 Iustin Pop

528 a8083063 Iustin Pop
  This is a multi-node call.
529 a8083063 Iustin Pop

530 a8083063 Iustin Pop
  """
531 a8083063 Iustin Pop
  c = Client("os_diagnose", [])
532 a8083063 Iustin Pop
  c.connect_list(node_list)
533 a8083063 Iustin Pop
  c.run()
534 a8083063 Iustin Pop
  result = c.getresult()
535 a8083063 Iustin Pop
  new_result = {}
536 a8083063 Iustin Pop
  for node_name in result:
537 a8083063 Iustin Pop
    if result[node_name]:
538 4e679f11 Guido Trotter
      nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
539 4e679f11 Guido Trotter
    else:
540 4e679f11 Guido Trotter
      nr = []
541 a8083063 Iustin Pop
    new_result[node_name] = nr
542 a8083063 Iustin Pop
  return new_result
543 a8083063 Iustin Pop
544 a8083063 Iustin Pop
545 00fe9e38 Guido Trotter
def call_os_get(node, name):
546 a8083063 Iustin Pop
  """Returns an OS definition.
547 a8083063 Iustin Pop

548 00fe9e38 Guido Trotter
  This is a single-node call.
549 a8083063 Iustin Pop

550 a8083063 Iustin Pop
  """
551 a8083063 Iustin Pop
  c = Client("os_get", [name])
552 00fe9e38 Guido Trotter
  c.connect(node)
553 a8083063 Iustin Pop
  c.run()
554 00fe9e38 Guido Trotter
  result = c.getresult().get(node, False)
555 00fe9e38 Guido Trotter
  if isinstance(result, dict):
556 dfa96ded Guido Trotter
    return objects.OS.FromDict(result)
557 00fe9e38 Guido Trotter
  else:
558 dfa96ded Guido Trotter
    return result
559 a8083063 Iustin Pop
560 a8083063 Iustin Pop
561 a8083063 Iustin Pop
def call_hooks_runner(node_list, hpath, phase, env):
562 a8083063 Iustin Pop
  """Call the hooks runner.
563 a8083063 Iustin Pop

564 a8083063 Iustin Pop
  Args:
565 a8083063 Iustin Pop
    - op: the OpCode instance
566 a8083063 Iustin Pop
    - env: a dictionary with the environment
567 a8083063 Iustin Pop

568 a8083063 Iustin Pop
  This is a multi-node call.
569 a8083063 Iustin Pop

570 a8083063 Iustin Pop
  """
571 a8083063 Iustin Pop
  params = [hpath, phase, env]
572 a8083063 Iustin Pop
  c = Client("hooks_runner", params)
573 a8083063 Iustin Pop
  c.connect_list(node_list)
574 a8083063 Iustin Pop
  c.run()
575 a8083063 Iustin Pop
  result = c.getresult()
576 a8083063 Iustin Pop
  return result
577 a8083063 Iustin Pop
578 a8083063 Iustin Pop
579 a8083063 Iustin Pop
def call_blockdev_snapshot(node, cf_bdev):
580 a8083063 Iustin Pop
  """Request a snapshot of the given block device.
581 a8083063 Iustin Pop

582 a8083063 Iustin Pop
  This is a single-node call.
583 a8083063 Iustin Pop

584 a8083063 Iustin Pop
  """
585 319856a9 Michael Hanselmann
  c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
586 a8083063 Iustin Pop
  c.connect(node)
587 a8083063 Iustin Pop
  c.run()
588 a8083063 Iustin Pop
  return c.getresult().get(node, False)
589 a8083063 Iustin Pop
590 a8083063 Iustin Pop
591 a8083063 Iustin Pop
def call_snapshot_export(node, snap_bdev, dest_node, instance):
592 a8083063 Iustin Pop
  """Request the export of a given snapshot.
593 a8083063 Iustin Pop

594 a8083063 Iustin Pop
  This is a single-node call.
595 a8083063 Iustin Pop

596 a8083063 Iustin Pop
  """
597 319856a9 Michael Hanselmann
  params = [snap_bdev.ToDict(), dest_node, instance.ToDict()]
598 a8083063 Iustin Pop
  c = Client("snapshot_export", params)
599 a8083063 Iustin Pop
  c.connect(node)
600 a8083063 Iustin Pop
  c.run()
601 a8083063 Iustin Pop
  return c.getresult().get(node, False)
602 a8083063 Iustin Pop
603 a8083063 Iustin Pop
604 a8083063 Iustin Pop
def call_finalize_export(node, instance, snap_disks):
605 a8083063 Iustin Pop
  """Request the completion of an export operation.
606 a8083063 Iustin Pop

607 a8083063 Iustin Pop
  This writes the export config file, etc.
608 a8083063 Iustin Pop

609 a8083063 Iustin Pop
  This is a single-node call.
610 a8083063 Iustin Pop

611 a8083063 Iustin Pop
  """
612 a8083063 Iustin Pop
  flat_disks = []
613 a8083063 Iustin Pop
  for disk in snap_disks:
614 319856a9 Michael Hanselmann
    flat_disks.append(disk.ToDict())
615 319856a9 Michael Hanselmann
  params = [instance.ToDict(), flat_disks]
616 a8083063 Iustin Pop
  c = Client("finalize_export", params)
617 a8083063 Iustin Pop
  c.connect(node)
618 a8083063 Iustin Pop
  c.run()
619 a8083063 Iustin Pop
  return c.getresult().get(node, False)
620 a8083063 Iustin Pop
621 a8083063 Iustin Pop
622 a8083063 Iustin Pop
def call_export_info(node, path):
623 a8083063 Iustin Pop
  """Queries the export information in a given path.
624 a8083063 Iustin Pop

625 a8083063 Iustin Pop
  This is a single-node call.
626 a8083063 Iustin Pop

627 a8083063 Iustin Pop
  """
628 a8083063 Iustin Pop
  c = Client("export_info", [path])
629 a8083063 Iustin Pop
  c.connect(node)
630 a8083063 Iustin Pop
  c.run()
631 a8083063 Iustin Pop
  result = c.getresult().get(node, False)
632 a8083063 Iustin Pop
  if not result:
633 a8083063 Iustin Pop
    return result
634 a8083063 Iustin Pop
  return objects.SerializableConfigParser.Loads(result)
635 a8083063 Iustin Pop
636 a8083063 Iustin Pop
637 a8083063 Iustin Pop
def call_instance_os_import(node, inst, osdev, swapdev, src_node, src_image):
638 a8083063 Iustin Pop
  """Request the import of a backup into an instance.
639 a8083063 Iustin Pop

640 a8083063 Iustin Pop
  This is a single-node call.
641 a8083063 Iustin Pop

642 a8083063 Iustin Pop
  """
643 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev, src_node, src_image]
644 a8083063 Iustin Pop
  c = Client("instance_os_import", params)
645 a8083063 Iustin Pop
  c.connect(node)
646 a8083063 Iustin Pop
  c.run()
647 a8083063 Iustin Pop
  return c.getresult().get(node, False)
648 a8083063 Iustin Pop
649 a8083063 Iustin Pop
650 a8083063 Iustin Pop
def call_export_list(node_list):
651 a8083063 Iustin Pop
  """Gets the stored exports list.
652 a8083063 Iustin Pop

653 a8083063 Iustin Pop
  This is a multi-node call.
654 a8083063 Iustin Pop

655 a8083063 Iustin Pop
  """
656 a8083063 Iustin Pop
  c = Client("export_list", [])
657 a8083063 Iustin Pop
  c.connect_list(node_list)
658 a8083063 Iustin Pop
  c.run()
659 a8083063 Iustin Pop
  result = c.getresult()
660 a8083063 Iustin Pop
  return result
661 a8083063 Iustin Pop
662 a8083063 Iustin Pop
663 a8083063 Iustin Pop
def call_export_remove(node, export):
664 a8083063 Iustin Pop
  """Requests removal of a given export.
665 a8083063 Iustin Pop

666 a8083063 Iustin Pop
  This is a single-node call.
667 a8083063 Iustin Pop

668 a8083063 Iustin Pop
  """
669 a8083063 Iustin Pop
  c = Client("export_remove", [export])
670 a8083063 Iustin Pop
  c.connect(node)
671 a8083063 Iustin Pop
  c.run()
672 a8083063 Iustin Pop
  return c.getresult().get(node, False)
673 a8083063 Iustin Pop
674 a8083063 Iustin Pop
675 a8083063 Iustin Pop
def call_node_leave_cluster(node):
676 a8083063 Iustin Pop
  """Requests a node to clean the cluster information it has.
677 a8083063 Iustin Pop

678 a8083063 Iustin Pop
  This will remove the configuration information from the ganeti data
679 a8083063 Iustin Pop
  dir.
680 a8083063 Iustin Pop

681 a8083063 Iustin Pop
  This is a single-node call.
682 a8083063 Iustin Pop

683 a8083063 Iustin Pop
  """
684 a8083063 Iustin Pop
  c = Client("node_leave_cluster", [])
685 a8083063 Iustin Pop
  c.connect(node)
686 a8083063 Iustin Pop
  c.run()
687 a8083063 Iustin Pop
  return c.getresult().get(node, False)
688 dcb93971 Michael Hanselmann
689 dcb93971 Michael Hanselmann
690 dcb93971 Michael Hanselmann
def call_node_volumes(node_list):
691 dcb93971 Michael Hanselmann
  """Gets all volumes on node(s).
692 dcb93971 Michael Hanselmann

693 dcb93971 Michael Hanselmann
  This is a multi-node call.
694 dcb93971 Michael Hanselmann

695 dcb93971 Michael Hanselmann
  """
696 dcb93971 Michael Hanselmann
  c = Client("node_volumes", [])
697 dcb93971 Michael Hanselmann
  c.connect_list(node_list)
698 dcb93971 Michael Hanselmann
  c.run()
699 dcb93971 Michael Hanselmann
  return c.getresult()
700 06009e27 Iustin Pop
701 06009e27 Iustin Pop
702 06009e27 Iustin Pop
def call_test_delay(node_list, duration):
703 06009e27 Iustin Pop
  """Sleep for a fixed time on given node(s).
704 06009e27 Iustin Pop

705 06009e27 Iustin Pop
  This is a multi-node call.
706 06009e27 Iustin Pop

707 06009e27 Iustin Pop
  """
708 06009e27 Iustin Pop
  c = Client("test_delay", [duration])
709 06009e27 Iustin Pop
  c.connect_list(node_list)
710 06009e27 Iustin Pop
  c.run()
711 06009e27 Iustin Pop
  return c.getresult()