local flag on remote, ensure 1 local remote. on archive, change to local remote

This commit is contained in:
sawka 2022-10-04 11:45:24 -07:00
parent 539e71ad47
commit f5b9ea07a1
7 changed files with 81 additions and 85 deletions

View File

@ -373,16 +373,6 @@ func main() {
fmt.Printf("[error] ensuring local remote: %v\n", err) fmt.Printf("[error] ensuring local remote: %v\n", err)
return return
} }
err = sstore.AddTest01Remote(context.Background())
if err != nil {
fmt.Printf("[error] ensuring test01 remote: %v\n", err)
return
}
//err = sstore.AddTest02Remote(context.Background())
//if err != nil {
// fmt.Printf("[error] ensuring test02 remote: %v\n", err)
// return
//}
_, err = sstore.EnsureDefaultSession(context.Background()) _, err = sstore.EnsureDefaultSession(context.Background())
if err != nil { if err != nil {
fmt.Printf("[error] ensuring default session: %v\n", err) fmt.Printf("[error] ensuring default session: %v\n", err)

View File

@ -94,6 +94,7 @@ CREATE TABLE remote (
sshopts json NOT NULL, sshopts json NOT NULL,
remoteopts json NOT NULL, remoteopts json NOT NULL,
lastconnectts bigint NOT NULL, lastconnectts bigint NOT NULL,
local boolean NOT NULL,
archived boolean NOT NULL, archived boolean NOT NULL,
remoteidx int NOT NULL remoteidx int NOT NULL
); );

View File

@ -5,7 +5,8 @@ CREATE TABLE client (
userid varchar(36) NOT NULL, userid varchar(36) NOT NULL,
activesessionid varchar(36) NOT NULL, activesessionid varchar(36) NOT NULL,
userpublickeybytes blob NOT NULL, userpublickeybytes blob NOT NULL,
userprivatekeybytes blob NOT NULL userprivatekeybytes blob NOT NULL,
winsize json NOT NULL
); );
CREATE TABLE session ( CREATE TABLE session (
sessionid varchar(36) PRIMARY KEY, sessionid varchar(36) PRIMARY KEY,
@ -83,10 +84,12 @@ 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,
lastconnectts bigint NOT NULL, lastconnectts bigint NOT NULL,
local boolean NOT NULL,
archived boolean NOT NULL, archived boolean NOT NULL,
remoteidx int NOT NULL remoteidx int NOT NULL
); );

View File

@ -805,6 +805,14 @@ func RemoteArchiveCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
return nil, fmt.Errorf("archiving remote: %v", err) return nil, fmt.Errorf("archiving remote: %v", err)
} }
update := sstore.InfoMsgUpdate("remote [%s] archived", ids.Remote.DisplayName) update := sstore.InfoMsgUpdate("remote [%s] archived", ids.Remote.DisplayName)
localRemote := remote.GetLocalRemote()
if localRemote != nil {
update.Window = &sstore.WindowType{
SessionId: ids.SessionId,
WindowId: ids.WindowId,
CurRemote: sstore.RemotePtrType{RemoteId: localRemote.GetRemoteId()},
}
}
return update, nil return update, nil
} }

View File

