diff options
| -rw-r--r-- | cloudinit/sources/DataSourceOVF.py | 34 | ||||
| -rw-r--r-- | cloudinit/sources/helpers/vmware/imc/config_file.py | 4 | ||||
| -rw-r--r-- | cloudinit/sources/helpers/vmware/imc/config_nic.py | 433 | ||||
| -rw-r--r-- | cloudinit/sources/helpers/vmware/imc/nic.py | 20 | ||||
| -rw-r--r-- | tests/unittests/test_vmware_config_file.py | 4 | 
5 files changed, 238 insertions, 257 deletions
diff --git a/cloudinit/sources/DataSourceOVF.py b/cloudinit/sources/DataSourceOVF.py index add7d243..6d3bf7bb 100644 --- a/cloudinit/sources/DataSourceOVF.py +++ b/cloudinit/sources/DataSourceOVF.py @@ -64,13 +64,12 @@ class DataSourceOVF(sources.DataSource):          (seedfile, contents) = get_ovf_env(self.paths.seed_dir)          dmi_info = dmi_data() -        system_uuid = ""          system_type = "" -        if dmi_info is False: +        if dmi_info is None:             LOG.debug("No dmidata utility found")          else: -           system_uuid, system_type = tuple(dmi_info) +           (_, system_type) = dmi_info          if 'vmware' in system_type.lower():              LOG.debug("VMware Virtual Platform found") @@ -172,11 +171,11 @@ class DataSourceOVFNet(DataSourceOVF):          self.supported_seed_starts = ("http://", "https://", "ftp://") -def wait_for_imc_cfg_file(directoryPath, filename, maxwait=180, naplen=5): +def wait_for_imc_cfg_file(dirpath, filename, maxwait=180, naplen=5):      waited = 0      while waited < maxwait: -        fileFullPath = search_file(directoryPath, filename) +        fileFullPath = search_file(dirpath, filename)          if fileFullPath:              return fileFullPath          time.sleep(naplen) @@ -357,28 +356,13 @@ def dmi_data():      return (sys_uuid.lower(), sys_type) -def search_file(directoryPath, filename): -    if not directoryPath or not filename: +def search_file(dirpath, filename): +    if not dirpath or not filename:         return None -    dirs = [] - -    if os.path.isdir(directoryPath): -       dirs.append(directoryPath) - -    while dirs: -        dir = dirs.pop() -        children = [] -        try: -            children.extend(os.listdir(dir)) -        except: -            LOG.debug("Ignoring the error while searching the directory %s" % dir) -        for child in children:  -            childFullPath = os.path.join(dir, child) -            if os.path.isdir(childFullPath): -                dirs.append(childFullPath) -            elif child == filename:  -                return childFullPath +    for root, dirs, files in os.walk(dirpath): +        if filename in files: +            return os.path.join(root, filename)      return None diff --git a/cloudinit/sources/helpers/vmware/imc/config_file.py b/cloudinit/sources/helpers/vmware/imc/config_file.py index 7c47d14c..bb9fb7dc 100644 --- a/cloudinit/sources/helpers/vmware/imc/config_file.py +++ b/cloudinit/sources/helpers/vmware/imc/config_file.py @@ -61,10 +61,6 @@ class ConfigFile(ConfigSource, dict):          self[key] = val -    def size(self): -        """Return the number of properties present.""" -        return len(self) -      def _loadConfigFile(self, filename):          """          Parses properties from the specified config file. diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py index 8e2fc5d3..d79e6936 100644 --- a/cloudinit/sources/helpers/vmware/imc/config_nic.py +++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py @@ -26,221 +26,222 @@ logger = logging.getLogger(__name__)  class NicConfigurator: -   def __init__(self, nics): -      """ -      Initialize the Nic Configurator -      @param nics (list) an array of nics to configure -      """ -      self.nics = nics -      self.mac2Name = {} -      self.ipv4PrimaryGateway = None -      self.ipv6PrimaryGateway = None -      self.find_devices() -      self._primaryNic = self.get_primary_nic() - -   def get_primary_nic(self): -      """ -      Retrieve the primary nic if it exists -      @return (NicBase): the primary nic if exists, None otherwise -      """ -      primaryNic = None - -      for nic in self.nics: -         if nic.primary: -            if primaryNic: -               raise Exception('There can only be one primary nic', -                               primaryNic.mac, nic.mac) +    def __init__(self, nics): +        """ +        Initialize the Nic Configurator +        @param nics (list) an array of nics to configure +        """ +        self.nics = nics +        self.mac2Name = {} +        self.ipv4PrimaryGateway = None +        self.ipv6PrimaryGateway = None +        self.find_devices() +        self._primaryNic = self.get_primary_nic() + +    def get_primary_nic(self): +        """ +        Retrieve the primary nic if it exists +        @return (NicBase): the primary nic if exists, None otherwise +        """ +        primaryNic = None + +        for nic in self.nics: +            if nic.primary: +                if primaryNic: +                    raise Exception('There can only be one primary nic', +                                    primaryNic.mac, nic.mac)              primaryNic = nic -      return primaryNic - -   def find_devices(self): -      """ -      Create the mac2Name dictionary -      The mac address(es) are in the lower case -      """ -      cmd = 'ip addr show' -      outText = subprocess.check_output(cmd, shell=True).decode() -      sections = re.split(r'\n\d+: ', '\n' + outText)[1:] - -      macPat = r'link/ether (([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))' -      for section in sections: -         matcher = re.search(macPat, section) -         if not matcher:  # Only keep info about nics -            continue -         mac = matcher.group(1).lower() -         name = section.split(':', 1)[0] -         self.mac2Name[mac] = name - -   def gen_one_nic(self, nic): -      """ -      Return the lines needed to configure a nic -      @return (str list): the string list to configure the nic -      @param nic (NicBase): the nic to configure -      """ -      lines = [] -      name = self.mac2Name.get(nic.mac.lower()) -      if not name: -         raise ValueError('No known device has MACADDR: %s' % nic.mac) - -      if nic.onboot: -         lines.append('auto %s' % name) - -      # Customize IPv4 -      lines.extend(self.gen_ipv4(name, nic)) - -      # Customize IPv6 -      lines.extend(self.gen_ipv6(name, nic)) - -      lines.append('') - -      return lines - -   def gen_ipv4(self, name, nic): -      """ -      Return the lines needed to configure the IPv4 setting of a nic -      @return (str list): the string list to configure the gateways -      @param name (str): name of the nic -      @param nic (NicBase): the nic to configure -      """ -      lines = [] - -      bootproto = nic.bootProto.lower() -      if nic.ipv4_mode.lower() == 'disabled': -         bootproto = 'manual' -      lines.append('iface %s inet %s' % (name, bootproto)) - -      if bootproto != 'static': -         return lines - -      # Static Ipv4 -      v4 = nic.staticIpv4 -      if v4.ip: -         lines.append('    address %s' % v4.ip) -      if v4.netmask: -         lines.append('    netmask %s' % v4.netmask) - -      # Add the primary gateway -      if nic.primary and v4.gateways: -         self.ipv4PrimaryGateway = v4.gateways[0] -         lines.append('    gateway %s metric 0' % self.ipv4PrimaryGateway) -         return lines - -      # Add routes if there is no primary nic -      if not self._primaryNic: -         lines.extend(self.gen_ipv4_route(nic, v4.gateways)) - -      return lines - -   def gen_ipv4_route(self, nic, gateways): -      """ -      Return the lines needed to configure additional Ipv4 route -      @return (str list): the string list to configure the gateways -      @param nic (NicBase): the nic to configure -      @param gateways (str list): the list of gateways -      """ -      lines = [] - -      for gateway in gateways: -         lines.append('    up route add default gw %s metric 10000' % gateway) - -      return lines - -   def gen_ipv6(self, name, nic): -      """ -      Return the lines needed to configure the gateways for a nic -      @return (str list): the string list to configure the gateways -      @param name (str): name of the nic -      @param nic (NicBase): the nic to configure -      """ -      lines = [] - -      if not nic.staticIpv6: -         return lines - -      # Static Ipv6 -      addrs = nic.staticIpv6 -      lines.append('iface %s inet6 static' % name) -      lines.append('    address %s' % addrs[0].ip) -      lines.append('    netmask %s' % addrs[0].netmask) - -      for addr in addrs[1:]: -         lines.append('    up ifconfig %s inet6 add %s/%s' % (name, addr.ip, -                                                              addr.netmask)) -      # Add the primary gateway -      if nic.primary: -         for addr in addrs: -            if addr.gateway: -               self.ipv6PrimaryGateway = addr.gateway -               lines.append('    gateway %s' % self.ipv6PrimaryGateway) -               return lines - -      # Add routes if there is no primary nic -      if not self._primaryNic: -         lines.extend(self._genIpv6Route(name, nic, addrs)) - -      return lines - -   def _genIpv6Route(self, name, nic, addrs): -      lines = [] - -      for addr in addrs: -         lines.append('    up route -A inet6 add default gw %s metric 10000' % -                      addr.gateway) - -      return lines - -   def generate(self): -      """Return the lines that is needed to configure the nics""" -      lines = [] -      lines.append('iface lo inet loopback') -      lines.append('auto lo') -      lines.append('') - -      for nic in self.nics: -         lines.extend(self.gen_one_nic(nic)) - -      return lines - -   def clear_dhcp(self): -      logger.info('Clearing DHCP leases') - -      subprocess.call('pkill dhclient', shell=True) -      subprocess.check_call('rm -f /var/lib/dhcp/*', shell=True) - -   def if_down_up(self): -      names = [] -      for nic in self.nics: -         name = self.mac2Name.get(nic.mac.lower()) -         names.append(name) - -      for name in names: -         logger.info('Bring down interface %s' % name) -         subprocess.check_call('ifdown %s' % name, shell=True) - -      self.clear_dhcp() - -      for name in names: -         logger.info('Bring up interface %s' % name) -         subprocess.check_call('ifup %s' % name, shell=True) - -   def configure(self): -      """ -      Configure the /etc/network/intefaces -      Make a back up of the original -      """ -      containingDir = '/etc/network' - -      interfaceFile = os.path.join(containingDir, 'interfaces') -      originalFile = os.path.join(containingDir, -                                  'interfaces.before_vmware_customization') - -      if not os.path.exists(originalFile) and os.path.exists(interfaceFile): -         os.rename(interfaceFile, originalFile) - -      lines = self.generate() -      with open(interfaceFile, 'w') as fp: -         for line in lines: -            fp.write('%s\n' % line) - -      self.if_down_up() +        return primaryNic + +    def find_devices(self): +        """ +        Create the mac2Name dictionary +        The mac address(es) are in the lower case +        """ +        cmd = 'ip addr show' +        outText = subprocess.check_output(cmd, shell=True).decode() +        sections = re.split(r'\n\d+: ', '\n' + outText)[1:] + +        macPat = r'link/ether (([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))' +        for section in sections: +            matcher = re.search(macPat, section) +            if not matcher:  # Only keep info about nics +                continue +            mac = matcher.group(1).lower() +            name = section.split(':', 1)[0] +            self.mac2Name[mac] = name + +    def gen_one_nic(self, nic): +        """ +        Return the lines needed to configure a nic +        @return (str list): the string list to configure the nic +        @param nic (NicBase): the nic to configure +        """ +        lines = [] +        name = self.mac2Name.get(nic.mac.lower()) +        if not name: +            raise ValueError('No known device has MACADDR: %s' % nic.mac) + +        if nic.onboot: +            lines.append('auto %s' % name) + +        # Customize IPv4 +        lines.extend(self.gen_ipv4(name, nic)) + +        # Customize IPv6 +        lines.extend(self.gen_ipv6(name, nic)) + +        lines.append('') + +        return lines + +    def gen_ipv4(self, name, nic): +        """ +        Return the lines needed to configure the IPv4 setting of a nic +        @return (str list): the string list to configure the gateways +        @param name (str): name of the nic +        @param nic (NicBase): the nic to configure +        """ +        lines = [] + +        bootproto = nic.bootProto.lower() +        if nic.ipv4_mode.lower() == 'disabled': +            bootproto = 'manual' +        lines.append('iface %s inet %s' % (name, bootproto)) + +        if bootproto != 'static': +            return lines + +        # Static Ipv4 +        v4 = nic.staticIpv4 +        if v4.ip: +            lines.append('    address %s' % v4.ip) +        if v4.netmask: +            lines.append('    netmask %s' % v4.netmask) + +        # Add the primary gateway +        if nic.primary and v4.gateways: +            self.ipv4PrimaryGateway = v4.gateways[0] +            lines.append('    gateway %s metric 0' % self.ipv4PrimaryGateway) +            return lines + +        # Add routes if there is no primary nic +        if not self._primaryNic: +            lines.extend(self.gen_ipv4_route(nic, v4.gateways)) + +        return lines + +    def gen_ipv4_route(self, nic, gateways): +        """ +        Return the lines needed to configure additional Ipv4 route +        @return (str list): the string list to configure the gateways +        @param nic (NicBase): the nic to configure +        @param gateways (str list): the list of gateways +        """ +        lines = [] + +        for gateway in gateways: +            lines.append('    up route add default gw %s metric 10000' % +                         gateway) + +        return lines + +    def gen_ipv6(self, name, nic): +        """ +        Return the lines needed to configure the gateways for a nic +        @return (str list): the string list to configure the gateways +        @param name (str): name of the nic +        @param nic (NicBase): the nic to configure +        """ +        lines = [] + +        if not nic.staticIpv6: +            return lines + +        # Static Ipv6 +        addrs = nic.staticIpv6 +        lines.append('iface %s inet6 static' % name) +        lines.append('    address %s' % addrs[0].ip) +        lines.append('    netmask %s' % addrs[0].netmask) + +        for addr in addrs[1:]: +            lines.append('    up ifconfig %s inet6 add %s/%s' % (name, addr.ip, +                                                                 addr.netmask)) +        # Add the primary gateway +        if nic.primary: +            for addr in addrs: +                if addr.gateway: +                    self.ipv6PrimaryGateway = addr.gateway +                    lines.append('    gateway %s' % self.ipv6PrimaryGateway) +                    return lines + +        # Add routes if there is no primary nic +        if not self._primaryNic: +            lines.extend(self._genIpv6Route(name, nic, addrs)) + +        return lines + +    def _genIpv6Route(self, name, nic, addrs): +        lines = [] + +        for addr in addrs: +            lines.append('    up route -A inet6 add default gw %s metric 10000' % +                         addr.gateway) + +        return lines + +    def generate(self): +        """Return the lines that is needed to configure the nics""" +        lines = [] +        lines.append('iface lo inet loopback') +        lines.append('auto lo') +        lines.append('') + +        for nic in self.nics: +            lines.extend(self.gen_one_nic(nic)) + +        return lines + +    def clear_dhcp(self): +        logger.info('Clearing DHCP leases') + +        subprocess.call('pkill dhclient', shell=True) +        subprocess.check_call('rm -f /var/lib/dhcp/*', shell=True) + +    def if_down_up(self): +        names = [] +        for nic in self.nics: +            name = self.mac2Name.get(nic.mac.lower()) +            names.append(name) + +        for name in names: +            logger.info('Bring down interface %s' % name) +            subprocess.check_call('ifdown %s' % name, shell=True) + +        self.clear_dhcp() + +        for name in names: +            logger.info('Bring up interface %s' % name) +            subprocess.check_call('ifup %s' % name, shell=True) + +    def configure(self): +        """ +        Configure the /etc/network/intefaces +        Make a back up of the original +        """ +        containingDir = '/etc/network' + +        interfaceFile = os.path.join(containingDir, 'interfaces') +        originalFile = os.path.join(containingDir, +                                    'interfaces.before_vmware_customization') + +        if not os.path.exists(originalFile) and os.path.exists(interfaceFile): +            os.rename(interfaceFile, originalFile) + +        lines = self.generate() +        with open(interfaceFile, 'w') as fp: +            for line in lines: +                fp.write('%s\n' % line) + +        self.if_down_up() diff --git a/cloudinit/sources/helpers/vmware/imc/nic.py b/cloudinit/sources/helpers/vmware/imc/nic.py index 6628a3ec..b5d704ea 100644 --- a/cloudinit/sources/helpers/vmware/imc/nic.py +++ b/cloudinit/sources/helpers/vmware/imc/nic.py @@ -49,35 +49,35 @@ class Nic(NicBase):      def primary(self):          value = self._get('PRIMARY')          if value: -           value = value.lower() -           return value == 'yes' or value == 'true' +            value = value.lower() +            return value == 'yes' or value == 'true'          else: -           return False +            return False      @property      def onboot(self):          value = self._get('ONBOOT')          if value: -           value = value.lower() -           return value == 'yes' or value == 'true' +            value = value.lower() +            return value == 'yes' or value == 'true'          else: -           return False +            return False      @property      def bootProto(self):          value = self._get('BOOTPROTO')          if value: -           return value.lower() +            return value.lower()          else: -           return "" +            return ""      @property      def ipv4_mode(self):          value = self._get('IPv4_MODE')          if value: -           return value.lower() +            return value.lower()          else: -           return "" +            return ""      @property      def staticIpv4(self): diff --git a/tests/unittests/test_vmware_config_file.py b/tests/unittests/test_vmware_config_file.py index 51166dd7..d5c7367b 100644 --- a/tests/unittests/test_vmware_config_file.py +++ b/tests/unittests/test_vmware_config_file.py @@ -36,12 +36,12 @@ class TestVmwareConfigFile(unittest.TestCase):          cf.clear() -        self.assertEqual(0, cf.size(), "clear size") +        self.assertEqual(0, len(cf), "clear size")          cf._insertKey("  PASSWORD|-PASS ", "  foo  ")          cf._insertKey("BAR", "   ") -        self.assertEqual(2, cf.size(), "insert size") +        self.assertEqual(2, len(cf), "insert size")          self.assertEqual('foo', cf["PASSWORD|-PASS"], "password")          self.assertTrue("PASSWORD|-PASS" in cf, "hasPassword")          self.assertFalse(cf.should_keep_current_value("PASSWORD|-PASS"),  | 
