efae7d796a
The i18n team has decided not to translate the logs because it seems like it not very useful; operators prefer to have them in English so that they can search for those strings on the internet. Partially fix on nova/conductor, nova/console, nova/consoleauth, nova/db and nova/image other paths will be fixed on next commits Change-Id: I132f60cb4743f85c96ec5231d6f860cfb0815758
92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
# 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.
|
|
|
|
"""Serial consoles module."""
|
|
|
|
import socket
|
|
|
|
from oslo_log import log as logging
|
|
import six.moves
|
|
|
|
import nova.conf
|
|
from nova import exception
|
|
from nova import utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
ALLOCATED_PORTS = set() # in-memory set of already allocated ports
|
|
SERIAL_LOCK = 'serial-lock'
|
|
|
|
CONF = nova.conf.CONF
|
|
|
|
# TODO(sahid): Add a method to initialize ALLOCATED_PORTS with the
|
|
# already binded TPC port(s). (cf from danpb: list all running guests and
|
|
# query the XML in libvirt driver to find out the TCP port(s) it uses).
|
|
|
|
|
|
@utils.synchronized(SERIAL_LOCK)
|
|
def acquire_port(host):
|
|
"""Returns a free TCP port on host.
|
|
|
|
Find and returns a free TCP port on 'host' in the range
|
|
of 'CONF.serial_console.port_range'.
|
|
"""
|
|
|
|
start, stop = _get_port_range()
|
|
|
|
for port in six.moves.range(start, stop):
|
|
if (host, port) in ALLOCATED_PORTS:
|
|
continue
|
|
try:
|
|
_verify_port(host, port)
|
|
ALLOCATED_PORTS.add((host, port))
|
|
return port
|
|
except exception.SocketPortInUseException as e:
|
|
LOG.warning(e.format_message())
|
|
|
|
raise exception.SocketPortRangeExhaustedException(host=host)
|
|
|
|
|
|
@utils.synchronized(SERIAL_LOCK)
|
|
def release_port(host, port):
|
|
"""Release TCP port to be used next time."""
|
|
ALLOCATED_PORTS.discard((host, port))
|
|
|
|
|
|
def _get_port_range():
|
|
config_range = CONF.serial_console.port_range
|
|
|
|
start, stop = map(int, config_range.split(':'))
|
|
if start >= stop:
|
|
default_port_range = nova.conf.serial_console.DEFAULT_PORT_RANGE
|
|
LOG.warning("serial_console.port_range should be in the "
|
|
"format <start>:<stop> and start < stop, "
|
|
"Given value %(port_range)s is invalid. "
|
|
"Taking the default port range %(default)s.",
|
|
{'port_range': config_range,
|
|
'default': default_port_range})
|
|
start, stop = map(int, default_port_range.split(':'))
|
|
return start, stop
|
|
|
|
|
|
def _verify_port(host, port):
|
|
s = socket.socket()
|
|
try:
|
|
s.bind((host, port))
|
|
except socket.error as e:
|
|
raise exception.SocketPortInUseException(
|
|
host=host, port=port, error=e)
|
|
finally:
|
|
s.close()
|