예제 #1
0
    def get_new_nw(self,auth,image_id,mode,node_id, op_level=None):
#        if image_id is not None:
#            image=ImageService().get_image(auth,image_id)
#            (vm_config,image_config)=image.get_configs()
        result=[]
        if mode in ["edit_image_settings","provision_vm","provision_image"]:
            (vif_entry, nw_entry) = self.get_new_nw_entry()
        else:
            managed_node=NodeService().get_managed_node(auth,node_id)
            # generate mac address and get the DEFAULT_BRIDGE if any
            mac=randomMAC()
            if managed_node is not None:
                bridge = managed_node.get_default_bridge()

            if not bridge:
                bridge="xenbr0"
            if managed_node.platform == 'kvm':
                bridge='br0'

            vif_entry=vifEntry('mac=%s,bridge=%s' % (mac,bridge))
            nw_entry = None

#       for vif in vif_entry:
        result.append(self.get_nw_entry(vif_entry, op_level))
        
        return result
예제 #2
0
    def instantiate_configs(self,
                            managed_node,
                            image_store, 
                            image_name, 
                            image_location,
                            vm_config, image_config):
     
        # get prepare template map
        template_map = {} 

        store_location = image_store.get_remote_location(managed_node)
     
        template_map["IMAGE_STORE"]    = store_location
        template_map["IMAGE_NAME"]     = image_name
        template_map["IMAGE_LOCATION"] = image_location
        template_map["VM_NAME"]        = vm_config["name"]

        # Auto generated MAC address
        # TODO: keep track of generated MAC's
        template_map["AUTOGEN_MAC"] = randomMAC()

        # image_config.instantiate_config(template_map)

        # instantiate vm_config with image configuration
        vm_config.instantiate_config(template_map)
        if image_config is not None:
            vm_config.instantiate_config(image_config)
예제 #3
0
    def get_vif_entry(self,auth,mode,node_id):
        if mode in ["EDIT_IMAGE","PROVISION_VM"]:
            (vif_entry, nw_entry) = self.get_new_nw_entry(None)
        else:
            # generate mac address and get the DEFAULT_BRIDGE if any
            managed_node=NodeService().get_managed_node(auth,node_id)
            mac=randomMAC()
            if managed_node is not None:
                bridge = managed_node.get_default_bridge()

            if not bridge:
                bridge="xenbr0"
            if managed_node.platform == 'kvm':
                bridge='br0'
                
            vif_entry=vifEntry('mac=%s,bridge=%s' % (mac,bridge))
        return vif_entry
