Commit 55cc0a44 authored by Michael Hanselmann's avatar Michael Hanselmann

Use new console information in hypervisor abstraction

This makes use of the new way of returning console information from the
master daemon. Unittests are included.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarRené Nussbaumer <rn@google.com>
parent 25ce3ec4
......@@ -449,7 +449,11 @@ python_tests = \
test/ganeti.ht_unittest.py \
test/ganeti.http_unittest.py \
test/ganeti.hypervisor_unittest.py \
test/ganeti.hypervisor.hv_chroot_unittest.py \
test/ganeti.hypervisor.hv_fake_unittest.py \
test/ganeti.hypervisor.hv_kvm_unittest.py \
test/ganeti.hypervisor.hv_lxc_unittest.py \
test/ganeti.hypervisor.hv_xen_unittest.py \
test/ganeti.impexpd_unittest.py \
test/ganeti.jqueue_unittest.py \
test/ganeti.locking_unittest.py \
......
......@@ -7691,14 +7691,9 @@ class LUConnectConsole(NoHooksLU):
# instance and then saving the defaults in the instance itself.
hvparams = cluster.FillHV(instance)
beparams = cluster.FillBE(instance)
console_cmd = hyper.GetShellCommandForConsole(instance, hvparams, beparams)
console = objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_SSH,
host=node,
user="root",
command=console_cmd)
console = hyper.GetInstanceConsole(instance, hvparams, beparams)
assert console.instance == instance.name
assert console.Validate()
return console.ToDict()
......
......@@ -206,8 +206,8 @@ class BaseHypervisor(object):
raise NotImplementedError
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
def GetInstanceConsole(cls, instance, hvparams, beparams):
"""Return information for connecting to the console of an instance.
"""
raise NotImplementedError
......
......@@ -31,6 +31,7 @@ import logging
from ganeti import constants
from ganeti import errors # pylint: disable-msg=W0611
from ganeti import utils
from ganeti import objects
from ganeti.hypervisor import hv_base
from ganeti.errors import HypervisorError
......@@ -246,15 +247,21 @@ class ChrootManager(hv_base.BaseHypervisor):
return self.GetLinuxNodeInfo()
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
def GetInstanceConsole(cls, instance, # pylint: disable-msg=W0221
hvparams, beparams, root_dir=None):
"""Return information for connecting to the console of an instance.
"""
root_dir = cls._InstanceDir(instance.name)
if not os.path.ismount(root_dir):
raise HypervisorError("Instance %s is not running" % instance.name)
return "chroot %s" % root_dir
if root_dir is None:
root_dir = cls._InstanceDir(instance.name)
if not os.path.ismount(root_dir):
raise HypervisorError("Instance %s is not running" % instance.name)
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_SSH,
host=instance.primary_node,
user=constants.GANETI_RUNAS,
command=["chroot", root_dir])
def Verify(self):
"""Verify the hypervisor.
......
......@@ -30,6 +30,7 @@ import logging
from ganeti import utils
from ganeti import constants
from ganeti import errors
from ganeti import objects
from ganeti.hypervisor import hv_base
......@@ -204,11 +205,14 @@ class FakeHypervisor(hv_base.BaseHypervisor):
return result
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
def GetInstanceConsole(cls, instance, hvparams, beparams):
"""Return information for connecting to the console of an instance.
"""
return "echo Console not available for fake hypervisor"
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_MESSAGE,
message=("Console not available for fake"
" hypervisor"))
def Verify(self):
"""Verify the hypervisor.
......
......@@ -1035,28 +1035,33 @@ class KVMHypervisor(hv_base.BaseHypervisor):
return self.GetLinuxNodeInfo()
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
def GetInstanceConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
"""
if hvparams[constants.HV_SERIAL_CONSOLE]:
shell_command = ("%s STDIO,%s UNIX-CONNECT:%s" %
(constants.SOCAT_PATH, cls._SocatUnixConsoleParams(),
utils.ShellQuote(cls._InstanceSerial(instance.name))))
else:
shell_command = "echo 'No serial shell for instance %s'" % instance.name
cmd = [constants.SOCAT_PATH,
"STDIO,%s" % cls._SocatUnixConsoleParams(),
"UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_SSH,
host=instance.primary_node,
user=constants.GANETI_RUNAS,
command=cmd)
vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
if vnc_bind_address:
if instance.network_port > constants.VNC_BASE_PORT:
display = instance.network_port - constants.VNC_BASE_PORT
vnc_command = ("echo 'Instance has VNC listening on %s:%d"
" (display: %d)'" % (vnc_bind_address,
instance.network_port,
display))
shell_command = "%s; %s" % (vnc_command, shell_command)
return shell_command
if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
display = instance.network_port - constants.VNC_BASE_PORT
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_VNC,
host=vnc_bind_address,
port=instance.network_port,
display=display)
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_MESSAGE,
message=("No serial shell for instance %s" %
instance.name))
def Verify(self):
"""Verify the hypervisor.
......@@ -1069,7 +1074,6 @@ class KVMHypervisor(hv_base.BaseHypervisor):
if not os.path.exists(constants.SOCAT_PATH):
return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
@classmethod
def CheckParameterSyntax(cls, hvparams):
"""Check the given parameters for validity.
......
......@@ -31,6 +31,7 @@ import logging
from ganeti import constants
from ganeti import errors # pylint: disable-msg=W0611
from ganeti import utils
from ganeti import objects
from ganeti.hypervisor import hv_base
from ganeti.errors import HypervisorError
......@@ -374,11 +375,15 @@ class LXCHypervisor(hv_base.BaseHypervisor):
return self.GetLinuxNodeInfo()
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
def GetInstanceConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
"""
return "lxc-console -n %s" % instance.name
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_SSH,
host=instance.primary_node,
user=constants.GANETI_RUNAS,
command=["lxc-console", "-n", instance.name])
def Verify(self):
"""Verify the hypervisor.
......
......@@ -31,6 +31,7 @@ from ganeti import errors
from ganeti import utils
from ganeti.hypervisor import hv_base
from ganeti import netutils
from ganeti import objects
class XenHypervisor(hv_base.BaseHypervisor):
......@@ -294,12 +295,15 @@ class XenHypervisor(hv_base.BaseHypervisor):
return result
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
def GetInstanceConsole(cls, instance, hvparams, beparams):
"""Return a command for connecting to the console of an instance.
"""
return "xm console %s" % instance.name
return objects.InstanceConsole(instance=instance.name,
kind=constants.CONS_SSH,
host=instance.primary_node,
user=constants.GANETI_RUNAS,
command=["xm", "console", instance.name])
def Verify(self):
"""Verify the hypervisor.
......
#!/usr/bin/python
#
# Copyright (C) 2011 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for testing ganeti.hypervisor.hv_chroot"""
import unittest
import tempfile
import shutil
from ganeti import constants
from ganeti import objects
from ganeti import hypervisor
from ganeti.hypervisor import hv_chroot
import testutils
class TestConsole(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tmpdir)
def test(self):
instance = objects.Instance(name="fake.example.com", primary_node="node837")
cons = hv_chroot.ChrootManager.GetInstanceConsole(instance, {}, {},
root_dir=self.tmpdir)
self.assertTrue(cons.Validate())
self.assertEqual(cons.kind, constants.CONS_SSH)
self.assertEqual(cons.host, instance.primary_node)
if __name__ == "__main__":
testutils.GanetiTestProgram()
#!/usr/bin/python
#
# Copyright (C) 2011 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for testing ganeti.hypervisor.hv_fake"""
import unittest
from ganeti import constants
from ganeti import objects
from ganeti import hypervisor
from ganeti.hypervisor import hv_fake
import testutils
class TestConsole(unittest.TestCase):
def test(self):
instance = objects.Instance(name="fake.example.com")
cons = hv_fake.FakeHypervisor.GetInstanceConsole(instance, {}, {})
self.assertTrue(cons.Validate())
self.assertEqual(cons.kind, constants.CONS_MESSAGE)
if __name__ == "__main__":
testutils.GanetiTestProgram()
#!/usr/bin/python
#
# Copyright (C) 2010 Google Inc.
# Copyright (C) 2010, 2011 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -80,5 +80,49 @@ class TestWriteNetScript(unittest.TestCase):
inst, nic, 2)
class TestConsole(unittest.TestCase):
def _Test(self, instance, hvparams):
cons = hv_kvm.KVMHypervisor.GetInstanceConsole(instance, hvparams, {})
self.assertTrue(cons.Validate())
return cons
def testSerial(self):
instance = objects.Instance(name="kvm.example.com",
primary_node="node6017")
hvparams = {
constants.HV_SERIAL_CONSOLE: True,
constants.HV_VNC_BIND_ADDRESS: None,
}
cons = self._Test(instance, hvparams)
self.assertEqual(cons.kind, constants.CONS_SSH)
self.assertEqual(cons.host, instance.primary_node)
self.assertEqual(cons.command[0], constants.SOCAT_PATH)
def testVnc(self):
instance = objects.Instance(name="kvm.example.com",
primary_node="node7235",
network_port=constants.VNC_BASE_PORT + 10)
hvparams = {
constants.HV_SERIAL_CONSOLE: False,
constants.HV_VNC_BIND_ADDRESS: "192.0.2.1",
}
cons = self._Test(instance, hvparams)
self.assertEqual(cons.kind, constants.CONS_VNC)
self.assertEqual(cons.host, "192.0.2.1")
self.assertEqual(cons.port, constants.VNC_BASE_PORT + 10)
self.assertEqual(cons.display, 10)
def testNoConsole(self):
instance = objects.Instance(name="kvm.example.com",
primary_node="node24325",
network_port=0)
hvparams = {
constants.HV_SERIAL_CONSOLE: False,
constants.HV_VNC_BIND_ADDRESS: None,
}
cons = self._Test(instance, hvparams)
self.assertEqual(cons.kind, constants.CONS_MESSAGE)
if __name__ == "__main__":
testutils.GanetiTestProgram()
#!/usr/bin/python
#
# Copyright (C) 2011 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for testing ganeti.hypervisor.hv_lxc"""
import unittest
from ganeti import constants
from ganeti import objects
from ganeti import hypervisor
from ganeti.hypervisor import hv_lxc
import testutils
class TestConsole(unittest.TestCase):
def test(self):
instance = objects.Instance(name="lxc.example.com", primary_node="node199")
cons = hv_lxc.LXCHypervisor.GetInstanceConsole(instance, {}, {})
self.assertTrue(cons.Validate())
self.assertEqual(cons.kind, constants.CONS_SSH)
self.assertEqual(cons.host, instance.primary_node)
self.assertEqual(cons.command[-1], instance.name)
if __name__ == "__main__":
testutils.GanetiTestProgram()
#!/usr/bin/python
#
# Copyright (C) 2011 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for testing ganeti.hypervisor.hv_lxc"""
import unittest
from ganeti import constants
from ganeti import objects
from ganeti import hypervisor
from ganeti.hypervisor import hv_xen
import testutils
class TestConsole(unittest.TestCase):
def test(self):
for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
instance = objects.Instance(name="xen.example.com",
primary_node="node24828")
cons = cls.GetInstanceConsole(instance, {}, {})
self.assertTrue(cons.Validate())
self.assertEqual(cons.kind, constants.CONS_SSH)
self.assertEqual(cons.host, instance.primary_node)
self.assertEqual(cons.command[-1], instance.name)
if __name__ == "__main__":
testutils.GanetiTestProgram()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment