original_docstring: Provision the datapath so that it can serve metadata.
  
          This function will create the namespace and VETH pair if needed
          and assign the IP addresses to the interface corresponding to the
          metadata port of the network. It will also remove existing IP
          addresses that are no longer needed.
  
          :return: The metadata namespace name of this datapath
          
docstring: Provision the datapath so that it can serve metadata.
  This function will create the namespace and VETH pair if needed
  and assign the IP addresses to the interface corresponding to the
  metadata port of the network. It will also remove existing IP
  addresses that are no longer needed.
docstring_tokens: Provision the datapath so that it can serve metadata . This function will create the namespace and VETH pair if needed and assign the IP addresses to the interface corresponding to the metadata port of the network . It will also remove existing IP addresses that are no longer needed .
code: def provision_datapath(self, datapath):
          """Provision the datapath so that it can serve metadata.
  
          This function will create the namespace and VETH pair if needed
          and assign the IP addresses to the interface corresponding to the
          metadata port of the network. It will also remove existing IP
          addresses that are no longer needed.
  
          :return: The metadata namespace name of this datapath
          """
          LOG.debug("Provisioning datapath %s", datapath)
          port = self.sb_idl.get_metadata_port_network(datapath)
          # If there's no metadata port or it doesn't have a MAC or IP
          # addresses, then tear the namespace down if needed. This might happen
          # when there are no subnets yet created so metadata port doesn't have
          # an IP address.
          if not (port and port.mac and
                  port.external_ids.get(ovn_const.OVN_CIDRS_EXT_ID_KEY, None)):
              LOG.debug("There is no metadata port for datapath %s or it has no "
                        "MAC or IP addresses configured, tearing the namespace "
                        "down if needed", datapath)
              self.teardown_datapath(datapath)
              return
  
          # First entry of the mac field must be the MAC address.
          match = MAC_PATTERN.match(port.mac[0].split(' ')[0])
          # If it is not, we can't provision the namespace. Tear it down if
          # needed and log the error.
          if not match:
              LOG.error("Metadata port for datapath %s doesn't have a MAC "
                        "address, tearing the namespace down if needed",
                        datapath)
              self.teardown_datapath(datapath)
              return
  
          mac = match.group()
          ip_addresses = set(
              port.external_ids[ovn_const.OVN_CIDRS_EXT_ID_KEY].split(' '))
          ip_addresses.add(METADATA_DEFAULT_CIDR)
          metadata_port = MetadataPortInfo(mac, ip_addresses)
  
          # Create the VETH pair if it's not created. Also the add_veth function
          # will create the namespace for us.
          namespace = self._get_namespace_name(datapath)
          veth_name = self._get_veth_name(datapath)
  
          ip1 = ip_lib.IPDevice(veth_name[0])
          if ip_lib.device_exists(veth_name[1], namespace):
              ip2 = ip_lib.IPDevice(veth_name[1], namespace)
          else:
              LOG.debug("Creating VETH %s in %s namespace", veth_name[1],
                        namespace)
              # Might happen that the end in the root namespace exists even
              # though the other end doesn't. Make sure we delete it first if
              # that's the case.
              if ip1.exists():
                  ip1.link.delete()
              ip1, ip2 = ip_lib.IPWrapper().add_veth(
                  veth_name[0], veth_name[1], namespace)
  
          # Make sure both ends of the VETH are up
          ip1.link.set_up()
          ip2.link.set_up()
  
          # Configure the MAC address.
          ip2.link.set_address(metadata_port.mac)
          dev_info = ip2.addr.list()
  
          # Configure the IP addresses on the VETH pair and remove those
          # that we no longer need.
          current_cidrs = {dev['cidr'] for dev in dev_info}
          for ipaddr in current_cidrs - metadata_port.ip_addresses:
              ip2.addr.delete(ipaddr)
          for ipaddr in metadata_port.ip_addresses - current_cidrs:
              # NOTE(dalvarez): metadata only works on IPv4. We're doing this
              # extra check here because it could be that the metadata port has
              # an IPv6 address if there's an IPv6 subnet with SLAAC in its
              # network. Neutron IPAM will autoallocate an IPv6 address for every
              # port in the network.
              if utils.get_ip_version(ipaddr) == 4:
                  ip2.addr.add(ipaddr)
  
          # Configure the OVS port and add external_ids:iface-id so that it
          # can be tracked by OVN.
          self.ovs_idl.add_port(self.conf.ovs_integration_bridge,
                                veth_name[0]).execute()
          self.ovs_idl.db_set(
              'Interface', veth_name[0],
              ('external_ids', {'iface-id': port.logical_port})).execute()
  
          # Spawn metadata proxy if it's not already running.
          metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
              self._process_monitor, namespace, METADATA_PORT,
              self.conf, network_id=datapath)
  
          self.update_chassis_metadata_networks(datapath)
          return namespace