@ -117,6 +117,7 @@ type RemoteRuntimeState struct {
UName string `json:"uname"` UName string `json:"uname"`
MShellVersion string `json:"mshellversion"` MShellVersion string `json:"mshellversion"`
WaitingForPassword bool `json:"waitingforpassword,omitempty"` WaitingForPassword bool `json:"waitingforpassword,omitempty"`
Local bool `json:"local,omitempty"`
} }
func (state RemoteRuntimeState) IsConnected() bool { func (state RemoteRuntimeState) IsConnected() bool {
@ -129,6 +130,12 @@ func (msh *MShellProc) GetStatus() string {
return msh.Status return msh.Status
} }
func (msh *MShellProc) GetRemoteId() string {
msh.Lock.Lock()
defer msh.Lock.Unlock()
return msh.Remote.RemoteId
}
func (msh *MShellProc) GetInstallStatus() string { func (msh *MShellProc) GetInstallStatus() string {
msh.Lock.Lock() msh.Lock.Lock()
defer msh.Lock.Unlock() defer msh.Lock.Unlock()
@ -166,12 +173,22 @@ func LoadRemotes(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
var numLocal int
for _, remote := range allRemotes { for _, remote := range allRemotes {
msh := MakeMShell(remote) msh := MakeMShell(remote)
GlobalStore.Map[remote.RemoteId] = msh GlobalStore.Map[remote.RemoteId] = msh
if remote.ConnectMode == sstore.ConnectModeStartup { if remote.ConnectMode == sstore.ConnectModeStartup {
go msh.Launch() go msh.Launch()
} }
if remote.Local {
numLocal++
}
}
if numLocal == 0 {
return fmt.Errorf("no local remote found")
}
if numLocal > 1 {
return fmt.Errorf("multiple local remotes found")
} }
return nil return nil
} }
@ -224,6 +241,10 @@ func AddRemote(ctx context.Context, r *sstore.RemoteType) error {
} }
r.RemoteId = erCopy.RemoteId r.RemoteId = erCopy.RemoteId
} }
if r.Local {
return fmt.Errorf("cannot create another local remote (there can be only one)")
}
err := sstore.UpsertRemote(ctx, r) err := sstore.UpsertRemote(ctx, r)
if err != nil { if err != nil {
return fmt.Errorf("cannot create remote %q: %v", r.RemoteCanonicalName, err) return fmt.Errorf("cannot create remote %q: %v", r.RemoteCanonicalName, err)
@ -247,6 +268,9 @@ func ArchiveRemote(ctx context.Context, remoteId string) error {
if msh.Status == StatusConnected { if msh.Status == StatusConnected {
return fmt.Errorf("cannot archive connected remote") return fmt.Errorf("cannot archive connected remote")
} }
if msh.Remote.Local {
return fmt.Errorf("cannot archive local remote")
}
rcopy := msh.GetRemoteCopy() rcopy := msh.GetRemoteCopy()
archivedRemote := &sstore.RemoteType{ archivedRemote := &sstore.RemoteType{
RemoteId: rcopy.RemoteId, RemoteId: rcopy.RemoteId,
@ -303,6 +327,17 @@ func GetRemoteById(remoteId string) *MShellProc {
return GlobalStore.Map[remoteId] return GlobalStore.Map[remoteId]
} }
func GetLocalRemote() *MShellProc {
GlobalStore.Lock.Lock()
defer GlobalStore.Lock.Unlock()
for _, msh := range GlobalStore.Map {
if msh.IsLocal() {
return msh
}
}
return nil
}
func ResolveRemoteRef(remoteRef string) *RemoteRuntimeState { func ResolveRemoteRef(remoteRef string) *RemoteRuntimeState {
GlobalStore.Lock.Lock() GlobalStore.Lock.Lock()
defer GlobalStore.Lock.Unlock() defer GlobalStore.Lock.Unlock()
@ -369,6 +404,12 @@ func makeShortHost(host string) string {
return host[0:dotIdx] return host[0:dotIdx]
} }
func (msh *MShellProc) IsLocal() bool {
msh.Lock.Lock()
defer msh.Lock.Unlock()
return msh.Remote.Local
}
func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState { func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
msh.Lock.Lock() msh.Lock.Lock()
defer msh.Lock.Unlock() defer msh.Lock.Unlock()
@ -386,6 +427,7 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
UName: msh.UName, UName: msh.UName,
InstallStatus: msh.InstallStatus, InstallStatus: msh.InstallStatus,
NeedsMShellUpgrade: msh.NeedsMShellUpgrade, NeedsMShellUpgrade: msh.NeedsMShellUpgrade,
Local: msh.Remote.Local,
} }
if msh.Err != nil { if msh.Err != nil {
state.ErrorStr = msh.Err.Error() state.ErrorStr = msh.Err.Error()
@ -396,7 +438,6 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
if msh.Status == StatusConnecting { if msh.Status == StatusConnecting {
state.WaitingForPassword = msh.isWaitingForPassword_nolock() state.WaitingForPassword = msh.isWaitingForPassword_nolock()
} }
local := (msh.Remote.SSHOpts == nil || msh.Remote.SSHOpts.Local)
vars := make(map[string]string) vars := make(map[string]string)
vars["user"] = msh.Remote.RemoteUser vars["user"] = msh.Remote.RemoteUser
vars["bestuser"] = vars["user"] vars["bestuser"] = vars["user"]
@ -411,7 +452,7 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
if msh.Remote.RemoteSudo { if msh.Remote.RemoteSudo {
vars["sudo"] = "1" vars["sudo"] = "1"
} }
if local { if msh.Remote.Local {
vars["local"] = "1" vars["local"] = "1"
} }
vars["port"] = "22" vars["port"] = "22"
@ -437,12 +478,12 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
vars["besthost"] = vars["remotehost"] vars["besthost"] = vars["remotehost"]
vars["bestshorthost"] = vars["remoteshorthost"] vars["bestshorthost"] = vars["remoteshorthost"]
} }
if local && msh.Remote.RemoteSudo { if msh.Remote.Local && msh.Remote.RemoteSudo {
vars["bestuser"] = "sudo" vars["bestuser"] = "sudo"
} else if msh.Remote.RemoteSudo { } else if msh.Remote.RemoteSudo {
vars["bestuser"] = "sudo@" + vars["bestuser"] vars["bestuser"] = "sudo@" + vars["bestuser"]
} }
if local { if msh.Remote.Local {
vars["bestname"] = vars["bestuser"] + "@local" vars["bestname"] = vars["bestuser"] + "@local"
vars["bestshortname"] = vars["bestuser"] + "@local" vars["bestshortname"] = vars["bestuser"] + "@local"
} else { } else {

View File

@ -73,6 +73,20 @@ func GetRemoteById(ctx context.Context, remoteId string) (*RemoteType, error) {
return remote, nil return remote, nil
} }
func GetLocalRemote(ctx context.Context) (*RemoteType, error) {
var remote *RemoteType
err := WithTx(ctx, func(tx *TxWrap) error {
query := `SELECT * FROM remote WHERE local`
m := tx.GetMap(query)
remote = RemoteFromMap(m)
return nil
})
if err != nil {
return nil, err
}
return remote, nil
}
func GetRemoteByCanonicalName(ctx context.Context, cname string) (*RemoteType, error) { func GetRemoteByCanonicalName(ctx context.Context, cname string) (*RemoteType, error) {
var remote *RemoteType var remote *RemoteType
err := WithTx(ctx, func(tx *TxWrap) error { err := WithTx(ctx, func(tx *TxWrap) error {
@ -131,8 +145,8 @@ func UpsertRemote(ctx context.Context, r *RemoteType) error {
maxRemoteIdx := tx.GetInt(query) maxRemoteIdx := tx.GetInt(query)
r.RemoteIdx = int64(maxRemoteIdx + 1) r.RemoteIdx = int64(maxRemoteIdx + 1)
query = `INSERT INTO remote query = `INSERT INTO remote
( remoteid, physicalid, remotetype, remotealias, remotecanonicalname, remotesudo, remoteuser, remotehost, connectmode, autoinstall, initpk, sshopts, remoteopts, lastconnectts, archived, remoteidx) VALUES ( remoteid, physicalid, remotetype, remotealias, remotecanonicalname, remotesudo, remoteuser, remotehost, connectmode, autoinstall, initpk, sshopts, remoteopts, lastconnectts, archived, remoteidx, local) VALUES
(:remoteid,:physicalid,:remotetype,:remotealias,:remotecanonicalname,:remotesudo,:remoteuser,:remotehost,:connectmode,:autoinstall,:initpk,:sshopts,:remoteopts,:lastconnectts,:archived,:remoteidx)` (:remoteid,:physicalid,:remotetype,:remotealias,:remotecanonicalname,:remotesudo,:remoteuser,:remotehost,:connectmode,:autoinstall,:initpk,:sshopts,:remoteopts,:lastconnectts,:archived,:remoteidx,:local)`
tx.NamedExecWrap(query, r.ToMap()) tx.NamedExecWrap(query, r.ToMap())
return nil return nil
}) })

View File

@ -508,6 +508,7 @@ type RemoteType struct {
LastConnectTs int64 `json:"lastconnectts"` LastConnectTs int64 `json:"lastconnectts"`
Archived bool `json:"archived"` Archived bool `json:"archived"`
RemoteIdx int64 `json:"remoteidx"` RemoteIdx int64 `json:"remoteidx"`
Local bool `json:"local"`
} }
func (r *RemoteType) GetName() string { func (r *RemoteType) GetName() string {
@ -551,6 +552,7 @@ func (r *RemoteType) ToMap() map[string]interface{} {
rtn["lastconnectts"] = r.LastConnectTs rtn["lastconnectts"] = r.LastConnectTs
rtn["archived"] = r.Archived rtn["archived"] = r.Archived
rtn["remoteidx"] = r.RemoteIdx rtn["remoteidx"] = r.RemoteIdx
rtn["local"] = r.Local
return rtn return rtn
} }
@ -575,6 +577,7 @@ func RemoteFromMap(m map[string]interface{}) *RemoteType {
quickSetInt64(&r.LastConnectTs, m, "lastconnectts") quickSetInt64(&r.LastConnectTs, m, "lastconnectts")
quickSetBool(&r.Archived, m, "archived") quickSetBool(&r.Archived, m, "archived")
quickSetInt64(&r.RemoteIdx, m, "remoteidx") quickSetInt64(&r.RemoteIdx, m, "remoteidx")
quickSetBool(&r.Local, m, "local")
return &r return &r
} }
@ -668,9 +671,9 @@ func EnsureLocalRemote(ctx context.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("getting local physical remoteid: %w", err) return fmt.Errorf("getting local physical remoteid: %w", err)
} }
remote, err := GetRemoteByPhysicalId(ctx, physicalId) remote, err := GetLocalRemote(ctx)
if err != nil { if err != nil {
return fmt.Errorf("getting remote[%s] from db: %w", physicalId, err) return fmt.Errorf("getting local remote from db: %w", err)
} }
if remote != nil { if remote != nil {
return nil return nil
@ -696,77 +699,13 @@ func EnsureLocalRemote(ctx context.Context) error {
ConnectMode: ConnectModeStartup, ConnectMode: ConnectModeStartup,
AutoInstall: true, AutoInstall: true,
SSHOpts: &SSHOpts{Local: true}, SSHOpts: &SSHOpts{Local: true},
Local: true,
} }
err = UpsertRemote(ctx, localRemote) err = UpsertRemote(ctx, localRemote)
if err != nil { if err != nil {
return err return err
} }
log.Printf("[db] added remote '%s', id=%s\n", localRemote.GetName(), localRemote.RemoteId) log.Printf("[db] added local remote '%s', id=%s\n", localRemote.RemoteCanonicalName, localRemote.RemoteId)
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: scbase.GenSCUUID(),
RemoteType: RemoteTypeSsh,
RemoteAlias: "test01",
RemoteCanonicalName: "ubuntu@test01.ec2",
RemoteSudo: false,
RemoteUser: "ubuntu",
RemoteHost: "test01.ec2",
SSHOpts: &SSHOpts{
Local: false,
SSHHost: "test01.ec2",
SSHUser: "ubuntu",
SSHIdentity: "/Users/mike/aws/mfmt.pem",
},
ConnectMode: ConnectModeStartup,
AutoInstall: true,
}
err = UpsertRemote(ctx, testRemote)
if err != nil {
return err
}
log.Printf("[db] added remote '%s', id=%s\n", testRemote.GetName(), testRemote.RemoteId)
return nil
}
func AddTest02Remote(ctx context.Context) error {
remote, err := GetRemoteByAlias(ctx, "test2")
if err != nil {
return fmt.Errorf("getting remote[test01] from db: %w", err)
}
if remote != nil {
return nil
}
testRemote := &RemoteType{
RemoteId: scbase.GenSCUUID(),
RemoteType: RemoteTypeSsh,
RemoteAlias: "test2",
RemoteCanonicalName: "test2@test01.ec2",
RemoteSudo: false,
RemoteUser: "test2",
RemoteHost: "test01.ec2",
SSHOpts: &SSHOpts{
Local: false,
SSHHost: "test01.ec2",
SSHUser: "test2",
},
ConnectMode: ConnectModeStartup,
AutoInstall: true,
}
err = UpsertRemote(ctx, testRemote)
if err != nil {
return err
}
log.Printf("[db] added remote '%s', id=%s\n", testRemote.GetName(), testRemote.RemoteId)
return nil return nil
} }