Exemplo n.º 1
0
    def host_uuid(self):
        """
        Determine host UUID and if there is no existing /etc/vdsm/vdsm.id
        it will genereate UUID and save/persist in /etc/vdsm/vdsm.id
        """

        if self.vdsm_uuid:
            self.uuid = self.vdsm_uuid
        else:
            self.uuid = host.uuid()

        self.url_reg += "&uniqueId={u}".format(u=self.uuid)

        self.logger.debug("Registration via: {u}".format(u=self.url_reg))

        __VDSM_ID = "/etc/vdsm/vdsm.id"

        if self.vdsm_uuid and os.path.exists(__VDSM_ID):
            os.unlink(__VDSM_ID)

        if not os.path.exists(__VDSM_ID):
            with open(__VDSM_ID, 'w') as f:
                f.write(self.uuid)

        self.logger.info("Host UUID: {u}".format(u=self.uuid))
Exemplo n.º 2
0
    def host_uuid(self):
        """
        Determine host UUID and if there is no existing /etc/vdsm/vdsm.id
        it will genereate UUID and save/persist in /etc/vdsm/vdsm.id
        """

        if self.vdsm_uuid:
            self.uuid = self.vdsm_uuid
        else:
            self.uuid = host.uuid()

        self.url_reg += "&uniqueId={u}".format(u=self.uuid)

        self.logger.debug("Registration via: {u}".format(u=self.url_reg))

        __VDSM_ID = "/etc/vdsm/vdsm.id"

        if self.vdsm_uuid and os.path.exists(__VDSM_ID):
            os.unlink(__VDSM_ID)

        if not os.path.exists(__VDSM_ID):
            with open(__VDSM_ID, 'w') as f:
                f.write(self.uuid)

        self.logger.info("Host UUID: {u}".format(u=self.uuid))
Exemplo n.º 3
0
def _config_for_vdsm():
    """
    Return dict with configuration options that vdsm cares about.
    """
    hardware_id = host.uuid()
    if hardware_id is None:
        raise RuntimeError(
            "Cannot get host hardware id: please add host to engine")

    return {

        # If not configured, sanlock generates a new UUID on each
        # restart.  Using constant host name, recovery from unclean
        # shutdown is 3 times faster. Using the host hardware id will
        # make it easier to detect which host is related to sanlock
        # issues.
        # See https://bugzilla.redhat.com/1508098
        "our_host_name": hardware_id,

        # If not configured, sanlock uses 8 worker threads, limiting
        # concurrent add_lockspace calls. Using 40 worker threads,
        # activating a host with 40 storage domains is 3 times faster.
        # We use 50 worker threads to optimize for 50 storage domains.
        # See https://bugzilla.redhat.com/1902468
        "max_worker_threads": "50",
    }
Exemplo n.º 4
0
    def host_uuid(self):
        """
        Determine host UUID and if there is no existing /etc/vdsm/vdsm.id
        it will genereate UUID and save/persist in /etc/vdsm/vdsm.id
        """

        if self.vdsm_uuid:
            self.uuid = self.vdsm_uuid
        else:
            self.uuid = host.uuid(legacy=False)

        self.url_reg += "&uniqueId={u}".format(u=self.uuid)

        self.logger.debug("Registration via: {u}".format(u=self.url_reg))

        __VDSM_ID = "/etc/vdsm/vdsm.id"

        if self.vdsm_uuid and os.path.exists(__VDSM_ID):
            if utils.isOvirtNode():
                from ovirt.node.utils.fs import Config
                Config().unpersist(__VDSM_ID)
            os.unlink(__VDSM_ID)

        if not os.path.exists(__VDSM_ID):
            with open(__VDSM_ID, 'w') as f:
                f.write(self.uuid)

            if utils.isOvirtNode():
                from ovirt.node.utils.fs import Config
                Config().persist(__VDSM_ID)

        self.logger.info("Host UUID: {u}".format(u=self.uuid))
Exemplo n.º 5
0
def replace_placeholders(dom, arch, serial=None):
    """
    Replace the placeholders, if any, in the domain XML.
    This is the entry point orchestration function.
    See the documentation of the specific functions
    for the supported placeholders.
    """
    if cpuarch.is_x86(arch):
        osd = osinfo.version()
        os_version = osd.get('version', '') + '-' + osd.get('release', '')
        serial_number = host.uuid() if serial is None else serial
        libvirtxml.update_sysinfo(dom, osd['name'], os_version, serial_number)
