Example #1
0
def _deploy_vm(vm_parameters, logger=None):
    from opennode.cli import actions
    storage_pool = actions.storage.get_default_pool()
    if storage_pool is None:
        raise Exception("Storage pool not defined")

    assert type(
        vm_parameters) is dict, 'Parameters must be a dict: %s' % vm_parameters
    vm_type = vm_parameters['vm_type']
    template = vm_parameters['template_name']
    # convert diskspace from MBs to GBs
    if 'disk' in vm_parameters:
        assert float(vm_parameters['disk']) > 1 and float(vm_parameters['disk']) < 600,\
                'Provided disk size is strange - MB vs GB issue?'

    if not template:
        if logger:
            logger("Cannot deploy because template is '%s'" % (template))
        raise Exception("Cannot deploy because template is '%s'" % (template))

    if vm_type == 'openvz':
        uuid = vm_parameters['uuid']
        try:
            conn = libvirt.open('openvz:///system')
            deployed_uuid_list = [ivm['uuid'] for ivm in _list_vms(conn)]

            if uuid in deployed_uuid_list:
                msg = (
                    'Deployment failed: a VM with UUID %s is already deployed '
                    '(%s)' % (uuid, deployed_uuid_list))
                logging.error(msg)
                return
            logging.info('Deploying %s: %s', uuid, deployed_uuid_list)
        finally:
            conn.close()

    ovf_file = OvfFile(
        os.path.join(get_pool_path(storage_pool), vm_type, "unpacked",
                     template + ".ovf"))
    vm = actions.vm.get_module(vm_type)
    settings = vm.get_ovf_template_settings(ovf_file)

    settings.update(vm_parameters)

    for disk in settings.get("disks", []):
        if disk["deploy_type"] == "file":
            volume_name = disk.get("source_file") or "disk"
            disk["source_file"] = '%s--%s.%s' % (
                volume_name, settings["uuid"],
                disk.get('template_format', 'qcow2'))

    if not get_config().getboolean('general', 'disable_vm_sys_adjustment',
                                   False):
        errors = vm.adjust_setting_to_systems_resources(settings)
        if errors:
            if logger:
                logger("Got %s" % (errors, ))
            raise Exception("got errors %s" % (errors, ))

    vm.deploy(settings, storage_pool)
Example #2
0
def get_active_template_settings(vm_name, storage_pool):
    """ Reads ovf settings of the specified VM """
    ovf_fnm = path.join(get_pool_path(storage_pool), "openvz", "unpacked",
                        get_template_name(vm_name) + ".ovf")
    if path.exists(ovf_fnm):
        ovf_file = OvfFile(ovf_fnm)
        return get_ovf_template_settings(ovf_file)
    else:
        return read_default_ovf_settings()
Example #3
0
def get_template_info(template_name, vm_type, storage_pool=None):
    config = get_config()
    if not storage_pool:
        storage_pool = config.getstring('general', 'default-storage-pool')
    ovf_file = OvfFile(os.path.join(storage.get_pool_path(storage_pool),
                                    vm_type, "unpacked",
                                    template_name + ".ovf"))
    vm = vm_ops.get_module(vm_type)
    template_settings = vm.get_ovf_template_settings(ovf_file)
    # XXX handle modification to system params
    #errors = vm.adjust_setting_to_systems_resources(template_settings)
    return template_settings
