On Fri, May 17, 2013 at 4:31 PM, Dimitris Aragiorgis <[email protected]>wrote:

> For every NIC write down a file that contains NIC's
> info (MAC, mode, link, network details), that can
> be sourced by any vif script.  The file location is:
> /var/run/ganeti/xen-hypervisor/nic/<domname>/<nicidx>.
>
> This file is created upon cfg file creation and before
> starting the instance.
>
> Upon Xen configuration file removal, remove corresponding
> NIC dir as well.
>
> Add new hv param vif_script that allows execution of
> a user defined vif script and overrides the one
> xend is configured with (in xend-config.sxp).
>
> Signed-off-by: Dimitris Aragiorgis <[email protected]>
> ---
>  lib/constants.py         |    4 +++
>  lib/hypervisor/hv_xen.py |   74
> ++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/lib/constants.py b/lib/constants.py
> index 0266b2b..97b9fe8 100644
> --- a/lib/constants.py
> +++ b/lib/constants.py
> @@ -943,6 +943,7 @@ HV_KVM_EXTRA = "kvm_extra"
>  HV_KVM_MACHINE_VERSION = "machine_version"
>  HV_KVM_PATH = "kvm_path"
>  HV_VIF_TYPE = "vif_type"
> +HV_VIF_SCRIPT = "vif_script"
>
>
>  HVS_PARAMETER_TYPES = {
> @@ -1013,6 +1014,7 @@ HVS_PARAMETER_TYPES = {
>    HV_KVM_EXTRA: VTYPE_STRING,
>    HV_KVM_MACHINE_VERSION: VTYPE_STRING,
>    HV_VIF_TYPE: VTYPE_STRING,
> +  HV_VIF_SCRIPT: VTYPE_STRING,
>    }
>
>  HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys())
> @@ -2020,6 +2022,7 @@ HVC_DEFAULTS = {
>      HV_CPU_MASK: CPU_PINNING_ALL,
>      HV_CPU_CAP: 0,
>      HV_CPU_WEIGHT: 256,
> +    HV_VIF_SCRIPT: "",
>      },
>    HT_XEN_HVM: {
>      HV_BOOT_ORDER: "cd",
> @@ -2042,6 +2045,7 @@ HVC_DEFAULTS = {
>      HV_CPU_CAP: 0,
>      HV_CPU_WEIGHT: 256,
>      HV_VIF_TYPE: HT_HVM_VIF_IOEMU,
> +    HV_VIF_SCRIPT: "",
>      },
>    HT_KVM: {
>      HV_KVM_PATH: KVM_PATH,
> diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
> index 653f6b2..b482892 100644
> --- a/lib/hypervisor/hv_xen.py
> +++ b/lib/hypervisor/hv_xen.py
> @@ -25,6 +25,7 @@
>
>  import logging
>  import string # pylint: disable=W0402
> +import shutil
>  from cStringIO import StringIO
>
>  from ganeti import constants
> @@ -310,6 +311,8 @@ class XenHypervisor(hv_base.BaseHypervisor):
>    CAN_MIGRATE = True
>    REBOOT_RETRY_COUNT = 60
>    REBOOT_RETRY_INTERVAL = 10
> +  _ROOT_DIR = pathutils.RUN_DIR + "/xen-hypervisor"
> +  _NICS_DIR = _ROOT_DIR + "/nic" # contains instances nic <-> tap
> associations
>
>    ANCILLARY_FILES = [
>      XEND_CONFIG_FILE,
> @@ -373,6 +376,60 @@ class XenHypervisor(hv_base.BaseHypervisor):
>      return utils.PathJoin(self._cfgdir, instance_name)
>
>    @classmethod
> +  def _WriteNICInfoFile(cls, instance_name, idx, nic):
> +    """Write the Xen config file for the instance.
> +
> +    This version of the function just writes the config file from static
> data.
> +
> +    """
> +    utils.EnsureDirs([(cls._InstanceNICDir(instance_name),
> +                     constants.RUN_DIRS_MODE)])
> +    cfg_file = cls._InstanceNICFile(instance_name, idx)
> +    data = StringIO()
> +
> +    if nic.netinfo:
> +      netinfo = objects.Network.FromDict(nic.netinfo)
> +      data.write("NETWORK_NAME=%s\n" % netinfo.name)
> +      if netinfo.network:
> +        data.write("NETWORK_SUBNET=%s\n" % netinfo.network)
> +      if netinfo.gateway:
> +        data.write("NETWORK_GATEWAY=%s\n" % netinfo.gateway)
> +      if netinfo.network6:
> +        data.write("NETWORK_SUBNET6=%s\n" % netinfo.network6)
> +      if netinfo.gateway6:
> +        data.write("NETWORK_GATEWAY6=%s\n" % netinfo.gateway6)
> +      if netinfo.mac_prefix:
> +        data.write("NETWORK_MAC_PREFIX=%s\n" % netinfo.mac_prefix)
> +      if netinfo.tags:
> +        data.write("NETWORK_TAGS=%s\n" % "\ ".join(netinfo.tags))
> +
> +    data.write("MAC=%s\n" % nic.mac)
> +    data.write("IP=%s\n" % nic.ip)
> +    data.write("MODE=%s\n" % nic.nicparams[constants.NIC_MODE])
> +    data.write("LINK=%s\n" % nic.nicparams[constants.NIC_LINK])
> +
> +    try:
> +      utils.WriteFile(cfg_file, data=data.getvalue())
> +    except EnvironmentError, err:
> +      raise errors.HypervisorError("Cannot write Xen instance
> configuration"
> +                                   " file %s: %s" % (cfg_file, err))
> +
> +  @classmethod
> +  def _InstanceNICDir(cls, instance_name):
> +    """Returns the name of the directory holding the tap device files for
> a
> +    given instance.
> +
> +    """
> +    return utils.PathJoin(cls._NICS_DIR, instance_name)
> +
> +  @classmethod
> +  def _InstanceNICFile(cls, instance_name, seq):
> +    """Returns the name of the file containing the tap device for a given
> NIC
> +
> +    """
> +    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
> +
> +  @classmethod
>    def _GetConfig(cls, instance, startup_memory, block_devices):
>      """Build Xen configuration for an instance.
>
> @@ -413,6 +470,11 @@ class XenHypervisor(hv_base.BaseHypervisor):
>
>      """
>      utils.RemoveFile(self._ConfigFileName(instance_name))
> +    try:
> +      shutil.rmtree(self._InstanceNICDir(instance_name))
> +    except OSError, err:
> +      if err.errno != errno.ENOENT:
> +        raise
>
>    def _GetXmList(self, include_node):
>      """Wrapper around module level L{_GetXmList}.
> @@ -789,6 +851,7 @@ class XenPvmHypervisor(XenHypervisor):
>      constants.HV_CPU_CAP: hv_base.OPT_NONNEGATIVE_INT_CHECK,
>      constants.HV_CPU_WEIGHT:
>        (False, lambda x: 0 < x < 65536, "invalid weight", None, None),
> +    constants.HV_VIF_SCRIPT: hv_base.NO_CHECK,
>

Shoudn't we actually check that this exist?


>      }
>
>    def _GetConfig(self, instance, startup_memory, block_devices):
> @@ -840,14 +903,17 @@ class XenPvmHypervisor(XenHypervisor):
>      config.write("name = '%s'\n" % instance.name)
>
>      vif_data = []
> -    for nic in instance.nics:
> +    for idx, nic in enumerate(instance.nics):
>        nic_str = "mac=%s" % (nic.mac)
>        ip = getattr(nic, "ip", None)
>        if ip is not None:
>          nic_str += ", ip=%s" % ip
>        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
>          nic_str += ", bridge=%s" % nic.nicparams[constants.NIC_LINK]
> +      if hvp[constants.HV_VIF_SCRIPT]:
> +        nic_str += ", script=%s" % hvp[constants.HV_VIF_SCRIPT]
>        vif_data.append("'%s'" % nic_str)
> +      cls._WriteNICInfoFile(instance.name, idx, nic)
>
>      disk_data = \
>        _GetConfigFileDiskData(block_devices,
> hvp[constants.HV_BLOCKDEV_PREFIX])
> @@ -911,6 +977,7 @@ class XenHvmHypervisor(XenHypervisor):
>        (False, lambda x: 0 < x < 65535, "invalid weight", None, None),
>      constants.HV_VIF_TYPE:
>        hv_base.ParamInSet(False, constants.HT_HVM_VALID_VIF_TYPES),
> +    constants.HV_VIF_SCRIPT: hv_base.NO_CHECK,
>      }
>
>    def _GetConfig(self, instance, startup_memory, block_devices):
> @@ -999,14 +1066,17 @@ class XenHvmHypervisor(XenHypervisor):
>        # parameter 'model' is only valid with type 'ioemu'
>        nic_type_str = ", model=%s, type=%s" % \
>          (nic_type, constants.HT_HVM_VIF_IOEMU)
> -    for nic in instance.nics:
> +    for idx, nic in enumerate(instance.nics):
>        nic_str = "mac=%s%s" % (nic.mac, nic_type_str)
>        ip = getattr(nic, "ip", None)
>        if ip is not None:
>          nic_str += ", ip=%s" % ip
>        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
>          nic_str += ", bridge=%s" % nic.nicparams[constants.NIC_LINK]
> +      if hvp[constants.HV_VIF_SCRIPT]:
> +        nic_str += ", script=%s" % hvp[constants.HV_VIF_SCRIPT]
>        vif_data.append("'%s'" % nic_str)
> +      cls._WriteNICInfoFile(instance.name, idx, nic)
>
>      config.write("vif = [%s]\n" % ",".join(vif_data))
>
>
Thanks,

Guido

Reply via email to