Exemplo n.º 6
0
    def _update_metadata(self, dom, metadata, job_status):
        updated_metadata = metadata.copy()
        updated_metadata["modified"] = int(time.time())
        updated_metadata["host_hardware_id"] = host.uuid()
        updated_metadata["job_status"] = job_status

        if job_status == sc.JOB_STATUS_SUCCEEDED:
            updated_metadata["generation"] = su.next_generation(
                metadata["generation"])

        log.info("Updated lease %s metadata: %r", self.lease.sd_id,
                 updated_metadata)

        dom.set_lvb(self.lease.lease_id, updated_metadata)
Exemplo n.º 7
0
def get():
    numa.update()
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(
        [str(cpu_id) for cpu_id in cpu_topology.online_cpus])

    caps['cpuTopology'] = [{
        'cpu_id': cpu.cpu_id,
        'numa_cell_id': cpu.numa_cell_id,
        'socket_id': cpu.socket_id,
        'die_id': cpu.die_id,
        'core_id': cpu.core_id,
    } for cpu in numa.cpu_info()]

    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(_getFlagsAndFeatures())
    caps['vdsmToCpusAffinity'] = list(taskset.get(os.getpid()))

    caps.update(dsaversion.version_info())

    proxy = supervdsm.getProxy()
    net_caps = proxy.network_caps()
    caps.update(net_caps)
    caps['ovnConfigured'] = proxy.is_ovn_configured()

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['realtimeKernel'] = osinfo.runtime_kernel_flags().realtime
    caps['kernelArgs'] = osinfo.kernel_args()
    caps['nestedVirtualization'] = osinfo.nested_virtualization().enabled
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] // 1024)
    caps['reservedMem'] = str(
        config.getint('vars', 'host_mem_reserve') +
        config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    caps['rngSources'] = rngsources.list_available()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    caps['liveSnapshot'] = 'true'
    caps['liveMerge'] = 'true'
    caps['kdumpStatus'] = osinfo.kdump_status()
    caps["deferred_preallocation"] = True

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    # TODO This needs to be removed after adding engine side support
    # and adding gdeploy support to enable libgfapi on RHHI by default
    caps['additionalFeatures'] = ['libgfapi_supported']
    if osinfo.glusterEnabled:
        from vdsm.gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    caps['hostedEngineDeployed'] = _isHostedEngineDeployed()
    caps['hugepages'] = hugepages.supported()
    caps['kernelFeatures'] = osinfo.kernel_features()
    caps['vncEncrypted'] = _isVncEncrypted()
    caps['backupEnabled'] = True
    caps['coldBackupEnabled'] = True
    caps['clearBitmapsEnabled'] = True
    caps['fipsEnabled'] = _getFipsEnabled()
    try:
        caps['boot_uuid'] = osinfo.boot_uuid()
    except Exception:
        logging.exception("Can not find boot uuid")
    caps['tscFrequency'] = _getTscFrequency()
    caps['tscScaling'] = _getTscScaling()

    try:
        caps["connector_info"] = managedvolume.connector_info()
    except se.ManagedVolumeNotSupported as e:
        logging.info("managedvolume not supported: %s", e)
    except se.ManagedVolumeHelperFailed as e:
        logging.exception("Error getting managedvolume connector info: %s", e)

    # Which domain versions are supported by this host.
    caps["domain_versions"] = sc.DOMAIN_VERSIONS

    caps["supported_block_size"] = backends.supported_block_size()
    caps["cd_change_pdiv"] = True
    caps["refresh_disk_supported"] = True

    return caps
Exemplo n.º 8
0
def get():
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(cpu_topology.online_cpus)
    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(cpuinfo.flags() +
                                machinetype.compatible_cpu_models())

    caps.update(_getVersionInfo())

    net_caps = supervdsm.getProxy().network_caps()
    caps.update(net_caps)

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['realtimeKernel'] = osinfo.runtime_kernel_flags().realtime
    caps['kernelArgs'] = osinfo.kernel_args()
    caps['nestedVirtualization'] = osinfo.nested_virtualization().enabled
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] // 1024)
    caps['reservedMem'] = str(
        config.getint('vars', 'host_mem_reserve') +
        config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    caps['rngSources'] = rngsources.list_available()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    caps['liveSnapshot'] = 'true'
    caps['liveMerge'] = 'true'
    caps['kdumpStatus'] = osinfo.kdump_status()

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    # TODO This needs to be removed after adding engine side support
    # and adding gdeploy support to enable libgfapi on RHHI by default
    caps['additionalFeatures'] = ['libgfapi_supported']
    if osinfo.glusterEnabled:
        from vdsm.gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    caps['containers'] = containersconnection.is_supported()
    caps['hostedEngineDeployed'] = _isHostedEngineDeployed()
    caps['hugepages'] = hugepages.supported()
    caps['kernelFeatures'] = osinfo.kernel_features()
    return caps
Exemplo n.º 9
0
def get():
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(cpu_topology.online_cpus)
    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(cpuinfo.flags() +
                                machinetype.compatible_cpu_models())

    caps.update(_getVersionInfo())

    net_caps = supervdsm.getProxy().network_caps()
    caps.update(net_caps)

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['kernelArgs'] = osinfo.kernel_args()
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] / 1024)
    caps['reservedMem'] = str(
        config.getint('vars', 'host_mem_reserve') +
        config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    caps['rngSources'] = rngsources.available_sources()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    liveSnapSupported = _getLiveSnapshotSupport(cpuarch.effective())
    if liveSnapSupported is not None:
        caps['liveSnapshot'] = str(liveSnapSupported).lower()
    caps['liveMerge'] = str(getLiveMergeSupport()).lower()
    caps['kdumpStatus'] = osinfo.kdump_status()

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    caps['additionalFeatures'] = []
    if osinfo.glusterEnabled:
        from gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    return caps
Exemplo n.º 10
0
Arquivo: caps.py Projeto: kanalun/vdsm
def get():
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(cpu_topology.online_cpus)
    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(cpuinfo.flags() +
                                machinetype.compatible_cpu_models())

    caps.update(_getVersionInfo())

    # TODO: Version requests by engine to ease handling of compatibility.
    netinfo_data = netinfo_cache.get(compatibility=30600)
    caps.update(netinfo_data)

    super_caps_networks = supervdsm.getProxy().caps_networks()
    caps.update(super_caps_networks)

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = storage.hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] / 1024)
    caps['reservedMem'] = str(config.getint('vars', 'host_mem_reserve') +
                              config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    # Verify that our libvirt supports virtio RNG (since 10.0.2-31)
    requiredVer = LooseVersion('0.10.2-31')
    if 'libvirt' not in caps['packages2']:
        libvirtVer = None
    else:
        libvirtVer = LooseVersion(
            '-'.join((caps['packages2']['libvirt']['version'],
                      caps['packages2']['libvirt']['release'])))

    if libvirtVer is None:
        logging.debug('VirtioRNG DISABLED: unknown libvirt version')
    elif libvirtVer < requiredVer:
        logging.debug('VirtioRNG DISABLED: libvirt version %s required >= %s',
                      libvirtVer, requiredVer)
    else:
        caps['rngSources'] = vmdevices.core.Rng.available_sources()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    liveSnapSupported = _getLiveSnapshotSupport(cpuarch.effective())
    if liveSnapSupported is not None:
        caps['liveSnapshot'] = str(liveSnapSupported).lower()
    caps['liveMerge'] = str(getLiveMergeSupport()).lower()
    caps['kdumpStatus'] = osinfo.kdump_status()

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    caps['additionalFeatures'] = []
    if osinfo.glusterEnabled:
        from gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    return caps
Exemplo n.º 11
0
def get():
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(cpu_topology.online_cpus)
    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(cpuinfo.flags() +
                                machinetype.compatible_cpu_models())

    caps.update(_getVersionInfo())

    net_caps = supervdsm.getProxy().network_caps()
    caps.update(net_caps)

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['realtimeKernel'] = osinfo.runtime_kernel_flags().realtime
    caps['kernelArgs'] = osinfo.kernel_args()
    caps['nestedVirtualization'] = osinfo.nested_virtualization().enabled
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] / 1024)
    caps['reservedMem'] = str(config.getint('vars', 'host_mem_reserve') +
                              config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    caps['rngSources'] = rngsources.list_available()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    liveSnapSupported = _getLiveSnapshotSupport(cpuarch.effective())
    if liveSnapSupported is not None:
        caps['liveSnapshot'] = str(liveSnapSupported).lower()
    caps['liveMerge'] = str(getLiveMergeSupport()).lower()
    caps['kdumpStatus'] = osinfo.kdump_status()

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    caps['additionalFeatures'] = []
    if osinfo.glusterEnabled:
        from vdsm.gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    caps['containers'] = containersconnection.is_supported()
    caps['hostedEngineDeployed'] = _isHostedEngineDeployed()
    return caps
Exemplo n.º 12
0
Arquivo: caps.py Projeto: nirs/vdsm
def get():
    caps = {}
    cpu_topology = numa.cpu_topology()

    caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()

    if config.getboolean('vars', 'report_host_threads_as_cores'):
        caps['cpuCores'] = str(cpu_topology.threads)
    else:
        caps['cpuCores'] = str(cpu_topology.cores)

    caps['cpuThreads'] = str(cpu_topology.threads)
    caps['cpuSockets'] = str(cpu_topology.sockets)
    caps['onlineCpus'] = ','.join(cpu_topology.online_cpus)
    caps['cpuSpeed'] = cpuinfo.frequency()
    caps['cpuModel'] = cpuinfo.model()
    caps['cpuFlags'] = ','.join(cpuinfo.flags() +
                                machinetype.compatible_cpu_models())

    caps.update(_getVersionInfo())

    net_caps = supervdsm.getProxy().network_caps()
    caps.update(net_caps)

    try:
        caps['hooks'] = hooks.installed()
    except:
        logging.debug('not reporting hooks', exc_info=True)

    caps['operatingSystem'] = osinfo.version()
    caps['uuid'] = host.uuid()
    caps['packages2'] = osinfo.package_versions()
    caps['realtimeKernel'] = osinfo.runtime_kernel_flags().realtime
    caps['kernelArgs'] = osinfo.kernel_args()
    caps['nestedVirtualization'] = osinfo.nested_virtualization().enabled
    caps['emulatedMachines'] = machinetype.emulated_machines(
        cpuarch.effective())
    caps['ISCSIInitiatorName'] = _getIscsiIniName()
    caps['HBAInventory'] = hba.HBAInventory()
    caps['vmTypes'] = ['kvm']

    caps['memSize'] = str(utils.readMemInfo()['MemTotal'] // 1024)
    caps['reservedMem'] = str(config.getint('vars', 'host_mem_reserve') +
                              config.getint('vars', 'extra_mem_reserve'))
    caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')

    caps['rngSources'] = rngsources.list_available()

    caps['numaNodes'] = dict(numa.topology())
    caps['numaNodeDistance'] = dict(numa.distances())
    caps['autoNumaBalancing'] = numa.autonuma_status()

    caps['selinux'] = osinfo.selinux_status()

    caps['liveSnapshot'] = 'true'
    caps['liveMerge'] = 'true'
    caps['kdumpStatus'] = osinfo.kdump_status()

    caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
    # TODO This needs to be removed after adding engine side support
    # and adding gdeploy support to enable libgfapi on RHHI by default
    caps['additionalFeatures'] = ['libgfapi_supported']
    if osinfo.glusterEnabled:
        from vdsm.gluster.api import glusterAdditionalFeatures
        caps['additionalFeatures'].extend(glusterAdditionalFeatures())
    caps['hostedEngineDeployed'] = _isHostedEngineDeployed()
    caps['hugepages'] = hugepages.supported()
    caps['kernelFeatures'] = osinfo.kernel_features()
    caps['vncEncrypted'] = _isVncEncrypted()
    caps['backupEnabled'] = False

    try:
        caps["connector_info"] = managedvolume.connector_info()
    except se.ManagedVolumeNotSupported as e:
        logging.info("managedvolume not supported: %s", e)
    except se.ManagedVolumeHelperFailed as e:
        logging.exception("Error getting managedvolume connector info: %s", e)

    return caps