예제 #4
0
    def start(self,config,timeout=5):
        if config is None:
            raise Exception("No context provided to start the vm")

        #config.dump()
        # check the version and prompt the user
        info = self.info()
        if info.get(key_version):
            v = info.get(key_version)
            if v.find('kvm-') < 0:
                raise Exception("You seem to have an older version of KVM/QEMU\n The version does not contain 'kvm-' token :%s\n Please make sure kvm-70 or higher is installed and is in PATH." % v)


        # take the config.. and generate a cmdline for kvm/qemu
        cmd = self.kvm_binary
        known_options = self.kvm_options
        if config.get("type") and config.get("type") == "qemu":
            print "Using simple qemu"
            cmd = self.qemu_binary
            known_options = self.qemu_options

        # build the cmd line
        cmdline = cmd
        vnc_processed = False
        skip_kernel_rd = False

        # add disks first
        opt = "disk"
        value = config.get(opt)
        disk_entries = config.getDisks()
        boot_flag=False
        for d in disk_entries:
            flag = 0
            if d.device.find(":cdrom") > -1 or \
                    d.filename == ("/dev/cdrom"):
                opt = "cdrom"
                hd=d.device.replace(":cdrom","")
                value1 = config.get(hd+"_use_drive_opt")
                if value1 and value1==1:
                    flag = 1
                    opt=hd
            else:
                opt = d.device
                use_drive = opt+"_use_drive_opt"
                value1 = config.get(use_drive)
                if value1 and value1==1:
                    flag = 1

            value = d.filename                 

            """
            here, if opt is either of vdx, then call one more function
            which adds the -drive option and other values

            """
            if opt.startswith("vd") or flag == 1:
                drive_boot=to_str(config.get(opt+"_drive_boot"))
                if drive_boot=="on":
                    cmdline = cmdline.replace(",boot=on","",1)
                cmdline = self.qemuCall(cmdline, opt, value, config)
                if boot_flag==False:
                    auto_boot=to_str(config.get("virtio_no_auto_boot"))
                    if auto_boot!="1":
                        cmdline+=",boot=on"
                    boot_flag=True
            # mode, and type are not used.
            # filename can be file or device so it would work.
            # mode : Dont know how to specify readonly disk
            else:
                cmdline = self.process_option(cmdline, opt, value,
                                          known_options)

        for opt in config.keys():
            value = config.get(opt)
            opt = opt.replace("_", "-") # python prohibits - in variables
            if opt == "extra":
                opt = "append"

            if opt == "memory" :
                opt = "m"
            elif opt == "vcpus":
                opt = "smp"
            elif opt == "stdvga":
                opt = "std-vga"
                if to_str(value) != '1':
                    continue
            elif opt == "ramdisk":
                opt = "initrd"
            elif opt == "acpi":
                if to_str(value) == '0':
                    cmdline = self.process_option(cmdline, "no-acpi", "",
                                                   known_options)
                continue

            elif opt == "vif" and not config.get("net"):
                #Transform vif in to -net options
                vifs = value
                if vifs:
                    vlan=-1
                    for vif in vifs:
                        vlan = vlan + 1
                        parts = vif.split(',')
                        x = dict([p.strip().split('=') for p in parts])
                        macaddr = x.get("mac")
                        if not macaddr:
                            macaddr=randomMAC()
                        opt_val = "nic,vlan=%d,macaddr=%s" % ( vlan, macaddr)
                        
                        # model
                        model = x.get("model")
                        if model:
                            opt_val = opt_val + ",model=" + model
                            
                        cmdline = self.process_option(cmdline, "net",
                                                      opt_val, known_options)
                        # if bridge is specified, lets try to specify the script
                        # Assumes bridge is created and script would
                        # add the tap interface to the bridge
                        
                        # TODO : if the bridge can be somehow specified as
                        # param to the script in /etc/qemu-ifup and
                        # /etc/qemu-ifdown
                        
                        bridge=x.get("bridge")

                        mode = config.get("network_mode")
                        if not mode:
                            if bridge:
                                mode = "tap"
                            else:
                                mode = "user"

                        opt_val = "%s,vlan=%d" % (mode, vlan)

                        if mode == "tap":
                            # interface name
                            ifname = x.get("ifname")
                            if ifname:
                                opt_val = opt_val + ",ifname=" + ifname
                            # script
                            script = x.get("script")
                            if script:
                                opt_val = opt_val + ",script=" + script
                            #downscript
                            down_script = x.get("downscript")
                            if down_script:
                                opt_val = opt_val + ",downscript=" + down_script
                            else:
                                # see if the bridge specific script is there.
                                if bridge:
                                    s1 = "/etc/kvm/kvm-ifup-%s" % (bridge,)
                                    s2 = "/etc/kvm/qemu-ifup-%s" % (bridge,)
                                    s3 = "/etc/qemu-ifup-%s" % (bridge,)
                                    s4 = "/etc/qemu/qemu-ifup-%s" % (bridge,)
                                    for s in [ s1, s2, s3, s4 ]:
                                        if self.node_proxy.file_exists(s):
                                            # assume it is executable.
                                            opt_val = opt_val + ",script=" + s
                                            break
                            # vhost
                            vhost = x.get("vhost")
                            if vhost:
                                opt_val = opt_val + ",vhost=" + vhost

                        elif mode == "user":
                            # hostname
                            hname = x.get("hostname")
                            if hname:
                                opt_val = opt_val + ",hostname=" + hname

                        cmdline = self.process_option(cmdline, "net",
                                                       opt_val, known_options)
                        
                        
                        # TODO : Support custom script
                continue
            elif opt in ["vnc","vncdisplay"] and not vnc_processed:
                vnc_processed = True
                value = config.get("vnc")
                if value == 1 or value == "1":
                    vncdisplay = config.get("vncdisplay")
                    if not vncdisplay:
                        vncdisplay = self.node.get_unused_display()
                    if vncdisplay:
                        value = ":" + to_str(vncdisplay)
                        cmdline = self.process_option(cmdline, opt, value,
                                                      known_options)
                continue
            elif opt in ["kernel", "initrd", "append"] :
                if not skip_kernel_rd :
                    # hack
                    k_value = config.get("kernel")
                    if k_value:
                        if k_value.find("hvmloader") > -1: #skip xen hvmloader 
                            skip_kernel_rd = True
                            continue
                else:
                    # ignore the initrd and append/extra too.
                    continue

            if opt in self.kvm_options_no_v:
                if value == 0 or value == "0" :
                    continue
                value = ""
            else:
                if not value:
                    continue

            cmdline = self.process_option(cmdline, opt, value, known_options)
                        
        # The following is done to have the convention and
        # temporarily have the name of VM available in the command line.
        if not self.node_proxy.file_exists(self.monitor_dir):
            mkdir2(self.node, self.monitor_dir)
        monitor_path = os.path.join(self.monitor_dir, config.get("name"))
        cmdline = cmdline + " -monitor " + """"unix:%s,server,nowait\"""" % (monitor_path,)
                 
        pid_fname = os.path.join(self.pid_dir, config.get("name"))
        cmdline = cmdline + " -pidfile  " + """"%s\"""" % (pid_fname,)
                    
        # daemonize.. the command can return
        cmdline = cmdline + " -daemonize"

        #incoming_val = config.get("incoming")
        #if incoming_val and (incoming_val.find("tcp://") == 0 or \
        #                     incoming_val.find("ssh://") == 0 ):
        #    cmdline += " &"

        print "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n**************************** CMDLINE ****************************** ", cmdline
        
        (output, ret) = self.node_proxy.exec_cmd(cmdline, self.kvm_binary_path,
                                                 timeout)
        if ret != 0:
            print "start failed :", cmdline,output
            raise Exception((output, ret))
        print "start : success ", output
        self.get_vms()
        if config.get("vncpasswd"):
            self.set_vnc_password(config.get("name"),config.get("vncpasswd"))

        return config.get("name")
