diff options
Diffstat (limited to 'api')
| -rw-r--r-- | api/api.go | 29 | ||||
| -rw-r--r-- | api/docker.go | 58 |
2 files changed, 86 insertions, 1 deletions
@@ -3,9 +3,11 @@ package api import ( "context" "encoding/json" + "io" "log/slog" "net/http" "os" + "strconv" "time" ) @@ -40,7 +42,7 @@ func respondOnline(w http.ResponseWriter, status ServerStatus) { jsonData, err := json.Marshal(status) if err != nil { http.Error(w, "Error constructing response", http.StatusInternalServerError) - Logger.Error("Error marshalling site status data") + Logger.Error("Error marshalling site status data", slog.Any("err", err)) return } @@ -61,6 +63,31 @@ func VttRedirect(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, VTT_URL, http.StatusMovedPermanently) } +func VttLogs(w http.ResponseWriter, req *http.Request) { + var lines uint = 0 + + linesParam := req.URL.Query().Get("lines") + if linesParam != "" { + lines_64, err := strconv.ParseUint(linesParam, 10, 64) + if err != nil { + Logger.ErrorContext(req.Context(), "Invalid line count in vtt logs request", slog.Any("err", err)) + http.Error(w, "Invalid line count in request", http.StatusBadRequest) + return + } + + lines = uint(lines_64) + } + + logReader, err := vttLogs(req.Context(), lines) + if err != nil { + http.Error(w, "Error occured while getting logs", http.StatusInternalServerError) + return + } + defer logReader.Close() + + io.Copy(w, logReader) +} + func SiteOnline(w http.ResponseWriter, req *http.Request) { const URL string = "https://dnd.jpappel.xyz" diff --git a/api/docker.go b/api/docker.go new file mode 100644 index 0000000..21d5c26 --- /dev/null +++ b/api/docker.go @@ -0,0 +1,58 @@ +package api + +import ( + "context" + "fmt" + "io" + "log/slog" + + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" +) + +const vttContainerId string = "foundry-foundry-1" + +func stopVtt(ctx context.Context) error { + apiClient, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + Logger.ErrorContext(ctx, "Failed to get docker api client", slog.Any("err", err)) + return err + } + + Logger.InfoContext(ctx, "Stopping foundry container") + err = apiClient.ContainerStop(ctx, vttContainerId, container.StopOptions{}) + if err != nil { + Logger.ErrorContext(ctx, "Error occured while stopping foundry container", slog.Any("err", err)) + return err + } + + return nil +} + +// Get readcloser for logs +// If lines is zero, returns all logs. +func vttLogs(ctx context.Context, lines uint) (io.ReadCloser, error) { + apiClient, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + Logger.ErrorContext(ctx, "Failed to get docker api client", slog.Any("err", err)) + return nil, err + } + + opts := container.LogsOptions{ + ShowStdout: true, + ShowStderr: true, + Timestamps: true, + } + if lines != 0 { + opts.Tail = fmt.Sprint(lines) + } + + Logger.DebugContext(ctx, "Getting container logs") + r, err := apiClient.ContainerLogs(ctx, vttContainerId, opts) + if err != nil { + Logger.ErrorContext(ctx, "Failed to get foundry container's logs", slog.Any("err", err)) + return nil, err + } + + return r, nil +} |
