func (this *Scp) copy(size int64, mode os.FileMode, fileName string, contents io.Reader, destination string) error { var ( session *ssh.Session err error ) ParallelController[this.Server].Session <- token session, err = this.client.NewSession() if nil != err { return errors.New("Failed to create new session" + err.Error()) } go func() { w, _ := session.StdinPipe() defer w.Close() fmt.Fprintf(w, "C%#o %d %s\n", mode, size, fileName) io.Copy(w, contents) fmt.Fprint(w, "\x00") <-ParallelController[this.Server].Session }() cmd := fmt.Sprintf("scp -t %s", destination) if err := session.Run(cmd); nil != err { return err } session.Close() return nil }
func (ssc *SSHConfig) Exec(cmd string, stdout, stderr io.Writer, input chan string) (err tree_lib.TreeError) { var ( session *ssh.Session stdin io.WriteCloser command_ended bool ) err.From = tree_lib.FROM_SSH_EXEC session, err.Err = ssc.conn.NewSession() if !err.IsNull() { return } defer session.Close() session.Stdout = stdout session.Stderr = stderr stdin, err.Err = session.StdinPipe() if !err.IsNull() { return } err.Err = session.Start(cmd) if !err.IsNull() { return } command_ended = false go func() { for !command_ended { io.Copy(stdin, bytes.NewBufferString(<-input)) } }() err.Err = session.Wait() command_ended = true return }
func (c *command) Run(arg ...string) ([][]string, error) { var err error var cmd waitable var session *ssh.Session joinedArgs := strings.Join(arg, " ") c.Path = c.Command + " " + joinedArgs c.Env = []string{"LC_CTYPE=C", "LANG=en_US.UTF-8"} id := uuid.New() logger.Log([]string{"ID:" + id, "START", c.Path}) if c.zh.Local { lcmd := c.LocalPrepare(arg...) err = lcmd.Start() cmd = lcmd } else { err, session = c.StartCommand() if session != nil { defer func() { session.Close() }() } cmd = session } logger.Log([]string{"ID:" + id, "DONE"}) if err != nil { return nil, &Error{ Err: err, Debug: strings.Join([]string{c.Command, joinedArgs}, " "), Stderr: c.stderr.String(), } } if err = cmd.Wait(); err != nil { return nil, &Error{ Err: err, Stderr: c.stderr.String(), Debug: strings.Join([]string{c.Command, joinedArgs}, " "), } } // assume if you passed in something for stdout, that you know what to do with it if c.Stdout != nil { return nil, nil } lines := strings.Split(c.stdout.String(), "\n") //last line is always blank lines = lines[0 : len(lines)-1] output := make([][]string, len(lines)) for i, l := range lines { output[i] = strings.Fields(l) } return output, err }
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result execResult) { result.Servername = c.ServerName result.Host = c.Host result.Port = c.Port var client *ssh.Client var err error if client, err = sshConnect(c); err != nil { result.Error = err result.ExitStatus = 999 return } defer client.Close() var session *ssh.Session if session, err = client.NewSession(); err != nil { result.Error = fmt.Errorf( "Failed to create a new session. servername: %s, err: %s", c.ServerName, err) result.ExitStatus = 999 return } defer session.Close() // http://blog.ralch.com/tutorial/golang-ssh-connection/ modes := ssh.TerminalModes{ ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err = session.RequestPty("xterm", 400, 256, modes); err != nil { result.Error = fmt.Errorf( "Failed to request for pseudo terminal. servername: %s, err: %s", c.ServerName, err) result.ExitStatus = 999 return } var stdoutBuf, stderrBuf bytes.Buffer session.Stdout = &stdoutBuf session.Stderr = &stderrBuf cmd = decolateCmd(c, cmd, sudo) if err := session.Run(cmd); err != nil { if exitErr, ok := err.(*ssh.ExitError); ok { result.ExitStatus = exitErr.ExitStatus() } else { result.ExitStatus = 999 } } else { result.ExitStatus = 0 } result.Stdout = stdoutBuf.String() result.Stderr = stderrBuf.String() result.Cmd = strings.Replace(cmd, "\n", "", -1) return }
// RunCommand runs a shell command in a vagrant node and returns it's exit status func (n *VagrantNode) RunCommand(cmd string) error { var ( s *ssh.Session err error ) if s, err = n.client.NewSession(); err != nil { return err } defer s.Close() return s.Run(newCmdStrWithSource(cmd)) }
// RunCommandWithOutput runs a shell command in a vagrant node and returns it's // exit status and output func (n *VagrantNode) RunCommandWithOutput(cmd string) (string, error) { var ( s *ssh.Session err error ) if s, err = n.client.NewSession(); err != nil { return "", err } defer s.Close() output, err := s.CombinedOutput(newCmdStrWithSource(cmd)) return string(output), err }
func (client *SSHClient) RunCommand(cmd *SSHCommand) (error, interface{}) { rescueStdout := os.Stdout r, w, _ := os.Pipe() cmd.Stdout = w var ( session *ssh.Session err error ) fmt.Println("Session creation") if session, err = client.newSession(); err != nil { fmt.Println("Session creation err", err) return err, nil } defer session.Close() if err = client.prepareCommand(session, cmd); err != nil { return err, nil } fmt.Println("Session run", cmd.Path) if err = session.Run(cmd.Path); err != nil { fmt.Println("Session run err", err) return err, nil } print(cmd.Stdout) w.Close() out, _ := ioutil.ReadAll(r) os.Stdout = rescueStdout if strings.Contains(cmd.Path, "providerLib") { s1 := string([]byte(out)) return err, s1 } else if strings.Contains(cmd.Path, "build") { fmt.Printf("-->%s<--", string([]byte(out))) s1 := string([]byte(out)) return err, s1 } defer w.Close() defer r.Close() return err, nil }
func (client *SSHClient) RunCommandAndWait(cmd *SSHCommand) ([]byte, error) { var ( session *ssh.Session err error baData []byte ) if session, err = client.newSession(); err != nil { return nil, err } defer session.Close() baData, err = session.Output(cmd.Path) return baData, err }
func copy(size int64, mode os.FileMode, fileName string, contents io.Reader, destination string, session *ssh.Session) error { defer session.Close() go func() { w, _ := session.StdinPipe() defer w.Close() fmt.Fprintf(w, "C%#o %d %s\n", mode, size, fileName) io.Copy(w, contents) fmt.Fprint(w, "\x00") }() cmd := fmt.Sprintf("scp -t %s", destination) if err := session.Run(cmd); err != nil { return err } return nil }
func (client *clientSSH) runCommand(cmd *sshCommand) ([]byte, error) { var session *ssh.Session var err error if session, err = client.newSession(); err != nil { return []byte{}, err } defer session.Close() if err = client.prepareCommand(session, cmd); err != nil { return []byte{}, err } return session.CombinedOutput(cmd.command) }
// RunCommandBackground runs a background command in a vagrant node func (n *VagrantNode) RunCommandBackground(cmd string) (string, error) { var ( s *ssh.Session err error ) if s, err = n.client.NewSession(); err != nil { return "", err } defer s.Close() // start and forget about the command as user asked to run in background. // The limitation is we/ won't know if it fails though. Not a worry right // now as the test will fail anyways, but might be good to find a better way. return "", s.Start(newCmdStrWithSource(cmd)) }
// RunCommand runs a shell command in a vagrant node and returns it's exit status func (n *VagrantNode) RunCommand(cmd string) error { var ( s *ssh.Session err error ) if s, err = n.client.NewSession(); err != nil { return err } defer s.Close() if err := s.RequestPty("vt100", 80, 25, ssh.TerminalModes{}); err != nil { fmt.Println(err) return err } return s.Run(newCmdStrWithSource(cmd)) }
func (client *SSHClient) RunCommand(cmd *SSHCommand) error { var ( session *ssh.Session err error ) if session, err = client.newSession(); err != nil { return err } defer session.Close() if err = client.prepareCommand(session, cmd); err != nil { return err } err = session.Run(cmd.Path) return err }
func writeFileToHost(session *ssh.Session, host *Host, file string, fileReader *os.File, fileInfo os.FileInfo, destination string, sessionWaitGroup *sync.WaitGroup) { defer sessionWaitGroup.Done() defer session.Close() sessionWaitGroup.Add(1) go func() { defer sessionWaitGroup.Done() mode := uint32(fileInfo.Mode().Perm()) header := fmt.Sprintf("C%04o %d %s\n", mode, fileInfo.Size(), filepath.Base(file)) OutputLocal(fmt.Sprintf("copy %s (%dMB) to %s:%s", file, fileInfo.Size()/1024/2014, host.Host, destination)) stdinPipe, _ := session.StdinPipe() defer stdinPipe.Close() _, err := stdinPipe.Write([]byte(header)) if err != nil { return } _, err = io.Copy(stdinPipe, fileReader) if err != nil { return } _, err = stdinPipe.Write([]byte{0}) if err != nil { return } }() if err := session.Run("/usr/bin/scp -trv " + destination); err != nil { fmt.Println("in here") fmt.Println(err.Error()) os.Exit(1) } }
func stream(command string, session *ssh.Session) (output chan string, done chan bool, err error) { outReader, err := session.StdoutPipe() Ω(err).ShouldNot(HaveOccurred()) errReader, err := session.StderrPipe() Ω(err).ShouldNot(HaveOccurred()) outputReader := io.MultiReader(outReader, errReader) err = session.Start(command) Ω(err).ShouldNot(HaveOccurred()) scanner := bufio.NewScanner(outputReader) outputChan := make(chan string) done = make(chan bool) go func(scanner *bufio.Scanner, out chan string, done chan bool) { defer close(outputChan) defer close(done) for scanner.Scan() { outputChan <- scanner.Text() } done <- true session.Close() }(scanner, outputChan, done) return outputChan, done, err }
func (s *BotClientT) Start(botId string, botInstance int, cmdline string, cfg *ConfigT, debugLevel int) error { var err error var sshclient *ssh.Client var session *ssh.Session // var wg sync.WaitGroup var cmd string if s.Host[botInstance].Status == BotStatPaused { return nil } if s.Host[botInstance].Status == BotStatRunning { err = s.PingAt(botId, botInstance, cfg) if err == nil { Goose.Ping.Logf(2, "bot %s@%s is alive", botId, s.Host[botInstance].Name) return nil } } Goose.StartStop.Logf(2, "Starting bot %s@%s", botId, s.Host[botInstance].Name) s.Host[botInstance].Status = BotStatUnreachable if s.Host[botInstance].OnStatUpdate != nil { s.Host[botInstance].OnStatUpdate(BotStatUnreachable) } cfg.SshClientConfig.User = s.SysUser sshclient, err = ssh.Dial("tcp", s.Host[botInstance].Name+":22", cfg.SshClientConfig) if err != nil { Goose.StartStop.Logf(1, "%s (%s)", ErrDialingToBot, err) return ErrDialingToBot } defer sshclient.Close() Goose.StartStop.Logf(3, "Dialed to bot %s@%s", botId, s.Host[botInstance].Name) session, err = sshclient.NewSession() if err != nil { Goose.StartStop.Logf(1, "%s (%s)", ErrCreatingSession, err) return ErrCreatingSession } defer session.Close() Goose.StartStop.Logf(3, "Session started at bot %s@%s", botId, s.Host[botInstance].Name) /* wg.Add(1) go func() { defer wg.Done() w, _ := session.StdinPipe() defer w.Close() Goose.StartStop.Logf(2,"Closing stdin for bot %s",botId) //fmt.Fprintf(w, "%s\n", config) }() */ /* // Set up terminal modes modes := ssh.TerminalModes{ ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } // Request pseudo terminal if err := session.RequestPty("xterm", 80, 40, modes); err != nil { Goose.StartStop.Fatalf(1,"request for pseudo terminal failed: %s", err) } session.Stdout = &bytes.Buffer{} session.Stderr = &bytes.Buffer{} */ cmd = fmt.Sprintf("%s%c%s -v %d %s", s.BinDir, os.PathSeparator, s.BinName, debugLevel, cmdline) Goose.StartStop.Logf(3, "Will run %s@%s using %s", botId, s.Host[botInstance].Name, cmd) err = session.Start(cmd) // err = session.Run(cmd) Goose.StartStop.Logf(2, "Running bot %s", botId) // wg.Wait() if err != nil { session.Signal(ssh.SIGKILL) Goose.StartStop.Logf(1, "%s (%s)", ErrFailedStartingBot, err) return ErrFailedStartingBot } Goose.StartStop.Logf(2, "Started bot %s with cmd:[%s]", botId, cmd) s.Host[botInstance].Status = BotStatRunning if s.Host[botInstance].OnStatUpdate != nil { s.Host[botInstance].OnStatUpdate(BotStatRunning) } return nil }
func runPipe(user, pass, host, cmd string) { fmt.Println("runPipe...") sshConfig := &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ssh.Password(pass)}, } sshConfig.SetDefaults() client, err := ssh.Dial("tcp", host, sshConfig) if err != nil { // errors.Wrap(err, err.Error()) fmt.Println(err.Error()) } var session *ssh.Session session, err = client.NewSession() if err != nil { // errors.Wrap(err, err.Error()) fmt.Println(err.Error()) } defer session.Close() // modes := ssh.TerminalModes{ // ssh.ECHO: 0, // disable echoing // ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud // ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud // } // if err := session.RequestPty("xterm", 80, 40, modes); err != nil { // log.Fatal(err) // } w, err := session.StdinPipe() if err != nil { panic(err) } // r, err := session.StdoutPipe() // if err != nil { // panic(err) // } var stdoutBuf bytes.Buffer session.Stdout = &stdoutBuf // session.Run(cmd) err = session.Shell() w.Write([]byte(fmt.Sprintf("%s\n", "configure"))) w.Write([]byte(fmt.Sprintf("%s %s\n", "set interfaces ethernet eth4 description", cmd))) w.Write([]byte(fmt.Sprintf("%s\n", "commit"))) w.Write([]byte(fmt.Sprintf("%s\n", "save"))) w.Write([]byte(fmt.Sprintf("%s\n", "exit"))) w.Write([]byte(fmt.Sprintf("%s\n", "exit"))) fmt.Println(stdoutBuf.String()) }
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result sshResult) { logger := getSSHLogger(log...) cmd = decolateCmd(c, cmd, sudo) logger.Debugf("Command: %s", strings.Replace(maskPassword(cmd, c.Password), "\n", "", -1)) var client *ssh.Client var err error client, err = sshConnect(c) defer client.Close() var session *ssh.Session if session, err = client.NewSession(); err != nil { logger.Errorf("Failed to new session. err: %s, c: %s", err, pp.Sprintf("%v", c)) result.ExitStatus = 999 return } defer session.Close() // http://blog.ralch.com/tutorial/golang-ssh-connection/ modes := ssh.TerminalModes{ ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err = session.RequestPty("xterm", 400, 256, modes); err != nil { logger.Errorf("Failed to request for pseudo terminal. err: %s, c: %s", err, pp.Sprintf("%v", c)) result.ExitStatus = 999 return } var stdoutBuf, stderrBuf bytes.Buffer session.Stdout = &stdoutBuf session.Stderr = &stderrBuf if err := session.Run(cmd); err != nil { if exitErr, ok := err.(*ssh.ExitError); ok { result.ExitStatus = exitErr.ExitStatus() } else { result.ExitStatus = 999 } } else { result.ExitStatus = 0 } result.Stdout = stdoutBuf.String() result.Stderr = stderrBuf.String() result.Host = c.Host result.Port = c.Port logger.Debugf( "SSH executed. cmd: %s, err: %#v, status: %d\nstdout: \n%s\nstderr: \n%s", maskPassword(cmd, c.Password), err, result.ExitStatus, result.Stdout, result.Stderr) return }
func runToHost(user, pass, host, cmd string) { sshConfig := &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ssh.Password(pass)}, } sshConfig.SetDefaults() client, err := ssh.Dial("tcp", host, sshConfig) if err != nil { // errors.Wrap(err, err.Error()) fmt.Println(err.Error()) } var session *ssh.Session session, err = client.NewSession() if err != nil { // errors.Wrap(err, err.Error()) fmt.Println(err.Error()) } defer session.Close() var stdoutBuf bytes.Buffer session.Stdout = &stdoutBuf session.Run(cmd) fmt.Println(stdoutBuf.String()) }