mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-10 07:58:41 +08:00
166 lines
3.2 KiB
Go
166 lines
3.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
// GetScriptExt return script extension default bash
|
|
func GetScriptExt(scriptMode string) string {
|
|
switch scriptMode {
|
|
case "sh", "zsh", "bash":
|
|
return "sh"
|
|
case "php":
|
|
return "php"
|
|
case "python":
|
|
return "py"
|
|
default:
|
|
return "sh"
|
|
}
|
|
}
|
|
|
|
// ParseCommandLine parse cmd arg
|
|
func ParseCommandLine(command string) ([]string, error) {
|
|
var args []string
|
|
state := "start"
|
|
current := ""
|
|
quote := "\""
|
|
escapeNext := true
|
|
for i := 0; i < len(command); i++ {
|
|
c := command[i]
|
|
|
|
if state == "quotes" {
|
|
if string(c) != quote {
|
|
current += string(c)
|
|
} else {
|
|
args = append(args, current)
|
|
current = ""
|
|
state = "start"
|
|
}
|
|
continue
|
|
}
|
|
|
|
if escapeNext {
|
|
current += string(c)
|
|
escapeNext = false
|
|
continue
|
|
}
|
|
|
|
if c == '\\' {
|
|
escapeNext = true
|
|
continue
|
|
}
|
|
|
|
if c == '"' || c == '\'' {
|
|
state = "quotes"
|
|
quote = string(c)
|
|
continue
|
|
}
|
|
|
|
if state == "arg" {
|
|
if c == ' ' || c == '=' || c == '\t' {
|
|
args = append(args, current)
|
|
current = ""
|
|
state = "start"
|
|
} else {
|
|
current += string(c)
|
|
}
|
|
continue
|
|
}
|
|
|
|
if c != ' ' && c != '=' && c != '\t' {
|
|
state = "arg"
|
|
current += string(c)
|
|
}
|
|
}
|
|
|
|
if state == "quotes" {
|
|
return []string{}, fmt.Errorf("unclosed quote in command line: %s", command)
|
|
}
|
|
|
|
if current != "" {
|
|
args = append(args, current)
|
|
}
|
|
|
|
return args, nil
|
|
}
|
|
|
|
// ConnectSSH connect ssh
|
|
func ConnectSSH(user, password, host string, port int) (*ssh.Session, error) {
|
|
var (
|
|
auth []ssh.AuthMethod
|
|
addr string
|
|
clientConfig *ssh.ClientConfig
|
|
client *ssh.Client
|
|
config ssh.Config
|
|
session *ssh.Session
|
|
err error
|
|
)
|
|
// get auth method
|
|
auth = make([]ssh.AuthMethod, 0)
|
|
|
|
pemBytes, err := ioutil.ReadFile(os.Getenv("SSHKEY_PATH"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var signer ssh.Signer
|
|
if password == "" {
|
|
signer, err = ssh.ParsePrivateKey(pemBytes)
|
|
} else {
|
|
signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password))
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
auth = append(auth, ssh.PublicKeys(signer))
|
|
|
|
config = ssh.Config{
|
|
Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
|
|
}
|
|
|
|
clientConfig = &ssh.ClientConfig{
|
|
User: user,
|
|
Auth: auth,
|
|
Timeout: 30 * time.Second,
|
|
Config: config,
|
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// connect to ssh
|
|
addr = fmt.Sprintf("%s:%d", host, port)
|
|
|
|
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// create session
|
|
if session, err = client.NewSession(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
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 {
|
|
return nil, err
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func ClearNewline(str string) string {
|
|
return strings.TrimRight(strings.Replace(str, "\r\n", "\n", -1), "\n")
|
|
}
|