forked from uncloud/uncloud
		
	
		
			
				
	
	
		
			81 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import uuid
 | 
						|
import os
 | 
						|
 | 
						|
from uncloud.host.virtualmachine import create_vxlan_br_tap
 | 
						|
from uncloud.oneshot import logger
 | 
						|
 | 
						|
class VM(object):
 | 
						|
    def __init__(self, vmm, config):
 | 
						|
        self.config = config
 | 
						|
        self.vmm = vmm
 | 
						|
 | 
						|
        # Extract VM specs/metadata from configuration.
 | 
						|
        self.name         = config.get('name', 'no-name')
 | 
						|
        self.memory       = config.get('memory', 1024)
 | 
						|
        self.cores        = config.get('cores', 1)
 | 
						|
        self.threads      = config.get('threads', 1)
 | 
						|
        self.image_format = config.get('image_format', 'qcow2')
 | 
						|
        self.image        = config.get('image')
 | 
						|
        self.uuid         = config.get('uuid', str(uuid.uuid4()))
 | 
						|
        self.mac          = config.get('mac')
 | 
						|
        self.accel        = config.get('accel', 'kvm')
 | 
						|
 | 
						|
        self.net_id             = config.get('net_id', 0)
 | 
						|
        self.upstream_interface = config.get('upstream_interface', 'eth0')
 | 
						|
        self.tap_interface      = config.get('tap_interface', 'uc0')
 | 
						|
        self.network            = config.get('network')
 | 
						|
 | 
						|
    def get_qemu_args(self):
 | 
						|
        command = (
 | 
						|
            "-uuid {uuid} -name {name} -machine pc,accel={accel}"
 | 
						|
            " -drive file={image},format={image_format},if=virtio"
 | 
						|
            " -device virtio-rng-pci"
 | 
						|
            " -m {memory} -smp cores={cores},threads={threads}"
 | 
						|
            " -netdev tap,id=vmnet{net_id},ifname={tap},script=no,downscript=no"
 | 
						|
            " -device virtio-net-pci,netdev=vmnet{net_id},mac={mac}"
 | 
						|
        ).format(
 | 
						|
            uuid=self.uuid, name=self.name, accel=self.accel,
 | 
						|
            image=self.image, image_format=self.image_format,
 | 
						|
            memory=self.memory, cores=self.cores, threads=self.threads,
 | 
						|
            net_id=self.net_id, tap=self.tap_interface, mac=self.mac
 | 
						|
        )
 | 
						|
 | 
						|
        return command.split(" ")
 | 
						|
 | 
						|
    def start(self):
 | 
						|
        # Check that VM image is available.
 | 
						|
        if not os.path.isfile(self.image):
 | 
						|
            logger.error("Image {} does not exist. Aborting.".format(self.image))
 | 
						|
 | 
						|
        # Create Bridge, VXLAN and tap interface for VM.
 | 
						|
        create_vxlan_br_tap(
 | 
						|
                self.net_id, self.upstream_interface, self.tap_interface, self.network
 | 
						|
                )
 | 
						|
 | 
						|
        # Generate config for and run QEMU.
 | 
						|
        qemu_args = self.get_qemu_args()
 | 
						|
        logger.debug("QEMU args for VM {}: {}".format(self.uuid, qemu_args))
 | 
						|
        self.vmm.start(
 | 
						|
                uuid=self.uuid,
 | 
						|
                migration=False,
 | 
						|
                *qemu_args
 | 
						|
                )
 | 
						|
 | 
						|
    def stop(self):
 | 
						|
        self.vmm.stop(self.uuid)
 | 
						|
 | 
						|
    def get_status(self):
 | 
						|
        return self.vmm.get_status(self.uuid)
 | 
						|
 | 
						|
    def get_vnc_addr(self):
 | 
						|
        return self.vmm.get_vnc(self.uuid)
 | 
						|
 | 
						|
    def get_uuid(self):
 | 
						|
        return self.uuid
 | 
						|
 | 
						|
    def get_name(self):
 | 
						|
        success, json = self.vmm.execute_command(self.uuid, 'query-name')
 | 
						|
        if success:
 | 
						|
            return json['return']['name']
 | 
						|
 | 
						|
        return None
 |