code_tokens: def provision_datapath ( self , datapath ) : LOG . debug ( "Provisioning datapath %s" , datapath ) port = self . sb_idl . get_metadata_port_network ( datapath ) if not ( port and port . mac and port . external_ids . get ( ovn_const . OVN_CIDRS_EXT_ID_KEY , None ) ) : LOG . debug ( "There is no metadata port for datapath %s or it has no " "MAC or IP addresses configured, tearing the namespace " "down if needed" , datapath ) self . teardown_datapath ( datapath ) return match = MAC_PATTERN . match ( port . mac [ 0 ] . split ( ' ' ) [ 0 ] ) if not match : LOG . error ( "Metadata port for datapath %s doesn't have a MAC " "address, tearing the namespace down if needed" , datapath ) self . teardown_datapath ( datapath ) return mac = match . group ( ) ip_addresses = set ( port . external_ids [ ovn_const . OVN_CIDRS_EXT_ID_KEY ] . split ( ' ' ) ) ip_addresses . add ( METADATA_DEFAULT_CIDR ) metadata_port = MetadataPortInfo ( mac , ip_addresses ) namespace = self . _get_namespace_name ( datapath ) veth_name = self . _get_veth_name ( datapath ) ip1 = ip_lib . IPDevice ( veth_name [ 0 ] ) if ip_lib . device_exists ( veth_name [ 1 ] , namespace ) : ip2 = ip_lib . IPDevice ( veth_name [ 1 ] , namespace ) else : LOG . debug ( "Creating VETH %s in %s namespace" , veth_name [ 1 ] , namespace ) if ip1 . exists ( ) : ip1 . link . delete ( ) ip1 , ip2 = ip_lib . IPWrapper ( ) . add_veth ( veth_name [ 0 ] , veth_name [ 1 ] , namespace ) ip1 . link . set_up ( ) ip2 . link . set_up ( ) ip2 . link . set_address ( metadata_port . mac ) dev_info = ip2 . addr . list ( ) current_cidrs = { dev [ 'cidr' ] for dev in dev_info } for ipaddr in current_cidrs - metadata_port . ip_addresses : ip2 . addr . delete ( ipaddr ) for ipaddr in metadata_port . ip_addresses - current_cidrs : if utils . get_ip_version ( ipaddr ) == 4 : ip2 . addr . add ( ipaddr ) self . ovs_idl . add_port ( self . conf . ovs_integration_bridge , veth_name [ 0 ] ) . execute ( ) self . ovs_idl . db_set ( 'Interface' , veth_name [ 0 ] , ( 'external_ids' , { 'iface-id' : port . logical_port } ) ) . execute ( ) metadata_driver . MetadataDriver . spawn_monitored_metadata_proxy ( self . _process_monitor , namespace , METADATA_PORT , self . conf , network_id = datapath ) self . update_chassis_metadata_networks ( datapath ) return namespace
short_docstring: Provision the datapath so that it can serve metadata.
short_docstring_tokens: Provision the datapath so that it can serve metadata .
comment: """Provision the datapath so that it can serve metadata.
  
          This function will create the namespace and VETH pair if needed
          and assign the IP addresses to the interface corresponding to the
          metadata port of the network. It will also remove existing IP
          addresses that are no longer needed.
  
          :return: The metadata namespace name of this datapath
          """$SEP$# If there's no metadata port or it doesn't have a MAC or IP$SEP$# addresses, then tear the namespace down if needed. This might happen$SEP$# when there are no subnets yet created so metadata port doesn't have$SEP$# an IP address.$SEP$# First entry of the mac field must be the MAC address.$SEP$# If it is not, we can't provision the namespace. Tear it down if$SEP$# needed and log the error.$SEP$# Create the VETH pair if it's not created. Also the add_veth function$SEP$# will create the namespace for us.$SEP$# Might happen that the end in the root namespace exists even$SEP$# though the other end doesn't. Make sure we delete it first if$SEP$# that's the case.$SEP$# Make sure both ends of the VETH are up$SEP$# Configure the MAC address.$SEP$# Configure the IP addresses on the VETH pair and remove those$SEP$# that we no longer need.$SEP$# NOTE(dalvarez): metadata only works on IPv4. We're doing this$SEP$# extra check here because it could be that the metadata port has$SEP$# an IPv6 address if there's an IPv6 subnet with SLAAC in its$SEP$# network. Neutron IPAM will autoallocate an IPv6 address for every$SEP$# port in the network.$SEP$# Configure the OVS port and add external_ids:iface-id so that it$SEP$# can be tracked by OVN.$SEP$# Spawn metadata proxy if it's not already running.