96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
package system
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"zlh-agent/internal/provision"
|
|
"zlh-agent/internal/state"
|
|
)
|
|
|
|
/*
|
|
console.go
|
|
Handles:
|
|
- Stdin command sending (bridge to process.go)
|
|
- Log tailing
|
|
- (future) WebSocket log streaming
|
|
*/
|
|
|
|
var (
|
|
consoleMu sync.Mutex
|
|
)
|
|
|
|
/* --------------------------------------------------------------------------
|
|
SendCommand (public wrapper)
|
|
Used by HTTP endpoint: /console/command?cmd=...
|
|
----------------------------------------------------------------------------*/
|
|
func SendCommand(cmd string) error {
|
|
return SendConsoleCommand(cmd)
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------
|
|
TailLatestLog (simple tail)
|
|
Returns last N bytes from logs/latest.log
|
|
|
|
Used now for API "tail logs"
|
|
Will be used by WebSocket console streaming later.
|
|
----------------------------------------------------------------------------*/
|
|
func TailLatestLog(cfg *state.Config, maxBytes int) ([]byte, error) {
|
|
dir := provision.ServerDir(*cfg)
|
|
logFile := filepath.Join(dir, "logs", "latest.log")
|
|
|
|
f, err := os.Open(logFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open log: %w", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
stat, err := f.Stat()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("stat log: %w", err)
|
|
}
|
|
|
|
size := stat.Size()
|
|
if size <= int64(maxBytes) {
|
|
// Read whole file
|
|
b, err := os.ReadFile(logFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
// Tail last N bytes
|
|
offset := size - int64(maxBytes)
|
|
buf := make([]byte, maxBytes)
|
|
|
|
_, err = f.ReadAt(buf, offset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return buf, nil
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------
|
|
Future: WebSocket Console Support
|
|
(stub, safe to leave here)
|
|
----------------------------------------------------------------------------*/
|
|
|
|
// PrepareWebSocketSession creates a placeholder session object.
|
|
// This will be expanded when we add WebSocket streaming.
|
|
func PrepareWebSocketSession() {
|
|
// Stub for future WebSocket log streaming
|
|
}
|
|
|
|
/*
|
|
Notes for WebSocket console:
|
|
|
|
- Use TailLatestLog() to send first chunk
|
|
- Then subscribe to real-time stdout/stderr pump via channels
|
|
- console.go will own log streaming
|
|
- process.go will expose a channel of new log lines
|
|
*/
|