checkpoint, working on autoinstall, semantic versioning, remoteshowall

This commit is contained in:
sawka
2022-09-24 19:54:06 -07:00
parent eb00fde596
commit 982d600d9b
7 changed files with 74 additions and 2 deletions
+1
View File
@@ -88,6 +88,7 @@ CREATE TABLE remote (
remoteuser varchar(50) NOT NULL, remoteuser varchar(50) NOT NULL,
remotehost varchar(200) NOT NULL, remotehost varchar(200) NOT NULL,
connectmode varchar(20) NOT NULL, connectmode varchar(20) NOT NULL,
autoinstall boolean NOT NULL,
initpk json NOT NULL, initpk json NOT NULL,
sshopts json NOT NULL, sshopts json NOT NULL,
remoteopts json NOT NULL, remoteopts json NOT NULL,
+1
View File
@@ -21,6 +21,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect
go.uber.org/atomic v1.7.0 // indirect go.uber.org/atomic v1.7.0 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
mvdan.cc/sh/v3 v3.5.1 // indirect mvdan.cc/sh/v3 v3.5.1 // indirect
) )
+2
View File
@@ -1192,6 +1192,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+45 -2
View File
@@ -575,8 +575,8 @@ func RemoteShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
} }
return sstore.ModelUpdate{ return sstore.ModelUpdate{
Info: &sstore.InfoMsgType{ Info: &sstore.InfoMsgType{
InfoTitle: fmt.Sprintf("show all remote info"), InfoTitle: fmt.Sprintf("show all remote info"),
InfoLines: splitLinesForInfo(buf.String()), RemoteShowAll: true,
}, },
}, nil }, nil
} }
@@ -1322,3 +1322,46 @@ func formatTermOpts(termOpts sstore.TermOpts) string {
} }
return rtnStr return rtnStr
} }
type ColMeta struct {
Title string
MinCols int
MaxCols int
}
func toInterfaceArr(sarr []string) []interface{} {
rtn := make([]interface{}, len(sarr))
for idx, s := range sarr {
rtn[idx] = s
}
return rtn
}
func formatTextTable(totalCols int, data [][]string, colMeta []ColMeta) []string {
numCols := len(colMeta)
maxColLen := make([]int, len(colMeta))
for i, cm := range colMeta {
maxColLen[i] = cm.MinCols
}
for _, row := range data {
for i := 0; i < numCols && i < len(row); i++ {
dlen := len(row[i])
if dlen > maxColLen[i] {
maxColLen[i] = dlen
}
}
}
fmtStr := ""
for idx, clen := range maxColLen {
if idx != 0 {
fmtStr += " "
}
fmtStr += fmt.Sprintf("%%%ds", clen)
}
var rtn []string
for _, row := range data {
sval := fmt.Sprintf(fmtStr, toInterfaceArr(row)...)
rtn = append(rtn, sval)
}
return rtn
}
+21
View File
@@ -24,6 +24,7 @@ import (
"github.com/scripthaus-dev/mshell/pkg/shexec" "github.com/scripthaus-dev/mshell/pkg/shexec"
"github.com/scripthaus-dev/sh2-server/pkg/scpacket" "github.com/scripthaus-dev/sh2-server/pkg/scpacket"
"github.com/scripthaus-dev/sh2-server/pkg/sstore" "github.com/scripthaus-dev/sh2-server/pkg/sstore"
"golang.org/x/mod/semver"
) )
const RemoteTypeMShell = "mshell" const RemoteTypeMShell = "mshell"
@@ -34,6 +35,9 @@ const RemoteTermRows = 8
const RemoteTermCols = 80 const RemoteTermCols = 80
const PtyReadBufSize = 100 const PtyReadBufSize = 100
const MShellVersion = "v0.1.0"
const MShellVersionConstraint = "^0.1"
const MShellServerCommand = ` const MShellServerCommand = `
PATH=$PATH:~/.mshell; PATH=$PATH:~/.mshell;
which mshell > /dev/null; which mshell > /dev/null;
@@ -53,6 +57,12 @@ const (
StatusError = "error" StatusError = "error"
) )
func init() {
if MShellVersion != base.MShellVersion {
panic(fmt.Sprintf("sh2-server mshell version must match '%s' vs '%s'", MShellVersion, base.MShellVersion))
}
}
var GlobalStore *Store var GlobalStore *Store
type Store struct { type Store struct {
@@ -73,6 +83,7 @@ type MShellProc struct {
ControllingPty *os.File ControllingPty *os.File
PtyBuffer *circbuf.Buffer PtyBuffer *circbuf.Buffer
MakeClientCancelFn context.CancelFunc MakeClientCancelFn context.CancelFunc
NeedsMShellUpgrade bool
RunningCmds []base.CommandKey RunningCmds []base.CommandKey
} }
@@ -88,6 +99,7 @@ type RemoteRuntimeState struct {
ErrorStr string `json:"errorstr,omitempty"` ErrorStr string `json:"errorstr,omitempty"`
DefaultState *sstore.RemoteState `json:"defaultstate"` DefaultState *sstore.RemoteState `json:"defaultstate"`
ConnectMode string `json:"connectmode"` ConnectMode string `json:"connectmode"`
AutoInstall bool `json:"autoinstall"`
Archived bool `json:"archived"` Archived bool `json:"archived"`
RemoteIdx int64 `json:"remoteidx"` RemoteIdx int64 `json:"remoteidx"`
UName string `json:"uname"` UName string `json:"uname"`
@@ -349,6 +361,7 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
PhysicalId: msh.Remote.PhysicalId, PhysicalId: msh.Remote.PhysicalId,
Status: msh.Status, Status: msh.Status,
ConnectMode: msh.Remote.ConnectMode, ConnectMode: msh.Remote.ConnectMode,
AutoInstall: msh.Remote.AutoInstall,
Archived: msh.Remote.Archived, Archived: msh.Remote.Archived,
RemoteIdx: msh.Remote.RemoteIdx, RemoteIdx: msh.Remote.RemoteIdx,
UName: msh.UName, UName: msh.UName,
@@ -649,17 +662,25 @@ func (msh *MShellProc) Launch() {
go msh.NotifyRemoteUpdate() go msh.NotifyRemoteUpdate()
}) })
cproc, uname, err := shexec.MakeClientProc(makeClientCtx, ecmd) cproc, uname, err := shexec.MakeClientProc(makeClientCtx, ecmd)
var mshellVersion string
msh.WithLock(func() { msh.WithLock(func() {
msh.UName = uname msh.UName = uname
msh.MakeClientCancelFn = nil msh.MakeClientCancelFn = nil
if cproc != nil && cproc.InitPk != nil { if cproc != nil && cproc.InitPk != nil {
msh.Remote.InitPk = cproc.InitPk msh.Remote.InitPk = cproc.InitPk
mshellVersion = cproc.InitPk.Version
}
if semver.Compare(mshellVersion, MShellVersion) < 0 {
msh.NeedsMShellUpgrade = true
} }
// no notify here, because we'll call notify in either case below // no notify here, because we'll call notify in either case below
}) })
if err == context.Canceled { if err == context.Canceled {
err = fmt.Errorf("forced disconnection") err = fmt.Errorf("forced disconnection")
} }
if semver.MajorMinor(mshellVersion) != semver.MajorMinor(MShellVersion) {
err = fmt.Errorf("mshell version is not compatible current=%s remote=%s", MShellVersion, mshellVersion)
}
if err != nil { if err != nil {
msh.setErrorStatus(err) msh.setErrorStatus(err)
msh.WriteToPtyBuffer("*error connecting to remote (uname=%q): %v\n", msh.UName, err) msh.WriteToPtyBuffer("*error connecting to remote (uname=%q): %v\n", msh.UName, err)
+3
View File
@@ -488,6 +488,7 @@ type RemoteType struct {
RemoteUser string `json:"remoteuser"` RemoteUser string `json:"remoteuser"`
RemoteHost string `json:"remotehost"` RemoteHost string `json:"remotehost"`
ConnectMode string `json:"connectmode"` ConnectMode string `json:"connectmode"`
AutoInstall bool `json:"autoinstall"`
InitPk *packet.InitPacketType `json:"inipk"` InitPk *packet.InitPacketType `json:"inipk"`
SSHOpts *SSHOpts `json:"sshopts"` SSHOpts *SSHOpts `json:"sshopts"`
RemoteOpts *RemoteOptsType `json:"remoteopts"` RemoteOpts *RemoteOptsType `json:"remoteopts"`
@@ -530,6 +531,7 @@ func (r *RemoteType) ToMap() map[string]interface{} {
rtn["remoteuser"] = r.RemoteUser rtn["remoteuser"] = r.RemoteUser
rtn["remotehost"] = r.RemoteHost rtn["remotehost"] = r.RemoteHost
rtn["connectmode"] = r.ConnectMode rtn["connectmode"] = r.ConnectMode
rtn["autoinstall"] = r.AutoInstall
rtn["initpk"] = quickJson(r.InitPk) rtn["initpk"] = quickJson(r.InitPk)
rtn["sshopts"] = quickJson(r.SSHOpts) rtn["sshopts"] = quickJson(r.SSHOpts)
rtn["remoteopts"] = quickJson(r.RemoteOpts) rtn["remoteopts"] = quickJson(r.RemoteOpts)
@@ -553,6 +555,7 @@ func RemoteFromMap(m map[string]interface{}) *RemoteType {
quickSetStr(&r.RemoteUser, m, "remoteuser") quickSetStr(&r.RemoteUser, m, "remoteuser")
quickSetStr(&r.RemoteHost, m, "remotehost") quickSetStr(&r.RemoteHost, m, "remotehost")
quickSetStr(&r.ConnectMode, m, "connectmode") quickSetStr(&r.ConnectMode, m, "connectmode")
quickSetBool(&r.AutoInstall, m, "autoinstall")
quickSetJson(&r.InitPk, m, "initpk") quickSetJson(&r.InitPk, m, "initpk")
quickSetJson(&r.SSHOpts, m, "sshopts") quickSetJson(&r.SSHOpts, m, "sshopts")
quickSetJson(&r.RemoteOpts, m, "remoteopts") quickSetJson(&r.RemoteOpts, m, "remoteopts")
+1
View File
@@ -88,6 +88,7 @@ type InfoMsgType struct {
InfoLines []string `json:"infolines,omitempty"` InfoLines []string `json:"infolines,omitempty"`
TimeoutMs int64 `json:"timeoutms,omitempty"` TimeoutMs int64 `json:"timeoutms,omitempty"`
PtyRemoteId string `json:"ptyremoteid,omitempty"` PtyRemoteId string `json:"ptyremoteid,omitempty"`
RemoteShowAll bool `json:"remoteshowall,omitempty"`
} }
type HistoryInfoType struct { type HistoryInfoType struct {