Beispiel #1
0
func cliVmConfig(c *minicli.Command, resp *minicli.Response) error {
	if c.BoolArgs["save"] {
		// Save the current config
		savedInfo[c.StringArgs["name"]] = vmConfig.Copy()

		return nil
	} else if c.BoolArgs["restore"] {
		if name, ok := c.StringArgs["name"]; ok {
			// Try to restore an existing config
			if _, ok := savedInfo[name]; !ok {
				return fmt.Errorf("config %v does not exist", name)
			}

			vmConfig = savedInfo[name].Copy()

			return nil
		} else if len(savedInfo) == 0 {
			return errors.New("no vm configs saved")
		}

		// List the save configs
		for k := range savedInfo {
			resp.Response += fmt.Sprintln(k)
		}

		return nil
	} else if c.BoolArgs["clone"] {
		// Clone the config of an existing vm
		vm := vms.FindVM(c.StringArgs["vm"])
		if vm == nil {
			return vmNotFound(c.StringArgs["vm"])
		}

		switch vm := vm.(type) {
		case *KvmVM:
			vmConfig.BaseConfig = vm.BaseConfig.Copy()
			vmConfig.KVMConfig = vm.KVMConfig.Copy()
		case *ContainerVM:
			vmConfig.BaseConfig = vm.BaseConfig.Copy()
			vmConfig.ContainerConfig = vm.ContainerConfig.Copy()
		}

		return nil
	}

	// Print the config
	resp.Response = vmConfig.String()
	return nil
}
Beispiel #2
0
func cliVmConfigTag(c *minicli.Command, resp *minicli.Response) error {
	k := c.StringArgs["key"]

	if v, ok := c.StringArgs["value"]; ok {
		// Setting a new value
		vmConfig.Tags[k] = v
	} else if k != "" {
		// Printing a single tag
		resp.Response = vmConfig.Tags[k]
	} else {
		// Printing all configured tags
		resp.Response = vmConfig.TagsString()
	}

	return nil
}
Beispiel #3
0
func cliHost(c *minicli.Command, resp *minicli.Response) error {
	// If they selected one of the fields to display
	for k := range c.BoolArgs {
		val, err := hostInfoFns[k]()
		if err != nil {
			return err
		}

		resp.Response = val
		return nil
	}

	// Must want all fields
	resp.Header = hostInfoKeys

	row := []string{}
	for _, k := range resp.Header {
		val, err := hostInfoFns[k]()
		if err != nil {
			return err
		}

		row = append(row, val)
	}
	resp.Tabular = [][]string{row}

	return nil
}
Beispiel #4
0
func cliVmConfigField(c *minicli.Command, resp *minicli.Response, field string) error {
	// If there are no args it means that we want to display the current value
	nArgs := len(c.StringArgs) + len(c.ListArgs) + len(c.BoolArgs)

	var ok bool
	var fns VMConfigFns
	var config interface{}

	// Find the right config functions, baseConfigFns has highest priority
	if fns, ok = baseConfigFns[field]; ok {
		config = &vmConfig.BaseConfig
	} else if fns, ok = kvmConfigFns[field]; ok {
		config = &vmConfig.KVMConfig
	} else if fns, ok = containerConfigFns[field]; ok {
		config = &vmConfig.ContainerConfig
	} else {
		return fmt.Errorf("unknown config field: `%s`", field)
	}

	if nArgs == 0 {
		resp.Response = fns.Print(config)
		return nil
	}

	return fns.Update(config, c)
}
Beispiel #5
0
func cliLogFile(c *minicli.Command, resp *minicli.Response) error {
	if len(c.StringArgs) == 0 {
		// Print true or false depending on whether file is enabled
		if logFile != nil {
			resp.Response = logFile.Name()
		}

		return nil
	}

	// Enable logging to file if it's not already enabled
	level, _ := log.LevelInt(*f_loglevel)

	if logFile != nil {
		if err := stopFileLogger(); err != nil {
			return err
		}
	}

	err := os.MkdirAll(filepath.Dir(c.StringArgs["file"]), 0755)
	if err != nil {
		return err
	}

	flags := os.O_WRONLY | os.O_APPEND | os.O_CREATE
	logFile, err = os.OpenFile(c.StringArgs["file"], flags, 0660)
	if err != nil {
		return err
	}

	log.AddLogger("file", logFile, level, false)
	return nil
}
Beispiel #6
0
func cliHelp(c *minicli.Command, resp *minicli.Response) error {
	input := ""
	if args, ok := c.ListArgs["command"]; ok {
		input = strings.Join(args, " ")
	}

	resp.Response = minicli.Help(input)
	return nil
}
Beispiel #7
0
// prefix
func cliCCPrefix(c *minicli.Command, resp *minicli.Response) error {
	if prefix, ok := c.StringArgs["prefix"]; ok {
		ccPrefix = prefix
		return nil
	}

	resp.Response = ccPrefix
	return nil
}
Beispiel #8
0
// routines for interfacing bridge mechanisms with the cli
func cliHostTap(c *minicli.Command, resp *minicli.Response) error {
	if c.BoolArgs["create"] {
		b := c.StringArgs["bridge"]

		tap, err := hostTapCreate(b, c.StringArgs["tap"], c.StringArgs["vlan"])
		if err != nil {
			return err
		}

		if c.BoolArgs["dhcp"] {
			log.Debug("obtaining dhcp on tap %v", tap)

			var out string
			out, err = processWrapper("dhcp", tap)
			if err != nil {
				err = fmt.Errorf("dhcp error %v: `%v`", err, out)
			}
		} else if c.StringArgs["ip"] != "" {
			ip := c.StringArgs["ip"]

			log.Debug("setting ip on tap %v: %v", tap, ip)

			var out string
			out, err = processWrapper("ip", "addr", "add", "dev", tap, ip)
			if err != nil {
				err = fmt.Errorf("ip error %v: `%v`", err, out)
			}
		}

		if err != nil {
			// One of the above cases failed, try to clean up the tap
			if err := hostTapDelete(tap); err != nil {
				// Welp, we're boned
				log.Error("zombie tap -- %v %v", tap, err)
			}

			return err
		}
		// Success!
		if ns := GetNamespace(); ns != nil {
			// TODO: probably need lock...
			ns.Taps[tap] = true
		}

		resp.Response = tap

		return nil
	} else if c.BoolArgs["delete"] {
		return hostTapDelete(c.StringArgs["id"])
	}

	// Must be the list command
	hostTapList(resp)

	return nil
}
Beispiel #9
0
func cliShell(c *minicli.Command, resp *minicli.Response, background bool) error {
	var sOut bytes.Buffer
	var sErr bytes.Buffer

	p, err := exec.LookPath(c.ListArgs["command"][0])
	if err != nil {
		return err
	}

	args := []string{p}
	if len(c.ListArgs["command"]) > 1 {
		args = append(args, c.ListArgs["command"][1:]...)
	}

	cmd := &exec.Cmd{
		Path:   p,
		Args:   args,
		Env:    nil,
		Dir:    "",
		Stdout: &sOut,
		Stderr: &sErr,
	}
	log.Info("starting: %v", args)
	if err := cmd.Start(); err != nil {
		return err
	}

	if background {
		go func() {
			if err := cmd.Wait(); err != nil {
				log.Error(err.Error())
				return
			}

			log.Info("command %v exited", args)
			if out := sOut.String(); out != "" {
				log.Info(out)
			}
			if err := sErr.String(); err != "" {
				log.Info(err)
			}
		}()

		return nil
	}

	if err = cmd.Wait(); err != nil {
		return err
	}

	resp.Response = sOut.String()
	resp.Error = sErr.String()

	return nil
}
Beispiel #10
0
func cliMeshageList(c *minicli.Command, resp *minicli.Response) error {
	mesh := meshageNode.Mesh()

	var keys []string
	for k, _ := range mesh {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, key := range keys {
		v := mesh[key]
		resp.Response += fmt.Sprintf("%s\n", key)
		sort.Strings(v)
		for _, x := range v {
			resp.Response += fmt.Sprintf(" |--%s\n", x)
		}
	}

	return nil
}
Beispiel #11
0
// cli commands for meshage control
func cliMeshageDegree(c *minicli.Command, resp *minicli.Response) error {
	if c.StringArgs["degree"] != "" {
		degree, err := strconv.ParseUint(c.StringArgs["degree"], 0, 10)
		if err != nil {
			return err
		}

		meshageNode.SetDegree(uint(degree))
		return nil
	}

	resp.Response = fmt.Sprintf("%d", meshageNode.GetDegree())
	return nil
}
Beispiel #12
0
func cliVmQmp(c *minicli.Command, resp *minicli.Response) error {
	vm, err := vms.FindKvmVM(c.StringArgs["vm"])
	if err != nil {
		return err
	}

	out, err := vm.QMPRaw(c.StringArgs["qmp"])
	if err != nil {
		return err
	}

	resp.Response = out
	return nil
}
Beispiel #13
0
func cliQuit(c *minicli.Command, resp *minicli.Response) error {
	if v, ok := c.StringArgs["delay"]; ok {
		delay, err := strconv.Atoi(v)
		if err != nil {
			return err
		}

		go func() {
			time.Sleep(time.Duration(delay) * time.Second)
			teardown()
		}()

		resp.Response = fmt.Sprintf("quitting after %v seconds", delay)
		return nil
	}

	teardown()
	return errors.New("unreachable")
}
Beispiel #14
0
func cliMeshageTimeout(c *minicli.Command, resp *minicli.Response) error {
	if c.StringArgs["timeout"] != "" {
		timeout, err := strconv.Atoi(c.StringArgs["timeout"])
		if err != nil {
			return err
		}

		meshageTimeout = time.Duration(timeout) * time.Second
		// If the timeout is 0, set to "unlimited"
		if meshageTimeout == 0 {
			meshageTimeout = math.MaxInt64
		}

		return nil
	}

	// get current value
	resp.Response = fmt.Sprintf("%v", meshageTimeout)
	return nil
}
Beispiel #15
0
func cliLogFilter(c *minicli.Command, resp *minicli.Response) error {
	if len(c.StringArgs) == 0 {
		var filters []string
		loggers := log.Loggers()

		for _, l := range loggers {
			filt, _ := log.Filters(l)
			for _, f := range filt {
				var found bool
				for _, v := range filters {
					if v == f {
						found = true
					}
				}
				if !found {
					filters = append(filters, f)
				}
			}
		}

		if len(filters) != 0 {
			resp.Response = fmt.Sprintf("%v", filters)
		}

		return nil
	}

	filter := c.StringArgs["filter"]

	for _, l := range log.Loggers() {
		err := log.AddFilter(l, filter)
		if err != nil {
			return err
		}
	}

	return nil
}
Beispiel #16
0
func cliLogStderr(c *minicli.Command, resp *minicli.Response) error {
	if c.BoolArgs["false"] {
		// Turn off logging to stderr
		log.DelLogger("stdio")
	} else if len(c.BoolArgs) == 0 {
		// Print true or false depending on whether stderr is enabled
		_, err := log.GetLevel("stdio")
		resp.Response = strconv.FormatBool(err == nil)
	} else if c.BoolArgs["true"] {
		// Enable stderr logging or adjust the level if already enabled
		level, _ := log.LevelInt(*f_loglevel)
		_, err := log.GetLevel("stdio")
		if err != nil {
			log.AddLogger("stdio", os.Stderr, level, true)
		} else {
			// TODO: Why do this? cliLogLevel updates stdio level whenever
			// f_loglevel is changed.
			log.SetLevel("stdio", level)
		}
	}

	return nil
}
Beispiel #17
0
func cliDeploy(c *minicli.Command, resp *minicli.Response) error {
	hosts := c.StringArgs["hosts"]
	user := c.StringArgs["user"]
	sudo := c.BoolArgs["sudo"]
	flagsList := c.ListArgs["minimega"]

	if c.BoolArgs["flags"] {
		if flagsList == nil {
			resp.Response = deployGetFlags()
			return nil
		}

		deployFlags = flagsList
		return nil
	}

	hostsExpanded, err := ranges.SplitList(hosts)
	if err != nil {
		return err
	}
	log.Debug("got expanded hosts: %v", hostsExpanded)

	// Append timestamp to filename so that each deploy produces a new binary
	// on the remote system. Using the timestamp allows us to quickly identify
	// the latest binary after multiple deployments.
	fname := fmt.Sprintf("minimega_deploy_%v", time.Now().Unix())
	remotePath := filepath.Join(os.TempDir(), fname)
	log.Debug("remotePath: %v", remotePath)

	// copy minimega
	errs := deployCopy(hostsExpanded, user, remotePath)

	// launch minimega on each remote node
	errs2 := deployRun(hostsExpanded, user, remotePath, sudo)

	return makeErrSlice(append(errs, errs2...))
}
Beispiel #18
0
func cliLogLevel(c *minicli.Command, resp *minicli.Response) error {
	if len(c.BoolArgs) == 0 {
		// Print the level
		resp.Response = *f_loglevel
		return nil
	}

	// Bool args should only have a single key that is the log level
	for k := range c.BoolArgs {
		level, err := log.LevelInt(k)
		if err != nil {
			return errors.New("unreachable")
		}

		*f_loglevel = k
		// forget the error, if they don't exist we shouldn't be setting
		// their level, so we're fine.
		log.SetLevel("stdio", level)
		log.SetLevel("file", level)
		log.SetLevel("syslog", level)
	}

	return nil
}
Beispiel #19
0
func cliDisk(c *minicli.Command, resp *minicli.Response) error {
	image := c.StringArgs["image"]

	// Ensure that relative paths are always relative to /files/
	if !filepath.IsAbs(image) {
		image = path.Join(*f_iomBase, image)
	}
	log.Debug("image: %v", image)

	if c.BoolArgs["snapshot"] {
		dst := c.StringArgs["dst"]

		if dst == "" {
			f, err := ioutil.TempFile(*f_iomBase, "snapshot")
			if err != nil {
				return errors.New("could not create a dst image")
			}

			dst = f.Name()
			resp.Response = dst
		} else if strings.Contains(dst, "/") {
			return errors.New("dst image must filename without path")
		} else {
			dst = path.Join(*f_iomBase, dst)
		}

		log.Debug("destination image: %v", dst)

		return diskSnapshot(image, dst)
	} else if c.BoolArgs["inject"] {
		partition := "1"

		if strings.Contains(image, ":") {
			parts := strings.Split(image, ":")
			if len(parts) != 2 {
				return errors.New("found way too many ':'s, expected <path/to/image>:<partition>")
			}

			image, partition = parts[0], parts[1]
		}

		options := fieldsQuoteEscape("\"", c.StringArgs["options"])
		log.Debug("got options: %v", options)

		pairs, err := parseInjectPairs(c.ListArgs["files"])
		if err != nil {
			return err
		}

		return diskInject(image, partition, pairs, options)
	} else if c.BoolArgs["create"] {
		size := c.StringArgs["size"]

		format := "raw"
		if _, ok := c.BoolArgs["qcow2"]; ok {
			format = "qcow2"
		}

		return diskCreate(format, image, size)
	} else if c.BoolArgs["info"] {
		info, err := diskInfo(image)
		if err != nil {
			return err
		}

		resp.Header = []string{"image", "format", "virtual size", "disk size", "backing file"}
		resp.Tabular = append(resp.Tabular, []string{
			image, info.Format, info.VirtualSize, info.DiskSize, info.BackingFile,
		})

		return nil
	}

	// boo, should be unreachable
	return errors.New("unreachable")
}
Beispiel #20
0
// cliCaptureNetflow manages the CLI for starting and stopping captures to netflow.
func cliCaptureNetflow(c *minicli.Command, resp *minicli.Response) error {
	if c.BoolArgs["delete"] {
		// Stop a capture
		return clearCapture("netflow", c.StringArgs["id"])
	} else if c.BoolArgs["timeout"] {
		// Set or get the netflow timeout
		timeout := c.StringArgs["timeout"]
		val, err := strconv.Atoi(timeout)
		if timeout != "" {
			resp.Response = strconv.Itoa(captureNFTimeout)
		} else if err != nil {
			return fmt.Errorf("invalid timeout parameter: `%v`", timeout)
		} else {
			captureNFTimeout = val
			captureUpdateNFTimeouts()
		}

		return nil
	} else if c.BoolArgs["file"] {
		// Capture -> netflow (file)
		return startCaptureNetflowFile(
			c.StringArgs["bridge"],
			c.StringArgs["filename"],
			c.BoolArgs["ascii"],
			c.BoolArgs["gzip"],
		)
	} else if c.BoolArgs["socket"] {
		// Capture -> netflow (socket)
		transport := "tcp"
		if c.BoolArgs["udp"] {
			transport = "udp"
		}

		return startCaptureNetflowSocket(
			c.StringArgs["bridge"],
			transport,
			c.StringArgs["hostname:port"],
			c.BoolArgs["ascii"],
		)
	}

	// List captures
	resp.Header = []string{"ID", "Bridge", "Path", "Mode", "Compress"}

	for _, v := range captureEntries {
		if v.Type == "netflow" {
			row := []string{
				strconv.Itoa(v.ID),
				v.Bridge,
				v.Path,
				v.Mode,
				strconv.FormatBool(v.Compress),
			}
			resp.Tabular = append(resp.Tabular, row)
		}
	}

	return nil

	// TODO: netflow stats?
}
Beispiel #21
0
// responses
func cliCCResponses(c *minicli.Command, resp *minicli.Response) error {
	raw := c.BoolArgs["raw"]
	id := c.StringArgs["id"]

	walker := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// Test if the file looks like a UUID. If it does, and a namespace is
		// active, check whether the VM is part of the active namespace. This
		// is a fairly naive way to filter the responses...
		if namespace != "" && isUUID(info.Name()) {
			if vm := vms.FindVM(info.Name()); vm == nil {
				log.Debug("skipping VM: %v", info.Name())
				return filepath.SkipDir
			}
		}

		if !info.IsDir() {
			log.Debug("add to response files: %v", path)

			data, err := ioutil.ReadFile(path)
			if err != nil {
				return err
			}

			if !raw {
				relPath, err := filepath.Rel(filepath.Join(*f_iomBase, ron.RESPONSE_PATH), path)
				if err != nil {
					return err
				}
				resp.Response += fmt.Sprintf("%v:\n", relPath)
			}
			resp.Response += fmt.Sprintf("%v\n", string(data))
		}
		return nil
	}

	if id == Wildcard {
		// all responses
		return filepath.Walk(filepath.Join(*f_iomBase, ron.RESPONSE_PATH), walker)
	} else if _, err := strconv.Atoi(id); err == nil {
		p := filepath.Join(*f_iomBase, ron.RESPONSE_PATH, id)
		if _, err := os.Stat(p); err != nil {
			return fmt.Errorf("no such response dir %v", p)
		}

		return filepath.Walk(p, walker)
	}

	// try a prefix. First, do we even have anything with this prefix?
	ids := ccPrefixIDs(id)
	if len(ids) == 0 {
		return fmt.Errorf("no such prefix %v", id)
	}

	for _, i := range ids {
		p := filepath.Join(*f_iomBase, ron.RESPONSE_PATH, fmt.Sprintf("%v", i))
		if _, err := os.Stat(p); err != nil {
			return fmt.Errorf("no such response dir %v", p)
		}
		if err := filepath.Walk(p, walker); err != nil {
			return err
		}
	}

	return nil
}
Beispiel #22
0
func cliHistory(c *minicli.Command, resp *minicli.Response) error {
	resp.Response = minicli.History()
	return nil
}
Beispiel #23
0
func cliVersion(c *minicli.Command, resp *minicli.Response) error {
	resp.Response = fmt.Sprintf("minimega %v %v", version.Revision, version.Date)
	return nil
}
Beispiel #24
0
func cliRouter(c *minicli.Command, resp *minicli.Response) error {
	vmName := c.StringArgs["vm"]

	vm := vms.FindVM(vmName)
	if vm == nil {
		return vmNotFound(vmName)
	}

	if vmName != "" && len(c.BoolArgs) == 0 { // a summary of a specific router
		rtr := FindRouter(vm)
		if rtr == nil {
			return fmt.Errorf("vm %v not a router", vmName)
		}
		resp.Response = rtr.String()
	}

	rtr := FindOrCreateRouter(vm)

	if c.BoolArgs["commit"] {
		return rtr.Commit()
	} else if c.BoolArgs["log"] {
		var level string
		if c.BoolArgs["fatal"] {
			level = "fatal"
		} else if c.BoolArgs["error"] {
			level = "error"
		} else if c.BoolArgs["warn"] {
			level = "warn"
		} else if c.BoolArgs["info"] {
			level = "info"
		} else if c.BoolArgs["debug"] {
			level = "debug"
		}
		rtr.LogLevel(level)
		return nil
	} else if c.BoolArgs["interface"] {
		network, err := strconv.Atoi(c.StringArgs["network"])
		if err != nil {
			return fmt.Errorf("invalid network: %v : %v", c.StringArgs["network"], err)
		}
		ip := c.StringArgs["IPv4/MASK"]

		return rtr.InterfaceAdd(network, ip)
	} else if c.BoolArgs["dhcp"] {
		addr := c.StringArgs["listen"]

		if c.BoolArgs["range"] {
			low := c.StringArgs["low"]
			high := c.StringArgs["high"]
			return rtr.DHCPAddRange(addr, low, high)
		} else if c.BoolArgs["router"] {
			r := c.StringArgs["router"]
			return rtr.DHCPAddRouter(addr, r)
		} else if c.BoolArgs["dns"] {
			dns := c.StringArgs["address"]
			return rtr.DHCPAddDNS(addr, dns)
		} else if c.BoolArgs["static"] {
			mac := c.StringArgs["mac"]
			ip := c.StringArgs["ip"]
			return rtr.DHCPAddStatic(addr, mac, ip)
		}
	} else if c.BoolArgs["dns"] {
		ip := c.StringArgs["ip"]
		hostname := c.StringArgs["hostname"]
		rtr.DNSAdd(ip, hostname)
		return nil
	} else if c.BoolArgs["upstream"] {
		ip := c.StringArgs["ip"]
		rtr.Upstream(ip)
		return nil
	} else if c.BoolArgs["ra"] {
		subnet := c.StringArgs["subnet"]
		rtr.RADAdd(subnet)
		return nil
	} else if c.BoolArgs["route"] {
		if c.BoolArgs["static"] {
			network := c.StringArgs["network"]
			nh := c.StringArgs["next-hop"]
			rtr.RouteStaticAdd(network, nh)
			return nil
		} else if c.BoolArgs["ospf"] {
			area := c.StringArgs["area"]
			iface := c.StringArgs["network"]
			rtr.RouteOSPFAdd(area, iface)
		}
	}

	return nil
}
Beispiel #25
0
func cliUptime(c *minicli.Command, resp *minicli.Response) error {
	resp.Response = fmt.Sprintf("Started %v up %v", started, time.Since(started))
	return nil
}
Beispiel #26
0
func cliEcho(c *minicli.Command, resp *minicli.Response) error {
	resp.Response = strings.Join(c.ListArgs["args"], " ")
	return nil
}
Beispiel #27
0
func cliVyatta(c *minicli.Command, resp *minicli.Response) error {
	log.Warnln("the vyatta API is deprecated and will be removed in a future release")

	if c.BoolArgs["dhcp"] {
		net := c.StringArgs["network"]

		if len(c.StringArgs) == 0 {
			// List the existing DHCP services
			resp.Header = []string{"Network", "GW", "Start address", "Stop address", "DNS"}
			resp.Tabular = [][]string{}
			for k, v := range vyatta.Dhcp {
				resp.Tabular = append(resp.Tabular, []string{k, v.Gw, v.Start, v.Stop, v.Dns})
			}
		} else if c.StringArgs["gateway"] != "" {
			// Add a new DHCP service
			vyatta.Dhcp[net] = &vyattaDhcp{
				Gw:    c.StringArgs["gateway"],
				Start: c.StringArgs["low"],
				Stop:  c.StringArgs["high"],
				Dns:   c.StringArgs["dns"],
			}

			log.Debug("vyatta add dhcp %v", vyatta.Dhcp[net])
		} else {
			// Deleting a DHCP service
			if _, ok := vyatta.Dhcp[net]; !ok {
				resp.Error = "no such Dhcp service"
			} else {
				log.Debug("vyatta delete dhcp %v", net)
				delete(vyatta.Dhcp, net)
			}
		}
	} else if c.BoolArgs["interfaces"] {
		// Get or update IPv4 interfaces
		if len(c.ListArgs) == 0 {
			resp.Response = fmt.Sprintf("%v", vyatta.Ipv4)
		} else {
			vyatta.Ipv4 = c.ListArgs["net"]
		}
	} else if c.BoolArgs["interfaces6"] {
		// Get or update IPv6 interfaces
		if len(c.ListArgs) == 0 {
			resp.Response = fmt.Sprintf("%v", vyatta.Ipv6)
		} else {
			vyatta.Ipv6 = c.ListArgs["net"]
		}
	} else if c.BoolArgs["rad"] {
		// Get or update rad
		if len(c.ListArgs) == 0 {
			resp.Response = fmt.Sprintf("%v", vyatta.Rad)
		} else {
			vyatta.Rad = c.ListArgs["prefix"]
		}
	} else if c.BoolArgs["ospf"] {
		// Get or update ospf
		if len(c.ListArgs) == 0 {
			resp.Response = fmt.Sprintf("%v", vyatta.Ospf)
		} else {
			vyatta.Ospf = c.ListArgs["network"]
		}
	} else if c.BoolArgs["ospf3"] {
		// Get or update ospf
		if len(c.ListArgs) == 0 {
			resp.Response = fmt.Sprintf("%v", vyatta.Ospf3)
		} else {
			vyatta.Ospf3 = c.ListArgs["network"]
		}
	} else if c.BoolArgs["routes"] {
		if len(c.ListArgs) == 0 {
			resp.Header = []string{"Network", "Route"}
			resp.Tabular = [][]string{}

			for _, v := range vyatta.Routes {
				resp.Tabular = append(resp.Tabular, []string{v.Route, v.NextHop})
			}
		} else {
			err := vyattaUpdateRoutes(c.ListArgs["network"])
			if err != nil {
				resp.Error = err.Error()
			}
		}
	} else if c.BoolArgs["config"] {
		// override everything and just cram the listed file into the floppy
		// image
		if len(c.StringArgs) == 0 {
			resp.Response = vyatta.ConfigFile
		} else {
			vyatta.ConfigFile = c.StringArgs["filename"]
		}
	} else if c.BoolArgs["write"] {
		var err error
		resp.Response, err = vyattaWrite(c.StringArgs["filename"])
		if err != nil {
			resp.Error = err.Error()
		}
	} else {
		// Display info about running services
		var dhcpKeys []string
		for k, _ := range vyatta.Dhcp {
			dhcpKeys = append(dhcpKeys, k)
		}

		var routes []string
		for _, k := range vyatta.Routes {
			routes = append(routes, k.Route)
		}

		resp.Header = []string{
			"IPv4 addresses",
			"IPv6 addresses",
			"RAD",
			"DHCP servers",
			"OSPF",
			"OSPF3",
			"Routes",
		}
		resp.Tabular = [][]string{[]string{
			fmt.Sprintf("%v", vyatta.Ipv4),
			fmt.Sprintf("%v", vyatta.Ipv6),
			fmt.Sprintf("%v", vyatta.Rad),
			fmt.Sprintf("%v", dhcpKeys),
			fmt.Sprintf("%v", vyatta.Ospf),
			fmt.Sprintf("%v", vyatta.Ospf3),
			fmt.Sprintf("%v", routes),
		}}
	}

	return nil
}
Beispiel #28
0
func cliOptimize(c *minicli.Command, resp *minicli.Response) error {
	if c.BoolArgs["ksm"] {
		if len(c.BoolArgs) == 1 {
			// Must want to print ksm status
			resp.Response = fmt.Sprintf("%v", ksmEnabled)
		} else if c.BoolArgs["true"] {
			// Must want to update ksm status to true
			ksmEnable()
		} else {
			// Must want to update ksm status to false
			ksmDisable()
		}

		return nil
	} else if c.BoolArgs["hugepages"] {
		if len(c.BoolArgs) == 1 {
			// Must want to print hugepage path
			resp.Response = fmt.Sprintf("%v", hugepagesMountPath)
		} else {
			hugepagesMountPath = c.StringArgs["path"]
		}

		return nil
	} else if c.BoolArgs["affinity"] {
		if len(c.BoolArgs) == 1 {
			// Must want to print affinity status
			resp.Header = []string{"CPU", "VMs"}
			resp.Tabular = [][]string{}

			var cpus []string
			for k, _ := range affinityCPUSets {
				cpus = append(cpus, k)
			}

			sort.Strings(cpus)

			for _, cpu := range cpus {
				var ids []int
				for _, vm := range affinityCPUSets[cpu] {
					ids = append(ids, vm.GetID())
				}
				resp.Tabular = append(resp.Tabular, []string{
					cpu,
					fmt.Sprintf("%v", ids)})
			}
		} else if c.BoolArgs["filter"] {
			r, err := ranges.NewRange("", 0, runtime.NumCPU()-1)
			if err != nil {
				return fmt.Errorf("cpu affinity ranges: %v", err)
			}

			cpus, err := r.SplitRange(c.StringArgs["filter"])
			if err != nil {
				return fmt.Errorf("cannot expand CPU range: %v", err)
			}

			affinityCPUSets = make(map[string][]*KvmVM)
			for _, v := range cpus {
				affinityCPUSets[v] = []*KvmVM{}
			}

			if affinityEnabled {
				affinityEnable()
			}
		} else if c.BoolArgs["true"] && !affinityEnabled {
			// Enabling affinity
			affinityEnable()
		} else if c.BoolArgs["false"] && affinityEnabled {
			// Disabling affinity
			affinityDisable()
		}

		return nil
	}

	// Summary of optimizations
	out, err := optimizeStatus()
	if err == nil {
		resp.Response = out
	}

	return err
}