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)
|
StopInstance(name string) (*instance.Process, error)
|
||||||
EvictLRUInstance() error
|
EvictLRUInstance() error
|
||||||
RestartInstance(name string) (*instance.Process, error)
|
RestartInstance(name string) (*instance.Process, error)
|
||||||
GetInstanceLogs(name string) (string, error)
|
GetInstanceLogs(name string, numLines int) (string, error)
|
||||||
Shutdown()
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ type RemoteManager interface {
|
|||||||
StartRemoteInstance(node *config.NodeConfig, name string) (*instance.Process, error)
|
StartRemoteInstance(node *config.NodeConfig, name string) (*instance.Process, error)
|
||||||
StopRemoteInstance(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)
|
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 {
|
type instanceManager struct {
|
||||||
|
|||||||
@@ -13,15 +13,33 @@ import (
|
|||||||
type MaxRunningInstancesError error
|
type MaxRunningInstancesError error
|
||||||
|
|
||||||
// ListInstances returns a list of all instances managed by the instance manager.
|
// 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) {
|
func (im *instanceManager) ListInstances() ([]*instance.Process, error) {
|
||||||
im.mu.RLock()
|
im.mu.RLock()
|
||||||
defer im.mu.RUnlock()
|
localInstances := make([]*instance.Process, 0, len(im.instances))
|
||||||
|
|
||||||
instances := make([]*instance.Process, 0, len(im.instances))
|
|
||||||
for _, inst := range 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.
|
// 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.
|
// 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) {
|
func (im *instanceManager) GetInstance(name string) (*instance.Process, error) {
|
||||||
im.mu.RLock()
|
im.mu.RLock()
|
||||||
inst, exists := im.instances[name]
|
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)
|
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 {
|
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
|
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.
|
// 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()
|
im.mu.RLock()
|
||||||
inst, exists := im.instances[name]
|
inst, exists := im.instances[name]
|
||||||
im.mu.RUnlock()
|
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
|
// Check if instance is remote and delegate to remote operation
|
||||||
if node := im.getNodeForInstance(inst); node != nil {
|
if node := im.getNodeForInstance(inst); node != nil {
|
||||||
return im.GetRemoteInstanceLogs(node, name)
|
return im.GetRemoteInstanceLogs(node, name, numLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement actual log retrieval logic
|
// Get logs from the local instance
|
||||||
return fmt.Sprintf("Logs for instance %s", name), nil
|
return inst.GetLogs(numLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPortFromOptions extracts the port from backend-specific options
|
// 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
|
// GetRemoteInstanceLogs retrieves logs for an instance from the remote node
|
||||||
func (im *instanceManager) GetRemoteInstanceLogs(nodeConfig *config.NodeConfig, name string) (string, error) {
|
func (im *instanceManager) GetRemoteInstanceLogs(nodeConfig *config.NodeConfig, name string, numLines int) (string, error) {
|
||||||
path := fmt.Sprintf("/api/v1/instances/%s/logs", name)
|
path := fmt.Sprintf("/api/v1/instances/%s/logs?lines=%d", name, numLines)
|
||||||
resp, err := im.makeRemoteRequest(nodeConfig, "GET", path, nil)
|
resp, err := im.makeRemoteRequest(nodeConfig, "GET", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|||||||
@@ -308,23 +308,18 @@ func (h *Handler) GetInstanceLogs() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lines := r.URL.Query().Get("lines")
|
lines := r.URL.Query().Get("lines")
|
||||||
if lines == "" {
|
numLines := -1 // Default to all lines
|
||||||
lines = "-1"
|
if lines != "" {
|
||||||
}
|
parsedLines, err := strconv.Atoi(lines)
|
||||||
|
|
||||||
num_lines, err := strconv.Atoi(lines)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Invalid lines parameter: "+err.Error(), http.StatusBadRequest)
|
http.Error(w, "Invalid lines parameter: "+err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
numLines = parsedLines
|
||||||
inst, err := h.InstanceManager.GetInstance(name)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, "Failed to get instance: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
if err != nil {
|
||||||
http.Error(w, "Failed to get logs: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Failed to get logs: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user