Example #4
0
def _generate_ovf_file(vm_settings):
    """
    Prepare OVF XML configuration file from Libvirt's KVM xml_dump.

    @return: KVM VM configuration in OVF standard
    @rtype: DOM Document
    """
    ovf = OvfFile()
    # Workaround for broken OvfFile.__init__
    ovf.files = []
    ovf.createEnvelope()
    ovf.envelope.setAttribute("xmlns:opennodens", "http://opennodecloud.com/schema/ovf/opennodens/1")

    instanceId = 0
    virtualSystem = ovf.createVirtualSystem(ident=vm_settings["template_name"],
                                            info="KVM OpenNode template")
    hardwareSection = ovf.createVirtualHardwareSection(node=virtualSystem,
                                ident="virtual_hardware",
                                info="Virtual hardware requirements for a virtual machine")

    # add virtual system
    ovf.createSystem(hardwareSection, "Virtual Hardware Family", str(instanceId),
                     {"VirtualSystemType": "%s-%s" % (vm_settings["domain_type"], vm_settings["arch"])})
    instanceId += 1

    # add cpu section
    for bound, cpu in zip(["normal", "min", "max"],
                          [vm_settings.get("vcpu%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if cpu:
            ovf.addResourceItem(hardwareSection, {
                "Caption": "%s virtual CPU" % cpu,
                "Description": "Number of virtual CPUs",
                "ElementName": "%s virtual CPU" % cpu,
                "InstanceID": str(instanceId),
                "ResourceType": "3",
                "VirtualQuantity": cpu
                }, bound=bound)
            instanceId += 1

    # add memory section
    for bound, memory in zip(["normal", "min", "max"],
                             [vm_settings.get("memory%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if memory:
            ovf.addResourceItem(hardwareSection, {
                "AllocationUnits": "GigaBytes",
                "Caption": "%s GB of memory" % memory,
                "Description": "Memory Size",
                "ElementName": "%s GB of memory" % memory,
                "InstanceID": str(instanceId),
                "ResourceType": "4",
                "VirtualQuantity": memory
                }, bound=bound)
            instanceId += 1

    # add network interfaces
    network_list = []
    for interface in vm_settings["interfaces"]:
        if interface["type"] == "bridge":
            ovf.addResourceItem(hardwareSection, {
                "Address": interface["mac_address"],
                "AutomaticAllocation": "true",
                "Caption": "Ethernet adapter on '%s'" % interface["source_bridge"],
                "Connection": interface["source_bridge"],
                "Description": "Network interface",
                "ElementName": "Ethernet adapter on '%s'" % interface["source_bridge"],
                "InstanceID": "%d" % instanceId,
                "ResourceSubType": "E1000",
                "ResourceType": "10",
            })
            network_list.append({
                "networkID": interface["source_bridge"],
                "networkName": interface["source_bridge"],
                "description": "Network for OVF appliance"
            })
            instanceId += 1
    ovf.createNetworkSection(network_list, "Network for OVF appliance")

    # add references of KVM VM disks (see http://gitorious.org/open-ovf/mainline/blobs/master/py/ovf/OvfReferencedFile.py)
    ovf_disk_list = []
    for disk in vm_settings["disks"]:
        ref_file = OvfReferencedFile(path=disk["new_path"], href=disk["filename"],
                                     file_id=disk["file_id"], size=disk["file_size"])
        ovf.addReferencedFile(ref_file)
        ovf_disk_list.append({
            "diskId": disk["disk_id"],
            "fileRef": disk["file_id"],
            "capacity": str(disk["disk_capacity"]),
            "format": "qcow2",
            "parentRef": None,
            "populatedSize": None,
            "capacityAllocUnits": None
        })
    ovf.createReferences()
    ovf.createDiskSection(ovf_disk_list, "KVM VM template disks")

    # Add OpenNode section to Virtual System node
    doc = xml.dom.minidom.Document()
    on_section = doc.createElement("opennodens:OpenNodeSection")
    on_section.setAttribute("ovf:required", "false")
    virtualSystem.appendChild(on_section)

    info_dom = doc.createElement("Info")
    on_section.appendChild(info_dom)
    info_value = doc.createTextNode("OpenNode Section for template customization")
    info_dom.appendChild(info_value)

    features_dom = doc.createElement("Features")
    on_section.appendChild(features_dom)

    admin_password = doc.createElement('AdminPassword')
    on_section.appendChild(admin_password)
    password_value = doc.createTextNode(vm_settings['passwd'])
    admin_password.appendChild(password_value)

    for feature in vm_settings["features"]:
        feature_dom = doc.createElement(feature)
        features_dom.appendChild(feature_dom)

    return ovf
Example #5
0
def _generate_ovf_file(vm_settings, ct_archive_fnm):
    ovf = OvfFile()
    # Workaround for broken OvfFile.__init__
    ovf.files = []
    ovf.createEnvelope()
    instanceId = 0
    virtualSystem = ovf.createVirtualSystem(ident=vm_settings["template_name"],
                                            info="OpenVZ OpenNode template")
    # add OS section
    ovf.createOperatingSystem(node=virtualSystem,
                              ident='operating_system',
                              info='Operating system type deployed in a template',
                              description=vm_settings.get('ostemplate', 'linux'))

    hardwareSection = ovf.createVirtualHardwareSection(node=virtualSystem,
                                ident="virtual_hardware",
                                info="Virtual hardware requirements for a virtual machine")
    ovf.createSystem(hardwareSection, "Virtual Hardware Family", str(instanceId),
                     {"VirtualSystemType": "openvz"})
    instanceId += 1

    # add cpu section
    for bound, cpu in zip(["normal", "min", "max"],
                          [vm_settings.get("vcpu%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if cpu:
            ovf.addResourceItem(hardwareSection, {
                "Caption": "%s virtual CPU" % cpu,
                "Description": "Number of virtual CPUs",
                "ElementName": "%s virtual CPU" % cpu,
                "InstanceID": str(instanceId),
                "ResourceType": "3",
                "VirtualQuantity": cpu
                }, bound=bound)
            instanceId += 1

    # add memory section
    for bound, memory in zip(["normal", "min", "max"],
                             [vm_settings.get("memory%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if memory:
            ovf.addResourceItem(hardwareSection, {
                "AllocationUnits": "GigaBytes",
                "Caption": "%s GB of memory" % memory,
                "Description": "Memory Size",
                "ElementName": "%s GB of memory" % memory,
                "InstanceID": str(instanceId),
                "ResourceType": "4",
                "VirtualQuantity": memory
                }, bound=bound)
            instanceId += 1

    def get_checksum(fnm):
        # calculate checksum for the file
        chunk_size = 1024 ** 2  # 1Mb
        sha = sha1()
        with open(fnm) as chkfile:
            while 1:
                data = chkfile.read(chunk_size)
                if not data:
                    break
                sha.update(data)
        return sha.hexdigest()

    # add reference a file (see http://gitorious.org/open-ovf/mainline/blobs/master/py/ovf/OvfReferencedFile.py)
    ref_file = OvfReferencedFile(path.dirname(ct_archive_fnm),
                                 path.basename("%s.tar.gz" % vm_settings["template_name"]),
                                 file_id="diskfile1",
                                 size=str(get_file_size_bytes(ct_archive_fnm)),
                                 compression="gz",
                                 checksum=get_checksum(ct_archive_fnm))
    ovf.addReferencedFile(ref_file)
    ovf.createReferences()

    def get_ct_disk_usage_bytes(ctid):
        return str(int(execute("du -s /vz/private/%s/" % ctid).split()[0]) * 1024)
    # add disk section
    ovf.createDiskSection([{
        "diskId": "vmdisk1",
        "capacity": str(round(float(vm_settings["disk"]) * 1024 ** 3)),  # in bytes
        "capacityAllocUnits": None,  # bytes default
        "populatedSize": get_ct_disk_usage_bytes(vm_settings["vm_name"]),
        "fileRef": "diskfile1",
        "parentRef": None,
        "format": "tar.gz"}],
        "OpenVZ CT template disks")
    return ovf
Example #6
0
def _generate_ovf_file(vm_settings):
    """
    Prepare OVF XML configuration file from Libvirt's KVM xml_dump.

    @return: KVM VM configuration in OVF standard
    @rtype: DOM Document
    """
    ovf = OvfFile()
    # Workaround for broken OvfFile.__init__
    ovf.files = []
    ovf.createEnvelope()
    ovf.envelope.setAttribute(
        "xmlns:opennodens", "http://opennodecloud.com/schema/ovf/opennodens/1")

    instanceId = 0
    virtualSystem = ovf.createVirtualSystem(ident=vm_settings["template_name"],
                                            info="KVM OpenNode template")
    hardwareSection = ovf.createVirtualHardwareSection(
        node=virtualSystem,
        ident="virtual_hardware",
        info="Virtual hardware requirements for a virtual machine")

    # add virtual system
    ovf.createSystem(
        hardwareSection, "Virtual Hardware Family", str(instanceId), {
            "VirtualSystemType":
            "%s-%s" % (vm_settings["domain_type"], vm_settings["arch"])
        })
    instanceId += 1

    # add cpu section
    for bound, cpu in zip(
        ["normal", "min", "max"],
        [vm_settings.get("vcpu%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if cpu:
            ovf.addResourceItem(hardwareSection, {
                "Caption": "%s virtual CPU" % cpu,
                "Description": "Number of virtual CPUs",
                "ElementName": "%s virtual CPU" % cpu,
                "InstanceID": str(instanceId),
                "ResourceType": "3",
                "VirtualQuantity": cpu
            },
                                bound=bound)
            instanceId += 1

    # add memory section
    for bound, memory in zip(
        ["normal", "min", "max"],
        [vm_settings.get("memory%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if memory:
            ovf.addResourceItem(hardwareSection, {
                "AllocationUnits": "GigaBytes",
                "Caption": "%s GB of memory" % memory,
                "Description": "Memory Size",
                "ElementName": "%s GB of memory" % memory,
                "InstanceID": str(instanceId),
                "ResourceType": "4",
                "VirtualQuantity": memory
            },
                                bound=bound)
            instanceId += 1

    # add network interfaces
    network_list = []
    for interface in vm_settings["interfaces"]:
        if interface["type"] == "bridge":
            ovf.addResourceItem(
                hardwareSection, {
                    "Address":
                    interface["mac_address"],
                    "AutomaticAllocation":
                    "true",
                    "Caption":
                    "Ethernet adapter on '%s'" % interface["source_bridge"],
                    "Connection":
                    interface["source_bridge"],
                    "Description":
                    "Network interface",
                    "ElementName":
                    "Ethernet adapter on '%s'" % interface["source_bridge"],
                    "InstanceID":
                    "%d" % instanceId,
                    "ResourceSubType":
                    "E1000",
                    "ResourceType":
                    "10",
                })
            network_list.append({
                "networkID": interface["source_bridge"],
                "networkName": interface["source_bridge"],
                "description": "Network for OVF appliance"
            })
            instanceId += 1
    ovf.createNetworkSection(network_list, "Network for OVF appliance")

    # add references of KVM VM disks (see http://gitorious.org/open-ovf/mainline/blobs/master/py/ovf/OvfReferencedFile.py)
    ovf_disk_list = []
    for disk in vm_settings["disks"]:
        ref_file = OvfReferencedFile(path=disk["new_path"],
                                     href=disk["filename"],
                                     file_id=disk["file_id"],
                                     size=disk["file_size"])
        ovf.addReferencedFile(ref_file)
        ovf_disk_list.append({
            "diskId": disk["disk_id"],
            "fileRef": disk["file_id"],
            "capacity": str(disk["disk_capacity"]),
            "format": "qcow2",
            "parentRef": None,
            "populatedSize": None,
            "capacityAllocUnits": None
        })
    ovf.createReferences()
    ovf.createDiskSection(ovf_disk_list, "KVM VM template disks")

    # Add OpenNode section to Virtual System node
    doc = xml.dom.minidom.Document()
    on_section = doc.createElement("opennodens:OpenNodeSection")
    on_section.setAttribute("ovf:required", "false")
    virtualSystem.appendChild(on_section)

    info_dom = doc.createElement("Info")
    on_section.appendChild(info_dom)
    info_value = doc.createTextNode(
        "OpenNode Section for template customization")
    info_dom.appendChild(info_value)

    features_dom = doc.createElement("Features")
    on_section.appendChild(features_dom)

    admin_password = doc.createElement('AdminPassword')
    on_section.appendChild(admin_password)
    password_value = doc.createTextNode(vm_settings['passwd'])
    admin_password.appendChild(password_value)

    for feature in vm_settings["features"]:
        feature_dom = doc.createElement(feature)
        features_dom.appendChild(feature_dom)

    return ovf
Example #7
0
def _generate_ovf_file(vm_settings, ct_archive_fnm):
    ovf = OvfFile()
    # Workaround for broken OvfFile.__init__
    ovf.files = []
    ovf.createEnvelope()
    instanceId = 0
    virtualSystem = ovf.createVirtualSystem(ident=vm_settings["template_name"],
                                            info="OpenVZ OpenNode template")
    # add OS section
    ovf.createOperatingSystem(
        node=virtualSystem,
        ident='operating_system',
        info='Operating system type deployed in a template',
        description=vm_settings.get('ostemplate', 'linux'))

    hardwareSection = ovf.createVirtualHardwareSection(
        node=virtualSystem,
        ident="virtual_hardware",
        info="Virtual hardware requirements for a virtual machine")
    ovf.createSystem(hardwareSection, "Virtual Hardware Family",
                     str(instanceId), {"VirtualSystemType": "openvz"})
    instanceId += 1

    # add cpu section
    for bound, cpu in zip(
        ["normal", "min", "max"],
        [vm_settings.get("vcpu%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if cpu:
            ovf.addResourceItem(hardwareSection, {
                "Caption": "%s virtual CPU" % cpu,
                "Description": "Number of virtual CPUs",
                "ElementName": "%s virtual CPU" % cpu,
                "InstanceID": str(instanceId),
                "ResourceType": "3",
                "VirtualQuantity": cpu
            },
                                bound=bound)
            instanceId += 1

    # add memory section
    for bound, memory in zip(
        ["normal", "min", "max"],
        [vm_settings.get("memory%s" % pfx) for pfx in ["", "_min", "_max"]]):
        if memory:
            ovf.addResourceItem(hardwareSection, {
                "AllocationUnits": "GigaBytes",
                "Caption": "%s GB of memory" % memory,
                "Description": "Memory Size",
                "ElementName": "%s GB of memory" % memory,
                "InstanceID": str(instanceId),
                "ResourceType": "4",
                "VirtualQuantity": memory
            },
                                bound=bound)
            instanceId += 1

    def get_checksum(fnm):
        # calculate checksum for the file
        chunk_size = 1024**2  # 1Mb
        sha = sha1()
        with open(fnm) as chkfile:
            while 1:
                data = chkfile.read(chunk_size)
                if not data:
                    break
                sha.update(data)
        return sha.hexdigest()

    # add reference a file (see http://gitorious.org/open-ovf/mainline/blobs/master/py/ovf/OvfReferencedFile.py)
    ref_file = OvfReferencedFile(path.dirname(ct_archive_fnm),
                                 path.basename("%s.tar.gz" %
                                               vm_settings["template_name"]),
                                 file_id="diskfile1",
                                 size=str(get_file_size_bytes(ct_archive_fnm)),
                                 compression="gz",
                                 checksum=get_checksum(ct_archive_fnm))
    ovf.addReferencedFile(ref_file)
    ovf.createReferences()

    def get_ct_disk_usage_bytes(ctid):
        return str(
            int(execute("du -s /vz/private/%s/" % ctid).split()[0]) * 1024)

    # add disk section
    ovf.createDiskSection(
        [{
            "diskId": "vmdisk1",
            "capacity": str(round(
                float(vm_settings["disk"]) * 1024**3)),  # in bytes
            "capacityAllocUnits": None,  # bytes default
            "populatedSize": get_ct_disk_usage_bytes(vm_settings["vm_name"]),
            "fileRef": "diskfile1",
            "parentRef": None,
            "format": "tar.gz"
        }],
        "OpenVZ CT template disks")
    return ovf