ironic/ironic/common/dhcp_factory.py
Vasyl Saienko 228a2a7885 Change pxe dhcp options name to codes.
There is difference between dhcp option names in different backends.
This patch changes options name to code according to [0].

[0] https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml

Closes-Bug: 1717236

This is an updated version of c377f5cbbd
which problems with PXE and dnsmasq due to buggy dnsmasq code which uses
siaddr field to specify tftp server. They are addressed now by always
sending server-ip-address to make sure that dnsmasq works.

More information about siaddr and option 150,66 can be found in
informational RFC https://tools.ietf.org/html/rfc5859

Change-Id: I55487d867979bf6bb4cf228fcf6408beae955d2b
2017-10-13 12:50:58 +03:00

104 lines
3.5 KiB
Python

# Copyright 2014 Rackspace, 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.
from oslo_concurrency import lockutils
import stevedore
from ironic.common import exception
from ironic.conf import CONF
_dhcp_provider = None
EM_SEMAPHORE = 'dhcp_provider'
class DHCPFactory(object):
# NOTE(lucasagomes): Instantiate a stevedore.driver.DriverManager
# only once, the first time DHCPFactory.__init__
# is called.
_dhcp_provider = None
def __init__(self, **kwargs):
if not DHCPFactory._dhcp_provider:
DHCPFactory._set_dhcp_provider(**kwargs)
# NOTE(lucasagomes): Use lockutils to avoid a potential race in eventlet
# that might try to create two dhcp factories.
@classmethod
@lockutils.synchronized(EM_SEMAPHORE)
def _set_dhcp_provider(cls, **kwargs):
"""Initialize the dhcp provider
:raises: DHCPLoadError if the dhcp_provider cannot be loaded.
"""
# NOTE(lucasagomes): In case multiple greenthreads queue up on
# this lock before _dhcp_provider is initialized,
# prevent creation of multiple DriverManager.
if cls._dhcp_provider:
return
dhcp_provider_name = CONF.dhcp.dhcp_provider
try:
_extension_manager = stevedore.driver.DriverManager(
'ironic.dhcp',
dhcp_provider_name,
invoke_kwds=kwargs,
invoke_on_load=True)
except Exception as e:
raise exception.DHCPLoadError(
dhcp_provider_name=dhcp_provider_name, reason=e
)
cls._dhcp_provider = _extension_manager.driver
def update_dhcp(self, task, dhcp_opts, ports=None):
"""Send or update the DHCP BOOT options for this node.
:param task: A TaskManager instance.
:param dhcp_opts: this will be a list of dicts, e.g.
::
[{'opt_name': '67',
'opt_value': 'pxelinux.0'},
{'opt_name': '66',
'opt_value': '123.123.123.456'}]
:param ports: A dict with keys 'ports' and 'portgroups' and
dicts as values. Each dict has key/value pairs of the form
<ironic UUID>:<neutron port UUID>. e.g.
::
{'ports': {'port.uuid': vif.id},
'portgroups': {'portgroup.uuid': vif.id}}
If the value is None, will get the list of ports/portgroups
from the Ironic port/portgroup objects.
"""
self.provider.update_dhcp_opts(task, dhcp_opts, ports)
def clean_dhcp(self, task):
"""Clean up the DHCP BOOT options for this node.
:param task: A TaskManager instance.
"""
self.provider.clean_dhcp_opts(task)
@property
def provider(self):
return self._dhcp_provider