diff --git a/pico/cli.go b/pico/cli.go index 613873d..48e7909 100644 --- a/pico/cli.go +++ b/pico/cli.go @@ -1,6 +1,8 @@ package pico import ( + "bufio" + "encoding/json" "fmt" "log/slog" "strings" @@ -34,12 +36,13 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) { } type Cmd struct { - User *db.User - Session shared.CmdSession - Log *slog.Logger - Dbpool db.DB - Write bool - Styles common.Styles + User *db.User + SshSession ssh.Session + Session shared.CmdSession + Log *slog.Logger + Dbpool db.DB + Write bool + Styles common.Styles } func (c *Cmd) output(out string) { @@ -62,6 +65,59 @@ func (c *Cmd) notifications() error { return nil } +func (c *Cmd) logs() error { + sshClient, err := shared.CreateSSHClient( + shared.GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"), + shared.GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"), + shared.GetEnv("PICO_SENDLOG_PASSPHRASE", ""), + shared.GetEnv("PICO_SENDLOG_REMOTE_HOST", "send.pico.sh"), + shared.GetEnv("PICO_SENDLOG_USER", "pico"), + ) + if err != nil { + return err + } + defer sshClient.Close() + + session, err := sshClient.NewSession() + defer func() { + _ = session.Close() + }() + if err != nil { + return err + } + + stdoutPipe, err := session.StdoutPipe() + if err != nil { + return err + } + + err = session.Start("sub log-drain -k") + if err != nil { + return err + } + + scanner := bufio.NewScanner(stdoutPipe) + for scanner.Scan() { + line := scanner.Text() + parsedData := map[string]any{} + + err := json.Unmarshal([]byte(line), &parsedData) + if err != nil { + c.Log.Error("json unmarshal", "err", err) + continue + } + + if userName, ok := parsedData["user"]; ok { + if userName, ok := userName.(string); ok { + if userName == c.User.Name { + wish.Println(c.SshSession, line) + } + } + } + } + return scanner.Err() +} + type CliHandler struct { DBPool db.DB Logger *slog.Logger @@ -113,11 +169,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware { } opts := Cmd{ - Session: sesh, - User: user, - Log: log, - Dbpool: dbpool, - Write: false, + Session: sesh, + SshSession: sesh, + User: user, + Log: log, + Dbpool: dbpool, + Write: false, } cmd := strings.TrimSpace(args[0]) @@ -125,6 +182,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware { if cmd == "help" { opts.help() return + } else if cmd == "logs" { + err = opts.logs() + if err != nil { + wish.Fatalln(sesh, err) + } + return } else if cmd == "pico+" { opts.plus() return diff --git a/shared/sendlog.go b/shared/sendlog.go index 7d9a476..b407ef7 100644 --- a/shared/sendlog.go +++ b/shared/sendlog.go @@ -138,7 +138,7 @@ func (c *SendLogWriter) Open() error { c.Done = make(chan struct{}) c.Messages = make(chan []byte, c.BufferSize) - sshClient, err := createSSHClient( + sshClient, err := CreateSSHClient( GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"), GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"), GetEnv("PICO_SENDLOG_PASSPHRASE", ""), @@ -248,7 +248,7 @@ func (c *SendLogWriter) Reconnect() { }() } -func createSSHClient(remoteHost string, keyLocation string, keyPassphrase string, remoteHostname string, remoteUser string) (*ssh.Client, error) { +func CreateSSHClient(remoteHost string, keyLocation string, keyPassphrase string, remoteHostname string, remoteUser string) (*ssh.Client, error) { if !strings.Contains(remoteHost, ":") { remoteHost += ":22" }