mirror of
https://github.com/lordmathis/llamactl.git
synced 2025-11-06 00:54:23 +00:00
Fix getting remote instance logs
This commit is contained in:
@@ -26,7 +26,7 @@ type InstanceManager interface {
|
||||
StopInstance(name string) (*instance.Process, error)
|
||||
EvictLRUInstance() error
|
||||
RestartInstance(name string) (*instance.Process, error)
|
||||
GetInstanceLogs(name string) (string, error)
|
||||
GetInstanceLogs(name string, numLines int) (string, error)
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ type RemoteManager interface {
|
||||
StartRemoteInstance(node *config.NodeConfig, name string) (*instance.Process, error)
|
||||
StopRemoteInstance(node *config.NodeConfig, name string) (*instance.Process, error)
|
||||
RestartRemoteInstance(node *config.NodeConfig, name string) (*instance.Process, error)
|
||||
GetRemoteInstanceLogs(node *config.NodeConfig, name string) (string, error)
|
||||
GetRemoteInstanceLogs(node *config.NodeConfig, name string, numLines int) (string, error)
|
||||
}
|
||||
|
||||
type instanceManager struct {
|
||||
|
||||
@@ -13,15 +13,33 @@ import (
|
||||
type MaxRunningInstancesError error
|
||||
|
||||
// ListInstances returns a list of all instances managed by the instance manager.
|
||||
// For remote instances, this fetches the live state from remote nodes and updates local stubs.
|
||||
func (im *instanceManager) ListInstances() ([]*instance.Process, error) {
|
||||
im.mu.RLock()
|
||||
defer im.mu.RUnlock()
|
||||
|
||||
instances := make([]*instance.Process, 0, len(im.instances))
|
||||
localInstances := make([]*instance.Process, 0, len(im.instances))
|
||||
for _, inst := range im.instances {
|
||||
instances = append(instances, inst)
|
||||
localInstances = append(localInstances, inst)
|
||||
}
|
||||
return instances, nil
|
||||
im.mu.RUnlock()
|
||||
|
||||
// Update remote instances with live state
|
||||
for _, inst := range localInstances {
|
||||
if node := im.getNodeForInstance(inst); node != nil {
|
||||
remoteInst, err := im.GetRemoteInstance(node, inst.Name)
|
||||
if err != nil {
|
||||
// Log error but continue with stale data
|
||||
// Don't fail the entire list operation due to one remote failure
|
||||
continue
|
||||
}
|
||||
|
||||
// Update the local stub's status to reflect remote state
|
||||
im.mu.Lock()
|
||||
inst.Status = remoteInst.Status
|
||||
im.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
return localInstances, nil
|
||||
}
|
||||
|
||||
// CreateInstance creates a new instance with the given options and returns it.
|
||||
@@ -115,6 +133,7 @@ func (im *instanceManager) CreateInstance(name string, options *instance.CreateI
|
||||
}
|
||||
|
||||
// GetInstance retrieves an instance by its name.
|
||||
// For remote instances, this fetches the live state from the remote node and updates the local stub.
|
||||
func (im *instanceManager) GetInstance(name string) (*instance.Process, error) {
|
||||
im.mu.RLock()
|
||||
inst, exists := im.instances[name]
|
||||
@@ -124,9 +143,20 @@ func (im *instanceManager) GetInstance(name string) (*instance.Process, error) {
|
||||
return nil, fmt.Errorf("instance with name %s not found", name)
|
||||
}
|
||||
|
||||
// Check if instance is remote and delegate to remote operation
|
||||
// Check if instance is remote and fetch live state
|
||||
if node := im.getNodeForInstance(inst); node != nil {
|
||||
return im.GetRemoteInstance(node, name)
|
||||
remoteInst, err := im.GetRemoteInstance(node, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update the local stub's status to reflect remote state
|
||||
im.mu.Lock()
|
||||
inst.Status = remoteInst.Status
|
||||
im.mu.Unlock()
|
||||
|
||||
// Return the local stub (preserving Nodes field)
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
return inst, nil
|
||||
@@ -401,7 +431,7 @@ func (im *instanceManager) RestartInstance(name string) (*instance.Process, erro
|
||||
}
|
||||
|
||||
// GetInstanceLogs retrieves the logs for a specific instance by its name.
|
||||
func (im *instanceManager) GetInstanceLogs(name string) (string, error) {
|
||||
func (im *instanceManager) GetInstanceLogs(name string, numLines int) (string, error) {
|
||||
im.mu.RLock()
|
||||
inst, exists := im.instances[name]
|
||||
im.mu.RUnlock()
|
||||
@@ -412,11 +442,11 @@ func (im *instanceManager) GetInstanceLogs(name string) (string, error) {
|
||||
|
||||
// Check if instance is remote and delegate to remote operation
|
||||
if node := im.getNodeForInstance(inst); node != nil {
|
||||
return im.GetRemoteInstanceLogs(node, name)
|
||||
return im.GetRemoteInstanceLogs(node, name, numLines)
|
||||
}
|
||||
|
||||
// TODO: Implement actual log retrieval logic
|
||||
return fmt.Sprintf("Logs for instance %s", name), nil
|
||||
// Get logs from the local instance
|
||||
return inst.GetLogs(numLines)
|
||||
}
|
||||
|
||||
// getPortFromOptions extracts the port from backend-specific options
|
||||
|
||||
@@ -211,8 +211,8 @@ func (im *instanceManager) RestartRemoteInstance(nodeConfig *config.NodeConfig,
|
||||
}
|
||||
|
||||
// GetRemoteInstanceLogs retrieves logs for an instance from the remote node
|
||||
func (im *instanceManager) GetRemoteInstanceLogs(nodeConfig *config.NodeConfig, name string) (string, error) {
|
||||
path := fmt.Sprintf("/api/v1/instances/%s/logs", name)
|
||||
func (im *instanceManager) GetRemoteInstanceLogs(nodeConfig *config.NodeConfig, name string, numLines int) (string, error) {
|
||||
path := fmt.Sprintf("/api/v1/instances/%s/logs?lines=%d", name, numLines)
|
||||
resp, err := im.makeRemoteRequest(nodeConfig, "GET", path, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -308,23 +308,18 @@ func (h *Handler) GetInstanceLogs() http.HandlerFunc {
|
||||
}
|
||||
|
||||
lines := r.URL.Query().Get("lines")
|
||||
if lines == "" {
|
||||
lines = "-1"
|
||||
}
|
||||
|
||||
num_lines, err := strconv.Atoi(lines)
|
||||
numLines := -1 // Default to all lines
|
||||
if lines != "" {
|
||||
parsedLines, err := strconv.Atoi(lines)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid lines parameter: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
inst, err := h.InstanceManager.GetInstance(name)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get instance: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
numLines = parsedLines
|
||||
}
|
||||
|
||||
logs, err := inst.GetLogs(num_lines)
|
||||
// Use the instance manager which handles both local and remote instances
|
||||
logs, err := h.InstanceManager.GetInstanceLogs(name, numLines)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get logs: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user