mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
testing a 2nd remote with mshell --server
This commit is contained in:
@@ -451,6 +451,11 @@ func main() {
|
||||
fmt.Printf("[error] ensuring local remote: %v\n", err)
|
||||
return
|
||||
}
|
||||
err = sstore.AddTest01Remote(context.Background())
|
||||
if err != nil {
|
||||
fmt.Printf("[error] ensuring test01 remote: %v\n", err)
|
||||
return
|
||||
}
|
||||
_, err = sstore.EnsureDefaultSession(context.Background())
|
||||
if err != nil {
|
||||
fmt.Printf("[error] ensuring default session: %v\n", err)
|
||||
|
||||
+21
-3
@@ -1,17 +1,28 @@
|
||||
CREATE TABLE schema_migrations (version uint64,dirty bool);
|
||||
CREATE UNIQUE INDEX version_unique ON schema_migrations (version);
|
||||
CREATE TABLE client (
|
||||
userid varchar(36) NOT NULL,
|
||||
userpublickeybytes blob NOT NULL,
|
||||
userprivatekeybytes blob NOT NULL
|
||||
);
|
||||
CREATE TABLE session (
|
||||
sessionid varchar(36) PRIMARY KEY,
|
||||
name varchar(50) NOT NULL,
|
||||
sessionidx int NOT NULL,
|
||||
activescreenid varchar(36) NOT NULL,
|
||||
notifynum int NOT NULL
|
||||
notifynum int NOT NULL,
|
||||
owneruserid varchar(36) NOT NULL,
|
||||
sharemode varchar(12) NOT NULL,
|
||||
accesskey varchar(36) NOT NULL
|
||||
);
|
||||
CREATE TABLE window (
|
||||
sessionid varchar(36) NOT NULL,
|
||||
windowid varchar(36) NOT NULL,
|
||||
curremote varchar(50) NOT NULL,
|
||||
winopts json NOT NULL,
|
||||
owneruserid varchar(36) NOT NULL,
|
||||
sharemode varchar(12) NOT NULL,
|
||||
shareopts json NOT NULL,
|
||||
PRIMARY KEY (sessionid, windowid)
|
||||
);
|
||||
CREATE TABLE screen (
|
||||
@@ -21,6 +32,8 @@ CREATE TABLE screen (
|
||||
activewindowid varchar(36) NOT NULL,
|
||||
screenidx int NOT NULL,
|
||||
screenopts json NOT NULL,
|
||||
owneruserid varchar(36) NOT NULL,
|
||||
sharemode varchar(12) NOT NULL,
|
||||
PRIMARY KEY (sessionid, screenid)
|
||||
);
|
||||
CREATE TABLE screen_window (
|
||||
@@ -43,7 +56,7 @@ CREATE TABLE remote_instance (
|
||||
CREATE TABLE line (
|
||||
sessionid varchar(36) NOT NULL,
|
||||
windowid varchar(36) NOT NULL,
|
||||
lineid int NOT NULL,
|
||||
lineid varchar(36) NOT NULL,
|
||||
userid varchar(36) NOT NULL,
|
||||
ts bigint NOT NULL,
|
||||
linetype varchar(10) NOT NULL,
|
||||
@@ -53,8 +66,13 @@ CREATE TABLE line (
|
||||
);
|
||||
CREATE TABLE remote (
|
||||
remoteid varchar(36) PRIMARY KEY,
|
||||
physicalid varchar(36) NOT NULL,
|
||||
remotetype varchar(10) NOT NULL,
|
||||
remotename varchar(50) NOT NULL,
|
||||
remotealias varchar(50) NOT NULL,
|
||||
remotecanonicalname varchar(200) NOT NULL,
|
||||
remotesudo boolean NOT NULL,
|
||||
remoteuser varchar(50) NOT NULL,
|
||||
remotehost varchar(200) NOT NULL,
|
||||
autoconnect boolean NOT NULL,
|
||||
initpk json NOT NULL,
|
||||
sshopts json NOT NULL,
|
||||
|
||||
@@ -88,6 +88,9 @@ func HandleCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor
|
||||
case "cd":
|
||||
return CdCommand(ctx, pk)
|
||||
|
||||
case "cr":
|
||||
return CrCommand(ctx, pk)
|
||||
|
||||
case "compgen":
|
||||
return CompGenCommand(ctx, pk)
|
||||
|
||||
@@ -189,8 +192,8 @@ func resolveScreenId(ctx context.Context, pk *scpacket.FeCommandPacketType, sess
|
||||
return resolveSessionScreen(ctx, sessionId, screenArg)
|
||||
}
|
||||
|
||||
func resolveRemote(ctx context.Context, pk *scpacket.FeCommandPacketType, sessionId string, windowId string) (string, string, *sstore.RemoteState, error) {
|
||||
remoteName := pk.Kwargs["remote"]
|
||||
// returns (remoteName, remoteId, state, err)
|
||||
func resolveRemote(ctx context.Context, remoteName string, sessionId string, windowId string) (string, string, *sstore.RemoteState, error) {
|
||||
if remoteName == "" {
|
||||
return "", "", nil, nil
|
||||
}
|
||||
@@ -242,7 +245,7 @@ func resolveIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype int
|
||||
}
|
||||
}
|
||||
if (rtype&R_Remote)+(rtype&R_RemoteOpt) > 0 {
|
||||
rtn.RemoteName, rtn.RemoteId, rtn.RemoteState, err = resolveRemote(ctx, pk, rtn.SessionId, rtn.WindowId)
|
||||
rtn.RemoteName, rtn.RemoteId, rtn.RemoteState, err = resolveRemote(ctx, pk.Kwargs["remote"], rtn.SessionId, rtn.WindowId)
|
||||
if err != nil {
|
||||
return rtn, err
|
||||
}
|
||||
@@ -332,6 +335,9 @@ func evalCommandInternal(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
if commandStr == "cd" || strings.HasPrefix(commandStr, "cd ") {
|
||||
metaCmd = "cd"
|
||||
commandStr = strings.TrimSpace(commandStr[2:])
|
||||
} else if commandStr == "cr" || strings.HasPrefix(commandStr, "cr ") {
|
||||
metaCmd = "cr"
|
||||
commandStr = strings.TrimSpace(commandStr[2:])
|
||||
} else if commandStr[0] == '/' {
|
||||
spaceIdx := strings.Index(commandStr, " ")
|
||||
if spaceIdx == -1 {
|
||||
@@ -419,14 +425,67 @@ func ScreenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveIds(ctx, pk, R_Session|R_Window)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/cr error: %w", err)
|
||||
}
|
||||
newRemote := firstArg(pk)
|
||||
if newRemote == "" {
|
||||
return nil, nil
|
||||
}
|
||||
remoteName, remoteId, _, err := resolveRemote(ctx, newRemote, ids.SessionId, ids.WindowId)
|
||||
fmt.Printf("found: name[%s] id[%s] err[%v]\n", remoteName, remoteId, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if remoteId == "" {
|
||||
return nil, fmt.Errorf("/cr error: remote not found")
|
||||
}
|
||||
err = sstore.UpdateCurRemote(ctx, ids.SessionId, ids.WindowId, remoteName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/cr error: cannot update curremote: %w", err)
|
||||
}
|
||||
update := sstore.WindowUpdate{
|
||||
Window: sstore.WindowType{
|
||||
SessionId: ids.SessionId,
|
||||
WindowId: ids.WindowId,
|
||||
CurRemote: remoteName,
|
||||
},
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoMsg: fmt.Sprintf("current remote = %s", remoteName),
|
||||
TimeoutMs: 2000,
|
||||
},
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func CdCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveIds(ctx, pk, R_Session|R_Window|R_Remote)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/cd error: %w", err)
|
||||
}
|
||||
newDir := firstArg(pk)
|
||||
curRemote := remote.GetRemoteById(ids.RemoteId)
|
||||
if curRemote == nil {
|
||||
return nil, fmt.Errorf("invalid remote, cannot change directory")
|
||||
}
|
||||
if !curRemote.IsConnected() {
|
||||
return nil, fmt.Errorf("remote is not connected, cannot change directory")
|
||||
}
|
||||
if newDir == "" {
|
||||
return nil, nil
|
||||
if ids.RemoteState == nil {
|
||||
return nil, fmt.Errorf("remote state is not available")
|
||||
}
|
||||
return sstore.InfoUpdate{
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoMsg: fmt.Sprintf("[%s] current directory = %s", ids.RemoteName, ids.RemoteState.Cwd),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
newDir, err = curRemote.ExpandHomeDir(newDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !strings.HasPrefix(newDir, "/") {
|
||||
if ids.RemoteState == nil {
|
||||
@@ -442,10 +501,6 @@ func CdCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up
|
||||
cdPacket := packet.MakeCdPacket()
|
||||
cdPacket.ReqId = uuid.New().String()
|
||||
cdPacket.Dir = newDir
|
||||
curRemote := remote.GetRemoteById(ids.RemoteId)
|
||||
if curRemote == nil {
|
||||
return nil, fmt.Errorf("invalid remote, cannot execute command")
|
||||
}
|
||||
resp, err := curRemote.PacketRpc(ctx, cdPacket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+45
-8
@@ -5,7 +5,8 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/scripthaus-dev/mshell/pkg/base"
|
||||
@@ -19,6 +20,17 @@ const DefaultTermRows = 25
|
||||
const DefaultTermCols = 80
|
||||
const DefaultTerm = "xterm-256color"
|
||||
|
||||
const MShellServerCommand = `
|
||||
PATH=$PATH:~/.mshell;
|
||||
which mshell > /dev/null;
|
||||
if [[ "$?" -ne 0 ]]
|
||||
then
|
||||
printf "\n##N{\"type\": \"init\", \"notfound\": true, \"uname\": \"%s | %s\"}\n" "$(uname -s)" "$(uname -m)"
|
||||
else
|
||||
mshell --server
|
||||
fi
|
||||
`
|
||||
|
||||
const (
|
||||
StatusInit = "init"
|
||||
StatusConnected = "connected"
|
||||
@@ -154,17 +166,23 @@ func MakeMShell(r *sstore.RemoteType) *MShellProc {
|
||||
return rtn
|
||||
}
|
||||
|
||||
func convertSSHOpts(opts *sstore.SSHOpts) shexec.SSHOpts {
|
||||
if opts == nil {
|
||||
return shexec.SSHOpts{}
|
||||
}
|
||||
return shexec.SSHOpts{
|
||||
SSHHost: opts.SSHHost,
|
||||
SSHOptsStr: opts.SSHOptsStr,
|
||||
SSHIdentity: opts.SSHIdentity,
|
||||
SSHUser: opts.SSHUser,
|
||||
}
|
||||
}
|
||||
|
||||
func (msh *MShellProc) Launch() {
|
||||
msh.Lock.Lock()
|
||||
defer msh.Lock.Unlock()
|
||||
|
||||
msPath, err := base.GetMShellPath()
|
||||
if err != nil {
|
||||
msh.Status = StatusError
|
||||
msh.Err = err
|
||||
return
|
||||
}
|
||||
ecmd := exec.Command(msPath, "--server")
|
||||
ecmd := convertSSHOpts(msh.Remote.SSHOpts).MakeSSHExecCmd(MShellServerCommand)
|
||||
cproc, err := shexec.MakeClientProc(ecmd)
|
||||
if err != nil {
|
||||
msh.Status = StatusError
|
||||
@@ -203,6 +221,25 @@ func (msh *MShellProc) GetDefaultState() *sstore.RemoteState {
|
||||
return &sstore.RemoteState{Cwd: msh.ServerProc.InitPk.HomeDir}
|
||||
}
|
||||
|
||||
func (msh *MShellProc) ExpandHomeDir(pathStr string) (string, error) {
|
||||
if pathStr != "~" && !strings.HasPrefix(pathStr, "~/") {
|
||||
return pathStr, nil
|
||||
}
|
||||
msh.Lock.Lock()
|
||||
defer msh.Lock.Unlock()
|
||||
if msh.ServerProc.InitPk == nil {
|
||||
return "", fmt.Errorf("remote not connected, does not have home directory set for ~ expansion")
|
||||
}
|
||||
homeDir := msh.ServerProc.InitPk.HomeDir
|
||||
if homeDir == "" {
|
||||
return "", fmt.Errorf("remote does not have HOME set, cannot do ~ expansion")
|
||||
}
|
||||
if pathStr == "~" {
|
||||
return homeDir, nil
|
||||
}
|
||||
return path.Join(homeDir, pathStr[2:]), nil
|
||||
}
|
||||
|
||||
func (msh *MShellProc) IsCmdRunning(ck base.CommandKey) bool {
|
||||
msh.Lock.Lock()
|
||||
defer msh.Lock.Unlock()
|
||||
|
||||
@@ -40,6 +40,20 @@ func GetAllRemotes(ctx context.Context) ([]*RemoteType, error) {
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func GetRemoteByAlias(ctx context.Context, alias string) (*RemoteType, error) {
|
||||
var remote *RemoteType
|
||||
err := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT * FROM remote WHERE remotealias = ?`
|
||||
m := tx.GetMap(query, alias)
|
||||
remote = RemoteFromMap(m)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return remote, nil
|
||||
}
|
||||
|
||||
func GetRemoteById(ctx context.Context, remoteId string) (*RemoteType, error) {
|
||||
var remote *RemoteType
|
||||
err := WithTx(ctx, func(tx *TxWrap) error {
|
||||
@@ -573,3 +587,16 @@ func UpdateRemoteCwd(ctx context.Context, rname string, sessionId string, window
|
||||
})
|
||||
return &ri, txErr
|
||||
}
|
||||
|
||||
func UpdateCurRemote(ctx context.Context, sessionId string, windowId string, remoteName string) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT windowid FROM window WHERE sessionid = ? AND windowid = ?`
|
||||
if !tx.Exists(query, sessionId, windowId) {
|
||||
return fmt.Errorf("cannot update curremote, no window found")
|
||||
}
|
||||
query = `UPDATE window SET curremote = ? WHERE sessionid = ? AND windowid = ?`
|
||||
tx.ExecWrap(query, remoteName, sessionId, windowId)
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
+37
-5
@@ -432,13 +432,13 @@ func AddCmdLine(ctx context.Context, sessionId string, windowId string, userId s
|
||||
}
|
||||
|
||||
func EnsureLocalRemote(ctx context.Context) error {
|
||||
remoteId, err := base.GetRemoteId()
|
||||
physicalId, err := base.GetRemoteId()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting local remoteid: %w", err)
|
||||
return fmt.Errorf("getting local physical remoteid: %w", err)
|
||||
}
|
||||
remote, err := GetRemoteById(ctx, remoteId)
|
||||
remote, err := GetRemoteByPhysicalId(ctx, physicalId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting remote[%s] from db: %w", remoteId, err)
|
||||
return fmt.Errorf("getting remote[%s] from db: %w", physicalId, err)
|
||||
}
|
||||
if remote != nil {
|
||||
return nil
|
||||
@@ -453,7 +453,8 @@ func EnsureLocalRemote(ctx context.Context) error {
|
||||
}
|
||||
// create the local remote
|
||||
localRemote := &RemoteType{
|
||||
RemoteId: remoteId,
|
||||
RemoteId: uuid.New().String(),
|
||||
PhysicalId: physicalId,
|
||||
RemoteType: "ssh",
|
||||
RemoteAlias: LocalRemoteName,
|
||||
RemoteCanonicalName: fmt.Sprintf("%s@%s", user.Username, hostName),
|
||||
@@ -470,6 +471,37 @@ func EnsureLocalRemote(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddTest01Remote(ctx context.Context) error {
|
||||
remote, err := GetRemoteByAlias(ctx, "test01")
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting remote[test01] from db: %w", err)
|
||||
}
|
||||
if remote != nil {
|
||||
return nil
|
||||
}
|
||||
testRemote := &RemoteType{
|
||||
RemoteId: uuid.New().String(),
|
||||
RemoteType: "ssh",
|
||||
RemoteAlias: "test01",
|
||||
RemoteCanonicalName: "ubuntu@test01.ec2",
|
||||
RemoteSudo: false,
|
||||
RemoteUser: "ubuntu",
|
||||
RemoteHost: "test01.ec2",
|
||||
SSHOpts: &SSHOpts{
|
||||
SSHHost: "test01.ec2",
|
||||
SSHUser: "ubuntu",
|
||||
SSHIdentity: "/Users/mike/aws/mfmt.pem",
|
||||
},
|
||||
AutoConnect: true,
|
||||
}
|
||||
err = InsertRemote(ctx, testRemote)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[db] added remote '%s', id=%s\n", testRemote.GetName(), testRemote.RemoteId)
|
||||
return nil
|
||||
}
|
||||
|
||||
func EnsureDefaultSession(ctx context.Context) (*SessionType, error) {
|
||||
session, err := GetSessionByName(ctx, DefaultSessionName)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,11 +16,6 @@ type UpdatePacket interface {
|
||||
UpdateType() string
|
||||
}
|
||||
|
||||
type UpdateCmd struct {
|
||||
CmdId string
|
||||
Status string
|
||||
}
|
||||
|
||||
type PtyDataUpdate struct {
|
||||
SessionId string `json:"sessionid"`
|
||||
CmdId string `json:"cmdid"`
|
||||
|
||||
Reference in New Issue
Block a user