Merge "Remove 'nova-console' service, 'console' RPC API"
This commit is contained in:
commit
a3499027f0
@ -31,7 +31,6 @@ redirectmatch 301 ^/nova/([^/]+)/man/nova-cells.html$ /nova/$1/cli/nova-cells.ht
|
||||
# this is gone and never coming back, indicate that to the end users
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-compute.html$ /nova/$1/cli/nova-compute.html
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-conductor.html$ /nova/$1/cli/nova-conductor.html
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-console.html$ /nova/$1/cli/nova-console.html
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-dhcpbridge.html$ /nova/$1/cli/nova-dhcpbridge.html
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-manage.html$ /nova/$1/cli/nova-manage.html
|
||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-network.html$ /nova/$1/cli/nova-network.html
|
||||
|
@ -87,5 +87,4 @@ deployments, but are documented for existing ones.
|
||||
|
||||
nova-dhcpbridge
|
||||
nova-network
|
||||
nova-console
|
||||
nova-xvpvncproxy
|
||||
|
@ -1,54 +0,0 @@
|
||||
============
|
||||
nova-console
|
||||
============
|
||||
|
||||
-------------------
|
||||
Nova Console Server
|
||||
-------------------
|
||||
|
||||
:Author: openstack@lists.openstack.org
|
||||
:Copyright: OpenStack Foundation
|
||||
:Manual section: 1
|
||||
:Manual group: cloud computing
|
||||
|
||||
Synopsis
|
||||
========
|
||||
|
||||
::
|
||||
|
||||
nova-console [options]
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
:program:`nova-console` is a server daemon that serves the Nova Console
|
||||
service, which is a console proxy to set up multi-tenant VM console access,
|
||||
e.g. with *XVP*.
|
||||
|
||||
.. deprecated:: 19.0.0
|
||||
|
||||
:program:`nova-console` is deprecated since 19.0.0 (Stein) and will be
|
||||
removed in an upcoming release.
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
**General options**
|
||||
|
||||
Files
|
||||
=====
|
||||
|
||||
* ``/etc/nova/nova.conf``
|
||||
* ``/etc/nova/policy.json``
|
||||
* ``/etc/nova/rootwrap.conf``
|
||||
* ``/etc/nova/rootwrap.d/``
|
||||
|
||||
See Also
|
||||
========
|
||||
|
||||
* :nova-doc:`OpenStack Nova <>`
|
||||
|
||||
Bugs
|
||||
====
|
||||
|
||||
* Nova bugs are managed at `Launchpad <https://bugs.launchpad.net/nova>`__
|
@ -86,7 +86,6 @@ _man_pages = [
|
||||
('nova-api-os-compute', u'Cloud controller fabric'),
|
||||
('nova-compute', u'Cloud controller fabric'),
|
||||
('nova-conductor', u'Cloud controller fabric'),
|
||||
('nova-console', u'Cloud controller fabric'),
|
||||
('nova-dhcpbridge', u'Cloud controller fabric'),
|
||||
('nova-manage', u'Cloud controller fabric'),
|
||||
('nova-network', u'Cloud controller fabric'),
|
||||
|
@ -31,7 +31,6 @@
|
||||
/nova/latest/man/nova-cells.html 301 /nova/latest/cli/nova-cells.html
|
||||
/nova/latest/man/nova-compute.html 301 /nova/latest/cli/nova-compute.html
|
||||
/nova/latest/man/nova-conductor.html 301 /nova/latest/cli/nova-conductor.html
|
||||
/nova/latest/man/nova-console.html 301 /nova/latest/cli/nova-console.html
|
||||
/nova/latest/man/nova-dhcpbridge.html 301 /nova/latest/cli/nova-dhcpbridge.html
|
||||
/nova/latest/man/nova-manage.html 301 /nova/latest/cli/nova-manage.html
|
||||
/nova/latest/man/nova-network.html 301 /nova/latest/cli/nova-network.html
|
||||
|
@ -1,51 +0,0 @@
|
||||
# Copyright (c) 2010 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Starter script for Nova Console Proxy."""
|
||||
|
||||
import sys
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_reports import guru_meditation_report as gmr
|
||||
from oslo_reports import opts as gmr_opts
|
||||
|
||||
from nova import config
|
||||
from nova.console import rpcapi as console_rpcapi
|
||||
from nova import objects
|
||||
from nova import service
|
||||
from nova import version
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger('nova.console')
|
||||
|
||||
|
||||
def main():
|
||||
config.parse_args(sys.argv)
|
||||
logging.setup(CONF, "nova")
|
||||
objects.register_all()
|
||||
gmr_opts.set_defaults(CONF)
|
||||
|
||||
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
|
||||
|
||||
LOG.warning('The nova-console service is deprecated as it is Xen '
|
||||
'specific, does not function properly in a multi-cell '
|
||||
'environment, and has effectively been replaced by noVNC '
|
||||
'and the nova-novncproxy service.')
|
||||
|
||||
server = service.Service.create(binary='nova-console',
|
||||
topic=console_rpcapi.RPC_TOPIC)
|
||||
service.serve(server)
|
||||
service.wait()
|
@ -69,7 +69,6 @@ from nova.compute.utils import wrap_instance_event
|
||||
from nova.compute import vm_states
|
||||
from nova import conductor
|
||||
import nova.conf
|
||||
from nova.console import rpcapi as console_rpcapi
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova import exception_wrapper
|
||||
@ -1522,6 +1521,7 @@ class ComputeManager(manager.Manager):
|
||||
except exception.InstanceNotFound:
|
||||
return power_state.NOSTATE
|
||||
|
||||
# TODO(stephenfin): Remove this once we bump the compute API to v6.0
|
||||
def get_console_topic(self, context):
|
||||
"""Retrieves the console host for a project on this host.
|
||||
|
||||
@ -1529,7 +1529,7 @@ class ComputeManager(manager.Manager):
|
||||
|
||||
"""
|
||||
# TODO(mdragon): perhaps make this variable by console_type?
|
||||
return '%s.%s' % (console_rpcapi.RPC_TOPIC, CONF.console_host)
|
||||
return 'console.%s' % CONF.console_host
|
||||
|
||||
@wrap_exception()
|
||||
def get_console_pool_info(self, context, console_type):
|
||||
|
@ -709,6 +709,7 @@ class ComputeAPI(object):
|
||||
return cctxt.call(ctxt, 'get_console_pool_info',
|
||||
console_type=console_type)
|
||||
|
||||
# TODO(stephenfin): This is no longer used and can be removed in v6.0
|
||||
def get_console_topic(self, ctxt, host):
|
||||
version = '5.0'
|
||||
cctxt = self.router.client(ctxt).prepare(
|
||||
|
@ -96,18 +96,6 @@ Conductor RPC API version cap.
|
||||
|
||||
Possible values:
|
||||
|
||||
* By default send the latest version the client knows about
|
||||
* A string representing a version number in the format 'N.N';
|
||||
for example, possible values might be '1.12' or '2.0'.
|
||||
* An OpenStack release name, in lower case, such as 'mitaka' or
|
||||
'liberty'.
|
||||
"""),
|
||||
cfg.StrOpt('console',
|
||||
help="""
|
||||
Console RPC API version cap.
|
||||
|
||||
Possible values:
|
||||
|
||||
* By default send the latest version the client knows about
|
||||
* A string representing a version number in the format 'N.N';
|
||||
for example, possible values might be '1.12' or '2.0'.
|
||||
|
@ -1,56 +0,0 @@
|
||||
# Copyright (c) 2010 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Handles ConsoleProxy API requests."""
|
||||
|
||||
|
||||
from nova.compute import rpcapi as compute_rpcapi
|
||||
from nova.console import rpcapi as console_rpcapi
|
||||
from nova.db import base
|
||||
from nova import objects
|
||||
|
||||
|
||||
class API(base.Base):
|
||||
"""API for spinning up or down console proxy connections."""
|
||||
def get_consoles(self, context, instance_uuid):
|
||||
return self.db.console_get_all_by_instance(context, instance_uuid,
|
||||
columns_to_join=['pool'])
|
||||
|
||||
def get_console(self, context, instance_uuid, console_uuid):
|
||||
return self.db.console_get(context, console_uuid, instance_uuid)
|
||||
|
||||
def delete_console(self, context, instance_uuid, console_uuid):
|
||||
console = self.db.console_get(context, console_uuid, instance_uuid)
|
||||
rpcapi = console_rpcapi.ConsoleAPI(topic=console_rpcapi.RPC_TOPIC,
|
||||
server=console['pool']['host'])
|
||||
rpcapi.remove_console(context, console['id'])
|
||||
|
||||
def create_console(self, context, instance_uuid):
|
||||
# NOTE(mdragon): If we wanted to return this the console info
|
||||
# here, as we would need to do a call.
|
||||
# They can just do an index later to fetch
|
||||
# console info. I am not sure which is better
|
||||
# here.
|
||||
instance = objects.Instance.get_by_uuid(context, instance_uuid)
|
||||
topic = self._get_console_topic(context, instance.host)
|
||||
server = None
|
||||
if '.' in topic:
|
||||
topic, server = topic.split('.', 1)
|
||||
rpcapi = console_rpcapi.ConsoleAPI(topic=topic, server=server)
|
||||
rpcapi.add_console(context, instance.id)
|
||||
|
||||
def _get_console_topic(self, context, instance_host):
|
||||
rpcapi = compute_rpcapi.ComputeAPI()
|
||||
return rpcapi.get_console_topic(context, instance_host)
|
@ -1,115 +0,0 @@
|
||||
# Copyright (c) 2010 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Console Proxy Service."""
|
||||
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging as messaging
|
||||
|
||||
from nova.compute import rpcapi as compute_rpcapi
|
||||
import nova.conf
|
||||
from nova.console import xvp
|
||||
from nova import exception
|
||||
from nova import manager
|
||||
from nova import objects
|
||||
from nova import utils
|
||||
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConsoleProxyManager(manager.Manager):
|
||||
"""Sets up and tears down any console proxy connections.
|
||||
|
||||
Needed for accessing instance consoles securely.
|
||||
|
||||
"""
|
||||
|
||||
target = messaging.Target(version='2.0')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.driver = xvp.XVPConsoleProxy()
|
||||
super(ConsoleProxyManager, self).__init__(service_name='console',
|
||||
*args, **kwargs)
|
||||
self.driver.host = self.host
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
||||
def reset(self):
|
||||
LOG.info('Reloading compute RPC API')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
||||
def init_host(self):
|
||||
self.driver.init_host()
|
||||
|
||||
def add_console(self, context, instance_id):
|
||||
instance = objects.Instance.get_by_id(context, instance_id)
|
||||
host = instance.host
|
||||
name = instance.name
|
||||
pool = self._get_pool_for_instance_host(context, host)
|
||||
try:
|
||||
console = self.db.console_get_by_pool_instance(context,
|
||||
pool['id'],
|
||||
instance.uuid)
|
||||
except exception.NotFound:
|
||||
LOG.debug('Adding console', instance=instance)
|
||||
password = utils.generate_password(8)
|
||||
port = self.driver.get_port(context)
|
||||
console_data = {'instance_name': name,
|
||||
'instance_uuid': instance.uuid,
|
||||
'password': password,
|
||||
'pool_id': pool['id']}
|
||||
if port:
|
||||
console_data['port'] = port
|
||||
console = self.db.console_create(context, console_data)
|
||||
self.driver.setup_console(context, console)
|
||||
|
||||
return console['id']
|
||||
|
||||
def remove_console(self, context, console_id):
|
||||
try:
|
||||
console = self.db.console_get(context, console_id)
|
||||
except exception.NotFound:
|
||||
LOG.debug('Tried to remove non-existent console '
|
||||
'%(console_id)s.',
|
||||
{'console_id': console_id})
|
||||
return
|
||||
self.db.console_delete(context, console_id)
|
||||
self.driver.teardown_console(context, console)
|
||||
|
||||
def _get_pool_for_instance_host(self, context, instance_host):
|
||||
context = context.elevated()
|
||||
console_type = self.driver.console_type
|
||||
try:
|
||||
pool = self.db.console_pool_get_by_host_type(context,
|
||||
instance_host,
|
||||
self.host,
|
||||
console_type)
|
||||
except exception.NotFound:
|
||||
# NOTE(mdragon): Right now, the only place this info exists is the
|
||||
# compute worker's flagfile, at least for
|
||||
# xenserver. Thus we need to ask.
|
||||
pool_info = self.compute_rpcapi.get_console_pool_info(context,
|
||||
instance_host, console_type)
|
||||
pool_info['password'] = self.driver.fix_pool_password(
|
||||
pool_info['password'])
|
||||
pool_info['host'] = self.host
|
||||
pool_info['public_hostname'] = \
|
||||
CONF.xenserver.console_public_hostname
|
||||
pool_info['console_type'] = self.driver.console_type
|
||||
pool_info['compute_host'] = instance_host
|
||||
pool = self.db.console_pool_create(context, pool_info)
|
||||
return pool
|
@ -1,77 +0,0 @@
|
||||
# Copyright 2013 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Client side of the console RPC API.
|
||||
"""
|
||||
|
||||
import oslo_messaging as messaging
|
||||
|
||||
import nova.conf
|
||||
from nova import profiler
|
||||
from nova import rpc
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
RPC_TOPIC = "console"
|
||||
|
||||
|
||||
@profiler.trace_cls("rpc")
|
||||
class ConsoleAPI(object):
|
||||
'''Client side of the console rpc API.
|
||||
|
||||
API version history:
|
||||
|
||||
1.0 - Initial version.
|
||||
1.1 - Added get_backdoor_port()
|
||||
|
||||
... Grizzly and Havana support message version 1.1. So, any changes to
|
||||
existing methods in 1.x after that point should be done such that they
|
||||
can handle the version_cap being set to 1.1.
|
||||
|
||||
2.0 - Major API rev for Icehouse
|
||||
|
||||
... Icehouse, Juno, Kilo, Liberty, Mitaka, Newton, and Ocata support
|
||||
message version 2.0. So, any changes to existing methods in 2.x after
|
||||
that point should be done such that they can handle the version_cap
|
||||
being set to 2.0.
|
||||
|
||||
'''
|
||||
|
||||
VERSION_ALIASES = {
|
||||
'grizzly': '1.1',
|
||||
'havana': '1.1',
|
||||
'icehouse': '2.0',
|
||||
'juno': '2.0',
|
||||
'kilo': '2.0',
|
||||
'liberty': '2.0',
|
||||
'mitaka': '2.0',
|
||||
'newton': '2.0',
|
||||
'ocata': '2.0',
|
||||
}
|
||||
|
||||
def __init__(self, topic=None, server=None):
|
||||
super(ConsoleAPI, self).__init__()
|
||||
topic = topic if topic else RPC_TOPIC
|
||||
target = messaging.Target(topic=topic, server=server, version='2.0')
|
||||
version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.console,
|
||||
CONF.upgrade_levels.console)
|
||||
self.client = rpc.get_client(target, version_cap=version_cap)
|
||||
|
||||
def add_console(self, ctxt, instance_id):
|
||||
cctxt = self.client.prepare()
|
||||
cctxt.cast(ctxt, 'add_console', instance_id=instance_id)
|
||||
|
||||
def remove_console(self, ctxt, console_id):
|
||||
cctxt = self.client.prepare()
|
||||
cctxt.cast(ctxt, 'remove_console', console_id=console_id)
|
@ -1413,21 +1413,7 @@ def project_get_networks(context, project_id, associate=True):
|
||||
return IMPL.project_get_networks(context, project_id, associate)
|
||||
|
||||
|
||||
###################
|
||||
|
||||
|
||||
def console_pool_create(context, values):
|
||||
"""Create console pool."""
|
||||
return IMPL.console_pool_create(context, values)
|
||||
|
||||
|
||||
def console_pool_get_by_host_type(context, compute_host, proxy_host,
|
||||
console_type):
|
||||
"""Fetch a console pool for a given proxy host, compute host, and type."""
|
||||
return IMPL.console_pool_get_by_host_type(context,
|
||||
compute_host,
|
||||
proxy_host,
|
||||
console_type)
|
||||
##################
|
||||
|
||||
|
||||
def console_pool_get_all_by_host_type(context, host, console_type):
|
||||
@ -1437,31 +1423,6 @@ def console_pool_get_all_by_host_type(context, host, console_type):
|
||||
console_type)
|
||||
|
||||
|
||||
def console_create(context, values):
|
||||
"""Create a console."""
|
||||
return IMPL.console_create(context, values)
|
||||
|
||||
|
||||
def console_delete(context, console_id):
|
||||
"""Delete a console."""
|
||||
return IMPL.console_delete(context, console_id)
|
||||
|
||||
|
||||
def console_get_by_pool_instance(context, pool_id, instance_uuid):
|
||||
"""Get console entry for a given instance and pool."""
|
||||
return IMPL.console_get_by_pool_instance(context, pool_id, instance_uuid)
|
||||
|
||||
|
||||
def console_get_all_by_instance(context, instance_uuid, columns_to_join=None):
|
||||
"""Get consoles for a given instance."""
|
||||
return IMPL.console_get_all_by_instance(context, instance_uuid,
|
||||
columns_to_join)
|
||||
|
||||
|
||||
def console_get(context, console_id, instance_uuid=None):
|
||||
"""Get a specific console (possibly on a given instance)."""
|
||||
return IMPL.console_get(context, console_id, instance_uuid)
|
||||
|
||||
##################
|
||||
|
||||
|
||||
|
@ -4487,40 +4487,6 @@ def migration_migrate_to_uuid(context, count):
|
||||
##################
|
||||
|
||||
|
||||
@pick_context_manager_writer
|
||||
def console_pool_create(context, values):
|
||||
pool = models.ConsolePool()
|
||||
pool.update(values)
|
||||
try:
|
||||
pool.save(context.session)
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.ConsolePoolExists(
|
||||
host=values["host"],
|
||||
console_type=values["console_type"],
|
||||
compute_host=values["compute_host"],
|
||||
)
|
||||
return pool
|
||||
|
||||
|
||||
@pick_context_manager_reader
|
||||
def console_pool_get_by_host_type(context, compute_host, host,
|
||||
console_type):
|
||||
|
||||
result = model_query(context, models.ConsolePool, read_deleted="no").\
|
||||
filter_by(host=host).\
|
||||
filter_by(console_type=console_type).\
|
||||
filter_by(compute_host=compute_host).\
|
||||
options(joinedload('consoles')).\
|
||||
first()
|
||||
|
||||
if not result:
|
||||
raise exception.ConsolePoolNotFoundForHostType(
|
||||
host=host, console_type=console_type,
|
||||
compute_host=compute_host)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@pick_context_manager_reader
|
||||
def console_pool_get_all_by_host_type(context, host, console_type):
|
||||
return model_query(context, models.ConsolePool, read_deleted="no").\
|
||||
@ -4530,71 +4496,6 @@ def console_pool_get_all_by_host_type(context, host, console_type):
|
||||
all()
|
||||
|
||||
|
||||
##################
|
||||
|
||||
|
||||
@pick_context_manager_writer
|
||||
def console_create(context, values):
|
||||
console = models.Console()
|
||||
console.update(values)
|
||||
console.save(context.session)
|
||||
return console
|
||||
|
||||
|
||||
@pick_context_manager_writer
|
||||
def console_delete(context, console_id):
|
||||
# NOTE(mdragon): consoles are meant to be transient.
|
||||
context.session.query(models.Console).\
|
||||
filter_by(id=console_id).\
|
||||
delete()
|
||||
|
||||
|
||||
@pick_context_manager_reader
|
||||
def console_get_by_pool_instance(context, pool_id, instance_uuid):
|
||||
result = model_query(context, models.Console, read_deleted="yes").\
|
||||
filter_by(pool_id=pool_id).\
|
||||
filter_by(instance_uuid=instance_uuid).\
|
||||
options(joinedload('pool')).\
|
||||
first()
|
||||
|
||||
if not result:
|
||||
raise exception.ConsoleNotFoundInPoolForInstance(
|
||||
pool_id=pool_id, instance_uuid=instance_uuid)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@pick_context_manager_reader
|
||||
def console_get_all_by_instance(context, instance_uuid, columns_to_join=None):
|
||||
query = model_query(context, models.Console, read_deleted="yes").\
|
||||
filter_by(instance_uuid=instance_uuid)
|
||||
if columns_to_join:
|
||||
for column in columns_to_join:
|
||||
query = query.options(joinedload(column))
|
||||
return query.all()
|
||||
|
||||
|
||||
@pick_context_manager_reader
|
||||
def console_get(context, console_id, instance_uuid=None):
|
||||
query = model_query(context, models.Console, read_deleted="yes").\
|
||||
filter_by(id=console_id).\
|
||||
options(joinedload('pool'))
|
||||
|
||||
if instance_uuid is not None:
|
||||
query = query.filter_by(instance_uuid=instance_uuid)
|
||||
|
||||
result = query.first()
|
||||
|
||||
if not result:
|
||||
if instance_uuid:
|
||||
raise exception.ConsoleNotFoundForInstance(
|
||||
instance_uuid=instance_uuid)
|
||||
else:
|
||||
raise exception.ConsoleNotFound(console_id=console_id)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
########################
|
||||
# User-provided metadata
|
||||
|
||||
|
@ -1001,6 +1001,7 @@ class ConsolePool(BASE, NovaBase, models.SoftDeleteMixin):
|
||||
compute_host = Column(String(255))
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove in V or later
|
||||
class Console(BASE, NovaBase, models.SoftDeleteMixin):
|
||||
"""Represents a console session for an instance."""
|
||||
__tablename__ = 'consoles'
|
||||
|
@ -1203,35 +1203,10 @@ class ConsoleLogOutputException(NovaException):
|
||||
"%(instance_id)s. Reason: %(reason)s")
|
||||
|
||||
|
||||
class ConsolePoolExists(NovaException):
|
||||
msg_fmt = _("Console pool with host %(host)s, console_type "
|
||||
"%(console_type)s and compute_host %(compute_host)s "
|
||||
"already exists.")
|
||||
|
||||
|
||||
class ConsolePoolNotFoundForHostType(NotFound):
|
||||
msg_fmt = _("Console pool of type %(console_type)s "
|
||||
"for compute host %(compute_host)s "
|
||||
"on proxy host %(host)s not found.")
|
||||
|
||||
|
||||
class ConsoleNotFound(NotFound):
|
||||
msg_fmt = _("Console %(console_id)s could not be found.")
|
||||
|
||||
|
||||
class ConsoleNotFoundForInstance(ConsoleNotFound):
|
||||
msg_fmt = _("Console for instance %(instance_uuid)s could not be found.")
|
||||
|
||||
|
||||
class ConsoleNotAvailable(NotFound):
|
||||
msg_fmt = _("Guest does not have a console available.")
|
||||
|
||||
|
||||
class ConsoleNotFoundInPoolForInstance(ConsoleNotFound):
|
||||
msg_fmt = _("Console for instance %(instance_uuid)s "
|
||||
"in pool %(pool_id)s could not be found.")
|
||||
|
||||
|
||||
class ConsoleTypeInvalid(Invalid):
|
||||
msg_fmt = _("Invalid console type %(console_type)s")
|
||||
|
||||
|
@ -796,6 +796,8 @@ class NotificationSource(BaseNovaEnum):
|
||||
# TODO(stephenfin): Remove when 'NotificationPublisher' object version is
|
||||
# bumped to 3.0
|
||||
CELLS = 'nova-cells'
|
||||
# TODO(stephenfin): Remove when 'NotificationPublisher' object version is
|
||||
# bumped to 3.0
|
||||
CONSOLE = 'nova-console'
|
||||
METADATA = 'nova-metadata'
|
||||
|
||||
|
@ -54,7 +54,6 @@ CONF = nova.conf.CONF
|
||||
|
||||
SERVICE_MANAGERS = {
|
||||
'nova-compute': 'nova.compute.manager.ComputeManager',
|
||||
'nova-console': 'nova.console.manager.ConsoleProxyManager',
|
||||
'nova-conductor': 'nova.conductor.manager.ConductorManager',
|
||||
'nova-metadata': 'nova.api.manager.MetadataManager',
|
||||
'nova-scheduler': 'nova.scheduler.manager.SchedulerManager',
|
||||
|
@ -1,199 +0,0 @@
|
||||
# Copyright (c) 2010 OpenStack Foundation
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Tests For Console proxy."""
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
|
||||
from nova.compute import rpcapi as compute_rpcapi
|
||||
from nova.console import api as console_api
|
||||
from nova.console import manager as console_manager
|
||||
from nova import context
|
||||
from nova.db import api as db
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests.unit import fake_instance
|
||||
from nova.tests.unit import fake_xvp_console_proxy
|
||||
|
||||
|
||||
class ConsoleTestCase(test.TestCase):
|
||||
"""Test case for console proxy manager."""
|
||||
def setUp(self):
|
||||
super(ConsoleTestCase, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'nova.console.manager.xvp.XVPConsoleProxy',
|
||||
fake_xvp_console_proxy.FakeConsoleProxy))
|
||||
self.console = console_manager.ConsoleProxyManager()
|
||||
self.user_id = 'fake'
|
||||
self.project_id = 'fake'
|
||||
self.context = context.RequestContext(self.user_id, self.project_id)
|
||||
self.host = 'test_compute_host'
|
||||
self.pool_info = {'address': '127.0.0.1',
|
||||
'username': 'test',
|
||||
'password': '1234pass'}
|
||||
|
||||
def test_reset(self):
|
||||
with mock.patch('nova.compute.rpcapi.ComputeAPI') as mock_rpc:
|
||||
old_rpcapi = self.console.compute_rpcapi
|
||||
self.console.reset()
|
||||
mock_rpc.assert_called_once_with()
|
||||
self.assertNotEqual(old_rpcapi,
|
||||
self.console.compute_rpcapi)
|
||||
|
||||
def _create_instance(self):
|
||||
"""Create a test instance."""
|
||||
inst = {}
|
||||
inst['image_id'] = 1
|
||||
inst['reservation_id'] = 'r-fakeres'
|
||||
inst['user_id'] = self.user_id
|
||||
inst['project_id'] = self.project_id
|
||||
inst['instance_type_id'] = 1
|
||||
inst['ami_launch_index'] = 0
|
||||
return fake_instance.fake_instance_obj(self.context, **inst)
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_pool_info')
|
||||
def test_get_pool_for_instance_host(self, mock_get):
|
||||
mock_get.return_value = self.pool_info
|
||||
pool = self.console._get_pool_for_instance_host(self.context,
|
||||
self.host)
|
||||
self.assertEqual(pool['compute_host'], self.host)
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_pool_info')
|
||||
def test_get_pool_creates_new_pool_if_needed(self, mock_get):
|
||||
mock_get.return_value = self.pool_info
|
||||
self.assertRaises(exception.NotFound,
|
||||
db.console_pool_get_by_host_type,
|
||||
self.context,
|
||||
self.host,
|
||||
self.console.host,
|
||||
self.console.driver.console_type)
|
||||
pool = self.console._get_pool_for_instance_host(self.context,
|
||||
self.host)
|
||||
pool2 = db.console_pool_get_by_host_type(self.context,
|
||||
self.host,
|
||||
self.console.host,
|
||||
self.console.driver.console_type)
|
||||
self.assertEqual(pool['id'], pool2['id'])
|
||||
|
||||
def test_get_pool_does_not_create_new_pool_if_exists(self):
|
||||
pool_info = {'address': '127.0.0.1',
|
||||
'username': 'test',
|
||||
'password': '1234pass',
|
||||
'host': self.console.host,
|
||||
'console_type': self.console.driver.console_type,
|
||||
'compute_host': 'sometesthostname'}
|
||||
new_pool = db.console_pool_create(self.context, pool_info)
|
||||
pool = self.console._get_pool_for_instance_host(self.context,
|
||||
'sometesthostname')
|
||||
self.assertEqual(pool['id'], new_pool['id'])
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_pool_info')
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_id')
|
||||
def test_add_console(self, mock_id, mock_get):
|
||||
mock_get.return_value = self.pool_info
|
||||
|
||||
instance = self._create_instance()
|
||||
mock_id.return_value = instance
|
||||
self.console.add_console(self.context, instance.id)
|
||||
pool = db.console_pool_get_by_host_type(self.context,
|
||||
instance.host, self.console.host,
|
||||
self.console.driver.console_type)
|
||||
|
||||
console_instances = [con['instance_uuid'] for con in pool['consoles']]
|
||||
self.assertIn(instance.uuid, console_instances)
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_pool_info')
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_id')
|
||||
def test_add_console_does_not_duplicate(self, mock_id, mock_get):
|
||||
mock_get.return_value = self.pool_info
|
||||
|
||||
instance = self._create_instance()
|
||||
mock_id.return_value = instance
|
||||
cons1 = self.console.add_console(self.context, instance.id)
|
||||
cons2 = self.console.add_console(self.context, instance.id)
|
||||
self.assertEqual(cons1, cons2)
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_pool_info')
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_id')
|
||||
def test_remove_console(self, mock_id, mock_get):
|
||||
mock_get.return_value = self.pool_info
|
||||
|
||||
instance = self._create_instance()
|
||||
mock_id.return_value = instance
|
||||
console_id = self.console.add_console(self.context, instance.id)
|
||||
self.console.remove_console(self.context, console_id)
|
||||
|
||||
self.assertRaises(exception.NotFound,
|
||||
db.console_get,
|
||||
self.context,
|
||||
console_id)
|
||||
|
||||
|
||||
class ConsoleAPITestCase(test.NoDBTestCase):
|
||||
"""Test case for console API."""
|
||||
def setUp(self):
|
||||
super(ConsoleAPITestCase, self).setUp()
|
||||
|
||||
self.context = context.RequestContext('fake', 'fake')
|
||||
self.console_api = console_api.API()
|
||||
self.fake_uuid = '00000000-aaaa-bbbb-cccc-000000000000'
|
||||
self.fake_instance = {
|
||||
'id': 1,
|
||||
'uuid': self.fake_uuid,
|
||||
'host': 'fake_host'
|
||||
}
|
||||
self.fake_console = {
|
||||
'pool': {'host': 'fake_host'},
|
||||
'id': 'fake_id'
|
||||
}
|
||||
|
||||
def _fake_db_console_get(_ctxt, _console_uuid, _instance_uuid):
|
||||
return self.fake_console
|
||||
self.stub_out('nova.db.api.console_get', _fake_db_console_get)
|
||||
|
||||
def _fake_db_console_get_all_by_instance(_ctxt, _instance_uuid,
|
||||
columns_to_join):
|
||||
return [self.fake_console]
|
||||
self.stub_out('nova.db.api.console_get_all_by_instance',
|
||||
_fake_db_console_get_all_by_instance)
|
||||
|
||||
def test_get_consoles(self):
|
||||
console = self.console_api.get_consoles(self.context, self.fake_uuid)
|
||||
self.assertEqual(console, [self.fake_console])
|
||||
|
||||
def test_get_console(self):
|
||||
console = self.console_api.get_console(self.context, self.fake_uuid,
|
||||
'fake_id')
|
||||
self.assertEqual(console, self.fake_console)
|
||||
|
||||
@mock.patch('nova.console.rpcapi.ConsoleAPI.remove_console')
|
||||
def test_delete_console(self, mock_remove):
|
||||
self.console_api.delete_console(self.context, self.fake_uuid,
|
||||
'fake_id')
|
||||
mock_remove.assert_called_once_with(self.context, 'fake_id')
|
||||
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_console_topic',
|
||||
return_value='compute.fake_host')
|
||||
@mock.patch.object(objects.Instance, 'get_by_uuid')
|
||||
def test_create_console(self, mock_get_instance_by_uuid,
|
||||
mock_get_console_topic):
|
||||
mock_get_instance_by_uuid.return_value = objects.Instance(
|
||||
**self.fake_instance)
|
||||
self.console_api.create_console(self.context, self.fake_uuid)
|
||||
mock_get_console_topic.assert_called_once_with(self.context,
|
||||
'fake_host')
|
@ -1,61 +0,0 @@
|
||||
# Copyright 2012, Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Unit Tests for nova.console.rpcapi
|
||||
"""
|
||||
|
||||
import mock
|
||||
|
||||
from nova.console import rpcapi as console_rpcapi
|
||||
from nova import context
|
||||
from nova import test
|
||||
|
||||
|
||||
class ConsoleRpcAPITestCase(test.NoDBTestCase):
|
||||
def _test_console_api(self, method, rpc_method, **kwargs):
|
||||
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||
|
||||
rpcapi = console_rpcapi.ConsoleAPI()
|
||||
self.assertIsNotNone(rpcapi.client)
|
||||
self.assertEqual(rpcapi.client.target.topic,
|
||||
console_rpcapi.RPC_TOPIC)
|
||||
|
||||
orig_prepare = rpcapi.client.prepare
|
||||
|
||||
with test.nested(
|
||||
mock.patch.object(rpcapi.client, rpc_method),
|
||||
mock.patch.object(rpcapi.client, 'prepare'),
|
||||
mock.patch.object(rpcapi.client, 'can_send_version'),
|
||||
) as (
|
||||
rpc_mock, prepare_mock, csv_mock
|
||||
):
|
||||
prepare_mock.return_value = rpcapi.client
|
||||
rpc_mock.return_value = 'foo' if rpc_method == 'call' else None
|
||||
csv_mock.side_effect = (
|
||||
lambda v: orig_prepare().can_send_version())
|
||||
|
||||
retval = getattr(rpcapi, method)(ctxt, **kwargs)
|
||||
self.assertEqual(retval, rpc_mock.return_value)
|
||||
|
||||
prepare_mock.assert_called_once_with()
|
||||
rpc_mock.assert_called_once_with(ctxt, method, **kwargs)
|
||||
|
||||
def test_add_console(self):
|
||||
self._test_console_api('add_console', instance_id='i',
|
||||
rpc_method='cast')
|
||||
|
||||
def test_remove_console(self):
|
||||
self._test_console_api('remove_console', console_id='i',
|
||||
rpc_method='cast')
|
@ -3210,25 +3210,6 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
|
||||
db.virtual_interface_create(ctxt, {'instance_uuid': uuid})
|
||||
|
||||
pool_values = {
|
||||
'address': '192.168.10.10',
|
||||
'username': 'user1',
|
||||
'password': 'passwd1',
|
||||
'console_type': 'type1',
|
||||
'public_hostname': 'public_host1',
|
||||
'host': 'host1',
|
||||
'compute_host': 'compute_host1',
|
||||
}
|
||||
console_pool = db.console_pool_create(ctxt, pool_values)
|
||||
console_values = {
|
||||
'instance_name': instance['name'],
|
||||
'instance_uuid': uuid,
|
||||
'password': 'pass',
|
||||
'port': 7878,
|
||||
'pool_id': console_pool['id']
|
||||
}
|
||||
db.console_create(self.ctxt, console_values)
|
||||
|
||||
# Hard delete the instance
|
||||
db.instance_destroy(ctxt, uuid, hard_delete=True)
|
||||
|
||||
@ -3260,10 +3241,7 @@ class InstanceTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
_assert_instance_id_mapping(ctxt, self, uuid)
|
||||
self.assertRaises(exception.InstanceNotFound,
|
||||
db.instance_destroy, ctxt, uuid)
|
||||
# NOTE(ttsiouts): Should these also be valid?
|
||||
# instance_consoles = db.console_get_all_by_instance(ctxt, uuid)
|
||||
# self.assertEqual(0, len(instance_consoles))
|
||||
# Also FixedIp has the instance_uuid as a foreign key
|
||||
# NOTE(ttsiouts): FixedIp has the instance_uuid as a foreign key
|
||||
|
||||
def test_check_instance_exists(self):
|
||||
instance = self.create_instance_with_args()
|
||||
@ -7916,207 +7894,6 @@ class CertificateTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
self._assertEqualObjects(self.created[1], cert[0])
|
||||
|
||||
|
||||
class ConsoleTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(ConsoleTestCase, self).setUp()
|
||||
self.ctxt = context.get_admin_context()
|
||||
pools_data = [
|
||||
{'address': '192.168.10.10',
|
||||
'username': 'user1',
|
||||
'password': 'passwd1',
|
||||
'console_type': 'type1',
|
||||
'public_hostname': 'public_host1',
|
||||
'host': 'host1',
|
||||
'compute_host': 'compute_host1',
|
||||
},
|
||||
{'address': '192.168.10.11',
|
||||
'username': 'user2',
|
||||
'password': 'passwd2',
|
||||
'console_type': 'type2',
|
||||
'public_hostname': 'public_host2',
|
||||
'host': 'host2',
|
||||
'compute_host': 'compute_host2',
|
||||
},
|
||||
]
|
||||
self.console_pools = [db.console_pool_create(self.ctxt, val)
|
||||
for val in pools_data]
|
||||
instance_uuid = uuidsentinel.uuid1
|
||||
db.instance_create(self.ctxt, {'uuid': instance_uuid})
|
||||
self.console_data = [{'instance_name': 'name' + str(x),
|
||||
'instance_uuid': instance_uuid,
|
||||
'password': 'pass' + str(x),
|
||||
'port': 7878 + x,
|
||||
'pool_id': self.console_pools[x]['id']}
|
||||
for x in range(len(pools_data))]
|
||||
self.consoles = [db.console_create(self.ctxt, val)
|
||||
for val in self.console_data]
|
||||
|
||||
def test_console_create(self):
|
||||
ignored_keys = ['id', 'deleted', 'deleted_at', 'created_at',
|
||||
'updated_at']
|
||||
for console in self.consoles:
|
||||
self.assertIsNotNone(console['id'])
|
||||
self._assertEqualListsOfObjects(self.console_data, self.consoles,
|
||||
ignored_keys=ignored_keys)
|
||||
|
||||
def test_console_get_by_id(self):
|
||||
console = self.consoles[0]
|
||||
console_get = db.console_get(self.ctxt, console['id'])
|
||||
self._assertEqualObjects(console, console_get,
|
||||
ignored_keys=['pool'])
|
||||
|
||||
def test_console_get_by_id_uuid(self):
|
||||
console = self.consoles[0]
|
||||
console_get = db.console_get(self.ctxt, console['id'],
|
||||
console['instance_uuid'])
|
||||
self._assertEqualObjects(console, console_get,
|
||||
ignored_keys=['pool'])
|
||||
|
||||
def test_console_get_by_pool_instance(self):
|
||||
console = self.consoles[0]
|
||||
console_get = db.console_get_by_pool_instance(self.ctxt,
|
||||
console['pool_id'], console['instance_uuid'])
|
||||
self._assertEqualObjects(console, console_get,
|
||||
ignored_keys=['pool'])
|
||||
|
||||
def test_console_get_all_by_instance(self):
|
||||
instance_uuid = self.consoles[0]['instance_uuid']
|
||||
consoles_get = db.console_get_all_by_instance(self.ctxt, instance_uuid)
|
||||
self._assertEqualListsOfObjects(self.consoles, consoles_get)
|
||||
|
||||
def test_console_get_all_by_instance_with_pool(self):
|
||||
instance_uuid = self.consoles[0]['instance_uuid']
|
||||
consoles_get = db.console_get_all_by_instance(self.ctxt, instance_uuid,
|
||||
columns_to_join=['pool'])
|
||||
self._assertEqualListsOfObjects(self.consoles, consoles_get,
|
||||
ignored_keys=['pool'])
|
||||
self._assertEqualListsOfObjects([pool for pool in self.console_pools],
|
||||
[c['pool'] for c in consoles_get])
|
||||
|
||||
def test_console_get_all_by_instance_empty(self):
|
||||
consoles_get = db.console_get_all_by_instance(self.ctxt,
|
||||
uuidsentinel.uuid2)
|
||||
self.assertEqual(consoles_get, [])
|
||||
|
||||
def test_console_delete(self):
|
||||
console_id = self.consoles[0]['id']
|
||||
db.console_delete(self.ctxt, console_id)
|
||||
self.assertRaises(exception.ConsoleNotFound, db.console_get,
|
||||
self.ctxt, console_id)
|
||||
|
||||
def test_console_get_by_pool_instance_not_found(self):
|
||||
self.assertRaises(exception.ConsoleNotFoundInPoolForInstance,
|
||||
db.console_get_by_pool_instance, self.ctxt,
|
||||
self.consoles[0]['pool_id'],
|
||||
uuidsentinel.uuid2)
|
||||
|
||||
def test_console_get_not_found(self):
|
||||
self.assertRaises(exception.ConsoleNotFound, db.console_get,
|
||||
self.ctxt, 100500)
|
||||
|
||||
def test_console_get_not_found_instance(self):
|
||||
self.assertRaises(exception.ConsoleNotFoundForInstance, db.console_get,
|
||||
self.ctxt, self.consoles[0]['id'],
|
||||
uuidsentinel.uuid2)
|
||||
|
||||
|
||||
class ConsolePoolTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
def setUp(self):
|
||||
super(ConsolePoolTestCase, self).setUp()
|
||||
|
||||
self.ctxt = context.get_admin_context()
|
||||
self.test_console_pool_1 = {
|
||||
'address': '192.168.2.10',
|
||||
'username': 'user_1',
|
||||
'password': 'secret_123',
|
||||
'console_type': 'type_1',
|
||||
'public_hostname': 'public_hostname_123',
|
||||
'host': 'localhost',
|
||||
'compute_host': '127.0.0.1',
|
||||
}
|
||||
self.test_console_pool_2 = {
|
||||
'address': '192.168.2.11',
|
||||
'username': 'user_2',
|
||||
'password': 'secret_1234',
|
||||
'console_type': 'type_2',
|
||||
'public_hostname': 'public_hostname_1234',
|
||||
'host': '127.0.0.1',
|
||||
'compute_host': 'localhost',
|
||||
}
|
||||
self.test_console_pool_3 = {
|
||||
'address': '192.168.2.12',
|
||||
'username': 'user_3',
|
||||
'password': 'secret_12345',
|
||||
'console_type': 'type_2',
|
||||
'public_hostname': 'public_hostname_12345',
|
||||
'host': '127.0.0.1',
|
||||
'compute_host': '192.168.1.1',
|
||||
}
|
||||
|
||||
def test_console_pool_create(self):
|
||||
console_pool = db.console_pool_create(
|
||||
self.ctxt, self.test_console_pool_1)
|
||||
self.assertIsNotNone(console_pool.get('id'))
|
||||
ignored_keys = ['deleted', 'created_at', 'updated_at',
|
||||
'deleted_at', 'id']
|
||||
self._assertEqualObjects(
|
||||
console_pool, self.test_console_pool_1, ignored_keys)
|
||||
|
||||
def test_console_pool_create_duplicate(self):
|
||||
db.console_pool_create(self.ctxt, self.test_console_pool_1)
|
||||
self.assertRaises(exception.ConsolePoolExists, db.console_pool_create,
|
||||
self.ctxt, self.test_console_pool_1)
|
||||
|
||||
def test_console_pool_get_by_host_type(self):
|
||||
params = [
|
||||
self.test_console_pool_1,
|
||||
self.test_console_pool_2,
|
||||
]
|
||||
|
||||
for p in params:
|
||||
db.console_pool_create(self.ctxt, p)
|
||||
|
||||
ignored_keys = ['deleted', 'created_at', 'updated_at',
|
||||
'deleted_at', 'id', 'consoles']
|
||||
|
||||
cp = self.test_console_pool_1
|
||||
db_cp = db.console_pool_get_by_host_type(
|
||||
self.ctxt, cp['compute_host'], cp['host'], cp['console_type']
|
||||
)
|
||||
self._assertEqualObjects(cp, db_cp, ignored_keys)
|
||||
|
||||
def test_console_pool_get_by_host_type_no_resuls(self):
|
||||
self.assertRaises(
|
||||
exception.ConsolePoolNotFoundForHostType,
|
||||
db.console_pool_get_by_host_type, self.ctxt, 'compute_host',
|
||||
'host', 'console_type')
|
||||
|
||||
def test_console_pool_get_all_by_host_type(self):
|
||||
params = [
|
||||
self.test_console_pool_1,
|
||||
self.test_console_pool_2,
|
||||
self.test_console_pool_3,
|
||||
]
|
||||
for p in params:
|
||||
db.console_pool_create(self.ctxt, p)
|
||||
ignored_keys = ['deleted', 'created_at', 'updated_at',
|
||||
'deleted_at', 'id', 'consoles']
|
||||
|
||||
cp = self.test_console_pool_2
|
||||
db_cp = db.console_pool_get_all_by_host_type(
|
||||
self.ctxt, cp['host'], cp['console_type'])
|
||||
|
||||
self._assertEqualListsOfObjects(
|
||||
db_cp, [self.test_console_pool_2, self.test_console_pool_3],
|
||||
ignored_keys)
|
||||
|
||||
def test_console_pool_get_all_by_host_type_no_results(self):
|
||||
res = db.console_pool_get_all_by_host_type(
|
||||
self.ctxt, 'cp_host', 'cp_console_type')
|
||||
self.assertEqual([], res)
|
||||
|
||||
|
||||
class DnsdomainTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
@ -8455,9 +8232,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
self.dns_domains = models.DNSDomain.__table__
|
||||
self.shadow_dns_domains = sqlalchemyutils.get_table(
|
||||
self.engine, "shadow_dns_domains")
|
||||
self.consoles = models.Console.__table__
|
||||
self.shadow_consoles = sqlalchemyutils.get_table(
|
||||
self.engine, "shadow_consoles")
|
||||
self.console_pools = models.ConsolePool.__table__
|
||||
self.shadow_console_pools = sqlalchemyutils.get_table(
|
||||
self.engine, "shadow_console_pools")
|
||||
@ -8813,41 +8587,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
'sqlite version too old for reliable SQLA foreign_keys')
|
||||
self.conn.execute("PRAGMA foreign_keys = ON")
|
||||
|
||||
def test_archive_deleted_rows_fk_constraint(self):
|
||||
# consoles.pool_id depends on console_pools.id
|
||||
self._check_sqlite_version_less_than_3_7()
|
||||
ins_stmt = self.console_pools.insert().values(deleted=1,
|
||||
deleted_at=timeutils.utcnow())
|
||||
result = self.conn.execute(ins_stmt)
|
||||
id1 = result.inserted_primary_key[0]
|
||||
ins_stmt = self.consoles.insert().values(deleted=1,
|
||||
deleted_at=timeutils.utcnow(),
|
||||
pool_id=id1)
|
||||
result = self.conn.execute(ins_stmt)
|
||||
result.inserted_primary_key[0]
|
||||
# The first try to archive console_pools should fail, due to FK.
|
||||
num = sqlalchemy_api._archive_deleted_rows_for_table(self.metadata,
|
||||
"console_pools",
|
||||
max_rows=None,
|
||||
before=None)
|
||||
self.assertEqual(num[0], 0)
|
||||
# Then archiving consoles should work.
|
||||
num = sqlalchemy_api._archive_deleted_rows_for_table(self.metadata,
|
||||
"consoles",
|
||||
max_rows=None,
|
||||
before=None)
|
||||
self.assertEqual(num[0], 1)
|
||||
# Then archiving console_pools should work.
|
||||
num = sqlalchemy_api._archive_deleted_rows_for_table(self.metadata,
|
||||
"console_pools",
|
||||
max_rows=None,
|
||||
before=None)
|
||||
self.assertEqual(num[0], 1)
|
||||
self._assert_shadow_tables_empty_except(
|
||||
'shadow_console_pools',
|
||||
'shadow_consoles'
|
||||
)
|
||||
|
||||
def test_archive_deleted_rows_for_migrations(self):
|
||||
# migrations.instance_uuid depends on instances.uuid
|
||||
self._check_sqlite_version_less_than_3_7()
|
||||
|
@ -55,8 +55,6 @@ class TestProfiler(test.NoDBTestCase):
|
||||
'nova.conductor.manager.ConductorManager',
|
||||
'nova.conductor.rpcapi.ComputeTaskAPI',
|
||||
'nova.conductor.rpcapi.ConductorAPI',
|
||||
'nova.console.manager.ConsoleProxyManager',
|
||||
'nova.console.rpcapi.ConsoleAPI',
|
||||
'nova.image.api.API',
|
||||
'nova.network.api.API',
|
||||
'nova.network.manager.FlatDHCPManager',
|
||||
|
@ -1,7 +1,13 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The following APIs have been removed. Calling these APIs will
|
||||
The ``nova-console`` service has been deprecated since the 19.0.0 Stein
|
||||
release and has now been removed. The following configuration options are
|
||||
therefore removed.
|
||||
|
||||
* ``[upgrade_levels] console``
|
||||
|
||||
In addition, the following APIs have been removed. Calling these APIs will
|
||||
now result in a ``410 HTTPGone`` error response:
|
||||
|
||||
* ``POST /servers/{server_id}/consoles``
|
||||
@ -9,7 +15,7 @@ upgrade:
|
||||
* ``GET /servers/{server_id}/consoles/{console_id}``
|
||||
* ``DELETE /servers/{server_id}/consoles/{console_id}``
|
||||
|
||||
In addition, the following policies are removed. These were related to the
|
||||
Finally, the following policies are removed. These were related to the
|
||||
removed APIs listed above and no longer had any effect:
|
||||
|
||||
* ``os_compute_api:os-consoles:index``
|
||||
|
@ -66,7 +66,6 @@ console_scripts =
|
||||
nova-api-os-compute = nova.cmd.api_os_compute:main
|
||||
nova-compute = nova.cmd.compute:main
|
||||
nova-conductor = nova.cmd.conductor:main
|
||||
nova-console = nova.cmd.console:main
|
||||
nova-dhcpbridge = nova.cmd.dhcpbridge:main
|
||||
nova-manage = nova.cmd.manage:main
|
||||
nova-network = nova.cmd.network:main
|
||||
|
Loading…
x
Reference in New Issue
Block a user