components/openstack/neutron/patches/02-dhcp-agent-add-solaris.patch
branchs11-update
changeset 3028 5e73a3a3f66a
equal deleted inserted replaced
3027:3bcf7d43558b 3028:5e73a3a3f66a
       
     1 In-house patch to split out the Linux specific implementation details of the
       
     2 Neutron DHCP agent into a separate module. This allows for a common
       
     3 main DHCP agent module on different platforms.  This patch has not yet
       
     4 been submitted upstream.
       
     5 
       
     6 --- quantum-2013.1.4/quantum/agent/dhcp_agent.py.~1~	2013-10-17 11:24:18.000000000 -0700
       
     7 +++ quantum-2013.1.4/quantum/agent/dhcp_agent.py	2014-03-13 01:37:26.539103862 -0700
       
     8 @@ -17,7 +17,6 @@
       
     9  
       
    10  import os
       
    11  import socket
       
    12 -import uuid
       
    13  
       
    14  import eventlet
       
    15  import netaddr
       
    16 @@ -26,11 +25,8 @@
       
    17  from quantum.agent.common import config
       
    18  from quantum.agent.linux import dhcp
       
    19  from quantum.agent.linux import external_process
       
    20 -from quantum.agent.linux import interface
       
    21 -from quantum.agent.linux import ip_lib
       
    22  from quantum.agent import rpc as agent_rpc
       
    23  from quantum.common import constants
       
    24 -from quantum.common import exceptions
       
    25  from quantum.common import topics
       
    26  from quantum import context
       
    27  from quantum import manager
       
    28 @@ -58,6 +54,9 @@
       
    29          cfg.StrOpt('dhcp_driver',
       
    30                     default='quantum.agent.linux.dhcp.Dnsmasq',
       
    31                     help=_("The driver used to manage the DHCP server.")),
       
    32 +        cfg.StrOpt('devicemanager',
       
    33 +                   default='quantum.agent.linux.device.DeviceManager',
       
    34 +                   help=_("The driver to manage OS specific devices.")),
       
    35          cfg.BoolOpt('use_namespaces', default=True,
       
    36                      help=_("Allow overlapping IP.")),
       
    37          cfg.BoolOpt('enable_isolated_metadata', default=False,
       
    38 @@ -77,7 +76,9 @@
       
    39          self.dhcp_driver_cls = importutils.import_class(self.conf.dhcp_driver)
       
    40          ctx = context.get_admin_context_without_session()
       
    41          self.plugin_rpc = DhcpPluginApi(topics.PLUGIN, ctx)
       
    42 -        self.device_manager = DeviceManager(self.conf, self.plugin_rpc)
       
    43 +        self.device_manager = \
       
    44 +            importutils.import_object(self.conf.devicemanager,
       
    45 +                                      self.conf, self.plugin_rpc)
       
    46          self.lease_relay = DhcpLeaseRelay(self.update_lease)
       
    47  
       
    48          self.dhcp_version = self.dhcp_driver_cls.check_version()
       
    49 @@ -494,167 +495,6 @@
       
    50                  'ports': num_ports}
       
    51  
       
    52  
       
    53 -class DeviceManager(object):
       
    54 -    OPTS = [
       
    55 -        cfg.StrOpt('interface_driver',
       
    56 -                   help=_("The driver used to manage the virtual interface."))
       
    57 -    ]
       
    58 -
       
    59 -    def __init__(self, conf, plugin):
       
    60 -        self.conf = conf
       
    61 -        self.root_helper = config.get_root_helper(conf)
       
    62 -        self.plugin = plugin
       
    63 -        if not conf.interface_driver:
       
    64 -            raise SystemExit(_('You must specify an interface driver'))
       
    65 -        try:
       
    66 -            self.driver = importutils.import_object(conf.interface_driver,
       
    67 -                                                    conf)
       
    68 -        except:
       
    69 -            msg = _("Error importing interface driver "
       
    70 -                    "'%s'") % conf.interface_driver
       
    71 -            raise SystemExit(msg)
       
    72 -
       
    73 -    def get_interface_name(self, network, port=None):
       
    74 -        """Return interface(device) name for use by the DHCP process."""
       
    75 -        if not port:
       
    76 -            device_id = self.get_device_id(network)
       
    77 -            port = self.plugin.get_dhcp_port(network.id, device_id)
       
    78 -        return self.driver.get_device_name(port)
       
    79 -
       
    80 -    def get_device_id(self, network):
       
    81 -        """Return a unique DHCP device ID for this host on the network."""
       
    82 -        # There could be more than one dhcp server per network, so create
       
    83 -        # a device id that combines host and network ids
       
    84 -
       
    85 -        host_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, socket.gethostname())
       
    86 -        return 'dhcp%s-%s' % (host_uuid, network.id)
       
    87 -
       
    88 -    def _get_device(self, network):
       
    89 -        """Return DHCP ip_lib device for this host on the network."""
       
    90 -        device_id = self.get_device_id(network)
       
    91 -        port = self.plugin.get_dhcp_port(network.id, device_id)
       
    92 -        interface_name = self.get_interface_name(network, port)
       
    93 -        namespace = NS_PREFIX + network.id
       
    94 -        return ip_lib.IPDevice(interface_name,
       
    95 -                               self.root_helper,
       
    96 -                               namespace)
       
    97 -
       
    98 -    def _set_default_route(self, network):
       
    99 -        """Sets the default gateway for this dhcp namespace.
       
   100 -
       
   101 -        This method is idempotent and will only adjust the route if adjusting
       
   102 -        it would change it from what it already is.  This makes it safe to call
       
   103 -        and avoids unnecessary perturbation of the system.
       
   104 -        """
       
   105 -        device = self._get_device(network)
       
   106 -        gateway = device.route.get_gateway()
       
   107 -
       
   108 -        for subnet in network.subnets:
       
   109 -            skip_subnet = (
       
   110 -                subnet.ip_version != 4
       
   111 -                or not subnet.enable_dhcp
       
   112 -                or subnet.gateway_ip is None)
       
   113 -
       
   114 -            if skip_subnet:
       
   115 -                continue
       
   116 -
       
   117 -            if gateway != subnet.gateway_ip:
       
   118 -                m = _('Setting gateway for dhcp netns on net %(n)s to %(ip)s')
       
   119 -                LOG.debug(m, {'n': network.id, 'ip': subnet.gateway_ip})
       
   120 -
       
   121 -                device.route.add_gateway(subnet.gateway_ip)
       
   122 -
       
   123 -            return
       
   124 -
       
   125 -        # No subnets on the network have a valid gateway.  Clean it up to avoid
       
   126 -        # confusion from seeing an invalid gateway here.
       
   127 -        if gateway is not None:
       
   128 -            msg = _('Removing gateway for dhcp netns on net %s')
       
   129 -            LOG.debug(msg, network.id)
       
   130 -
       
   131 -            device.route.delete_gateway(gateway)
       
   132 -
       
   133 -    def setup(self, network, reuse_existing=False):
       
   134 -        """Create and initialize a device for network's DHCP on this host."""
       
   135 -        device_id = self.get_device_id(network)
       
   136 -        port = self.plugin.get_dhcp_port(network.id, device_id)
       
   137 -
       
   138 -        interface_name = self.get_interface_name(network, port)
       
   139 -
       
   140 -        if self.conf.use_namespaces:
       
   141 -            namespace = NS_PREFIX + network.id
       
   142 -        else:
       
   143 -            namespace = None
       
   144 -
       
   145 -        if ip_lib.device_exists(interface_name,
       
   146 -                                self.root_helper,
       
   147 -                                namespace):
       
   148 -            if not reuse_existing:
       
   149 -                raise exceptions.PreexistingDeviceFailure(
       
   150 -                    dev_name=interface_name)
       
   151 -
       
   152 -            LOG.debug(_('Reusing existing device: %s.'), interface_name)
       
   153 -        else:
       
   154 -            self.driver.plug(network.id,
       
   155 -                             port.id,
       
   156 -                             interface_name,
       
   157 -                             port.mac_address,
       
   158 -                             namespace=namespace)
       
   159 -        ip_cidrs = []
       
   160 -        for fixed_ip in port.fixed_ips:
       
   161 -            subnet = fixed_ip.subnet
       
   162 -            net = netaddr.IPNetwork(subnet.cidr)
       
   163 -            ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
       
   164 -            ip_cidrs.append(ip_cidr)
       
   165 -
       
   166 -        if (self.conf.enable_isolated_metadata and
       
   167 -            self.conf.use_namespaces):
       
   168 -            ip_cidrs.append(METADATA_DEFAULT_IP)
       
   169 -
       
   170 -        self.driver.init_l3(interface_name, ip_cidrs,
       
   171 -                            namespace=namespace)
       
   172 -
       
   173 -        # ensure that the dhcp interface is first in the list
       
   174 -        if namespace is None:
       
   175 -            device = ip_lib.IPDevice(interface_name,
       
   176 -                                     self.root_helper)
       
   177 -            device.route.pullup_route(interface_name)
       
   178 -
       
   179 -        if self.conf.enable_metadata_network:
       
   180 -            meta_cidr = netaddr.IPNetwork(METADATA_DEFAULT_IP)
       
   181 -            metadata_subnets = [s for s in network.subnets if
       
   182 -                                netaddr.IPNetwork(s.cidr) in meta_cidr]
       
   183 -            if metadata_subnets:
       
   184 -                # Add a gateway so that packets can be routed back to VMs
       
   185 -                device = ip_lib.IPDevice(interface_name,
       
   186 -                                         self.root_helper,
       
   187 -                                         namespace)
       
   188 -                # Only 1 subnet on metadata access network
       
   189 -                gateway_ip = metadata_subnets[0].gateway_ip
       
   190 -                device.route.add_gateway(gateway_ip)
       
   191 -        elif self.conf.use_namespaces:
       
   192 -            self._set_default_route(network)
       
   193 -
       
   194 -        return interface_name
       
   195 -
       
   196 -    def update(self, network):
       
   197 -        """Update device settings for the network's DHCP on this host."""
       
   198 -        if self.conf.use_namespaces and not self.conf.enable_metadata_network:
       
   199 -            self._set_default_route(network)
       
   200 -
       
   201 -    def destroy(self, network, device_name):
       
   202 -        """Destroy the device used for the network's DHCP on this host."""
       
   203 -        if self.conf.use_namespaces:
       
   204 -            namespace = NS_PREFIX + network.id
       
   205 -        else:
       
   206 -            namespace = None
       
   207 -
       
   208 -        self.driver.unplug(device_name, namespace=namespace)
       
   209 -
       
   210 -        self.plugin.release_dhcp_port(network.id,
       
   211 -                                      self.get_device_id(network))
       
   212 -
       
   213 -
       
   214  class DictModel(object):
       
   215      """Convert dict into an object that provides attribute access to values."""
       
   216      def __init__(self, d):
       
   217 @@ -783,11 +623,11 @@
       
   218      cfg.CONF.register_opts(DhcpAgent.OPTS)
       
   219      config.register_agent_state_opts_helper(cfg.CONF)
       
   220      config.register_root_helper(cfg.CONF)
       
   221 -    cfg.CONF.register_opts(DeviceManager.OPTS)
       
   222      cfg.CONF.register_opts(DhcpLeaseRelay.OPTS)
       
   223      cfg.CONF.register_opts(dhcp.OPTS)
       
   224 -    cfg.CONF.register_opts(interface.OPTS)
       
   225      cfg.CONF(project='quantum')
       
   226 +    if not cfg.CONF.devicemanager:
       
   227 +        raise SystemExit(_('You must specify a devicemanager'))
       
   228      config.setup_logging(cfg.CONF)
       
   229      server = quantum_service.Service.create(
       
   230          binary='quantum-dhcp-agent',
       
   231 --- quantum-2013.1.4/quantum/db/dhcp_rpc_base.py.~1~	2013-10-17 11:24:18.000000000 -0700
       
   232 +++ quantum-2013.1.4/quantum/db/dhcp_rpc_base.py	2014-03-13 01:27:46.731450967 -0700
       
   233 @@ -97,11 +97,14 @@
       
   234                  for fixed_ip in port['fixed_ips']:
       
   235                      if fixed_ip['subnet_id'] in dhcp_enabled_subnet_ids:
       
   236                          dhcp_enabled_subnet_ids.remove(fixed_ip['subnet_id'])
       
   237 -                port['fixed_ips'].extend(
       
   238 -                    [dict(subnet_id=s) for s in dhcp_enabled_subnet_ids])
       
   239 +                if dhcp_enabled_subnet_ids:
       
   240 +                    port['fixed_ips'].extend(
       
   241 +                        [dict(subnet_id=s) for s in dhcp_enabled_subnet_ids])
       
   242  
       
   243 -                retval = plugin.update_port(context, port['id'],
       
   244 -                                            dict(port=port))
       
   245 +                    retval = plugin.update_port(context, port['id'],
       
   246 +                                                dict(port=port))
       
   247 +                else:
       
   248 +                    retval = port
       
   249  
       
   250          except exc.NoResultFound:
       
   251              pass