mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-31 18:18:02 +01:00
pass uname back when mshell isn't found, parse, and give install command
This commit is contained in:
parent
ec4bd5eaa1
commit
26479f59c0
@ -320,6 +320,10 @@ func parseClientOpts() (*shexec.ClientOpts, error) {
|
||||
opts.Cwd = iter.Next()
|
||||
continue
|
||||
}
|
||||
if argStr == "--detach" {
|
||||
opts.Detach = true
|
||||
continue
|
||||
}
|
||||
if argStr == "--debug" {
|
||||
opts.Debug = true
|
||||
continue
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
"github.com/scripthaus-dev/mshell/pkg/packet"
|
||||
)
|
||||
|
||||
const ReadBufSize = 32 * 1024
|
||||
const WriteBufSize = 32 * 1024
|
||||
const ReadBufSize = 128 * 1024
|
||||
const WriteBufSize = 128 * 1024
|
||||
const MaxSingleWriteSize = 4 * 1024
|
||||
|
||||
type Multiplexer struct {
|
||||
|
@ -341,6 +341,7 @@ type InitPacketType struct {
|
||||
Env []string `json:"env,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
NotFound bool `json:"notfound,omitempty"`
|
||||
UName string `json:"uname,omitempty"`
|
||||
}
|
||||
|
||||
func (*InitPacketType) GetType() string {
|
||||
|
@ -76,10 +76,13 @@ func MakePacketParser(input io.Reader) *PacketParser {
|
||||
parser.MainCh <- MakeRawPacket(line[:len(line)-1])
|
||||
continue
|
||||
}
|
||||
packetLen, err := strconv.Atoi(line[2:bracePos])
|
||||
if err != nil || packetLen != len(line)-bracePos-1 {
|
||||
parser.MainCh <- MakeRawPacket(line[:len(line)-1])
|
||||
continue
|
||||
packetLen := -1
|
||||
if line[2:bracePos] != "N" {
|
||||
packetLen, err = strconv.Atoi(line[2:bracePos])
|
||||
if err != nil || packetLen != len(line)-bracePos-1 {
|
||||
parser.MainCh <- MakeRawPacket(line[:len(line)-1])
|
||||
continue
|
||||
}
|
||||
}
|
||||
pk, err := ParseJsonPacket([]byte(line[bracePos:]))
|
||||
if err != nil {
|
||||
|
@ -32,10 +32,10 @@ const FirstExtraFilesFdNum = 3
|
||||
|
||||
const ClientCommand = `
|
||||
PATH=$PATH:~/.mshell;
|
||||
which mshell > /dev/null;
|
||||
which mshell2 > /dev/null;
|
||||
if [[ "$?" -ne 0 ]]
|
||||
then
|
||||
printf "\n##34{\"type\": \"init\", \"notfound\": true}\n"
|
||||
printf "\n##N{\"type\": \"init\", \"notfound\": true, \"uname\": \"%s | %s\"}\n" "$(uname -s)" "$(uname -m)"
|
||||
else
|
||||
mshell --single
|
||||
fi
|
||||
@ -175,6 +175,19 @@ func ValidateRunPacket(pk *packet.RunPacketType) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rfd := range pk.Fds {
|
||||
if rfd.Write {
|
||||
return fmt.Errorf("cannot detach command with writable remote files fd=%d", rfd.FdNum)
|
||||
}
|
||||
if rfd.Read {
|
||||
if rfd.Content == "" {
|
||||
return fmt.Errorf("cannot detach command with readable remote files fd=%d", rfd.FdNum)
|
||||
}
|
||||
if len(rfd.Content) > mpio.ReadBufSize {
|
||||
return fmt.Errorf("cannot detach command, constant readable input too large fd=%d, len=%d, max=%d", rfd.FdNum, len(rfd.Content), mpio.ReadBufSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if pk.Cwd != "" {
|
||||
realCwd := base.ExpandHomeDir(pk.Cwd)
|
||||
@ -227,6 +240,7 @@ type ClientOpts struct {
|
||||
SudoWithPass bool
|
||||
SudoPw string
|
||||
CommandStdinFdNum int
|
||||
Detach bool
|
||||
}
|
||||
|
||||
func (opts *ClientOpts) MakeExecCmd() *exec.Cmd {
|
||||
@ -251,8 +265,30 @@ func (opts *ClientOpts) MakeExecCmd() *exec.Cmd {
|
||||
}
|
||||
}
|
||||
|
||||
func (opts *ClientOpts) MakeInstallCommandString(goos string, goarch string) string {
|
||||
var moreSSHOpts []string
|
||||
if opts.SSHIdentity != "" {
|
||||
identityOpt := fmt.Sprintf("-i %s", shellescape.Quote(opts.SSHIdentity))
|
||||
moreSSHOpts = append(moreSSHOpts, identityOpt)
|
||||
}
|
||||
if opts.SSHUser != "" {
|
||||
userOpt := fmt.Sprintf("-l %s", shellescape.Quote(opts.SSHUser))
|
||||
moreSSHOpts = append(moreSSHOpts, userOpt)
|
||||
}
|
||||
if opts.SSHOptsStr != "" {
|
||||
optsOpt := fmt.Sprintf("--ssh-opts %s", shellescape.Quote(opts.SSHOptsStr))
|
||||
moreSSHOpts = append(moreSSHOpts, optsOpt)
|
||||
}
|
||||
if opts.SSHHost != "" {
|
||||
sshArg := fmt.Sprintf("--ssh %s", shellescape.Quote(opts.SSHHost))
|
||||
moreSSHOpts = append(moreSSHOpts, sshArg)
|
||||
}
|
||||
return fmt.Sprintf("mshell --install %s %s_%s", strings.Join(moreSSHOpts, " "), goos, goarch)
|
||||
}
|
||||
|
||||
func (opts *ClientOpts) MakeRunPacket() (*packet.RunPacketType, error) {
|
||||
runPacket := packet.MakeRunPacket()
|
||||
runPacket.Detached = opts.Detach
|
||||
runPacket.Cwd = opts.Cwd
|
||||
runPacket.Fds = opts.Fds
|
||||
if !opts.Sudo {
|
||||
@ -417,7 +453,16 @@ func RunClientSSHCommandAndWait(opts *ClientOpts) (*packet.CmdDonePacketType, er
|
||||
if pk.GetType() == packet.InitPacketStr {
|
||||
initPk := pk.(*packet.InitPacketType)
|
||||
if initPk.NotFound {
|
||||
return nil, fmt.Errorf("mshell command not found on remote server, can install with 'mshell --install'")
|
||||
fmt.Printf("UNAME> %s\n", initPk.UName)
|
||||
if initPk.UName == "" {
|
||||
return nil, fmt.Errorf("mshell command not found on remote server, no uname detected")
|
||||
}
|
||||
goos, goarch, err := UNameStringToGoArch(initPk.UName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mshell command not found on remote server, architecture cannot be detected (might be incompatible with mshell): %w", err)
|
||||
}
|
||||
installCmd := opts.MakeInstallCommandString(goos, goarch)
|
||||
return nil, fmt.Errorf("mshell command not found on remote server, can install with '%s'", installCmd)
|
||||
}
|
||||
if initPk.Version != "0.1.0" {
|
||||
return nil, fmt.Errorf("invalid remote mshell version 'v%s', must be v0.1.0", initPk.Version)
|
||||
@ -444,6 +489,29 @@ func RunClientSSHCommandAndWait(opts *ClientOpts) (*packet.CmdDonePacketType, er
|
||||
return donePacket, nil
|
||||
}
|
||||
|
||||
func UNameStringToGoArch(uname string) (string, string, error) {
|
||||
fields := strings.SplitN(uname, "|", 2)
|
||||
if len(fields) != 2 {
|
||||
return "", "", fmt.Errorf("invalid uname string returned")
|
||||
}
|
||||
osVal := strings.TrimSpace(strings.ToLower(fields[0]))
|
||||
archVal := strings.TrimSpace(strings.ToLower(fields[1]))
|
||||
if osVal != "darwin" && osVal != "linux" {
|
||||
return "", "", fmt.Errorf("invalid uname OS '%s', mshell only supports OS X (darwin) and linux", osVal)
|
||||
}
|
||||
goos := osVal
|
||||
goarch := ""
|
||||
if archVal == "x86_64" || archVal == "i686" || archVal == "amd64" {
|
||||
goarch = "amd64"
|
||||
} else if archVal == "aarch64" || archVal == "amd64" {
|
||||
goarch = "arm64"
|
||||
}
|
||||
if goarch == "" {
|
||||
return "", "", fmt.Errorf("invalid uname machine type '%s', mshell only supports aarch64 (amd64) and x86_64 (amd64)", archVal)
|
||||
}
|
||||
return goos, goarch, nil
|
||||
}
|
||||
|
||||
func (cmd *ShExecType) RunRemoteIOAndWait(packetParser *packet.PacketParser, sender *packet.PacketSender) {
|
||||
defer cmd.Close()
|
||||
cmd.Multiplexer.RunIOAndWait(packetParser, sender, true, false, false)
|
||||
|
Loading…
Reference in New Issue
Block a user