mirror of https://github.com/jetkvm/kvm.git
Handle error conditions better and detect support methods automatically
This commit is contained in:
parent
e61decfb33
commit
2428c15f88
|
@ -53,8 +53,10 @@ func (p *PluginInstall) GetStatus() (*PluginStatus, error) {
|
||||||
Enabled: p.Enabled,
|
Enabled: p.Enabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.rpcServer != nil && p.rpcServer.status.Status != "disconnected" {
|
// If the rpc server is connected and the plugin is reporting status, use that
|
||||||
log.Printf("Status from RPC: %v", p.rpcServer.status)
|
if p.rpcServer != nil &&
|
||||||
|
p.rpcServer.status.Status != "disconnected" &&
|
||||||
|
p.rpcServer.status.Status != "unknown" {
|
||||||
status.Status = p.rpcServer.status.Status
|
status.Status = p.rpcServer.status.Status
|
||||||
status.Message = p.rpcServer.status.Message
|
status.Message = p.rpcServer.status.Message
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ func (p *PluginInstall) GetStatus() (*PluginStatus, error) {
|
||||||
if p.processManager != nil {
|
if p.processManager != nil {
|
||||||
status.Status = "running"
|
status.Status = "running"
|
||||||
if p.processManager.LastError != nil {
|
if p.processManager.LastError != nil {
|
||||||
status.Status = "errored"
|
status.Status = "error"
|
||||||
status.Message = p.processManager.LastError.Error()
|
status.Message = p.processManager.LastError.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,12 +20,17 @@ type PluginRpcStatus struct {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
PluginRpcStatusDisconnected = PluginRpcStatus{"disconnected", ""}
|
PluginRpcStatusDisconnected = PluginRpcStatus{"disconnected", ""}
|
||||||
|
PluginRpcStatusUnknown = PluginRpcStatus{"unknown", ""}
|
||||||
PluginRpcStatusLoading = PluginRpcStatus{"loading", ""}
|
PluginRpcStatusLoading = PluginRpcStatus{"loading", ""}
|
||||||
PluginRpcStatusPendingConfiguration = PluginRpcStatus{"pending-configuration", ""}
|
PluginRpcStatusPendingConfiguration = PluginRpcStatus{"pending-configuration", ""}
|
||||||
PluginRpcStatusRunning = PluginRpcStatus{"running", ""}
|
PluginRpcStatusRunning = PluginRpcStatus{"running", ""}
|
||||||
PluginRpcStatusError = PluginRpcStatus{"error", ""}
|
PluginRpcStatusError = PluginRpcStatus{"error", ""}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PluginRpcSupportedMethods struct {
|
||||||
|
SupportedRpcMethods []string `json:"supported_rpc_methods"`
|
||||||
|
}
|
||||||
|
|
||||||
type PluginRpcServer struct {
|
type PluginRpcServer struct {
|
||||||
install *PluginInstall
|
install *PluginInstall
|
||||||
workingDir string
|
workingDir string
|
||||||
|
@ -103,10 +109,10 @@ func (s *PluginRpcServer) handleConnection(conn net.Conn) {
|
||||||
// TODO: if read 65k bytes, then likey there is more data to read... figure out how to handle this
|
// TODO: if read 65k bytes, then likey there is more data to read... figure out how to handle this
|
||||||
n, err := conn.Read(buf)
|
n, err := conn.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to read message: %v", err)
|
|
||||||
if errors.Is(err, net.ErrClosed) {
|
if errors.Is(err, net.ErrClosed) {
|
||||||
s.status = PluginRpcStatusDisconnected
|
s.status = PluginRpcStatusDisconnected
|
||||||
} else {
|
} else {
|
||||||
|
log.Printf("Failed to read message: %v", err)
|
||||||
s.status = PluginRpcStatusError
|
s.status = PluginRpcStatusError
|
||||||
s.status.Message = fmt.Errorf("failed to read message: %v", err).Error()
|
s.status.Message = fmt.Errorf("failed to read message: %v", err).Error()
|
||||||
}
|
}
|
||||||
|
@ -124,21 +130,23 @@ func (s *PluginRpcServer) handleConnection(conn net.Conn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrpc.JSONRPCServer) {
|
func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrpc.JSONRPCServer) {
|
||||||
// log.Printf("Plugin rpc server started. Getting supported methods...")
|
s.status = PluginRpcStatusUnknown
|
||||||
// supportedMethodsResponse, err := rpcserver.Request("getPluginSupportedMethods", map[string]interface{}{})
|
|
||||||
// if err != nil {
|
|
||||||
// log.Printf("Failed to get supported methods: %v", err)
|
|
||||||
// s.status = PluginRpcStatusError
|
|
||||||
// s.status.Message = fmt.Errorf("error getting supported methods: %v", err).Error()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if supportedMethodsResponse.Error != nil {
|
log.Printf("Plugin rpc server started. Getting supported methods...")
|
||||||
// log.Printf("Failed to get supported methods: %v", supportedMethodsResponse.Error)
|
var supportedMethodsResponse PluginRpcSupportedMethods
|
||||||
// s.status = PluginRpcStatusError
|
err := rpcserver.Request("getPluginSupportedMethods", nil, &supportedMethodsResponse)
|
||||||
// s.status.Message = fmt.Errorf("error getting supported methods: %v", supportedMethodsResponse.Error).Error()
|
if err != nil {
|
||||||
// }
|
log.Printf("Failed to get supported methods: %v", err)
|
||||||
|
s.status = PluginRpcStatusError
|
||||||
|
s.status.Message = fmt.Errorf("error getting supported methods: %v", err.Message).Error()
|
||||||
|
}
|
||||||
|
|
||||||
// log.Printf("Plugin has supported methods: %v", supportedMethodsResponse.Result)
|
log.Printf("Plugin has supported methods: %v", supportedMethodsResponse.SupportedRpcMethods)
|
||||||
|
|
||||||
|
if !slices.Contains(supportedMethodsResponse.SupportedRpcMethods, "getPluginStatus") {
|
||||||
|
log.Printf("Plugin does not support getPluginStatus method")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(1 * time.Second)
|
ticker := time.NewTicker(1 * time.Second)
|
||||||
for {
|
for {
|
||||||
|
@ -147,7 +155,7 @@ func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrp
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
var statusResponse PluginRpcStatus
|
var statusResponse PluginRpcStatus
|
||||||
err := rpcserver.Request("getPluginStatus", map[string]interface{}{}, &statusResponse)
|
err := rpcserver.Request("getPluginStatus", nil, &statusResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to get status: %v", err)
|
log.Printf("Failed to get status: %v", err)
|
||||||
if err, ok := err.Data.(error); ok && errors.Is(err, net.ErrClosed) {
|
if err, ok := err.Data.(error); ok && errors.Is(err, net.ErrClosed) {
|
||||||
|
|
|
@ -134,7 +134,7 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
||||||
</p>
|
</p>
|
||||||
<Card className={cx(
|
<Card className={cx(
|
||||||
"text-gray-500 dark:text-gray-400 p-4 border",
|
"text-gray-500 dark:text-gray-400 p-4 border",
|
||||||
plugin.status === "errored" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400",
|
plugin.status === "error" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400",
|
||||||
)}>
|
)}>
|
||||||
{plugin.message}
|
{plugin.message}
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -7,7 +7,7 @@ export function PluginStatusIcon({ plugin }: { plugin: PluginStatus; }) {
|
||||||
classNames = "bg-green-500 border-green-600";
|
classNames = "bg-green-500 border-green-600";
|
||||||
} else if (plugin.enabled && plugin.status === "pending-configuration") {
|
} else if (plugin.enabled && plugin.status === "pending-configuration") {
|
||||||
classNames = "bg-yellow-500 border-yellow-600";
|
classNames = "bg-yellow-500 border-yellow-600";
|
||||||
} else if (plugin.enabled && plugin.status === "errored") {
|
} else if (plugin.enabled && plugin.status === "error") {
|
||||||
classNames = "bg-red-500 border-red-600";
|
classNames = "bg-red-500 border-red-600";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -539,7 +539,7 @@ export interface PluginManifest {
|
||||||
|
|
||||||
export interface PluginStatus extends PluginManifest {
|
export interface PluginStatus extends PluginManifest {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
status: "stopped" | "running" | "loading" | "pending-configuration" | "errored";
|
status: "stopped" | "running" | "loading" | "pending-configuration" | "error";
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue