예제 #1
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiApplianceName(ui *gui.DialogUi, defaultName string, driver deployer.EnvDriver) (string, error) {
	var name string
	var err error

	for {
		ui.SetSize(8, len(defaultName)+10)
		ui.SetTitle("Virtual machine name")
		ui.HelpButton(true)
		ui.SetHelpLabel("Back")
		name, err = ui.Inputbox(defaultName)
		if err != nil {
			return "", err
		}
		if name != "" {
			name = strings.Replace(name, ".", "-", -1)
			if driver != nil {
				if driver.DomainExists(name) {
					ui.Output(gui.Warning, "domain "+name+" already exists.", "Press <OK> to return to menu.")
					continue
				}
			}
			break
		}
	}
	return name, nil
}
예제 #2
0
파일: ui.go 프로젝트: weldpua2008/deployer
// UiEulaMsg prints out appropriate EULA message
func UiEulaMsg(ui *gui.DialogUi, pathToEula string) {
	ui.SetOkLabel("Agree")
	ui.SetExtraLabel("Disagree")
	ui.SetTitle("End User License Agreement")
	ui.SetSize(30, 80)
	if err := ui.Textbox(pathToEula); err != nil {
		os.Exit(1)
	}
}
예제 #3
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiRemoteMode(ui *gui.DialogUi) (bool, error) {
	ui.SetTitle("Deployment Mode")
	ui.SetSize(9, 28)
	answer, err := ui.Menu(2, "1", "Local", "2", "Remote")
	if err != nil {
		return false, err
	}
	if answer == "1" {
		return false, nil
	}

	if _, err := exec.LookPath("sshfs"); err != nil {
		ui.Output(gui.Error, "sshfs utility is not installed")
	}
	return true, nil
}
예제 #4
0
파일: ui.go 프로젝트: weldpua2008/deployer
func uiNetworkPolicySelector(ui *gui.DialogUi, net *xmlinput.Network) ([]xmlinput.ConnectionMode, error) {
	matrix := make(map[string][]xmlinput.ConnectionMode)
	for _, mode := range net.UiModeBinding {
		if _, ok := matrix[mode.Appear]; !ok {
			matrix[mode.Appear] = make([]xmlinput.ConnectionMode, 0)
		}
		matrix[mode.Appear] = append(matrix[mode.Appear], mode.Type)
	}

	var temp []string
	index := 1
	for appear, _ := range matrix {
		temp = append(temp, strconv.Itoa(index), appear)
		index++
	}

	length := len(matrix)
	ui.SetSize(length+8, 50)
	ui.SetTitle(fmt.Sprintf("Network interface type for network \"%s\"", net.Name))
	ui.HelpButton(true)
	ui.SetHelpLabel("Back")
	if net.Optional {
		ui.SetExtraLabel("Skip")
	}
	val, err := ui.Menu(length, temp[0:]...)
	if err != nil {
		return nil, err
	}
	resultInt, err := strconv.Atoi(val)
	if err != nil {
		return nil, utils.FormatError(err)
	}
	if resultInt != 1 {
		resultInt++
	}
	return matrix[temp[resultInt]], nil
}
예제 #5
0
func uiBundleConfig(ui *gui.DialogUi, configs []*Config, advancedConfig bool) (*Config, error) {
	var temp []string
	index := 0
	for _, c := range configs {
		index += 1
		temp = append(temp, strconv.Itoa(index),
			fmt.Sprintf("%-15s [ vCPU %-2d | RAM %-3dMB]", c.Name, c.CPUs, c.RAM))
	}

	advIndex := index + 1
	temp = append(temp, strconv.Itoa(advIndex), "Custom configuration")

	sliceLength := len(temp)
	var configNumStr string
	var err error
	for {
		ui.SetSize(sliceLength+6, 50)
		ui.SetLabel("Select Virtual Machine configuration")
		configNumStr, err = ui.Menu(sliceLength+6, temp[0:]...)
		if err != nil {
			return nil, err
		}
		if configNumStr != "" {
			break
		}
	}

	configNumInt, err := strconv.Atoi(configNumStr)
	if err != nil {
		return nil, utils.FormatError(err)
	}
	if configNumInt == advIndex {
		return nil, nil
	}
	return configs[configNumInt-1], nil
}
예제 #6
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiWarningOnOptimizationFailure(ui *gui.DialogUi, warningStr string) bool {
	ui.SetTitle(gui.Warning)
	ui.SetSize(10, 80)
	ui.SetLabel("Virtual machine configuration can not be optimized.\n" + warningStr + "\n\nDo you want to continue?")
	return ui.Yesno()
}
예제 #7
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiNumaRamNotOK(ui *gui.DialogUi, driver deployer.HostinfoDriver, c *guest.Config, selectedRamInMb int) (bool, error) {
	// file, err := os.Create("/tmp/_setNUMATuneData.txt")
	// defer file.Close()

	numas, err := driver.NUMAInfo()
	if err != nil {
		return true, utils.FormatError(err)
	}
	NumaForCheck := make([]int, 0)
	// file.WriteString("uiNumaRamNotOK\n")
	for _, n := range c.NUMAs {
		// file.WriteString("c.NUMAs\n")
		for _, nic := range n.NICs {
			if nic.HostNIC.Type == host.NicTypePhys || nic.HostNIC.Type == host.NicTypePhysVF {
				isAdd := true
				for _, v := range NumaForCheck {
					if v == nic.HostNIC.NUMANode {
						isAdd = false
					}
				}
				if isAdd {
					NumaForCheck = append(NumaForCheck, nic.HostNIC.NUMANode)
					// file.WriteString("NumaForCheck: [" + strconv.Itoa(nic.HostNIC.NUMANode) + "]\n")
				}
			}
		}
	}
	// selectedRamInMb = 1
	var requiredMemory float64
	var freeRam float64
	numberOfNumas := len(NumaForCheck)
	if numberOfNumas < 1 {
		numberOfNumas = 1
	}
	requiredMemoryMB := selectedRamInMb / numberOfNumas
	requiredMemory = float64(selectedRamInMb / numberOfNumas)
	requiredMemoryStr := strconv.FormatFloat((requiredMemory / 1024), 'f', 1, 64)
	// file.WriteString("requiredMemoryStr: " + requiredMemoryStr + " selectedRamInMb:" + strconv.Itoa(selectedRamInMb) + " \n")
	for _, node := range numas {
		for _, CellID := range NumaForCheck {
			// file.WriteString("CellID: " + strconv.Itoa(CellID) + " node.CellID: " + strconv.Itoa(node.CellID) + "\n")
			if node.CellID != CellID {
				continue
			}
			numafreeRamMb := node.FreeRAM / 1024

			// file.WriteString("requiredMemoryMB: " + strconv.Itoa(requiredMemoryMB) + " node.FreeRAM:" + strconv.Itoa(numafreeRamMb) + " \n")
			// numafreeRamMb = 0
			if numafreeRamMb < requiredMemoryMB {
				freeRam = float64(node.FreeRAM / (1024 * 1024))
				freeRamStr := strconv.FormatFloat(freeRam, 'f', 1, 64)
				ui.SetTitle(gui.Warning)
				ui.SetSize(10, 80)
				ui.SetLabel("Virtual machine configuration can not be optimized.\n" + requiredMemoryStr + " GB RAM are required on NUMA " + strconv.Itoa(node.CellID) + " but just " + freeRamStr + "Gb are available\n\nDo you want to continue?")
				return ui.Yesno(), nil
			}
		}
	}

	return true, nil

}
예제 #8
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiVCPUsOvercommit(ui *gui.DialogUi, installedCpus int) bool {
	ui.SetSize(8, 75)
	ui.SetTitle(gui.Warning)
	ui.SetLabel(fmt.Sprintf("\nThe host only has %d CPUs.Overcommitting vCPUs can reduce performance!\nWould you like to proceed?", installedCpus))
	return ui.Yesno()
}
예제 #9
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiVmConfig(ui *gui.DialogUi, driver deployer.HostinfoDriver, xidata *xmlinput.XMLInputData,
	pathToMainImage string, sconf *image.Storage, conf *guest.Config) error {
	var installedRamMb int
	var maxRAM int
	var err error

	list := make([]string, 0)
	index := 1

	if xidata.CPU.Configure {
		cpuStr := fmt.Sprintf("  %-9s |  %d-%d", "CPU", xidata.CPU.Min, xidata.CPU.Max)
		list = []string{cpuStr, strconv.Itoa(index), "1", strconv.Itoa(xidata.CPU.Default), "1", "30", "6", "0", "0"}
		index++
	} else if xidata.CPU.Default > 0 {
		conf.CPUs = xidata.CPU.Default
	}
	if xidata.RAM.Configure {
		installedRamMb, err = driver.RAMSize()
		if err != nil {
			return utils.FormatError(err)
		}
		if xidata.RAM.Max > installedRamMb || xidata.RAM.Max == xmlinput.UnlimitedAlloc {
			maxRAM = installedRamMb
		} else {
			maxRAM = xidata.RAM.Max
		}

		ramStr := fmt.Sprintf("  %-9s |  %d-%dG", "RAM", xidata.RAM.Min/1024, maxRAM/1024)
		list = append(list, []string{ramStr, strconv.Itoa(index), "1", strconv.Itoa(xidata.RAM.Default / 1024), "2", "30", "6", "0", "0"}...)
		index++
	} else if xidata.RAM.Default > 0 {
		conf.RamMb = xidata.RAM.Default
	}
	if xidata.Disks.Configure {
		diskName := "Disk"
		for i, disk := range xidata.Disks.Configs {
			if i > 0 {
				diskName = strconv.Itoa(i) + "_" + strconv.Itoa(i)
			}
			diskStr := fmt.Sprintf("  %-9s |  %d-%dG", diskName, disk.Min/1024, disk.Max/1024)
			indexStr := strconv.Itoa(index)
			list = append(list, []string{diskStr, indexStr, "1", strconv.Itoa(disk.Default / 1024), indexStr, "30", "6", "0", "0"}...)
			index++
		}
	}
	str := " ______________________________________\n|	 Resource	 |		Maximum		|		Allocated		|"
	installedCpus, err := driver.CPUs()
	if err != nil {
		return utils.FormatError(err)
	}

	index--

	if index > 1 {

	MainLoop:
		for {
			ui.SetSize(11, 46)
			ui.SetTitle("Virtual Machine configuration")
			ui.HelpButton(true)
			ui.SetHelpLabel("Back")
			resultIndex := 0
			result, err := ui.Mixedform(str, false, list[0:]...)
			if err != nil {
				return err
			}
			if len(result) < index {
				continue
			}
			if xidata.CPU.Configure {
				selectedCpus, err := strconv.Atoi(result[resultIndex])
				if err != nil {
					continue
				}
				if uiCpuNotOK(ui, selectedCpus, installedCpus, xidata.CPU.Min, xidata.CPU.Max) {
					continue
				}
				conf.CPUs = selectedCpus
				resultIndex++
			}
			if xidata.RAM.Configure {
				selectedRamMb, err := utils.FloatStringToInt(result[resultIndex], 1024)
				if err != nil {
					continue MainLoop
				}
				if uiRamNotOK(ui, selectedRamMb, installedRamMb, xidata.RAM.Min, maxRAM) {
					continue
				}
				conf.RamMb = selectedRamMb
				resultIndex++
			}
			if xidata.Disks.Configure {
				disks := make([]int, 0)
				for _, disk := range xidata.Disks.Configs {
					selectedDiskSizeMb, err := utils.FloatStringToInt(result[resultIndex], 1024)
					if err != nil {
						continue MainLoop
					}
					if uiDiskNotOK(ui, selectedDiskSizeMb, disk.Min, disk.Max) {
						continue MainLoop
					}
					disks = append(disks, selectedDiskSizeMb*1024)
					resultIndex++
				}
				if conf.Storage, err = config.StorageConfig(pathToMainImage, 0, sconf, disks); err != nil {
					return err
				}
			}
			break
		}
	}
	return nil
}
예제 #10
0
파일: ui.go 프로젝트: weldpua2008/deployer
// UiWelcomeMsg prints out appropriate welcome message
func UiWelcomeMsg(ui *gui.DialogUi, name string) {
	msg := "Welcome to the " + name + " deployment procedure!"
	ui.SetSize(6, len(msg)+5)
	ui.Msgbox(msg)
}
예제 #11
0
파일: ui.go 프로젝트: weldpua2008/deployer
func uiNicSelectMenu(ui *gui.DialogUi, data *xmlinput.XMLInputData, guestPortCounter *int,
	guestPciSlotCounter *int, hnics host.NICList, net *xmlinput.Network, index int) (guest.NICList, error) {
	list := make([]string, 0)
	keeper := make(map[string]*host.NIC)
	indexStrToInt := make(map[string][]int)
	indexInt := 1
	for _, hnic := range hnics {
		indexStr := strconv.Itoa(indexInt)
		list = append(list, indexStr, fmt.Sprintf("%-22s%-15s%-68s%-10s", hnic.Name, hnic.PCIAddr, hnic.Desc, uiNUMAIntToString(hnic.NUMANode)))
		keeper[indexStr] = hnic
		if indexInt == 1 {
			// index 0 - element index in the list
			// index 1 - element counter
			// index 2 - PCI slot number represented as integer
			indexStrToInt[indexStr] = []int{1, 0, 0}
		} else {
			indexStrToInt[indexStr] = []int{indexInt*2 - 1, 0, 0}
		}
		indexInt++
	}

	listLength := len(list)
	gnics := guest.NewNICList()
	var disjuncNicVendor string
	var disjuncNicModel string

	for {
		if index > 0 {
			ui.HelpButton(true)
			ui.SetHelpLabel("Back")
		}
		width := uiHeaderSelectNics(ui)
		ui.SetSize(listLength+8, width+5)
		ui.SetTitle(fmt.Sprintf("Select interface for network \"%s\"", net.Name))
		nicNumStr, err := ui.Menu(listLength+5, list[0:]...)
		if err != nil {
			if err.Error() == gui.DialogNext {
				if len(gnics) == 0 && net.Optional == false {
					continue
				}
				break
			}
			*guestPciSlotCounter -= len(gnics)
			*guestPortCounter -= len(gnics)
			return nil, err
		}

		hnic := keeper[nicNumStr]
		// verify that we need to proceed with "disjunction"
		if net.NicsDisjunction && (hnic.Type == host.NicTypePhys || hnic.Type == host.NicTypePhysVF) &&
			(hnic.Vendor != disjuncNicVendor && hnic.Model != disjuncNicModel) {
			// back to menu in case "disjunction" entries already exist
			if host_hwfilter.NicDisjunctionFound(hnic, data.HostNics.Allowed) && disjuncNicVendor != "" {
				msg := fmt.Sprintf("'%s' cannot be selected alongside '%s %s'", hnic.Desc, disjuncNicVendor, disjuncNicModel)
				ui.Output(gui.Warning, msg, "Press <OK> to return to menu.")
				continue
			}
			// set the new entries
			disjuncNicVendor = hnic.Vendor
			disjuncNicModel = hnic.Model
		}

		delNicCounter := indexStrToInt[nicNumStr][1]
		// counter for the NIC found,we should remove the NIC object and its references
		if delNicCounter > 0 {
			// find the guest NIC object in the guest NICs list
			if _, index, err := gnics.NicByHostNicObj(hnic); err == nil {
				// if found :
				// - remove the object
				// - decrement guestPortCounter
				// - decriment guestPciSlotCounter
				gnics.Remove(index)
				if *guestPortCounter > 0 {
					*guestPortCounter--
				}
				if *guestPciSlotCounter > data.GuestNic.PCI.FirstSlot {
					*guestPciSlotCounter--
				}
				// update the list with the new entry containing deselected NIC
				list[indexStrToInt[nicNumStr][0]] = fmt.Sprintf("%-22s%-15s%-68s%-10s", hnic.Name, hnic.PCIAddr, hnic.Desc, uiNUMAIntToString(hnic.NUMANode))
				// - reset element counter
				// - reset PCI slot number
				indexStrToInt[nicNumStr][1] = 0
				indexStrToInt[nicNumStr][2] = 0
			}
			// iterate over the map and update entries
			for nicIndex, data := range indexStrToInt {
				nicCounter := data[1]
				if nicCounter > delNicCounter {
					tmpNic := keeper[nicIndex]
					nicCounter--
					list[data[0]] = fmt.Sprintf("%-22s%-15s%-68s%-9s%d", tmpNic.Name, tmpNic.PCIAddr,
						tmpNic.Desc, uiNUMAIntToString(tmpNic.NUMANode), nicCounter)
					indexStrToInt[nicIndex][1] = nicCounter
					indexStrToInt[nicIndex][2]--
					if gnic, _, err := gnics.NicByHostNicObj(tmpNic); err == nil {
						gnic.PCIAddr.Slot = utils.IntToHexString(indexStrToInt[nicIndex][2])
					}
				}
			}
			// clear "disjunction" entries in case gnics slice is empty
			if gnics.Length() == 0 {
				disjuncNicVendor = ""
				disjuncNicModel = ""
			}
			continue
		}
		// create new guest NIC, set his  number and counter
		indexStrToInt[nicNumStr][1] = *guestPortCounter
		indexStrToInt[nicNumStr][2] = *guestPciSlotCounter
		list[indexStrToInt[nicNumStr][0]] = fmt.Sprintf("%-22s%-15s%-68s%-9s%d", hnic.Name, hnic.PCIAddr,
			hnic.Desc, uiNUMAIntToString(hnic.NUMANode), *guestPortCounter)
		gnic := guest.NewNIC()
		gnic.Network = net.Name
		gnic.PCIAddr.Domain = data.PCI.Domain
		gnic.PCIAddr.Bus = data.PCI.Bus
		gnic.PCIAddr.Slot = utils.IntToHexString(*guestPciSlotCounter)
		gnic.PCIAddr.Function = data.PCI.Function
		gnic.HostNIC = hnic
		gnics.Add(gnic)
		*guestPciSlotCounter++
		*guestPortCounter++
	}
	return gnics, nil
}
예제 #12
0
파일: ui.go 프로젝트: weldpua2008/deployer
func UiSshConfig(ui *gui.DialogUi) (*sshconf.Config, error) {
	cfg := new(sshconf.Config)
	cfg.Port = "22"
	cfg.User = "******"
	origlist := []string{"IP      : ", "1", "1", "", "1", "10", "22", "0", "0",
		"SSH Port: ", "2", "1", cfg.Port, "2", "10", "22", "0", "0",
		"Username: "******"3", "1", cfg.User, "3", "10", "22", "0", "0"}

MainLoop:
	for {
		ui.HelpButton(true)
		ui.SetHelpLabel("Back")
		reslist, err := ui.Mixedform("Remote session configuration", false, origlist[0:]...)
		if err != nil {
			return nil, err
		}
		if len(reslist) < 3 {
			continue
		}
		if net.ParseIP(reslist[0]) == nil {
			continue
		}
		cfg.Host = reslist[0]

		portDig, err := strconv.Atoi(reslist[1])
		if err != nil {
			return nil, utils.FormatError(err)
		}
		if portDig > 65535 {
			continue
		}

	AuthLoop:
		for {
			ui.SetTitle("Authentication method")
			ui.SetSize(9, 18)
			ui.HelpButton(true)
			ui.SetHelpLabel("Back")
			val, err := ui.Menu(2, "1", "Password", "2", "Private key")
			if err != nil {
				switch err.Error() {
				case gui.DialogMoveBack:
					continue MainLoop
				case gui.DialogExit:
					os.Exit(1)
				}
			}

			switch val {
			case "1":
				cfg.Password, err = ui.GetPasswordFromInput(cfg.Host, cfg.User, "Back", "", false)
			case "2":
				cfg.PrvtKeyFile, err = ui.GetPathToFileFromInput("Path to ssh private key file", "Back", "")
			}
			if err != nil {
				switch err.Error() {
				case gui.DialogMoveBack:
					continue AuthLoop
				case gui.DialogExit:
					os.Exit(1)
				}
			}
			break MainLoop
		}
	}

	run := utils.RunFunc(cfg)
	errCh := make(chan error)
	defer close(errCh)
	go func() {
		// verifying that user is able execute a command by using sudo
		_, err := run("uname")
		errCh <- err
	}()

	if err := ui.Wait("Trying to establish SSH connection to remote host.\nPlease wait...", time.Second*1, time.Second*5, errCh); err != nil {
		ui.Output(gui.Warning, "Unable to establish SSH connection.", "Press <OK> to return to menu.")
		goto MainLoop
	}
	return cfg, nil
}