func cmdIp(c *cli.Context) { checkFlagsIncompatible(c, "nic_id", "network", "network_id") var ( vm *goca.VM err error ) if vm, err = GetVM(c.Args().First()); err != nil { log.Fatal(err) } if err = vm.Info(); err != nil { log.Fatal(err) } xpath := "/VM/TEMPLATE/NIC" if c.IsSet("nic_id") { xpath += fmt.Sprintf("[NIC_ID='%d']", c.Int("nic_id")) } else if c.IsSet("network_id") { xpath += fmt.Sprintf("[NETWORK_ID='%d']", c.Int("network_id")) } else if c.IsSet("network") { xpath += fmt.Sprintf("[NETWORK='%s']", c.String("network")) } if c.Bool("all") { iter := vm.XPathIter(xpath) for iter.Next() { node := iter.Node() ip, ok := node.XPath("IP") if ok == false { exitError("Unable to find IP.") } fmt.Println(ip) } } else { xpath += "/IP" ip, ok := vm.XPath(xpath) if ok == false { exitError("Unable to find IP.") } fmt.Println(ip) } }
func cmdSSH(c *cli.Context) { checkFlagsIncompatible(c, "nic_id", "network", "network_id") var ( vm *goca.VM err error interval time.Duration = time.Duration(c.Int("interval")) baseSSHArgs = []string{ "-o", "PasswordAuthentication=no", "-o", "IdentitiesOnly=yes", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." "-o", "ConnectionAttempts=3", // retry 3 times if SSH connection fails "-o", "ConnectTimeout=10", // timeout after 10 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=no", "exit", "0", } ) if vm, err = GetVM(c.Args().First()); err != nil { log.Fatal(err) } if err = vm.Info(); err != nil { log.Fatal(err) } xpath := "/VM/TEMPLATE/NIC" if c.IsSet("nic_id") { xpath += fmt.Sprintf("[NIC_ID='%d']", c.Int("nic_id")) } else if c.IsSet("network_id") { xpath += fmt.Sprintf("[NETWORK_ID='%d']", c.Int("network_id")) } else if c.IsSet("network") { xpath += fmt.Sprintf("[NETWORK='%s']", c.String("network")) } xpath += "/IP" ip, ok := vm.XPath(xpath) if ok == false { exitError("Unable to find IP.") } ssh_args := []string{ip, "-l", "root"} ssh_args = append(ssh_args, c.Args()[1:]...) if c.Bool("wait") { // add the wait args ssh_args = append(ssh_args, baseSSHArgs...) for r := 0; r < c.Int("retries"); r++ { if err = vm.Info(); err != nil { exitError(err.Error()) } vm_state, lcm_state, err := vm.StateString() if err != nil { exitError(err.Error()) } if strings.Contains(vm_state, "FAIL") || strings.Contains(lcm_state, "FAIL") { exitError("ssh not ready (vm failed).") } cmd := exec.Command("ssh", ssh_args...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err = cmd.Run(); err == nil { return } time.Sleep(interval * time.Second) } exitError("ssh not ready.") } else { ssh_path, err := exec.LookPath("ssh") if err != nil { exitError("ssh executable not found.") } fmt.Println("ssh", strings.Join(ssh_args, " ")) ssh_args = append([]string{ssh_path}, ssh_args...) env := os.Environ() err = syscall.Exec(ssh_path, ssh_args, env) if err != nil { panic(err) } } }