Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ e873317a

History | View | Annotate | Download (17.7 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 7c0d6283 Michael Hanselmann
42 a8083063 Iustin Pop
class NodeController:
43 a8083063 Iustin Pop
  """Node-handling class.
44 a8083063 Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

204 a8083063 Iustin Pop
  """
205 319856a9 Michael Hanselmann
  c = Client("instance_shutdown", [instance.ToDict()])
206 a8083063 Iustin Pop
  c.connect(node)
207 a8083063 Iustin Pop
  c.run()
208 a8083063 Iustin Pop
  return c.getresult().get(node, False)
209 a8083063 Iustin Pop
210 a8083063 Iustin Pop
211 2a10865c Iustin Pop
def call_instance_migrate(node, instance, target, live):
212 2a10865c Iustin Pop
  """Migrate an instance.
213 2a10865c Iustin Pop

214 2a10865c Iustin Pop
  This is a single-node call.
215 2a10865c Iustin Pop

216 2a10865c Iustin Pop
  """
217 2a10865c Iustin Pop
  c = Client("instance_migrate", [instance.name, target, live])
218 2a10865c Iustin Pop
  c.connect(node)
219 2a10865c Iustin Pop
  c.run()
220 2a10865c Iustin Pop
  return c.getresult().get(node, False)
221 2a10865c Iustin Pop
222 2a10865c Iustin Pop
223 007a2f3e Alexander Schreiber
def call_instance_reboot(node, instance, reboot_type, extra_args):
224 007a2f3e Alexander Schreiber
  """Reboots an instance.
225 007a2f3e Alexander Schreiber

226 007a2f3e Alexander Schreiber
  This is a single-node call.
227 007a2f3e Alexander Schreiber

228 007a2f3e Alexander Schreiber
  """
229 007a2f3e Alexander Schreiber
  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
230 007a2f3e Alexander Schreiber
  c.connect(node)
231 007a2f3e Alexander Schreiber
  c.run()
232 007a2f3e Alexander Schreiber
  return c.getresult().get(node, False)
233 007a2f3e Alexander Schreiber
234 007a2f3e Alexander Schreiber
235 a8083063 Iustin Pop
def call_instance_os_add(node, inst, osdev, swapdev):
236 a8083063 Iustin Pop
  """Installs an OS on the given instance.
237 a8083063 Iustin Pop

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

240 a8083063 Iustin Pop
  """
241 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev]
242 a8083063 Iustin Pop
  c = Client("instance_os_add", params)
243 a8083063 Iustin Pop
  c.connect(node)
244 a8083063 Iustin Pop
  c.run()
245 a8083063 Iustin Pop
  return c.getresult().get(node, False)
246 a8083063 Iustin Pop
247 a8083063 Iustin Pop
248 decd5f45 Iustin Pop
def call_instance_run_rename(node, inst, old_name, osdev, swapdev):
249 decd5f45 Iustin Pop
  """Run the OS rename script for an instance.
250 decd5f45 Iustin Pop

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

253 decd5f45 Iustin Pop
  """
254 319856a9 Michael Hanselmann
  params = [inst.ToDict(), old_name, osdev, swapdev]
255 decd5f45 Iustin Pop
  c = Client("instance_run_rename", params)
256 decd5f45 Iustin Pop
  c.connect(node)
257 decd5f45 Iustin Pop
  c.run()
258 decd5f45 Iustin Pop
  return c.getresult().get(node, False)
259 decd5f45 Iustin Pop
260 decd5f45 Iustin Pop
261 a8083063 Iustin Pop
def call_instance_info(node, instance):
262 a8083063 Iustin Pop
  """Returns information about a single instance.
263 a8083063 Iustin Pop

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

266 a8083063 Iustin Pop
  """
267 a8083063 Iustin Pop
  c = Client("instance_info", [instance])
268 a8083063 Iustin Pop
  c.connect(node)
269 a8083063 Iustin Pop
  c.run()
270 a8083063 Iustin Pop
  return c.getresult().get(node, False)
