Example #1
0
func (cmd) Execute(arguments map[string]interface{}) bool {
	URL := arguments["<URL>"].(string)
	command := arguments["<command>"].([]string)
	tty := isatty.IsTerminal(os.Stdout.Fd())

	// Parse URL
	u, err := url.Parse(URL)
	if err != nil {
		fmt.Println("Failed to parse URL, error: ", err)
		return false
	}
	qs := u.Query()

	// Set the command, if we have one
	if len(command) > 0 {
		qs["command"] = command
	}

	// Set tty=true if we're in a tty
	if tty {
		qs.Set("tty", "true")
	}

	// Update query string
	u.RawQuery = qs.Encode()

	// Connect to remove websocket
	ws, res, err := dialer.Dial(u.String(), nil)
	if err == websocket.ErrBadHandshake {
		fmt.Println("Failed to connect, status: ", res.StatusCode)
		return false
	}
	if err != nil {
		fmt.Println("Failed to connect, error: ", err)
		return false
	}

	// Create shell client
	shell := shellclient.New(ws)

	// Switch terminal to raw mode
	cleanup := func() {}
	if tty {
		cleanup = SetupRawTerminal(shell.SetSize)
	}

	// Connect pipes
	go ioext.CopyAndClose(shell.StdinPipe(), os.Stdin)
	go io.Copy(os.Stdout, shell.StdoutPipe())
	go io.Copy(os.Stderr, shell.StderrPipe())

	// Wait for shell to be done
	success, _ := shell.Wait()

	// If we were in a tty we let's restore state
	cleanup()

	return success
}
// ExecShell will send an action to guest-tools to execute a shell, then wait
// for guest-tools to callback establish a websocket and connect to an
// implementation of engines.Shell
func (s *MetaService) ExecShell(command []string, tty bool) (engines.Shell, error) {
	var Shell engines.Shell
	var Err error
	Err = engines.ErrNonFatalInternalError

	s.asyncRequest(Action{
		Type:    "exec-shell",
		Command: command,
		TTY:     tty,
	}, func(w http.ResponseWriter, r *http.Request) {
		ws, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			debug("Failed to upgrade request to websocket, error: %s", err)
			Err = engines.ErrNonFatalInternalError
			return
		}

		Shell = shellclient.New(ws)
		Err = nil
	})

	return Shell, Err
}