mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
checkpoint, working on autoinstall, semantic versioning, remoteshowall
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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=
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user