Compare commits
19 Commits
b2eb9d3116
...
main
Author | SHA1 | Date | |
---|---|---|---|
4a79011793 | |||
0b62ac9ecd | |||
c9b14730ad | |||
2ee8a95a90 | |||
8bc1759dcb | |||
e60b9f62f1 | |||
5d241e9ade | |||
b8c8da9e31 | |||
55a05a5571 | |||
2bfe4161b2 | |||
0b1d9907a7 | |||
c78761fe20 | |||
2e8ec1735a | |||
29d0d25a3b | |||
3f01074e3f | |||
532cda72d3 | |||
0e545e56de | |||
92b9c356b8 | |||
c86165f88c |
@@ -11,7 +11,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/mycelium_client"
|
"git.threefold.info/herocode/heroagent/pkg/mycelium_client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/mycelium_client"
|
"git.threefold.info/herocode/heroagent/pkg/mycelium_client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
|
"git.threefold.info/herocode/heroagent/pkg/system/stats"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ func (h *AdminHandler) getProcessStatsJSON(c *fiber.Ctx) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
"success": false,
|
"success": false,
|
||||||
"error": "Failed to get process stats: " + err.Error(),
|
"error": "Failed to get process stats: " + err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@@ -3,7 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/sal/executor"
|
"git.threefold.info/herocode/heroagent/pkg/sal/executor"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
@@ -7,9 +7,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager/interfaces"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager/interfaces"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager/interfaces/openrpc"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager/interfaces/openrpc"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,26 +102,26 @@ func (h *ServiceHandler) getProcessList() ([]ProcessDisplayInfo, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
// Try to handle the result as a map or other structure
|
// Try to handle the result as a map or other structure
|
||||||
h.logger.Printf("Warning: unexpected result type from ListProcesses, trying alternative parsing")
|
h.logger.Printf("Warning: unexpected result type from ListProcesses, trying alternative parsing")
|
||||||
|
|
||||||
// Try to convert the result to JSON and then parse it
|
// Try to convert the result to JSON and then parse it
|
||||||
resultJSON, err := json.Marshal(result)
|
resultJSON, err := json.Marshal(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Printf("Error marshaling result to JSON: %v", err)
|
h.logger.Printf("Error marshaling result to JSON: %v", err)
|
||||||
return nil, fmt.Errorf("failed to marshal result: %w", err)
|
return nil, fmt.Errorf("failed to marshal result: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var processStatuses []interfaces.ProcessStatus
|
var processStatuses []interfaces.ProcessStatus
|
||||||
if err := json.Unmarshal(resultJSON, &processStatuses); err != nil {
|
if err := json.Unmarshal(resultJSON, &processStatuses); err != nil {
|
||||||
h.logger.Printf("Error unmarshaling result to ProcessStatus: %v", err)
|
h.logger.Printf("Error unmarshaling result to ProcessStatus: %v", err)
|
||||||
return nil, fmt.Errorf("failed to unmarshal process list result: %w", err)
|
return nil, fmt.Errorf("failed to unmarshal process list result: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to display info format
|
// Convert to display info format
|
||||||
displayInfoList := make([]ProcessDisplayInfo, 0, len(processStatuses))
|
displayInfoList := make([]ProcessDisplayInfo, 0, len(processStatuses))
|
||||||
for _, proc := range processStatuses {
|
for _, proc := range processStatuses {
|
||||||
// Calculate uptime based on start time
|
// Calculate uptime based on start time
|
||||||
uptime := formatUptime(time.Since(proc.StartTime))
|
uptime := formatUptime(time.Since(proc.StartTime))
|
||||||
|
|
||||||
displayInfo := ProcessDisplayInfo{
|
displayInfo := ProcessDisplayInfo{
|
||||||
ID: fmt.Sprintf("%d", proc.PID),
|
ID: fmt.Sprintf("%d", proc.PID),
|
||||||
Name: proc.Name,
|
Name: proc.Name,
|
||||||
@@ -133,7 +133,7 @@ func (h *ServiceHandler) getProcessList() ([]ProcessDisplayInfo, error) {
|
|||||||
}
|
}
|
||||||
displayInfoList = append(displayInfoList, displayInfo)
|
displayInfoList = append(displayInfoList, displayInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug: Log the number of processes
|
// Debug: Log the number of processes
|
||||||
h.logger.Printf("Found %d processes", len(displayInfoList))
|
h.logger.Printf("Found %d processes", len(displayInfoList))
|
||||||
return displayInfoList, nil
|
return displayInfoList, nil
|
||||||
@@ -144,7 +144,7 @@ func (h *ServiceHandler) getProcessList() ([]ProcessDisplayInfo, error) {
|
|||||||
for _, proc := range processStatuses {
|
for _, proc := range processStatuses {
|
||||||
// Calculate uptime based on start time
|
// Calculate uptime based on start time
|
||||||
uptime := formatUptime(time.Since(proc.StartTime))
|
uptime := formatUptime(time.Since(proc.StartTime))
|
||||||
|
|
||||||
displayInfo := ProcessDisplayInfo{
|
displayInfo := ProcessDisplayInfo{
|
||||||
ID: fmt.Sprintf("%d", proc.PID),
|
ID: fmt.Sprintf("%d", proc.PID),
|
||||||
Name: proc.Name,
|
Name: proc.Name,
|
||||||
@@ -276,7 +276,7 @@ func (h *ServiceHandler) stopService(c *fiber.Ctx) error {
|
|||||||
"error": fmt.Sprintf("Failed to stop service: %v", err),
|
"error": fmt.Sprintf("Failed to stop service: %v", err),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the result indicates success
|
// Check if the result indicates success
|
||||||
if !result.Success {
|
if !result.Success {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
@@ -331,7 +331,7 @@ func (h *ServiceHandler) restartService(c *fiber.Ctx) error {
|
|||||||
"error": fmt.Sprintf("Failed to restart service: %v", err),
|
"error": fmt.Sprintf("Failed to restart service: %v", err),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the result indicates success
|
// Check if the result indicates success
|
||||||
if !result.Success {
|
if !result.Success {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
@@ -382,7 +382,7 @@ func (h *ServiceHandler) deleteService(c *fiber.Ctx) error {
|
|||||||
"error": fmt.Sprintf("Failed to delete service: %v", err),
|
"error": fmt.Sprintf("Failed to delete service: %v", err),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the result indicates success
|
// Check if the result indicates success
|
||||||
if !result.Success {
|
if !result.Success {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
@@ -12,16 +12,16 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroagent/api"
|
"git.threefold.info/herocode/heroagent/pkg/heroagent/api"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroagent/handlers"
|
"git.threefold.info/herocode/heroagent/pkg/heroagent/handlers"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroagent/pages"
|
"git.threefold.info/herocode/heroagent/pkg/heroagent/pages"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/sal/executor"
|
"git.threefold.info/herocode/heroagent/pkg/sal/executor"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/servers/redisserver"
|
"git.threefold.info/herocode/heroagent/pkg/servers/redisserver"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
|
"git.threefold.info/herocode/heroagent/pkg/system/stats"
|
||||||
|
|
||||||
// "github.com/freeflowuniverse/heroagent/pkg/vfs/interfaces"
|
// "git.threefold.info/herocode/heroagent/pkg/vfs/interfaces"
|
||||||
// "github.com/freeflowuniverse/heroagent/pkg/vfs/interfaces/mock"
|
// "git.threefold.info/herocode/heroagent/pkg/vfs/interfaces/mock"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||||
@@ -239,7 +239,7 @@ func (hl *HeroLauncher) GetUptime() string {
|
|||||||
func (hl *HeroLauncher) startProcessManager() error {
|
func (hl *HeroLauncher) startProcessManager() error {
|
||||||
_, filename, _, _ := runtime.Caller(0)
|
_, filename, _, _ := runtime.Caller(0)
|
||||||
projectRoot := filepath.Join(filepath.Dir(filename), "../..")
|
projectRoot := filepath.Join(filepath.Dir(filename), "../..")
|
||||||
processManagerPath := filepath.Join(projectRoot, "cmd/processmanager/main.go")
|
processManagerPath := filepath.Join(projectRoot, "pkg/processmanager/examples/openrpc/main.go")
|
||||||
|
|
||||||
log.Printf("Starting process manager from: %s", processManagerPath)
|
log.Printf("Starting process manager from: %s", processManagerPath)
|
||||||
|
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"strconv" // Added strconv for JobID parsing
|
"strconv" // Added strconv for JobID parsing
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/herojobs"
|
"git.threefold.info/herocode/heroagent/pkg/herojobs"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
@@ -10,7 +10,7 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/herojobs"
|
"git.threefold.info/herocode/heroagent/pkg/herojobs"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/logger"
|
"git.threefold.info/herocode/heroagent/pkg/logger"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,40 +65,40 @@ func NewLogHandler(logPath string) (*LogHandler, error) {
|
|||||||
type LogType string
|
type LogType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LogTypeSystem LogType = "system"
|
LogTypeSystem LogType = "system"
|
||||||
LogTypeService LogType = "service"
|
LogTypeService LogType = "service"
|
||||||
LogTypeJob LogType = "job"
|
LogTypeJob LogType = "job"
|
||||||
LogTypeProcess LogType = "process"
|
LogTypeProcess LogType = "process"
|
||||||
LogTypeAll LogType = "all" // Special type to retrieve logs from all sources
|
LogTypeAll LogType = "all" // Special type to retrieve logs from all sources
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLogs renders the logs page with logs content
|
// GetLogs renders the logs page with logs content
|
||||||
func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
||||||
// Check which logger to use based on the log type parameter
|
// Check which logger to use based on the log type parameter
|
||||||
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
||||||
|
|
||||||
// Parse query parameters
|
// Parse query parameters
|
||||||
category := c.Query("category", "")
|
category := c.Query("category", "")
|
||||||
logItemType := parseLogType(c.Query("type", ""))
|
logItemType := parseLogType(c.Query("type", ""))
|
||||||
maxItems := c.QueryInt("max_items", 100)
|
maxItems := c.QueryInt("max_items", 100)
|
||||||
page := c.QueryInt("page", 1)
|
page := c.QueryInt("page", 1)
|
||||||
itemsPerPage := 20 // Default items per page
|
itemsPerPage := 20 // Default items per page
|
||||||
|
|
||||||
// Parse time range
|
// Parse time range
|
||||||
fromTime := parseTimeParam(c.Query("from", ""))
|
fromTime := parseTimeParam(c.Query("from", ""))
|
||||||
toTime := parseTimeParam(c.Query("to", ""))
|
toTime := parseTimeParam(c.Query("to", ""))
|
||||||
|
|
||||||
// Create search arguments
|
// Create search arguments
|
||||||
searchArgs := logger.SearchArgs{
|
searchArgs := logger.SearchArgs{
|
||||||
Category: category,
|
Category: category,
|
||||||
LogType: logItemType,
|
LogType: logItemType,
|
||||||
MaxItems: maxItems,
|
MaxItems: maxItems,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fromTime.IsZero() {
|
if !fromTime.IsZero() {
|
||||||
searchArgs.TimestampFrom = &fromTime
|
searchArgs.TimestampFrom = &fromTime
|
||||||
}
|
}
|
||||||
|
|
||||||
if !toTime.IsZero() {
|
if !toTime.IsZero() {
|
||||||
searchArgs.TimestampTo = &toTime
|
searchArgs.TimestampTo = &toTime
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
var logs []logger.LogItem
|
var logs []logger.LogItem
|
||||||
var err error
|
var err error
|
||||||
var logTypeTitle string
|
var logTypeTitle string
|
||||||
|
|
||||||
// Check if we want to merge logs from all sources
|
// Check if we want to merge logs from all sources
|
||||||
if LogType(logTypeParam) == LogTypeAll {
|
if LogType(logTypeParam) == LogTypeAll {
|
||||||
// Get merged logs from all loggers
|
// Get merged logs from all loggers
|
||||||
@@ -116,7 +116,7 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
// Select the appropriate logger based on the log type
|
// Select the appropriate logger based on the log type
|
||||||
var selectedLogger *logger.Logger
|
var selectedLogger *logger.Logger
|
||||||
|
|
||||||
switch LogType(logTypeParam) {
|
switch LogType(logTypeParam) {
|
||||||
case LogTypeService:
|
case LogTypeService:
|
||||||
selectedLogger = h.serviceLogger
|
selectedLogger = h.serviceLogger
|
||||||
@@ -131,13 +131,13 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
selectedLogger = h.systemLogger
|
selectedLogger = h.systemLogger
|
||||||
logTypeTitle = "System Logs"
|
logTypeTitle = "System Logs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the selected logger is properly initialized
|
// Check if the selected logger is properly initialized
|
||||||
if selectedLogger == nil {
|
if selectedLogger == nil {
|
||||||
return c.Render("admin/system/logs", fiber.Map{
|
return c.Render("admin/system/logs", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"error": "Logger not initialized",
|
"error": "Logger not initialized",
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -149,25 +149,24 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
// Handle search error
|
// Handle search error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Render("admin/system/logs", fiber.Map{
|
return c.Render("admin/system/logs", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Calculate total pages
|
// Calculate total pages
|
||||||
totalLogs := len(logs)
|
totalLogs := len(logs)
|
||||||
totalPages := (totalLogs + itemsPerPage - 1) / itemsPerPage
|
totalPages := (totalLogs + itemsPerPage - 1) / itemsPerPage
|
||||||
|
|
||||||
// Apply pagination
|
// Apply pagination
|
||||||
startIndex := (page - 1) * itemsPerPage
|
startIndex := (page - 1) * itemsPerPage
|
||||||
endIndex := startIndex + itemsPerPage
|
endIndex := startIndex + itemsPerPage
|
||||||
if endIndex > totalLogs {
|
if endIndex > totalLogs {
|
||||||
endIndex = totalLogs
|
endIndex = totalLogs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice logs for current page
|
// Slice logs for current page
|
||||||
pagedLogs := logs
|
pagedLogs := logs
|
||||||
if startIndex < totalLogs {
|
if startIndex < totalLogs {
|
||||||
@@ -175,7 +174,7 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
pagedLogs = []logger.LogItem{}
|
pagedLogs = []logger.LogItem{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert logs to a format suitable for the UI
|
// Convert logs to a format suitable for the UI
|
||||||
formattedLogs := make([]fiber.Map, 0, len(pagedLogs))
|
formattedLogs := make([]fiber.Map, 0, len(pagedLogs))
|
||||||
for _, log := range pagedLogs {
|
for _, log := range pagedLogs {
|
||||||
@@ -185,7 +184,7 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
logTypeStr = "ERROR"
|
logTypeStr = "ERROR"
|
||||||
logTypeClass = "log-error"
|
logTypeClass = "log-error"
|
||||||
}
|
}
|
||||||
|
|
||||||
formattedLogs = append(formattedLogs, fiber.Map{
|
formattedLogs = append(formattedLogs, fiber.Map{
|
||||||
"timestamp": log.Timestamp.Format("2006-01-02T15:04:05"),
|
"timestamp": log.Timestamp.Format("2006-01-02T15:04:05"),
|
||||||
"category": log.Category,
|
"category": log.Category,
|
||||||
@@ -194,20 +193,20 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
"typeClass": logTypeClass,
|
"typeClass": logTypeClass,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Render("admin/system/logs", fiber.Map{
|
return c.Render("admin/system/logs", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
"logs": formattedLogs,
|
"logs": formattedLogs,
|
||||||
"total": totalLogs,
|
"total": totalLogs,
|
||||||
"showing": len(formattedLogs),
|
"showing": len(formattedLogs),
|
||||||
"page": page,
|
"page": page,
|
||||||
"totalPages": totalPages,
|
"totalPages": totalPages,
|
||||||
"categoryParam": category,
|
"categoryParam": category,
|
||||||
"typeParam": c.Query("type", ""),
|
"typeParam": c.Query("type", ""),
|
||||||
"fromParam": c.Query("from", ""),
|
"fromParam": c.Query("from", ""),
|
||||||
"toParam": c.Query("to", ""),
|
"toParam": c.Query("to", ""),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,27 +214,27 @@ func (h *LogHandler) GetLogs(c *fiber.Ctx) error {
|
|||||||
func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
||||||
// Check which logger to use based on the log type parameter
|
// Check which logger to use based on the log type parameter
|
||||||
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
||||||
|
|
||||||
// Parse query parameters
|
// Parse query parameters
|
||||||
category := c.Query("category", "")
|
category := c.Query("category", "")
|
||||||
logItemType := parseLogType(c.Query("type", ""))
|
logItemType := parseLogType(c.Query("type", ""))
|
||||||
maxItems := c.QueryInt("max_items", 100)
|
maxItems := c.QueryInt("max_items", 100)
|
||||||
|
|
||||||
// Parse time range
|
// Parse time range
|
||||||
fromTime := parseTimeParam(c.Query("from", ""))
|
fromTime := parseTimeParam(c.Query("from", ""))
|
||||||
toTime := parseTimeParam(c.Query("to", ""))
|
toTime := parseTimeParam(c.Query("to", ""))
|
||||||
|
|
||||||
// Create search arguments
|
// Create search arguments
|
||||||
searchArgs := logger.SearchArgs{
|
searchArgs := logger.SearchArgs{
|
||||||
Category: category,
|
Category: category,
|
||||||
LogType: logItemType,
|
LogType: logItemType,
|
||||||
MaxItems: maxItems,
|
MaxItems: maxItems,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fromTime.IsZero() {
|
if !fromTime.IsZero() {
|
||||||
searchArgs.TimestampFrom = &fromTime
|
searchArgs.TimestampFrom = &fromTime
|
||||||
}
|
}
|
||||||
|
|
||||||
if !toTime.IsZero() {
|
if !toTime.IsZero() {
|
||||||
searchArgs.TimestampTo = &toTime
|
searchArgs.TimestampTo = &toTime
|
||||||
}
|
}
|
||||||
@@ -243,7 +242,7 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
// Variables for logs and error
|
// Variables for logs and error
|
||||||
var logs []logger.LogItem
|
var logs []logger.LogItem
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Check if we want to merge logs from all sources
|
// Check if we want to merge logs from all sources
|
||||||
if LogType(logTypeParam) == LogTypeAll {
|
if LogType(logTypeParam) == LogTypeAll {
|
||||||
// Get merged logs from all loggers
|
// Get merged logs from all loggers
|
||||||
@@ -251,7 +250,7 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
// Select the appropriate logger based on the log type
|
// Select the appropriate logger based on the log type
|
||||||
var selectedLogger *logger.Logger
|
var selectedLogger *logger.Logger
|
||||||
|
|
||||||
switch LogType(logTypeParam) {
|
switch LogType(logTypeParam) {
|
||||||
case LogTypeService:
|
case LogTypeService:
|
||||||
selectedLogger = h.serviceLogger
|
selectedLogger = h.serviceLogger
|
||||||
@@ -262,7 +261,7 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
default:
|
default:
|
||||||
selectedLogger = h.systemLogger
|
selectedLogger = h.systemLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the selected logger is properly initialized
|
// Check if the selected logger is properly initialized
|
||||||
if selectedLogger == nil {
|
if selectedLogger == nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
@@ -280,7 +279,7 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert logs to a format suitable for the UI
|
// Convert logs to a format suitable for the UI
|
||||||
response := make([]fiber.Map, 0, len(logs))
|
response := make([]fiber.Map, 0, len(logs))
|
||||||
for _, log := range logs {
|
for _, log := range logs {
|
||||||
@@ -288,7 +287,7 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
if log.LogType == logger.LogTypeError {
|
if log.LogType == logger.LogTypeError {
|
||||||
logTypeStr = "ERROR"
|
logTypeStr = "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
response = append(response, fiber.Map{
|
response = append(response, fiber.Map{
|
||||||
"timestamp": log.Timestamp.Format(time.RFC3339),
|
"timestamp": log.Timestamp.Format(time.RFC3339),
|
||||||
"category": log.Category,
|
"category": log.Category,
|
||||||
@@ -296,9 +295,9 @@ func (h *LogHandler) GetLogsAPI(c *fiber.Ctx) error {
|
|||||||
"type": logTypeStr,
|
"type": logTypeStr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"logs": response,
|
"logs": response,
|
||||||
"total": len(logs),
|
"total": len(logs),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -309,29 +308,29 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
// Check which logger to use based on the log type parameter
|
// Check which logger to use based on the log type parameter
|
||||||
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
logTypeParam := c.Query("log_type", string(LogTypeSystem))
|
||||||
|
|
||||||
// Parse query parameters
|
// Parse query parameters
|
||||||
category := c.Query("category", "")
|
category := c.Query("category", "")
|
||||||
logItemType := parseLogType(c.Query("type", ""))
|
logItemType := parseLogType(c.Query("type", ""))
|
||||||
maxItems := c.QueryInt("max_items", 100)
|
maxItems := c.QueryInt("max_items", 100)
|
||||||
page := c.QueryInt("page", 1)
|
page := c.QueryInt("page", 1)
|
||||||
itemsPerPage := 20 // Default items per page
|
itemsPerPage := 20 // Default items per page
|
||||||
|
|
||||||
// Parse time range
|
// Parse time range
|
||||||
fromTime := parseTimeParam(c.Query("from", ""))
|
fromTime := parseTimeParam(c.Query("from", ""))
|
||||||
toTime := parseTimeParam(c.Query("to", ""))
|
toTime := parseTimeParam(c.Query("to", ""))
|
||||||
|
|
||||||
// Create search arguments
|
// Create search arguments
|
||||||
searchArgs := logger.SearchArgs{
|
searchArgs := logger.SearchArgs{
|
||||||
Category: category,
|
Category: category,
|
||||||
LogType: logItemType,
|
LogType: logItemType,
|
||||||
MaxItems: maxItems,
|
MaxItems: maxItems,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fromTime.IsZero() {
|
if !fromTime.IsZero() {
|
||||||
searchArgs.TimestampFrom = &fromTime
|
searchArgs.TimestampFrom = &fromTime
|
||||||
}
|
}
|
||||||
|
|
||||||
if !toTime.IsZero() {
|
if !toTime.IsZero() {
|
||||||
searchArgs.TimestampTo = &toTime
|
searchArgs.TimestampTo = &toTime
|
||||||
}
|
}
|
||||||
@@ -340,7 +339,7 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
var logs []logger.LogItem
|
var logs []logger.LogItem
|
||||||
var err error
|
var err error
|
||||||
var logTypeTitle string
|
var logTypeTitle string
|
||||||
|
|
||||||
// Check if we want to merge logs from all sources
|
// Check if we want to merge logs from all sources
|
||||||
if LogType(logTypeParam) == LogTypeAll {
|
if LogType(logTypeParam) == LogTypeAll {
|
||||||
// Get merged logs from all loggers
|
// Get merged logs from all loggers
|
||||||
@@ -349,7 +348,7 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
// Select the appropriate logger based on the log type
|
// Select the appropriate logger based on the log type
|
||||||
var selectedLogger *logger.Logger
|
var selectedLogger *logger.Logger
|
||||||
|
|
||||||
switch LogType(logTypeParam) {
|
switch LogType(logTypeParam) {
|
||||||
case LogTypeService:
|
case LogTypeService:
|
||||||
selectedLogger = h.serviceLogger
|
selectedLogger = h.serviceLogger
|
||||||
@@ -364,13 +363,13 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
selectedLogger = h.systemLogger
|
selectedLogger = h.systemLogger
|
||||||
logTypeTitle = "System Logs"
|
logTypeTitle = "System Logs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the selected logger is properly initialized
|
// Check if the selected logger is properly initialized
|
||||||
if selectedLogger == nil {
|
if selectedLogger == nil {
|
||||||
return c.Render("admin/system/logs_fragment", fiber.Map{
|
return c.Render("admin/system/logs_fragment", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"error": "Logger not initialized",
|
"error": "Logger not initialized",
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -382,24 +381,24 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
// Handle search error
|
// Handle search error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Render("admin/system/logs_fragment", fiber.Map{
|
return c.Render("admin/system/logs_fragment", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total pages
|
// Calculate total pages
|
||||||
totalLogs := len(logs)
|
totalLogs := len(logs)
|
||||||
totalPages := (totalLogs + itemsPerPage - 1) / itemsPerPage
|
totalPages := (totalLogs + itemsPerPage - 1) / itemsPerPage
|
||||||
|
|
||||||
// Apply pagination
|
// Apply pagination
|
||||||
startIndex := (page - 1) * itemsPerPage
|
startIndex := (page - 1) * itemsPerPage
|
||||||
endIndex := startIndex + itemsPerPage
|
endIndex := startIndex + itemsPerPage
|
||||||
if endIndex > totalLogs {
|
if endIndex > totalLogs {
|
||||||
endIndex = totalLogs
|
endIndex = totalLogs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice logs for current page
|
// Slice logs for current page
|
||||||
pagedLogs := logs
|
pagedLogs := logs
|
||||||
if startIndex < totalLogs {
|
if startIndex < totalLogs {
|
||||||
@@ -407,7 +406,7 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
pagedLogs = []logger.LogItem{}
|
pagedLogs = []logger.LogItem{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert logs to a format suitable for the UI
|
// Convert logs to a format suitable for the UI
|
||||||
formattedLogs := make([]fiber.Map, 0, len(pagedLogs))
|
formattedLogs := make([]fiber.Map, 0, len(pagedLogs))
|
||||||
for _, log := range pagedLogs {
|
for _, log := range pagedLogs {
|
||||||
@@ -417,7 +416,7 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
logTypeStr = "ERROR"
|
logTypeStr = "ERROR"
|
||||||
logTypeClass = "log-error"
|
logTypeClass = "log-error"
|
||||||
}
|
}
|
||||||
|
|
||||||
formattedLogs = append(formattedLogs, fiber.Map{
|
formattedLogs = append(formattedLogs, fiber.Map{
|
||||||
"timestamp": log.Timestamp.Format("2006-01-02T15:04:05"),
|
"timestamp": log.Timestamp.Format("2006-01-02T15:04:05"),
|
||||||
"category": log.Category,
|
"category": log.Category,
|
||||||
@@ -426,18 +425,18 @@ func (h *LogHandler) GetLogsFragment(c *fiber.Ctx) error {
|
|||||||
"typeClass": logTypeClass,
|
"typeClass": logTypeClass,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set layout to empty to disable the layout for fragment responses
|
// Set layout to empty to disable the layout for fragment responses
|
||||||
return c.Render("admin/system/logs_fragment", fiber.Map{
|
return c.Render("admin/system/logs_fragment", fiber.Map{
|
||||||
"title": logTypeTitle,
|
"title": logTypeTitle,
|
||||||
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
"logTypes": []LogType{LogTypeAll, LogTypeSystem, LogTypeService, LogTypeJob, LogTypeProcess},
|
||||||
"selectedLogType": logTypeParam,
|
"selectedLogType": logTypeParam,
|
||||||
"logs": formattedLogs,
|
"logs": formattedLogs,
|
||||||
"total": totalLogs,
|
"total": totalLogs,
|
||||||
"showing": len(formattedLogs),
|
"showing": len(formattedLogs),
|
||||||
"page": page,
|
"page": page,
|
||||||
"totalPages": totalPages,
|
"totalPages": totalPages,
|
||||||
"layout": "", // Disable layout for partial template
|
"layout": "", // Disable layout for partial template
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,12 +457,12 @@ func parseTimeParam(timeStr string) time.Time {
|
|||||||
if timeStr == "" {
|
if timeStr == "" {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := time.Parse(time.RFC3339, timeStr)
|
t, err := time.Parse(time.RFC3339, timeStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,10 +470,10 @@ func parseTimeParam(timeStr string) time.Time {
|
|||||||
func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, error) {
|
func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, error) {
|
||||||
// Create a slice to hold all logs
|
// Create a slice to hold all logs
|
||||||
allLogs := make([]logger.LogItem, 0)
|
allLogs := make([]logger.LogItem, 0)
|
||||||
|
|
||||||
// Create a map to track errors
|
// Create a map to track errors
|
||||||
errors := make(map[string]error)
|
errors := make(map[string]error)
|
||||||
|
|
||||||
// Get logs from system logger if available
|
// Get logs from system logger if available
|
||||||
if h.systemLogger != nil {
|
if h.systemLogger != nil {
|
||||||
systemLogs, err := h.systemLogger.Search(args)
|
systemLogs, err := h.systemLogger.Search(args)
|
||||||
@@ -488,7 +487,7 @@ func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, er
|
|||||||
allLogs = append(allLogs, systemLogs...)
|
allLogs = append(allLogs, systemLogs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get logs from service logger if available
|
// Get logs from service logger if available
|
||||||
if h.serviceLogger != nil {
|
if h.serviceLogger != nil {
|
||||||
serviceLogs, err := h.serviceLogger.Search(args)
|
serviceLogs, err := h.serviceLogger.Search(args)
|
||||||
@@ -502,7 +501,7 @@ func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, er
|
|||||||
allLogs = append(allLogs, serviceLogs...)
|
allLogs = append(allLogs, serviceLogs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get logs from job logger if available
|
// Get logs from job logger if available
|
||||||
if h.jobLogger != nil {
|
if h.jobLogger != nil {
|
||||||
jobLogs, err := h.jobLogger.Search(args)
|
jobLogs, err := h.jobLogger.Search(args)
|
||||||
@@ -516,7 +515,7 @@ func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, er
|
|||||||
allLogs = append(allLogs, jobLogs...)
|
allLogs = append(allLogs, jobLogs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get logs from process logger if available
|
// Get logs from process logger if available
|
||||||
if h.processLogger != nil {
|
if h.processLogger != nil {
|
||||||
processLogs, err := h.processLogger.Search(args)
|
processLogs, err := h.processLogger.Search(args)
|
||||||
@@ -530,7 +529,7 @@ func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, er
|
|||||||
allLogs = append(allLogs, processLogs...)
|
allLogs = append(allLogs, processLogs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have any logs
|
// Check if we have any logs
|
||||||
if len(allLogs) == 0 && len(errors) > 0 {
|
if len(allLogs) == 0 && len(errors) > 0 {
|
||||||
// Combine error messages
|
// Combine error messages
|
||||||
@@ -540,16 +539,16 @@ func (h *LogHandler) getMergedLogs(args logger.SearchArgs) ([]logger.LogItem, er
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to retrieve logs: %s", strings.Join(errorMsgs, "; "))
|
return nil, fmt.Errorf("failed to retrieve logs: %s", strings.Join(errorMsgs, "; "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort logs by timestamp (newest first)
|
// Sort logs by timestamp (newest first)
|
||||||
sort.Slice(allLogs, func(i, j int) bool {
|
sort.Slice(allLogs, func(i, j int) bool {
|
||||||
return allLogs[i].Timestamp.After(allLogs[j].Timestamp)
|
return allLogs[i].Timestamp.After(allLogs[j].Timestamp)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Apply max items limit if specified
|
// Apply max items limit if specified
|
||||||
if args.MaxItems > 0 && len(allLogs) > args.MaxItems {
|
if args.MaxItems > 0 && len(allLogs) > args.MaxItems {
|
||||||
allLogs = allLogs[:args.MaxItems]
|
allLogs = allLogs[:args.MaxItems]
|
||||||
}
|
}
|
||||||
|
|
||||||
return allLogs, nil
|
return allLogs, nil
|
||||||
}
|
}
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
|
"git.threefold.info/herocode/heroagent/pkg/system/stats"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,8 +43,8 @@ func (h *ProcessHandler) GetProcessStatsJSON(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
// Convert to fiber.Map for JSON response
|
// Convert to fiber.Map for JSON response
|
||||||
response := fiber.Map{
|
response := fiber.Map{
|
||||||
"total": processData.Total,
|
"total": processData.Total,
|
||||||
"filtered": processData.Filtered,
|
"filtered": processData.Filtered,
|
||||||
"timestamp": time.Now().Unix(),
|
"timestamp": time.Now().Unix(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (h *ProcessHandler) GetProcessStatsJSON(c *fiber.Ctx) error {
|
|||||||
"is_current": proc.IsCurrent,
|
"is_current": proc.IsCurrent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response["processes"] = processes
|
response["processes"] = processes
|
||||||
|
|
||||||
// Return JSON response
|
// Return JSON response
|
||||||
@@ -127,8 +127,8 @@ func (h *ProcessHandler) GetProcessesData(c *fiber.Ctx) error {
|
|||||||
// Check if StatsManager is properly initialized
|
// Check if StatsManager is properly initialized
|
||||||
if h.statsManager == nil {
|
if h.statsManager == nil {
|
||||||
return c.Render("admin/system/processes_data", fiber.Map{
|
return c.Render("admin/system/processes_data", fiber.Map{
|
||||||
"error": "System error: Stats manager not initialized",
|
"error": "System error: Stats manager not initialized",
|
||||||
"layout": "",
|
"layout": "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ func (h *ProcessHandler) GetProcessesData(c *fiber.Ctx) error {
|
|||||||
} else {
|
} else {
|
||||||
processData, err = h.statsManager.GetProcessStatsFresh(0)
|
processData, err = h.statsManager.GetProcessStatsFresh(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Handle AJAX requests differently from regular requests
|
// Handle AJAX requests differently from regular requests
|
||||||
isAjax := c.Get("X-Requested-With") == "XMLHttpRequest"
|
isAjax := c.Get("X-Requested-With") == "XMLHttpRequest"
|
||||||
@@ -165,8 +165,8 @@ func (h *ProcessHandler) GetProcessesData(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
// For regular requests, render the error within the fragment
|
// For regular requests, render the error within the fragment
|
||||||
return c.Render("admin/system/processes_data", fiber.Map{
|
return c.Render("admin/system/processes_data", fiber.Map{
|
||||||
"error": "Failed to get process data: " + err.Error(),
|
"error": "Failed to get process data: " + err.Error(),
|
||||||
"layout": "",
|
"layout": "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,9 +197,7 @@ func (h *ProcessHandler) GetProcessesData(c *fiber.Ctx) error {
|
|||||||
"processStats": processStats,
|
"processStats": processStats,
|
||||||
"layout": "", // Disable layout for partial template
|
"layout": "", // Disable layout for partial template
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return only the table HTML content directly to be injected into the processes-table-content div
|
// Return only the table HTML content directly to be injected into the processes-table-content div
|
||||||
return c.Render("admin/system/processes_data", templateData)
|
return c.Render("admin/system/processes_data", templateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager/interfaces"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager/interfaces"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager/interfaces/openrpc"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager/interfaces/openrpc"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
|
"git.threefold.info/herocode/heroagent/pkg/system/stats"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/shirou/gopsutil/v3/host"
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
)
|
)
|
||||||
@@ -335,7 +335,7 @@ func (h *SystemHandler) GetProcessStatsAPI(c *fiber.Ctx) error {
|
|||||||
"is_current": proc.IsCurrent,
|
"is_current": proc.IsCurrent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response["processes"] = processes
|
response["processes"] = processes
|
||||||
|
|
||||||
// Return JSON response
|
// Return JSON response
|
@@ -7,8 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroagent/handlers"
|
"git.threefold.info/herocode/heroagent/pkg/heroagent/handlers"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/system/stats"
|
"git.threefold.info/herocode/heroagent/pkg/system/stats"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/shirou/gopsutil/v3/host"
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
)
|
)
|
||||||
@@ -68,12 +68,12 @@ func (h *AdminHandler) RegisterRoutes(app *fiber.App) {
|
|||||||
// System routes
|
// System routes
|
||||||
admin.Get("/system/info", h.getSystemInfo)
|
admin.Get("/system/info", h.getSystemInfo)
|
||||||
admin.Get("/system/hardware-stats", h.getHardwareStats)
|
admin.Get("/system/hardware-stats", h.getHardwareStats)
|
||||||
|
|
||||||
// Create process handler
|
// Create process handler
|
||||||
processHandler := handlers.NewProcessHandler(h.statsManager)
|
processHandler := handlers.NewProcessHandler(h.statsManager)
|
||||||
admin.Get("/system/processes", processHandler.GetProcesses)
|
admin.Get("/system/processes", processHandler.GetProcesses)
|
||||||
admin.Get("/system/processes-data", processHandler.GetProcessesData)
|
admin.Get("/system/processes-data", processHandler.GetProcessesData)
|
||||||
|
|
||||||
// Create log handler
|
// Create log handler
|
||||||
// Ensure log directory exists
|
// Ensure log directory exists
|
||||||
// Using the same shared logs path as process manager
|
// Using the same shared logs path as process manager
|
||||||
@@ -81,7 +81,7 @@ func (h *AdminHandler) RegisterRoutes(app *fiber.App) {
|
|||||||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||||
fmt.Printf("Error creating log directory: %v\n", err)
|
fmt.Printf("Error creating log directory: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logHandler, err := handlers.NewLogHandler(logDir)
|
logHandler, err := handlers.NewLogHandler(logDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error creating log handler: %v\n", err)
|
fmt.Printf("Error creating log handler: %v\n", err)
|
||||||
@@ -96,11 +96,11 @@ func (h *AdminHandler) RegisterRoutes(app *fiber.App) {
|
|||||||
// but it now just redirects to the main logs endpoint
|
// but it now just redirects to the main logs endpoint
|
||||||
admin.Get("/system/logs-fragment", logHandler.GetLogsFragment)
|
admin.Get("/system/logs-fragment", logHandler.GetLogsFragment)
|
||||||
admin.Get("/system/logs-test", h.getSystemLogsTest) // Keep the test logs route
|
admin.Get("/system/logs-test", h.getSystemLogsTest) // Keep the test logs route
|
||||||
|
|
||||||
// Log API endpoints
|
// Log API endpoints
|
||||||
app.Get("/api/logs", logHandler.GetLogsAPI)
|
app.Get("/api/logs", logHandler.GetLogsAPI)
|
||||||
}
|
}
|
||||||
|
|
||||||
admin.Get("/system/settings", h.getSystemSettings)
|
admin.Get("/system/settings", h.getSystemSettings)
|
||||||
|
|
||||||
// OpenRPC routes
|
// OpenRPC routes
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/herojobs"
|
"git.threefold.info/herocode/heroagent/pkg/herojobs"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
@@ -4,14 +4,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager/interfaces/openrpc"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager/interfaces/openrpc"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceHandler handles service-related page routes
|
// ServiceHandler handles service-related page routes
|
||||||
type ServiceHandler struct {
|
type ServiceHandler struct {
|
||||||
client *openrpc.Client
|
client *openrpc.Client
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServiceHandler creates a new service handler with the provided socket path and secret
|
// NewServiceHandler creates a new service handler with the provided socket path and secret
|
||||||
@@ -90,7 +90,7 @@ func (h *ServiceHandler) getProcessList() ([]ProcessDisplayInfo, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a ProcessDisplayInfo from the map
|
// Create a ProcessDisplayInfo from the map
|
||||||
displayInfo := ProcessDisplayInfo{
|
displayInfo := ProcessDisplayInfo{
|
||||||
ID: fmt.Sprintf("%v", procMap["pid"]),
|
ID: fmt.Sprintf("%v", procMap["pid"]),
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProcessDisplayInfo represents information about a process for display purposes
|
// ProcessDisplayInfo represents information about a process for display purposes
|
||||||
@@ -22,7 +22,7 @@ type ProcessDisplayInfo struct {
|
|||||||
func ConvertToDisplayInfo(info *processmanager.ProcessInfo) ProcessDisplayInfo {
|
func ConvertToDisplayInfo(info *processmanager.ProcessInfo) ProcessDisplayInfo {
|
||||||
// Calculate uptime from start time
|
// Calculate uptime from start time
|
||||||
uptime := formatUptime(time.Since(info.StartTime))
|
uptime := formatUptime(time.Since(info.StartTime))
|
||||||
|
|
||||||
return ProcessDisplayInfo{
|
return ProcessDisplayInfo{
|
||||||
ID: fmt.Sprintf("%d", info.PID),
|
ID: fmt.Sprintf("%d", info.PID),
|
||||||
Name: info.Name,
|
Name: info.Name,
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 844 B |
@@ -35,7 +35,7 @@ Key features:
|
|||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create a new playbook from HeroScript text
|
// Create a new playbook from HeroScript text
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory/herohandler"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory/herohandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -24,7 +24,7 @@ func main() {
|
|||||||
fmt.Printf("Failed to initialize hero handler: %v\n", err)
|
fmt.Printf("Failed to initialize hero handler: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the default instance
|
// Get the default instance
|
||||||
handler := herohandler.DefaultInstance
|
handler := herohandler.DefaultInstance
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ func main() {
|
|||||||
tcpAddressStr = *tcpAddress
|
tcpAddressStr = *tcpAddress
|
||||||
fmt.Printf("TCP address: %s\n", tcpAddressStr)
|
fmt.Printf("TCP address: %s\n", tcpAddressStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.StartTelnet(socketPathStr, tcpAddressStr)
|
err = handler.StartTelnet(socketPathStr, tcpAddressStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to start telnet server: %v\n", err)
|
fmt.Printf("Failed to start telnet server: %v\n", err)
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
@@ -3,8 +3,8 @@ package internal
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlers"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExampleHandler handles example actions
|
// ExampleHandler handles example actions
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/cmd/herohandler/internal"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/cmd/herohandler/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -30,7 +30,7 @@ func main() {
|
|||||||
|
|
||||||
// Get the command from arguments
|
// Get the command from arguments
|
||||||
command := strings.Join(os.Args[1:], " ")
|
command := strings.Join(os.Args[1:], " ")
|
||||||
|
|
||||||
// Format as proper HeroScript with !! prefix if not already prefixed
|
// Format as proper HeroScript with !! prefix if not already prefixed
|
||||||
script := command
|
script := command
|
||||||
if !strings.HasPrefix(script, "!!") {
|
if !strings.HasPrefix(script, "!!") {
|
@@ -10,7 +10,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory/herohandler"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory/herohandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -92,7 +92,7 @@ func showSupportedActions() {
|
|||||||
// We need to implement this function to get supported actions
|
// We need to implement this function to get supported actions
|
||||||
// Since we can't directly access the factory field, we'll use the telnet interface
|
// Since we can't directly access the factory field, we'll use the telnet interface
|
||||||
script := "!!core.actions"
|
script := "!!core.actions"
|
||||||
|
|
||||||
// Try TCP first, then Unix socket if TCP fails
|
// Try TCP first, then Unix socket if TCP fails
|
||||||
result, err := Send(script, "localhost:8023", false)
|
result, err := Send(script, "localhost:8023", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -103,7 +103,7 @@ func showSupportedActions() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Supported actions by actor:")
|
fmt.Println("Supported actions by actor:")
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ func Send(command string, address string, isUnixSocket bool) (string, error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.WriteString(line)
|
response.WriteString(line)
|
||||||
|
|
||||||
// If we've received a complete response, break
|
// If we've received a complete response, break
|
||||||
if strings.Contains(line, "\n") && strings.TrimSpace(line) == "" {
|
if strings.Contains(line, "\n") && strings.TrimSpace(line) == "" {
|
||||||
break
|
break
|
||||||
@@ -187,7 +187,7 @@ func runTestScript() {
|
|||||||
result, err = Send(script, "/tmp/hero.sock", true)
|
result, err = Send(script, "/tmp/hero.sock", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Unix socket connection failed: %v\n", err)
|
fmt.Printf("Unix socket connection failed: %v\n", err)
|
||||||
|
|
||||||
// We can't directly access the factory field, so we'll just report the error
|
// We can't directly access the factory field, so we'll just report the error
|
||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("Error: %v\n", err)
|
||||||
return
|
return
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
const exampleScript = `
|
const exampleScript = `
|
@@ -16,7 +16,7 @@ The VM handler example shows how to:
|
|||||||
To run the example:
|
To run the example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/code/github/freeflowuniverse/heroagent/pkg/handlerfactory/cmd/vmhandler
|
cd ~/code/github/freeflowuniverse/herocode/heroagent/pkg/handlerfactory/cmd/vmhandler
|
||||||
go run . tutorial
|
go run . tutorial
|
||||||
#to run just the server do
|
#to run just the server do
|
||||||
go run .
|
go run .
|
@@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory"
|
||||||
)
|
)
|
||||||
|
|
||||||
// runTutorial runs an interactive tutorial demonstrating the VM handler
|
// runTutorial runs an interactive tutorial demonstrating the VM handler
|
||||||
@@ -50,7 +50,7 @@ func runTutorial() {
|
|||||||
|
|
||||||
// Process heroscript commands
|
// Process heroscript commands
|
||||||
fmt.Println("\nStep 5: Process heroscript commands")
|
fmt.Println("\nStep 5: Process heroscript commands")
|
||||||
|
|
||||||
// Define a VM
|
// Define a VM
|
||||||
defineScript := `!!vm.define name:'tutorial_vm' cpu:2 memory:'4GB' storage:'50GB'
|
defineScript := `!!vm.define name:'tutorial_vm' cpu:2 memory:'4GB' storage:'50GB'
|
||||||
description: 'A tutorial VM for demonstration purposes'`
|
description: 'A tutorial VM for demonstration purposes'`
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VMHandler handles VM-related actions
|
// VMHandler handles VM-related actions
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/handlerfactory"
|
"git.threefold.info/herocode/heroagent/pkg/handlerfactory"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The tutorial functions are defined in tutorial.go
|
// The tutorial functions are defined in tutorial.go
|
@@ -30,7 +30,7 @@ The Handler Factory exposes two interfaces for communication:
|
|||||||
to get started
|
to get started
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /root/code/github/freeflowuniverse/heroagent/pkg/handlerfactory/herohandler/cmd
|
cd /root/code/github/freeflowuniverse/herocode/heroagent/pkg/handlerfactory/herohandler/cmd
|
||||||
go run .
|
go run .
|
||||||
```
|
```
|
||||||
|
|
@@ -5,8 +5,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/paramsparser"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/paramsparser"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler interface defines methods that all handlers must implement
|
// Handler interface defines methods that all handlers must implement
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerFactory manages a collection of handlers
|
// HandlerFactory manages a collection of handlers
|
@@ -12,7 +12,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ANSI color codes for terminal output
|
// ANSI color codes for terminal output
|
||||||
@@ -43,23 +43,23 @@ type TelnetServer struct {
|
|||||||
sigCh chan os.Signal
|
sigCh chan os.Signal
|
||||||
onShutdown func()
|
onShutdown func()
|
||||||
// Map to store client preferences (like json formatting)
|
// Map to store client preferences (like json formatting)
|
||||||
clientPrefs map[net.Conn]map[string]bool
|
clientPrefs map[net.Conn]map[string]bool
|
||||||
prefsMutex sync.RWMutex
|
prefsMutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTelnetServer creates a new telnet server
|
// NewTelnetServer creates a new telnet server
|
||||||
func NewTelnetServer(factory *HandlerFactory, secrets ...string) *TelnetServer {
|
func NewTelnetServer(factory *HandlerFactory, secrets ...string) *TelnetServer {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
return &TelnetServer{
|
return &TelnetServer{
|
||||||
factory: factory,
|
factory: factory,
|
||||||
secrets: secrets,
|
secrets: secrets,
|
||||||
clients: make(map[net.Conn]bool),
|
clients: make(map[net.Conn]bool),
|
||||||
clientPrefs: make(map[net.Conn]map[string]bool),
|
clientPrefs: make(map[net.Conn]map[string]bool),
|
||||||
running: false,
|
running: false,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
sigCh: make(chan os.Signal, 1),
|
sigCh: make(chan os.Signal, 1),
|
||||||
onShutdown: func() {},
|
onShutdown: func() {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ func (ts *TelnetServer) handleConnection(conn net.Conn) {
|
|||||||
ts.clientsMutex.Lock()
|
ts.clientsMutex.Lock()
|
||||||
ts.clients[conn] = false
|
ts.clients[conn] = false
|
||||||
ts.clientsMutex.Unlock()
|
ts.clientsMutex.Unlock()
|
||||||
|
|
||||||
// Initialize client preferences
|
// Initialize client preferences
|
||||||
ts.prefsMutex.Lock()
|
ts.prefsMutex.Lock()
|
||||||
ts.clientPrefs[conn] = make(map[string]bool)
|
ts.clientPrefs[conn] = make(map[string]bool)
|
||||||
@@ -284,7 +284,7 @@ func (ts *TelnetServer) handleConnection(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle JSON format toggle
|
// Handle JSON format toggle
|
||||||
if line == "!!json" {
|
if line == "!!json" {
|
||||||
ts.prefsMutex.Lock()
|
ts.prefsMutex.Lock()
|
||||||
@@ -293,12 +293,12 @@ func (ts *TelnetServer) handleConnection(conn net.Conn) {
|
|||||||
prefs = make(map[string]bool)
|
prefs = make(map[string]bool)
|
||||||
ts.clientPrefs[conn] = prefs
|
ts.clientPrefs[conn] = prefs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle JSON format preference
|
// Toggle JSON format preference
|
||||||
currentSetting := prefs["json"]
|
currentSetting := prefs["json"]
|
||||||
prefs["json"] = !currentSetting
|
prefs["json"] = !currentSetting
|
||||||
ts.prefsMutex.Unlock()
|
ts.prefsMutex.Unlock()
|
||||||
|
|
||||||
if prefs["json"] {
|
if prefs["json"] {
|
||||||
conn.Write([]byte("JSON format will be automatically added to all heroscripts.\n"))
|
conn.Write([]byte("JSON format will be automatically added to all heroscripts.\n"))
|
||||||
} else {
|
} else {
|
||||||
@@ -416,7 +416,7 @@ func (ts *TelnetServer) executeHeroscript(script string, conn net.Conn, interact
|
|||||||
ts.prefsMutex.RLock()
|
ts.prefsMutex.RLock()
|
||||||
prefs, exists := ts.clientPrefs[conn]
|
prefs, exists := ts.clientPrefs[conn]
|
||||||
ts.prefsMutex.RUnlock()
|
ts.prefsMutex.RUnlock()
|
||||||
|
|
||||||
if exists && prefs["json"] {
|
if exists && prefs["json"] {
|
||||||
// Add format:json if not already present
|
// Add format:json if not already present
|
||||||
if !strings.Contains(script, "format:json") {
|
if !strings.Contains(script, "format:json") {
|
||||||
@@ -424,7 +424,7 @@ func (ts *TelnetServer) executeHeroscript(script string, conn net.Conn, interact
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if interactive {
|
if interactive {
|
||||||
// Format the script with colors
|
// Format the script with colors
|
||||||
formattedScript := formatHeroscript(script)
|
formattedScript := formatHeroscript(script)
|
||||||
@@ -466,8 +466,6 @@ func (ts *TelnetServer) addJsonFormat(script string) string {
|
|||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// formatHeroscript formats heroscript with colors for console output only
|
// formatHeroscript formats heroscript with colors for console output only
|
||||||
// This is not used for telnet responses, only for server-side logging
|
// This is not used for telnet responses, only for server-side logging
|
||||||
func formatHeroscript(script string) string {
|
func formatHeroscript(script string) string {
|
||||||
@@ -611,12 +609,12 @@ func (ts *TelnetServer) generateHelpText(interactive bool) string {
|
|||||||
// Try to call the Help method on each handler using reflection
|
// Try to call the Help method on each handler using reflection
|
||||||
handlerValue := reflect.ValueOf(handler)
|
handlerValue := reflect.ValueOf(handler)
|
||||||
helpMethod := handlerValue.MethodByName("Help")
|
helpMethod := handlerValue.MethodByName("Help")
|
||||||
|
|
||||||
if helpMethod.IsValid() {
|
if helpMethod.IsValid() {
|
||||||
// Call the Help method
|
// Call the Help method
|
||||||
args := []reflect.Value{reflect.ValueOf("")}
|
args := []reflect.Value{reflect.ValueOf("")}
|
||||||
result := helpMethod.Call(args)
|
result := helpMethod.Call(args)
|
||||||
|
|
||||||
// Get the result
|
// Get the result
|
||||||
if len(result) > 0 && result[0].Kind() == reflect.String {
|
if len(result) > 0 && result[0].Kind() == reflect.String {
|
||||||
helpText := result[0].String()
|
helpText := result[0].String()
|
@@ -3,7 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthHandler handles authentication actions
|
// AuthHandler handles authentication actions
|
@@ -5,9 +5,9 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/paramsparser"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/paramsparser"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BaseHandler provides common functionality for all handlers
|
// BaseHandler provides common functionality for all handlers
|
@@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerFactory manages a collection of handlers for processing HeroScript commands
|
// HandlerFactory manages a collection of handlers for processing HeroScript commands
|
@@ -1,7 +1,7 @@
|
|||||||
package herohandler
|
package herohandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFactory returns the handler factory
|
// GetFactory returns the handler factory
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/herohandler"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/herohandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
@@ -4,10 +4,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
|
|
||||||
// "github.com/freeflowuniverse/heroagent/pkg/handlerfactory/heroscript/handlerfactory/fakehandler"
|
// "git.threefold.info/herocode/heroagent/pkg/handlerfactory/heroscript/handlerfactory/fakehandler"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/processmanagerhandler"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/processmanagerhandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HeroHandler is the main handler factory that manages all registered handlers
|
// HeroHandler is the main handler factory that manages all registered handlers
|
@@ -3,7 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/playbook"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
@@ -3,8 +3,8 @@ package processmanagerhandler
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/heroscript/handlerfactory/core"
|
"git.threefold.info/herocode/heroagent/pkg/heroscript/handlerfactory/core"
|
||||||
"github.com/freeflowuniverse/heroagent/pkg/processmanager"
|
"git.threefold.info/herocode/heroagent/pkg/processmanager"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProcessManagerHandler handles process manager-related actions
|
// ProcessManagerHandler handles process manager-related actions
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user