From fe3fb6d3778efa78d531a9de77f08b9d62533f11 Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 23 Feb 2023 15:17:47 -0800 Subject: [PATCH] updates for activity, buildtime, etc. --- cmd/main-server.go | 9 ++++++++- go.mod | 2 +- pkg/cmdrunner/cmdrunner.go | 7 +++++++ pkg/scbase/scbase.go | 33 +++++++++++++++++++++++++++++++++ pkg/scpacket/scpacket.go | 1 + pkg/sstore/dbops.go | 11 ++++++----- pkg/sstore/sstore.go | 3 +++ scripthaus.md | 2 +- 8 files changed, 60 insertions(+), 8 deletions(-) diff --git a/cmd/main-server.go b/cmd/main-server.go index e983920f..b582908e 100644 --- a/cmd/main-server.go +++ b/cmd/main-server.go @@ -50,6 +50,7 @@ const TelemetryInterval = 8 * time.Hour var GlobalLock = &sync.Mutex{} var WSStateMap = make(map[string]*scws.WSState) // clientid -> WsState var GlobalAuthKey string +var BuildTime = "0" type ClientActiveState struct { Fg bool `json:"fg"` @@ -460,6 +461,8 @@ func stdinReadWatch() { } func main() { + scbase.BuildTime = BuildTime + if len(os.Args) >= 2 && os.Args[1] == "--test" { log.Printf("running test fn\n") err := test() @@ -470,7 +473,7 @@ func main() { } scHomeDir := scbase.GetPromptHomeDir() - log.Printf("[prompt] local server version %s\n", scbase.PromptVersion) + log.Printf("[prompt] local server version %s+%s\n", scbase.PromptVersion, scbase.BuildTime) log.Printf("[prompt] homedir = %q\n", scHomeDir) scLock, err := scbase.AcquirePromptLock() @@ -528,6 +531,10 @@ func main() { } log.Printf("PCLOUD_ENDPOINT=%s\n", pcloud.GetEndpoint()) + err = sstore.UpdateCurrentActivity(context.Background(), sstore.ActivityUpdate{NumConns: remote.NumRemotes()}) // set at least one record into activity + if err != nil { + log.Printf("[error] updating activity: %v\n", err) + } go telemetryLoop() go stdinReadWatch() go runWebSocketServer() diff --git a/go.mod b/go.mod index c4ed9eb8..b2e96554 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/scripthaus-dev/sh2-server -go 1.17 +go 1.18 require ( github.com/alessio/shellescape v1.4.1 diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 444378c8..c9b3dafa 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -2355,12 +2355,19 @@ func ClientShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (s if err != nil { return nil, fmt.Errorf("cannot retrieve db version: %v\n", err) } + clientVersion := "-" + if pk.UIContext != nil && pk.UIContext.Build != "" { + clientVersion = pk.UIContext.Build + } var buf bytes.Buffer buf.WriteString(fmt.Sprintf(" %-15s %s\n", "userid", clientData.UserId)) buf.WriteString(fmt.Sprintf(" %-15s %s\n", "clientid", clientData.ClientId)) buf.WriteString(fmt.Sprintf(" %-15s %s\n", "backend", scbase.PromptVersion)) buf.WriteString(fmt.Sprintf(" %-15s %s\n", "telemetry", boolToStr(clientData.ClientOpts.NoTelemetry, "off", "on"))) buf.WriteString(fmt.Sprintf(" %-15s %d\n", "db-version", dbVersion)) + buf.WriteString(fmt.Sprintf(" %-15s %s\n", "client-version", clientVersion)) + buf.WriteString(fmt.Sprintf(" %-15s %s %s\n", "server-version", scbase.PromptVersion, scbase.BuildTime)) + buf.WriteString(fmt.Sprintf(" %-15s %s (%s)\n", "arch", scbase.ClientArch(), scbase.MacOSRelease())) update := sstore.ModelUpdate{ Info: &sstore.InfoMsgType{ InfoTitle: fmt.Sprintf("client info"), diff --git a/pkg/scbase/scbase.go b/pkg/scbase/scbase.go index c8b71eab..12b68bd9 100644 --- a/pkg/scbase/scbase.go +++ b/pkg/scbase/scbase.go @@ -1,16 +1,21 @@ package scbase import ( + "context" "errors" "fmt" "io" "io/fs" "log" "os" + "os/exec" "path" + "regexp" "runtime" "strconv" + "strings" "sync" + "time" "github.com/google/uuid" "github.com/scripthaus-dev/mshell/pkg/base" @@ -32,6 +37,7 @@ const MShellVersion = "v0.2.0" var SessionDirCache = make(map[string]string) var BaseLock = &sync.Mutex{} +var BuildTime = "-" func IsDevMode() bool { pdev := os.Getenv(PromptDevVarName) @@ -322,3 +328,30 @@ func NumFormatB2(num int64) string { func ClientArch() string { return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) } + +var releaseRegex = regexp.MustCompile(`^\d+\.\d+\.\d+$`) +var osReleaseOnce = &sync.Once{} +var osRelease string + +func macOSRelease() string { + ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) + defer cancelFn() + out, err := exec.CommandContext(ctx, "uname", "-r").CombinedOutput() + if err != nil { + log.Printf("error executing uname -r: %v\n", err) + return "-" + } + releaseStr := strings.TrimSpace(string(out)) + if !releaseRegex.MatchString(releaseStr) { + log.Printf("invalid uname -r output: [%s]\n", releaseStr) + return "-" + } + return releaseStr +} + +func MacOSRelease() string { + osReleaseOnce.Do(func() { + osRelease = macOSRelease() + }) + return osRelease +} diff --git a/pkg/scpacket/scpacket.go b/pkg/scpacket/scpacket.go index bb88338d..8c1b8184 100644 --- a/pkg/scpacket/scpacket.go +++ b/pkg/scpacket/scpacket.go @@ -55,6 +55,7 @@ type UIContextType struct { WindowId string `json:"windowid"` Remote *sstore.RemotePtrType `json:"remote,omitempty"` WinSize *packet.WinSize `json:"winsize,omitempty"` + Build string `json:"build,omitempty"` } type FeInputPacketType struct { diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index 89f4f66d..612d2ed7 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -1920,13 +1920,13 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error { query := `SELECT tdata FROM activity WHERE day = ?` found := tx.Get(&tdata, query, dayStr) if !found { - query = `INSERT INTO activity (day, uploaded, tdata, tzname, tzoffset, clientversion, clientarch) - VALUES (?, 0, ?, ?, ?, ?, ?)` + query = `INSERT INTO activity (day, uploaded, tdata, tzname, tzoffset, clientversion, clientarch, buildtime, osrelease) + VALUES (?, 0, ?, ?, ?, ?, ? , ? , ?)` tzName, tzOffset := now.Zone() if len(tzName) > MaxTzNameLen { tzName = tzName[0:MaxTzNameLen] } - tx.Exec(query, dayStr, tdata, tzName, tzOffset, scbase.PromptVersion, scbase.ClientArch()) + tx.Exec(query, dayStr, tdata, tzName, tzOffset, scbase.PromptVersion, scbase.ClientArch(), scbase.BuildTime, scbase.MacOSRelease()) } tdata.NumCommands += update.NumCommands tdata.FgMinutes += update.FgMinutes @@ -1940,9 +1940,10 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error { } query = `UPDATE activity SET tdata = ?, - clientversion = ? + clientversion = ?, + buildtime = ? WHERE day = ?` - tx.Exec(query, tdata, scbase.PromptVersion, dayStr) + tx.Exec(query, tdata, scbase.PromptVersion, scbase.BuildTime, dayStr) return nil }) if txErr != nil { diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 1ab2cb88..1cd80414 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -122,6 +122,7 @@ type ActivityUpdate struct { HistoryView int BookmarksView int NumConns int + BuildTime string } type ActivityType struct { @@ -132,6 +133,8 @@ type ActivityType struct { TzOffset int `json:"tzoffset"` ClientVersion string `json:"clientversion"` ClientArch string `json:"clientarch"` + BuildTime string `json:"buildtime"` + OSRelease string `json:"osrelease"` } type TelemetryData struct { diff --git a/scripthaus.md b/scripthaus.md index 88dc22bd..8768504e 100644 --- a/scripthaus.md +++ b/scripthaus.md @@ -12,5 +12,5 @@ sqlite3 /Users/mike/prompt-dev/prompt.db ```bash # @scripthaus command build -go build -o ~/prompt-dev/local-server cmd/main-server.go +go build -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M')" -o ~/prompt-dev/local-server ./cmd ```