On Fri, May 17, 2013 at 2:23 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.
>
> Additionally a custom vif script is provided, vif-ganeti
> that is stored in /usr/lib/ganeti/vif-ganeti. This
> script is executed instead of the one defined in
> xend-config.sxp. Include this script in build process.
> TODO: debian/links should include
> a symlink of that file within /etc/xen/scripts/.
>
> Cleanup NIC dir when removing config files. Upon Xen
> configuration file removal, remove NIC dir as well.
>
> Signed-off-by: Dimitris Aragiorgis <[email protected]>
> ---
>  Makefile.am              |    7 +++++
>  lib/hypervisor/hv_xen.py |   74
> ++++++++++++++++++++++++++++++++++++++++++++--
>  tools/vif-ganeti.in      |   47 +++++++++++++++++++++++++++++
>  3 files changed, 126 insertions(+), 2 deletions(-)
>  create mode 100755 tools/vif-ganeti.in
>
> diff --git a/Makefile.am b/Makefile.am
> index 037cf53..4e46d8f 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -192,6 +192,7 @@ CLEANFILES = \
>         $(man_MANS) \
>         $(manhtml) \
>         tools/kvm-ifup \
> +       tools/vif-ganeti \
>         tools/users-setup \
>         tools/vcluster-setup \
>         stamp-directories \
> @@ -904,6 +905,7 @@ nodist_pkglib_python_scripts = \
>  myexeclib_SCRIPTS = \
>         daemons/daemon-util \
>         tools/kvm-ifup \
> +       tools/vif-ganeti \
>         $(pkglib_python_scripts) \
>         $(HS_MYEXECLIB_PROGS)
>
> @@ -939,6 +941,7 @@ EXTRA_DIST = \
>         devel/upload \
>         devel/webserver \
>         tools/kvm-ifup.in \
> +       tools/vif-ganeti.in \
>         tools/users-setup.in \
>         tools/vcluster-setup.in \
>         $(docinput) \
> @@ -1337,6 +1340,10 @@ tools/kvm-ifup: tools/kvm-ifup.in$(REPLACE_VARS_SED)
>         sed -f $(REPLACE_VARS_SED) < $< > $@
>         chmod +x $@
>
> +tools/vif-ganeti: tools/vif-ganeti.in $(REPLACE_VARS_SED)
> +       sed -f $(REPLACE_VARS_SED) < $< > $@
> +       chmod +x $@
> +
>  tools/users-setup: tools/users-setup.in $(REPLACE_VARS_SED)
>         sed -f $(REPLACE_VARS_SED) < $< > $@
>         chmod +x $@
> diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
> index 653f6b2..9c0c86e 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
> @@ -41,6 +42,8 @@ XEND_CONFIG_FILE =
> utils.PathJoin(pathutils.XEN_CONFIG_DIR, "xend-config.sxp")
>  XL_CONFIG_FILE = utils.PathJoin(pathutils.XEN_CONFIG_DIR, "xen/xl.conf")
>  VIF_BRIDGE_SCRIPT = utils.PathJoin(pathutils.XEN_CONFIG_DIR,
>                                     "scripts/vif-bridge")
> +VIF_GANETI_SCRIPT = utils.PathJoin(pathutils.XEN_CONFIG_DIR,
> +                                   "scripts/vif-ganeti")
>  _DOM0_NAME = "Domain-0"
>  _DISK_LETTERS = string.ascii_lowercase
>
> @@ -310,6 +313,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,12 +378,68 @@ 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.
>
>      """
>      raise NotImplementedError
>
> +
>

Nack to the extra empty line.


>    def _WriteConfigFile(self, instance_name, data):
>      """Write the Xen config file for the instance.
>
> @@ -413,6 +474,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
>
>
Ack, but we should probably stash this file away for debugging in case of
failing to start an instance (see balazs' super-recent patch).


>    def _GetXmList(self, include_node):
>      """Wrapper around module level L{_GetXmList}.
> @@ -840,14 +906,16 @@ 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]
> +      nic_str += ", script=%s" % VIF_GANETI_SCRIPT
>        vif_data.append("'%s'" % nic_str)
> +      cls._WriteNICInfoFile(instance.name, idx, nic)
>
>      disk_data = \
>        _GetConfigFileDiskData(block_devices,
> hvp[constants.HV_BLOCKDEV_PREFIX])
> @@ -999,14 +1067,16 @@ 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]
> +      nic_str += ", script=%s" % VIF_GANETI_SCRIPT
>        vif_data.append("'%s'" % nic_str)
> +      cls._WriteNICInfoFile(instance.name, idx, nic)
>
>      config.write("vif = [%s]\n" % ",".join(vif_data))
>
> diff --git a/tools/vif-ganeti.in b/tools/vif-ganeti.in
> new file mode 100755
> index 0000000..a8eebea
> --- /dev/null
> +++ b/tools/vif-ganeti.in
> @@ -0,0 +1,47 @@
> +#!/bin/bash
> +
> +if [ -x "@SYSCONFDIR@/xen/scripts/vif-custom" ]; then
> +       exec @SYSCONFDIR@/xen/scripts/vif-custom $*
> +fi
> +
> +dir=$(dirname "$0")
> +. "$dir"/vif-common.sh
> +
> +# taken from older vif-common.sh
> +dev=$vif
> +dev_=${dev#vif}
> +domid=${dev_%.*}
> +devid=${dev_#*.}
> +domname=$(xm domname $domid)
> +
> +GANETI_NIC_DIR=/var/run/ganeti/xen-hypervisor/nic
> +INTERFACE=$dev
> +INSTANCE=$domname
> +
> +source $GANETI_NIC_DIR/$domname/$devid
> +
> +function setup_routed_mode {
> +
> +  ;;
> +
> +}
> +
> +
> +function setup_bridged_mode {
> +
> +  ;;
> +
> +}
> +
> +ip link set $INTERFACE up
> +
> +if [ "$MODE" == "routed" ]; then
> +  setup_routed_mode
> +elif [ "$MODE" == "bridged" ]; then
> +  BRIDGE=$(xenstore_read_default "$XENBUS_PATH/bridge" "$LINK")
> +  brctl addif $BRIDGE $INTERFACE
> +  setup_bridged_mode
> +fi
> +
> +success
>

Couldn't we share some of this between the xen and kvm script?
Also, could we not support openvswitch (the same way as we do in the kvm
one).

Thanks,

Guido

Reply via email to