Beispiel #1
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)
Beispiel #2
0
    def start(self, config, timeout=5):
        if config is None:
            raise Exception("No context provided to start the vm")
        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
                            down_script = x.get('down_script')
                            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

                        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,)
        #cmdline = cmdline + ' -localtime' 
        #cmdline = cmdline + ' clock=host'           
        # 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 += " &"
        cmdline = self.replaceCmdline(cmdline)
        print "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")