Revision 3d942d8b
b/lib/hypervisor/hv_xen.py | ||
---|---|---|
320 | 320 |
XL_CONFIG_FILE, |
321 | 321 |
] |
322 | 322 |
|
323 |
def __init__(self, _cfgdir=None): |
|
323 |
def __init__(self, _cfgdir=None, _run_cmd_fn=None, _cmd=None):
|
|
324 | 324 |
hv_base.BaseHypervisor.__init__(self) |
325 | 325 |
|
326 | 326 |
if _cfgdir is None: |
... | ... | |
328 | 328 |
else: |
329 | 329 |
self._cfgdir = _cfgdir |
330 | 330 |
|
331 |
if _run_cmd_fn is None: |
|
332 |
self._run_cmd_fn = utils.RunCmd |
|
333 |
else: |
|
334 |
self._run_cmd_fn = _run_cmd_fn |
|
335 |
|
|
336 |
self._cmd = _cmd |
|
337 |
|
|
338 |
def _GetCommand(self): |
|
339 |
if self._cmd is None: |
|
340 |
# TODO: Make command a hypervisor parameter |
|
341 |
cmd = constants.XEN_CMD |
|
342 |
else: |
|
343 |
cmd = self._cmd |
|
344 |
|
|
345 |
if cmd not in constants.KNOWN_XEN_COMMANDS: |
|
346 |
raise errors.ProgrammerError("Unknown Xen command '%s'" % cmd) |
|
347 |
|
|
348 |
return cmd |
|
349 |
|
|
350 |
def _RunXen(self, args): |
|
351 |
"""Wrapper around L{utils.RunCmd} to run Xen command. |
|
352 |
|
|
353 |
@see: L{utils.RunCmd} |
|
354 |
|
|
355 |
""" |
|
356 |
cmd = [self._GetCommand()] |
|
357 |
cmd.extend(args) |
|
358 |
|
|
359 |
return self._run_cmd_fn(cmd) |
|
360 |
|
|
331 | 361 |
def _ConfigFileName(self, instance_name): |
332 | 362 |
"""Get the config file name for an instance. |
333 | 363 |
|
... | ... | |
381 | 411 |
""" |
382 | 412 |
utils.RemoveFile(self._ConfigFileName(instance_name)) |
383 | 413 |
|
384 |
@staticmethod |
|
385 |
def _GetXmList(include_node): |
|
414 |
def _GetXmList(self, include_node): |
|
386 | 415 |
"""Wrapper around module level L{_GetXmList}. |
387 | 416 |
|
388 | 417 |
""" |
389 |
# TODO: Abstract running Xen command for testing |
|
390 |
return _GetXmList(lambda: utils.RunCmd([constants.XEN_CMD, "list"]), |
|
391 |
include_node) |
|
418 |
return _GetXmList(lambda: self._RunXen(["list"]), include_node) |
|
392 | 419 |
|
393 | 420 |
def ListInstances(self): |
394 | 421 |
"""Get the list of running instances. |
... | ... | |
445 | 472 |
|
446 | 473 |
self._MakeConfigFile(instance, startup_memory, block_devices) |
447 | 474 |
|
448 |
cmd = [constants.XEN_CMD, "create"]
|
|
475 |
cmd = ["create"] |
|
449 | 476 |
if startup_paused: |
450 |
cmd.extend(["-p"]) |
|
451 |
cmd.extend([self._ConfigFileName(instance.name)]) |
|
452 |
result = utils.RunCmd(cmd) |
|
477 |
cmd.append("-p") |
|
478 |
cmd.append(self._ConfigFileName(instance.name)) |
|
453 | 479 |
|
480 |
result = self._RunXen(cmd) |
|
454 | 481 |
if result.failed: |
455 | 482 |
raise errors.HypervisorError("Failed to start instance %s: %s (%s)" % |
456 | 483 |
(instance.name, result.fail_reason, |
... | ... | |
464 | 491 |
name = instance.name |
465 | 492 |
|
466 | 493 |
if force: |
467 |
command = [constants.XEN_CMD, "destroy", name]
|
|
494 |
action = "destroy"
|
|
468 | 495 |
else: |
469 |
command = [constants.XEN_CMD, "shutdown", name] |
|
470 |
result = utils.RunCmd(command) |
|
496 |
action = "shutdown" |
|
471 | 497 |
|
498 |
result = self._RunXen([action, name]) |
|
472 | 499 |
if result.failed: |
473 | 500 |
raise errors.HypervisorError("Failed to stop instance %s: %s, %s" % |
474 | 501 |
(name, result.fail_reason, result.output)) |
... | ... | |
486 | 513 |
raise errors.HypervisorError("Failed to reboot instance %s," |
487 | 514 |
" not running" % instance.name) |
488 | 515 |
|
489 |
result = utils.RunCmd([constants.XEN_CMD, "reboot", instance.name])
|
|
516 |
result = self._RunXen(["reboot", instance.name])
|
|
490 | 517 |
if result.failed: |
491 | 518 |
raise errors.HypervisorError("Failed to reboot instance %s: %s, %s" % |
492 | 519 |
(instance.name, result.fail_reason, |
... | ... | |
519 | 546 |
@param mem: actual memory size to use for instance runtime |
520 | 547 |
|
521 | 548 |
""" |
522 |
cmd = [constants.XEN_CMD, "mem-set", instance.name, mem] |
|
523 |
result = utils.RunCmd(cmd) |
|
549 |
result = self._RunXen(["mem-set", instance.name, mem]) |
|
524 | 550 |
if result.failed: |
525 | 551 |
raise errors.HypervisorError("Failed to balloon instance %s: %s (%s)" % |
526 | 552 |
(instance.name, result.fail_reason, |
527 | 553 |
result.output)) |
554 |
|
|
555 |
# Update configuration file |
|
528 | 556 |
cmd = ["sed", "-ie", "s/^memory.*$/memory = %s/" % mem] |
529 | 557 |
cmd.append(self._ConfigFileName(instance.name)) |
558 |
|
|
530 | 559 |
result = utils.RunCmd(cmd) |
531 | 560 |
if result.failed: |
532 | 561 |
raise errors.HypervisorError("Failed to update memory for %s: %s (%s)" % |
... | ... | |
539 | 568 |
@see: L{_GetNodeInfo} and L{_ParseNodeInfo} |
540 | 569 |
|
541 | 570 |
""" |
542 |
# TODO: Abstract running Xen command for testing |
|
543 |
result = utils.RunCmd([constants.XEN_CMD, "info"]) |
|
571 |
result = self._RunXen(["info"]) |
|
544 | 572 |
if result.failed: |
545 | 573 |
logging.error("Can't run 'xm info' (%s): %s", result.fail_reason, |
546 | 574 |
result.output) |
... | ... | |
568 | 596 |
@return: Problem description if something is wrong, C{None} otherwise |
569 | 597 |
|
570 | 598 |
""" |
571 |
result = utils.RunCmd([constants.XEN_CMD, "info"])
|
|
599 |
result = self._RunXen(["info"])
|
|
572 | 600 |
if result.failed: |
573 | 601 |
return "'xm info' failed: %s, %s" % (result.fail_reason, result.output) |
574 | 602 |
|
... | ... | |
634 | 662 |
|
635 | 663 |
port = instance.hvparams[constants.HV_MIGRATION_PORT] |
636 | 664 |
|
637 |
if (constants.XEN_CMD == constants.XEN_CMD_XM and
|
|
665 |
if (self._cmd == constants.XEN_CMD_XM and
|
|
638 | 666 |
not netutils.TcpPing(target, port, live_port_needed=True)): |
639 | 667 |
raise errors.HypervisorError("Remote host %s not listening on port" |
640 | 668 |
" %s, cannot migrate" % (target, port)) |
641 | 669 |
|
642 |
args = [constants.XEN_CMD, "migrate"] |
|
643 |
if constants.XEN_CMD == constants.XEN_CMD_XM: |
|
670 |
args = ["migrate"] |
|
671 |
|
|
672 |
if self._cmd == constants.XEN_CMD_XM: |
|
644 | 673 |
args.extend(["-p", "%d" % port]) |
645 | 674 |
if live: |
646 | 675 |
args.append("-l") |
647 |
elif constants.XEN_CMD == constants.XEN_CMD_XL: |
|
676 |
|
|
677 |
elif self._cmd == constants.XEN_CMD_XL: |
|
648 | 678 |
cluster_name = ssconf.SimpleStore().GetClusterName() |
649 | 679 |
args.extend(["-s", constants.XL_SSH_CMD % cluster_name]) |
650 | 680 |
args.extend(["-C", self._ConfigFileName(instance.name)]) |
681 |
|
|
651 | 682 |
else: |
652 |
raise errors.HypervisorError("Unsupported xen command: %s" % |
|
653 |
constants.XEN_CMD) |
|
683 |
raise errors.HypervisorError("Unsupported xen command: %s" % self._cmd) |
|
654 | 684 |
|
655 | 685 |
args.extend([instance.name, target]) |
656 |
result = utils.RunCmd(args) |
|
686 |
|
|
687 |
result = self._RunXen(args) |
|
657 | 688 |
if result.failed: |
658 | 689 |
raise errors.HypervisorError("Failed to migrate instance %s: %s" % |
659 | 690 |
(instance.name, result.output)) |
Also available in: Unified diff