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, } 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)) -- 1.7.10.4
signature.asc
Description: Digital signature