271 a8083063 Iustin Pop
272 a8083063 Iustin Pop
273 a8083063 Iustin Pop
def call_all_instances_info(node_list):
274 a8083063 Iustin Pop
  """Returns information about all instances on a given node.
275 a8083063 Iustin Pop

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

278 a8083063 Iustin Pop
  """
279 a8083063 Iustin Pop
  c = Client("all_instances_info", [])
280 a8083063 Iustin Pop
  c.connect_list(node_list)
281 a8083063 Iustin Pop
  c.run()
282 a8083063 Iustin Pop
  return c.getresult()
283 a8083063 Iustin Pop
284 a8083063 Iustin Pop
285 a8083063 Iustin Pop
def call_instance_list(node_list):
286 a8083063 Iustin Pop
  """Returns the list of running instances on a given node.
287 a8083063 Iustin Pop

288 a8083063 Iustin Pop
  This is a single-node call.
289 a8083063 Iustin Pop

290 a8083063 Iustin Pop
  """
291 a8083063 Iustin Pop
  c = Client("instance_list", [])
292 a8083063 Iustin Pop
  c.connect_list(node_list)
293 a8083063 Iustin Pop
  c.run()
294 a8083063 Iustin Pop
  return c.getresult()
295 a8083063 Iustin Pop
296 a8083063 Iustin Pop
297 16abfbc2 Alexander Schreiber
def call_node_tcp_ping(node, source, target, port, timeout, live_port_needed):
298 16abfbc2 Alexander Schreiber
  """Do a TcpPing on the remote node
299 16abfbc2 Alexander Schreiber

300 16abfbc2 Alexander Schreiber
  This is a single-node call.
301 16abfbc2 Alexander Schreiber
  """
302 16abfbc2 Alexander Schreiber
  c = Client("node_tcp_ping", [source, target, port, timeout,
303 16abfbc2 Alexander Schreiber
                               live_port_needed])
304 16abfbc2 Alexander Schreiber
  c.connect(node)
305 16abfbc2 Alexander Schreiber
  c.run()
306 16abfbc2 Alexander Schreiber
  return c.getresult().get(node, False)
307 16abfbc2 Alexander Schreiber
308 16abfbc2 Alexander Schreiber
309 a8083063 Iustin Pop
def call_node_info(node_list, vg_name):
310 a8083063 Iustin Pop
  """Return node information.
311 a8083063 Iustin Pop

312 a8083063 Iustin Pop
  This will return memory information and volume group size and free
313 a8083063 Iustin Pop
  space.
314 a8083063 Iustin Pop

315 a8083063 Iustin Pop
  This is a multi-node call.
316 a8083063 Iustin Pop

317 a8083063 Iustin Pop
  """
318 a8083063 Iustin Pop
  c = Client("node_info", [vg_name])
319 a8083063 Iustin Pop
  c.connect_list(node_list)
320 a8083063 Iustin Pop
  c.run()
321 a8083063 Iustin Pop
  retux = c.getresult()
322 a8083063 Iustin Pop
323 a8083063 Iustin Pop
  for node_name in retux:
324 a8083063 Iustin Pop
    ret = retux.get(node_name, False)
325 a8083063 Iustin Pop
    if type(ret) != dict:
326 a8083063 Iustin Pop
      logger.Error("could not connect to node %s" % (node_name))
327 a8083063 Iustin Pop
      ret = {}
328 a8083063 Iustin Pop
329 a8083063 Iustin Pop
    utils.CheckDict(ret,
330 a8083063 Iustin Pop
                    { 'memory_total' : '-',
331 a8083063 Iustin Pop
                      'memory_dom0' : '-',
332 a8083063 Iustin Pop
                      'memory_free' : '-',
333 a8083063 Iustin Pop
                      'vg_size' : 'node_unreachable',
334 a8083063 Iustin Pop
                      'vg_free' : '-' },
335 a8083063 Iustin Pop
                    "call_node_info",
336 a8083063 Iustin Pop
                    )
337 a8083063 Iustin Pop
  return retux