예제 #5
0
    def start(self, config, timeout=5, extra_para=None):
        if config is None:
            raise Exception("No context provided to start the vm")

        #config.dump()
        # check the version and prompt the user
        info = self.info()
        if info.get(key_version):
            v = info.get(key_version)
            if v.find('kvm-') < 0:
                raise Exception(
                    "You seem to have an older version of KVM/QEMU\n The version does not contain 'kvm-' token :%s\n Please make sure kvm-70 or higher is installed and is in PATH."
                    % v)

        # take the config.. and generate a cmdline for kvm/qemu
        cmd = self.kvm_binary
        known_options = self.kvm_options
        if config.get("type") and config.get("type") == "qemu":
            print "Using simple qemu"
            cmd = self.qemu_binary
            known_options = self.qemu_options

        # build the cmd line
        cmdline = cmd
        vnc_processed = False
        skip_kernel_rd = False

        if extra_para:
            for key in extra_para:
                if key == "loadvm":
                    cmdline = self.process_option(cmdline, "loadvm",
                                                  extra_para[key],
                                                  known_options)

        # add disks first
        opt = "disk"
        value = config.get(opt)
        disk_entries = config.getDisks()
        boot_flag = False
        for d in disk_entries:
            flag = 0
            if d.device.find(":cdrom") > -1 or \
                    d.filename == ("/dev/cdrom"):
                opt = "cdrom"
                hd = d.device.replace(":cdrom", "")
                value1 = config.get(hd + "_use_drive_opt")
                if value1 and value1 == 1:
                    flag = 1
                    opt = hd
            else:
                opt = d.device
                use_drive = opt + "_use_drive_opt"
                value1 = config.get(use_drive)
                if value1 and value1 == 1:
                    flag = 1

            value = d.filename
            """
            here, if opt is either of vdx, then call one more function
            which adds the -drive option and other values

            """
            if opt.startswith("vd") or flag == 1:
                drive_boot = to_str(config.get(opt + "_drive_boot"))
                if drive_boot == "on":
                    cmdline = cmdline.replace(",boot=on", "", 1)
                cmdline = self.qemuCall(cmdline, opt, value, config)
                if boot_flag == False:
                    auto_boot = to_str(config.get("virtio_no_auto_boot"))
                    if auto_boot != "1":
                        cmdline += ",boot=on"
                    boot_flag = True
            # mode, and type are not used.
            # filename can be file or device so it would work.
            # mode : Dont know how to specify readonly disk
            else:
                cmdline = self.process_option(cmdline, opt, value,
                                              known_options)

        for opt in config.keys():
            value = config.get(opt)
            opt = opt.replace("_", "-")  # python prohibits - in variables
            if opt == "extra":
                opt = "append"

            if opt == "memory":
                opt = "m"
            elif opt == "vcpus":
                opt = "smp"
                if (config.get("os_name") == "Windows 7"):
                    socks = 2
                    cores = int((value + socks - 1) / socks)
                    value = str(value) + ",sockets=2,cores=" + str(cores)
            elif opt == "stdvga":
                opt = "std-vga"
                if to_str(value) != '1':
                    continue
            elif opt == "ramdisk":
                opt = "initrd"
            elif opt == "acpi":
                if to_str(value) == '0':
                    cmdline = self.process_option(cmdline, "no-acpi", "",
                                                  known_options)
                continue

            elif opt == "vif" and not config.get("net"):
                #Transform vif in to -net options
                vifs = value
                if vifs:
                    vlan = -1
                    for vif in vifs:
                        vlan = vlan + 1
                        parts = vif.split(',')
                        x = dict([p.strip().split('=') for p in parts])
                        macaddr = x.get("mac")
                        if not macaddr:
                            macaddr = randomMAC()
                        opt_val = "nic,vlan=%d,macaddr=%s" % (vlan, macaddr)

                        # model
                        model = x.get("model")
                        if model:
                            opt_val = opt_val + ",model=" + model

                        cmdline = self.process_option(cmdline, "net", opt_val,
                                                      known_options)
                        # if bridge is specified, lets try to specify the script
                        # Assumes bridge is created and script would
                        # add the tap interface to the bridge

                        # TODO : if the bridge can be somehow specified as
                        # param to the script in /etc/qemu-ifup and
                        # /etc/qemu-ifdown

                        bridge = x.get("bridge")

                        mode = config.get("network_mode")
                        if not mode:
                            if bridge:
                                mode = "tap"
                            else:
                                mode = "user"

                        opt_val = "%s,vlan=%d" % (mode, vlan)

                        if mode == "tap":
                            # interface name
                            ifname = x.get("ifname")
                            if ifname:
                                opt_val = opt_val + ",ifname=" + ifname
                            # script
                            script = x.get("script")
                            if script:
                                opt_val = opt_val + ",script=" + script
                            #downscript
                            down_script = x.get("downscript")
                            if down_script:
                                opt_val = opt_val + ",downscript=" + down_script
                            else:
                                # see if the bridge specific script is there.
                                if bridge:
                                    s1 = "/etc/kvm/kvm-ifup-%s" % (bridge, )
                                    s2 = "/etc/kvm/qemu-ifup-%s" % (bridge, )
                                    s3 = "/etc/qemu-ifup-%s" % (bridge, )
                                    s4 = "/etc/qemu/qemu-ifup-%s" % (bridge, )
                                    for s in [s1, s2, s3, s4]:
                                        if self.node_proxy.file_exists(s):
                                            # assume it is executable.
                                            opt_val = opt_val + ",script=" + s
                                            break
                            # vhost
                            vhost = x.get("vhost")
                            if vhost:
                                opt_val = opt_val + ",vhost=" + vhost

                        elif mode == "user":
                            # hostname
                            hname = x.get("hostname")
                            if hname:
                                opt_val = opt_val + ",hostname=" + hname

                        cmdline = self.process_option(cmdline, "net", opt_val,
                                                      known_options)

                        # TODO : Support custom script
                continue
            elif opt in ["vnc", "vncdisplay"] and not vnc_processed:
                vnc_processed = True
                value = config.get("vnc")
                if value == 1 or value == "1":
                    vncdisplay = config.get("vncdisplay")
                    if not vncdisplay:
                        vncdisplay = self.node.get_unused_display()
                    if vncdisplay:
                        value = ":" + to_str(vncdisplay)
                        cmdline = self.process_option(cmdline, opt, value,
                                                      known_options)
                continue
            elif opt in ["spice"]:
                if not isinstance(value, int):
                    raise Exception("spice port is not correct :" + value)

                #default value is 0, means no spice support for vm
                if value == 0:
                    continue

                spicevmc_id = "vdagent" + to_str(value)
                value = "port=" + to_str(value) + ",disable-ticketing"
                cmdline = self.process_option(cmdline, "vga", "qxl",
                                              known_options)
                cmdline = self.process_option(cmdline, opt, value,
                                              known_options)

                #for drag and drop
                cmdline = self.process_option(cmdline, "device",
                                              "virtio-serial", known_options)

                cmdline = self.process_option(
                    cmdline, "chardev",
                    "spicevmc,id=" + spicevmc_id + ",debug=0,name=vdagent",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device", "virtserialport,chardev=" +
                    spicevmc_id + ",name=com.redhat.spice.0", known_options)

                #for audio support
                cmdline = self.process_option(cmdline, "soundhw", "ac97",
                                              known_options)
                #for usb redir
                cmdline = self.process_option(cmdline, "device",
                                              "ich9-usb-ehci1,id=usb",
                                              known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "ich9-usb-uhci2,masterbus=usb.0,firstport=2",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "ich9-usb-uhci3,masterbus=usb.0,firstport=4",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "chardev",
                    "spicevmc,name=usbredir,id=usbredirchardev1",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "usb-redir,chardev=usbredirchardev1,id=usbredirdev1",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "chardev",
                    "spicevmc,name=usbredir,id=usbredirchardev2",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "usb-redir,chardev=usbredirchardev2,id=usbredirdev2",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "chardev",
                    "spicevmc,name=usbredir,id=usbredirchardev3",
                    known_options)
                cmdline = self.process_option(
                    cmdline, "device",
                    "usb-redir,chardev=usbredirchardev3,id=usbredirdev3",
                    known_options)

                continue
            elif opt in ["kernel", "initrd", "append"]:
                if not skip_kernel_rd:
                    # hack
                    k_value = config.get("kernel")
                    if k_value:
                        if k_value.find("hvmloader") > -1:  #skip xen hvmloader
                            skip_kernel_rd = True
                            continue
                else:
                    # ignore the initrd and append/extra too.
                    continue

            if opt in self.kvm_options_no_v:
                if value == 0 or value == "0":
                    continue
                value = ""
            else:
                if not value:
                    continue

            cmdline = self.process_option(cmdline, opt, value, known_options)

        # The following is done to have the convention and
        # temporarily have the name of VM available in the command line.
        if not self.node_proxy.file_exists(self.monitor_dir):
            mkdir2(self.node, self.monitor_dir)
        monitor_path = os.path.join(self.monitor_dir, config.get("name"))
        cmdline = cmdline + " -monitor " + """"unix:%s,server,nowait\"""" % (
            monitor_path, )

        pid_fname = os.path.join(self.pid_dir, config.get("name"))
        cmdline = cmdline + " -pidfile  " + """"%s\"""" % (pid_fname, )

        # daemonize.. the command can return
        cmdline = cmdline + " -daemonize"

        #incoming_val = config.get("incoming")
        #if incoming_val and (incoming_val.find("tcp://") == 0 or \
        #                     incoming_val.find("ssh://") == 0 ):
        #    cmdline += " &"

        print "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n**************************** CMDLINE ****************************** ", cmdline

        (output, ret) = self.node_proxy.exec_cmd(cmdline, self.kvm_binary_path,
                                                 timeout)
        if ret != 0:
            print "start failed :", cmdline, output
            raise Exception((output, ret))
        print "start : success ", output
        self.get_vms()
        if config.get("vncpasswd"):
            self.set_vnc_password(config.get("name"), config.get("vncpasswd"))

        return config.get("name")