diff --git a/OliveTin.proto b/OliveTin.proto index 2e46f06..4ea1fca 100644 --- a/OliveTin.proto +++ b/OliveTin.proto @@ -22,10 +22,22 @@ message StartActionRequest { } message StartActionResponse { - string stdout = 1; - string stderr = 2; - bool timedOut = 3; - int32 exitCode = 4; + LogEntry logEntry = 1; +} + +message GetLogsRequest{}; + +message LogEntry { + string datetime = 1; + string actionTitle = 2; + string stdout = 3; + string stderr = 4; + bool timedOut = 5; + int32 exitCode = 6; +} + +message GetLogsResponse { + repeated LogEntry logs = 1; } service OliveTinApi { @@ -41,4 +53,9 @@ service OliveTinApi { }; } + rpc GetLogs(GetLogsRequest) returns (GetLogsResponse) { + option (google.api.http) = { + get: "/api/GetLogs" + }; + } } diff --git a/internal/executor/executor.go b/internal/executor/executor.go index e389fe8..de69960 100644 --- a/internal/executor/executor.go +++ b/internal/executor/executor.go @@ -11,8 +11,22 @@ import ( "time" ) +type InternalLogEntry struct { + Datetime string + Content string + Stdout string + Stderr string + TimedOut bool + ExitCode int32 + ActionTitle string +} + +type Executor struct { + Logs []InternalLogEntry +} + // ExecAction executes an action. -func ExecAction(cfg *config.Config, action string) *pb.StartActionResponse { +func (e *Executor) ExecAction(cfg *config.Config, action string) *pb.StartActionResponse { log.WithFields(log.Fields{ "actionName": action, }).Infof("StartAction") @@ -23,16 +37,31 @@ func ExecAction(cfg *config.Config, action string) *pb.StartActionResponse { log.Errorf("Error finding action %s, %s", err, action) return &pb.StartActionResponse{ - TimedOut: false, + LogEntry: nil, } } - return execAction(cfg, actualAction) + res := execAction(cfg, actualAction) + + e.Logs = append(e.Logs, *res); + + return &pb.StartActionResponse{ + LogEntry: &pb.LogEntry { + ActionTitle: actualAction.Title, + TimedOut: res.TimedOut, + Stderr: res.Stderr, + Stdout: res.Stdout, + ExitCode: res.ExitCode, + }, + }; } -func execAction(cfg *config.Config, actualAction *config.ActionButton) *pb.StartActionResponse { - res := &pb.StartActionResponse{} - res.TimedOut = false +func execAction(cfg *config.Config, actualAction *config.ActionButton) *InternalLogEntry { + res := &InternalLogEntry { + Datetime: time.Now().Format("2006-01-02 15:04:05"), + TimedOut: false, + ActionTitle: actualAction.Title, + } log.WithFields(log.Fields{ "title": actualAction.Title, diff --git a/internal/grpcapi/grpcApi.go b/internal/grpcapi/grpcApi.go index a9373c0..2ead0ba 100644 --- a/internal/grpcapi/grpcApi.go +++ b/internal/grpcapi/grpcApi.go @@ -15,6 +15,7 @@ import ( var ( cfg *config.Config + ex = executor.Executor{} ) type oliveTinAPI struct { @@ -22,7 +23,7 @@ type oliveTinAPI struct { } func (api *oliveTinAPI) StartAction(ctx ctx.Context, req *pb.StartActionRequest) (*pb.StartActionResponse, error) { - return executor.ExecAction(cfg, req.ActionName), nil + return ex.ExecAction(cfg, req.ActionName), nil } func (api *oliveTinAPI) GetButtons(ctx ctx.Context, req *pb.GetButtonsRequest) (*pb.GetButtonsResponse, error) { @@ -43,6 +44,25 @@ func (api *oliveTinAPI) GetButtons(ctx ctx.Context, req *pb.GetButtonsRequest) ( return res, nil } +func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *pb.GetLogsRequest) (*pb.GetLogsResponse, error) { + ret := &pb.GetLogsResponse{}; + + // TODO Limit to 10 entries or something to prevent browser lag. + + for _, logEntry := range ex.Logs { + ret.Logs = append(ret.Logs, &pb.LogEntry{ + ActionTitle: logEntry.ActionTitle, + Datetime: logEntry.Datetime, + Stdout: logEntry.Stdout, + Stderr: logEntry.Stderr, + TimedOut: logEntry.TimedOut, + ExitCode: logEntry.ExitCode, + }) + } + + return ret, nil +} + // Start will start the GRPC API. func Start(globalConfig *config.Config) { cfg = globalConfig diff --git a/webui/index.html b/webui/index.html index 21c5b8f..fab9ab6 100644 --- a/webui/index.html +++ b/webui/index.html @@ -12,9 +12,27 @@
-
- OliveTin Actions +
+ +
+ + + +