338 a8083063 Iustin Pop
339 a8083063 Iustin Pop
340 a8083063 Iustin Pop
def call_node_add(node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
341 a8083063 Iustin Pop
  """Add a node to the cluster.
342 a8083063 Iustin Pop

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

345 a8083063 Iustin Pop
  """
346 a8083063 Iustin Pop
  params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
347 a8083063 Iustin Pop
  c = Client("node_add", params)
348 a8083063 Iustin Pop
  c.connect(node)
349 a8083063 Iustin Pop
  c.run()
350 a8083063 Iustin Pop
  return c.getresult().get(node, False)
351 a8083063 Iustin Pop
352 a8083063 Iustin Pop
353 a8083063 Iustin Pop
def call_node_verify(node_list, checkdict):
354 a8083063 Iustin Pop
  """Request verification of given parameters.
355 a8083063 Iustin Pop

356 a8083063 Iustin Pop
  This is a multi-node call.
357 a8083063 Iustin Pop

358 a8083063 Iustin Pop
  """
359 a8083063 Iustin Pop
  c = Client("node_verify", [checkdict])
360 a8083063 Iustin Pop
  c.connect_list(node_list)
361 a8083063 Iustin Pop
  c.run()
362 a8083063 Iustin Pop
  return c.getresult()
363 a8083063 Iustin Pop
364 a8083063 Iustin Pop
365 1c65840b Iustin Pop
def call_node_start_master(node, start_daemons):
366 a8083063 Iustin Pop
  """Tells a node to activate itself as a master.
367 a8083063 Iustin Pop

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

370 a8083063 Iustin Pop
  """
371 1c65840b Iustin Pop
  c = Client("node_start_master", [start_daemons])
372 a8083063 Iustin Pop
  c.connect(node)
373 a8083063 Iustin Pop
  c.run()
374 a8083063 Iustin Pop
  return c.getresult().get(node, False)
375 a8083063 Iustin Pop
376 a8083063 Iustin Pop
377 1c65840b Iustin Pop
def call_node_stop_master(node, stop_daemons):
378 a8083063 Iustin Pop
  """Tells a node to demote itself from master status.
379 a8083063 Iustin Pop

380 a8083063 Iustin Pop
  This is a single-node call.
381 a8083063 Iustin Pop

382 a8083063 Iustin Pop
  """
383 1c65840b Iustin Pop
  c = Client("node_stop_master", [stop_daemons])
384 a8083063 Iustin Pop
  c.connect(node)
385 a8083063 Iustin Pop
  c.run()
386 a8083063 Iustin Pop
  return c.getresult().get(node, False)
387 a8083063 Iustin Pop
388 a8083063 Iustin Pop
389 a8083063 Iustin Pop
def call_version(node_list):
390 a8083063 Iustin Pop
  """Query node version.
391 a8083063 Iustin Pop

392 a8083063 Iustin Pop
  This is a multi-node call.
393 a8083063 Iustin Pop

394 a8083063 Iustin Pop
  """
395 a8083063 Iustin Pop
  c = Client("version", [])
396 a8083063 Iustin Pop
  c.connect_list(node_list)
397 a8083063 Iustin Pop
  c.run()
398 a8083063 Iustin Pop
  return c.getresult()
399 a8083063 Iustin Pop
400 a8083063 Iustin Pop
401 3f78eef2 Iustin Pop
def call_blockdev_create(node, bdev, size, owner, on_primary, info):
402 a8083063 Iustin Pop
  """Request creation 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 3f78eef2 Iustin Pop
  params = [bdev.ToDict(), size, owner, on_primary, info]
408 a8083063 Iustin Pop
  c = Client("blockdev_create", params)
409 a8083063 Iustin Pop
  c.connect(node)
410 a8083063 Iustin Pop
  c.run()
411 a8083063 Iustin Pop
  return c.getresult().get(node, False)
412 a8083063 Iustin Pop
413 a8083063 Iustin Pop
414 a8083063 Iustin Pop
def call_blockdev_remove(node, bdev):
415 a8083063 Iustin Pop
  """Request removal of a given block device.
416 a8083063 Iustin Pop

417 a8083063 Iustin Pop
  This is a single-node call.
418 a8083063 Iustin Pop

419 a8083063 Iustin Pop
  """
420 319856a9 Michael Hanselmann
  c = Client("blockdev_remove", [bdev.ToDict()])
421 a8083063 Iustin Pop
  c.connect(node)
422 a8083063 Iustin Pop
  c.run()
423 a8083063 Iustin Pop
  return c.getresult().get(node, False)
424 a8083063 Iustin Pop
425 a8083063 Iustin Pop
426 f3e513ad Iustin Pop
def call_blockdev_rename(node, devlist):
427 f3e513ad Iustin Pop
  """Request rename of the given block devices.
428 f3e513ad Iustin Pop

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

431 f3e513ad Iustin Pop
  """
432 f3e513ad Iustin Pop
  params = [(d.ToDict(), uid) for d, uid in devlist]
433 f3e513ad Iustin Pop
  c = Client("blockdev_rename", params)
434 f3e513ad Iustin Pop
  c.connect(node)
435 f3e513ad Iustin Pop
  c.run()
436 f3e513ad Iustin Pop
  return c.getresult().get(node, False)
437 f3e513ad Iustin Pop
438 f3e513ad Iustin Pop
439 3f78eef2 Iustin Pop
def call_blockdev_assemble(node, disk, owner, on_primary):
440 a8083063 Iustin Pop
  """Request assembling 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 3f78eef2 Iustin Pop
  params = [disk.ToDict(), owner, on_primary]
446 a8083063 Iustin Pop
  c = Client("blockdev_assemble", params)
447 a8083063 Iustin Pop
  c.connect(node)
448 a8083063 Iustin Pop
  c.run()
449 a8083063 Iustin Pop
  return c.getresult().get(node, False)
450 a8083063 Iustin Pop
451 a8083063 Iustin Pop
452 a8083063 Iustin Pop
def call_blockdev_shutdown(node, disk):
453 a8083063 Iustin Pop
  """Request shutdown of a given block device.
454 a8083063 Iustin Pop

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

457 a8083063 Iustin Pop
  """
458 319856a9 Michael Hanselmann
  c = Client("blockdev_shutdown", [disk.ToDict()])
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_addchildren(node, bdev, ndevs):
465 153d9724 Iustin Pop
  """Request adding a list of children to 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_addchildren", 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 153d9724 Iustin Pop
def call_blockdev_removechildren(node, bdev, ndevs):
478 153d9724 Iustin Pop
  """Request removing a list of children from 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 153d9724 Iustin Pop
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
484 153d9724 Iustin Pop
  c = Client("blockdev_removechildren", 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_getmirrorstatus(node, disks):
491 a8083063 Iustin Pop
  """Request status of a (mirroring) 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
  params = [dsk.ToDict() for dsk in disks]
497 a8083063 Iustin Pop
  c = Client("blockdev_getmirrorstatus", params)
498 a8083063 Iustin Pop
  c.connect(node)
499 a8083063 Iustin Pop
  c.run()
500 a8083063 Iustin Pop
  return c.getresult().get(node, False)
501 a8083063 Iustin Pop
502 a8083063 Iustin Pop
503 a8083063 Iustin Pop
def call_blockdev_find(node, disk):
504 a8083063 Iustin Pop
  """Request identification of a given block device.
505 a8083063 Iustin Pop

506 a8083063 Iustin Pop
  This is a single-node call.
507 a8083063 Iustin Pop

508 a8083063 Iustin Pop
  """
509 319856a9 Michael Hanselmann
  c = Client("blockdev_find", [disk.ToDict()])
510 a8083063 Iustin Pop
  c.connect(node)
511 a8083063 Iustin Pop
  c.run()
512 a8083063 Iustin Pop
  return c.getresult().get(node, False)
513 a8083063 Iustin Pop
514 a8083063 Iustin Pop
515 d61cbe76 Iustin Pop
def call_blockdev_close(node, disks):
516 d61cbe76 Iustin Pop
  """Closes the given block devices.
517 d61cbe76 Iustin Pop

518 d61cbe76 Iustin Pop
  This is a single-node call.
519 d61cbe76 Iustin Pop

520 d61cbe76 Iustin Pop
  """
521 d61cbe76 Iustin Pop
  params = [cf.ToDict() for cf in disks]
522 d61cbe76 Iustin Pop
  c = Client("blockdev_close", params)
523 d61cbe76 Iustin Pop
  c.connect(node)
524 d61cbe76 Iustin Pop
  c.run()
525 d61cbe76 Iustin Pop
  return c.getresult().get(node, False)
526 d61cbe76 Iustin Pop
527 d61cbe76 Iustin Pop
528 a8083063 Iustin Pop
def call_upload_file(node_list, file_name):
529 a8083063 Iustin Pop
  """Upload a file.
530 a8083063 Iustin Pop

531 a8083063 Iustin Pop
  The node will refuse the operation in case the file is not on the
532 a8083063 Iustin Pop
  approved file list.
533 a8083063 Iustin Pop

534 a8083063 Iustin Pop
  This is a multi-node call.
535 a8083063 Iustin Pop

536 a8083063 Iustin Pop
  """
537 a8083063 Iustin Pop
  fh = file(file_name)
538 a8083063 Iustin Pop
  try:
539 a8083063 Iustin Pop
    data = fh.read()
540 a8083063 Iustin Pop
  finally:
541 a8083063 Iustin Pop
    fh.close()
542 a8083063 Iustin Pop
  st = os.stat(file_name)
543 a8083063 Iustin Pop
  params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
544 a8083063 Iustin Pop
            st.st_atime, st.st_mtime]
545 a8083063 Iustin Pop
  c = Client("upload_file", params)
546 a8083063 Iustin Pop
  c.connect_list(node_list)
547 a8083063 Iustin Pop
  c.run()
548 a8083063 Iustin Pop
  return c.getresult()
549 a8083063 Iustin Pop
550 a8083063 Iustin Pop
551 a8083063 Iustin Pop
def call_os_diagnose(node_list):
552 a8083063 Iustin Pop
  """Request a diagnose of OS definitions.
553 a8083063 Iustin Pop

554 a8083063 Iustin Pop
  This is a multi-node call.
555 a8083063 Iustin Pop

556 a8083063 Iustin Pop
  """
557 a8083063 Iustin Pop
  c = Client("os_diagnose", [])
558 a8083063 Iustin Pop
  c.connect_list(node_list)
559 a8083063 Iustin Pop
  c.run()
560 a8083063 Iustin Pop
  result = c.getresult()
561 a8083063 Iustin Pop
  new_result = {}
562 a8083063 Iustin Pop
  for node_name in result:
563 a8083063 Iustin Pop
    if result[node_name]:
564 4e679f11 Guido Trotter
      nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
565 4e679f11 Guido Trotter
    else:
566 4e679f11 Guido Trotter
      nr = []
567 a8083063 Iustin Pop
    new_result[node_name] = nr
568 a8083063 Iustin Pop
  return new_result
569 a8083063 Iustin Pop
570 a8083063 Iustin Pop
571 00fe9e38 Guido Trotter
def call_os_get(node, name):
572 a8083063 Iustin Pop
  """Returns an OS definition.
573 a8083063 Iustin Pop

574 00fe9e38 Guido Trotter
  This is a single-node call.
575 a8083063 Iustin Pop

576 a8083063 Iustin Pop
  """
577 a8083063 Iustin Pop
  c = Client("os_get", [name])
578 00fe9e38 Guido Trotter
  c.connect(node)
579 a8083063 Iustin Pop
  c.run()
580 00fe9e38 Guido Trotter
  result = c.getresult().get(node, False)
581 00fe9e38 Guido Trotter
  if isinstance(result, dict):
582 dfa96ded Guido Trotter
    return objects.OS.FromDict(result)
583 00fe9e38 Guido Trotter
  else:
584 dfa96ded Guido Trotter
    return result
585 a8083063 Iustin Pop
586 a8083063 Iustin Pop
587 a8083063 Iustin Pop
def call_hooks_runner(node_list, hpath, phase, env):
588 a8083063 Iustin Pop
  """Call the hooks runner.
589 a8083063 Iustin Pop

590 a8083063 Iustin Pop
  Args:
591 a8083063 Iustin Pop
    - op: the OpCode instance
592 a8083063 Iustin Pop
    - env: a dictionary with the environment
593 a8083063 Iustin Pop

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

596 a8083063 Iustin Pop
  """
597 a8083063 Iustin Pop
  params = [hpath, phase, env]
598 a8083063 Iustin Pop
  c = Client("hooks_runner", params)
599 a8083063 Iustin Pop
  c.connect_list(node_list)
600 a8083063 Iustin Pop
  c.run()
601 a8083063 Iustin Pop
  result = c.getresult()
602 a8083063 Iustin Pop
  return result
603 a8083063 Iustin Pop
604 a8083063 Iustin Pop
605 8d528b7c Iustin Pop
def call_iallocator_runner(node, name, idata):
606 8d528b7c Iustin Pop
  """Call an iallocator on a remote node
607 8d528b7c Iustin Pop

608 8d528b7c Iustin Pop
  Args:
609 8d528b7c Iustin Pop
    - name: the iallocator name
610 8d528b7c Iustin Pop
    - input: the json-encoded input string
611 8d528b7c Iustin Pop

612 8d528b7c Iustin Pop
  This is a single-node call.
613 8d528b7c Iustin Pop

614 8d528b7c Iustin Pop
  """
615 8d528b7c Iustin Pop
  params = [name, idata]
616 8d528b7c Iustin Pop
  c = Client("iallocator_runner", params)
617 8d528b7c Iustin Pop
  c.connect(node)
618 8d528b7c Iustin Pop
  c.run()
619 8d528b7c Iustin Pop
  result = c.getresult().get(node, False)
620 8d528b7c Iustin Pop
  return result
621 8d528b7c Iustin Pop
622 8d528b7c Iustin Pop
623 4c8ba8b3 Iustin Pop
def call_blockdev_grow(node, cf_bdev, amount):
624 4c8ba8b3 Iustin Pop
  """Request a snapshot of the given block device.
625 4c8ba8b3 Iustin Pop

626 4c8ba8b3 Iustin Pop
  This is a single-node call.
627 4c8ba8b3 Iustin Pop

628 4c8ba8b3 Iustin Pop
  """
629 4c8ba8b3 Iustin Pop
  c = Client("blockdev_grow", [cf_bdev.ToDict(), amount])
630 4c8ba8b3 Iustin Pop
  c.connect(node)
631 4c8ba8b3 Iustin Pop
  c.run()
632 4c8ba8b3 Iustin Pop
  return c.getresult().get(node, False)
633 4c8ba8b3 Iustin Pop
634 4c8ba8b3 Iustin Pop
635 a8083063 Iustin Pop
def call_blockdev_snapshot(node, cf_bdev):
636 a8083063 Iustin Pop
  """Request a snapshot of the given block device.
637 a8083063 Iustin Pop

638 a8083063 Iustin Pop
  This is a single-node call.
639 a8083063 Iustin Pop

640 a8083063 Iustin Pop
  """
641 319856a9 Michael Hanselmann
  c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
642 a8083063 Iustin Pop
  c.connect(node)
643 a8083063 Iustin Pop
  c.run()
644 a8083063 Iustin Pop
  return c.getresult().get(node, False)
645 a8083063 Iustin Pop
646 a8083063 Iustin Pop
647 a8083063 Iustin Pop
def call_snapshot_export(node, snap_bdev, dest_node, instance):
648 a8083063 Iustin Pop
  """Request the export of a given snapshot.
649 a8083063 Iustin Pop

650 a8083063 Iustin Pop
  This is a single-node call.
651 a8083063 Iustin Pop

652 a8083063 Iustin Pop
  """
653 319856a9 Michael Hanselmann
  params = [snap_bdev.ToDict(), dest_node, instance.ToDict()]
654 a8083063 Iustin Pop
  c = Client("snapshot_export", params)
655 a8083063 Iustin Pop
  c.connect(node)
656 a8083063 Iustin Pop
  c.run()
657 a8083063 Iustin Pop
  return c.getresult().get(node, False)
658 a8083063 Iustin Pop
659 a8083063 Iustin Pop
660 a8083063 Iustin Pop
def call_finalize_export(node, instance, snap_disks):
661 a8083063 Iustin Pop
  """Request the completion of an export operation.
662 a8083063 Iustin Pop

663 a8083063 Iustin Pop
  This writes the export config file, etc.
664 a8083063 Iustin Pop

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

667 a8083063 Iustin Pop
  """
668 a8083063 Iustin Pop
  flat_disks = []
669 a8083063 Iustin Pop
  for disk in snap_disks:
670 319856a9 Michael Hanselmann
    flat_disks.append(disk.ToDict())
671 319856a9 Michael Hanselmann
  params = [instance.ToDict(), flat_disks]
672 a8083063 Iustin Pop
  c = Client("finalize_export", params)
673 a8083063 Iustin Pop
  c.connect(node)
674 a8083063 Iustin Pop
  c.run()
675 a8083063 Iustin Pop
  return c.getresult().get(node, False)
676 a8083063 Iustin Pop
677 a8083063 Iustin Pop
678 a8083063 Iustin Pop
def call_export_info(node, path):
679 a8083063 Iustin Pop
  """Queries the export information in a given path.
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("export_info", [path])
685 a8083063 Iustin Pop
  c.connect(node)
686 a8083063 Iustin Pop
  c.run()
687 a8083063 Iustin Pop
  result = c.getresult().get(node, False)
688 a8083063 Iustin Pop
  if not result:
689 a8083063 Iustin Pop
    return result
690 2d3e73c4 Michael Hanselmann
  return objects.SerializableConfigParser.Loads(str(result))
691 a8083063 Iustin Pop
692 a8083063 Iustin Pop
693 a8083063 Iustin Pop
def call_instance_os_import(node, inst, osdev, swapdev, src_node, src_image):
694 a8083063 Iustin Pop
  """Request the import of a backup into an instance.
695 a8083063 Iustin Pop

696 a8083063 Iustin Pop
  This is a single-node call.
697 a8083063 Iustin Pop

698 a8083063 Iustin Pop
  """
699 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev, src_node, src_image]
700 a8083063 Iustin Pop
  c = Client("instance_os_import", params)
701 a8083063 Iustin Pop
  c.connect(node)
702 a8083063 Iustin Pop
  c.run()
703 a8083063 Iustin Pop
  return c.getresult().get(node, False)
704 a8083063 Iustin Pop
705 a8083063 Iustin Pop
706 a8083063 Iustin Pop
def call_export_list(node_list):
707 a8083063 Iustin Pop
  """Gets the stored exports list.
708 a8083063 Iustin Pop

709 a8083063 Iustin Pop
  This is a multi-node call.
710 a8083063 Iustin Pop

711 a8083063 Iustin Pop
  """
712 a8083063 Iustin Pop
  c = Client("export_list", [])
713 a8083063 Iustin Pop
  c.connect_list(node_list)
714 a8083063 Iustin Pop
  c.run()
715 a8083063 Iustin Pop
  result = c.getresult()
716 a8083063 Iustin Pop
  return result
717 a8083063 Iustin Pop
718 a8083063 Iustin Pop
719 a8083063 Iustin Pop
def call_export_remove(node, export):
720 a8083063 Iustin Pop
  """Requests removal of a given export.
721 a8083063 Iustin Pop

722 a8083063 Iustin Pop
  This is a single-node call.
723 a8083063 Iustin Pop

724 a8083063 Iustin Pop
  """
725 a8083063 Iustin Pop
  c = Client("export_remove", [export])
726 a8083063 Iustin Pop
  c.connect(node)
727 a8083063 Iustin Pop
  c.run()
728 a8083063 Iustin Pop
  return c.getresult().get(node, False)
729 a8083063 Iustin Pop
730 a8083063 Iustin Pop
731 a8083063 Iustin Pop
def call_node_leave_cluster(node):
732 a8083063 Iustin Pop
  """Requests a node to clean the cluster information it has.
733 a8083063 Iustin Pop

734 a8083063 Iustin Pop
  This will remove the configuration information from the ganeti data
735 a8083063 Iustin Pop
  dir.
736 a8083063 Iustin Pop

737 a8083063 Iustin Pop
  This is a single-node call.
738 a8083063 Iustin Pop

739 a8083063 Iustin Pop
  """
740 a8083063 Iustin Pop
  c = Client("node_leave_cluster", [])
741 a8083063 Iustin Pop
  c.connect(node)
742 a8083063 Iustin Pop
  c.run()
743 a8083063 Iustin Pop
  return c.getresult().get(node, False)
744 dcb93971 Michael Hanselmann
745 dcb93971 Michael Hanselmann
746 dcb93971 Michael Hanselmann
def call_node_volumes(node_list):
747 dcb93971 Michael Hanselmann
  """Gets all volumes on node(s).
748 dcb93971 Michael Hanselmann

749 dcb93971 Michael Hanselmann
  This is a multi-node call.
750 dcb93971 Michael Hanselmann

751 dcb93971 Michael Hanselmann
  """
752 dcb93971 Michael Hanselmann
  c = Client("node_volumes", [])
753 dcb93971 Michael Hanselmann
  c.connect_list(node_list)
754 dcb93971 Michael Hanselmann
  c.run()
755 dcb93971 Michael Hanselmann
  return c.getresult()
756 06009e27 Iustin Pop
757 06009e27 Iustin Pop
758 06009e27 Iustin Pop
def call_test_delay(node_list, duration):
759 06009e27 Iustin Pop
  """Sleep for a fixed time on given node(s).
760 06009e27 Iustin Pop

761 06009e27 Iustin Pop
  This is a multi-node call.
762 06009e27 Iustin Pop

763 06009e27 Iustin Pop
  """
764 06009e27 Iustin Pop
  c = Client("test_delay", [duration])
765 06009e27 Iustin Pop
  c.connect_list(node_list)
766 06009e27 Iustin Pop
  c.run()
767 06009e27 Iustin Pop
  return c.getresult()
768 5e04ed8b Manuel Franceschini
769 5e04ed8b Manuel Franceschini
770 5e04ed8b Manuel Franceschini
def call_file_storage_dir_create(node, file_storage_dir):
771 5e04ed8b Manuel Franceschini
  """Create the given file storage directory.
772 5e04ed8b Manuel Franceschini

773 5e04ed8b Manuel Franceschini
  This is a single-node call.
774 5e04ed8b Manuel Franceschini

775 5e04ed8b Manuel Franceschini
  """
776 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_create", [file_storage_dir])
777 5e04ed8b Manuel Franceschini
  c.connect(node)
778 5e04ed8b Manuel Franceschini
  c.run()
779 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)
780 5e04ed8b Manuel Franceschini
781 5e04ed8b Manuel Franceschini
782 5e04ed8b Manuel Franceschini
def call_file_storage_dir_remove(node, file_storage_dir):
783 5e04ed8b Manuel Franceschini
  """Remove the given file storage directory.
784 5e04ed8b Manuel Franceschini

785 5e04ed8b Manuel Franceschini
  This is a single-node call.
786 5e04ed8b Manuel Franceschini

787 5e04ed8b Manuel Franceschini
  """
788 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_remove", [file_storage_dir])
789 5e04ed8b Manuel Franceschini
  c.connect(node)
790 5e04ed8b Manuel Franceschini
  c.run()
791 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)
792 5e04ed8b Manuel Franceschini
793 5e04ed8b Manuel Franceschini
794 5e04ed8b Manuel Franceschini
def call_file_storage_dir_rename(node, old_file_storage_dir,
795 5e04ed8b Manuel Franceschini
                                 new_file_storage_dir):
796 5e04ed8b Manuel Franceschini
  """Rename file storage directory.
797 5e04ed8b Manuel Franceschini

798 5e04ed8b Manuel Franceschini
  This is a single-node call.
799 5e04ed8b Manuel Franceschini

800 5e04ed8b Manuel Franceschini
  """
801 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_rename",
802 5e04ed8b Manuel Franceschini
             [old_file_storage_dir, new_file_storage_dir])
803 5e04ed8b Manuel Franceschini
  c.connect(node)
804 5e04ed8b Manuel Franceschini
  c.run()
805 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)