191 lines
5.0 KiB
Go
191 lines
5.0 KiB
Go
package apps
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/texm/dokku-go"
|
|
"gitlab.com/texm/shokku/internal/env"
|
|
"gitlab.com/texm/shokku/internal/server/commands"
|
|
"gitlab.com/texm/shokku/internal/server/dto"
|
|
"net/http"
|
|
)
|
|
|
|
func GetAppProcesses(e *env.Env, c echo.Context) error {
|
|
var req dto.GetAppProcessesRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
scales, err := e.Dokku.GetAppProcessScale(req.Name)
|
|
if err != nil {
|
|
return fmt.Errorf("getting app process scale: %w", err)
|
|
}
|
|
|
|
processes := make([]string, len(scales))
|
|
i := 0
|
|
for processName := range scales {
|
|
processes[i] = processName
|
|
i++
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, dto.GetAppProcessesResponse{
|
|
Processes: processes,
|
|
})
|
|
}
|
|
|
|
func GetAppProcessReport(e *env.Env, c echo.Context) error {
|
|
var req dto.GetAppProcessReportRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
resourceReport, err := e.Dokku.GetAppResourceReport(req.Name)
|
|
if err != nil {
|
|
return fmt.Errorf("getting app resource report: %w", err)
|
|
}
|
|
|
|
processScale, err := e.Dokku.GetAppProcessScale(req.Name)
|
|
if err != nil {
|
|
return fmt.Errorf("getting app process scale: %w", err)
|
|
}
|
|
|
|
processMap := map[string]dto.AppProcessInfo{}
|
|
for processName, scale := range processScale {
|
|
appResources := dto.AppProcessInfo{
|
|
Scale: scale,
|
|
}
|
|
if psSettings, ok := resourceReport.Processes[processName]; ok {
|
|
appResources.Resources = psSettings
|
|
}
|
|
processMap[processName] = appResources
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, dto.GetAppProcessReportResponse{
|
|
ResourceDefaults: resourceReport.Defaults,
|
|
Processes: processMap,
|
|
})
|
|
}
|
|
|
|
func SetAppProcessResources(e *env.Env, c echo.Context) error {
|
|
var req dto.SetAppProcessResourcesRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
limits := req.ResourceLimits
|
|
reservations := req.ResourceReservations
|
|
|
|
if limits.CPU != nil {
|
|
err := e.Dokku.SetAppProcessResourceLimit(req.Name, req.Process,
|
|
dokku.ResourceCPU, *limits.CPU)
|
|
if err != nil {
|
|
return fmt.Errorf("setting app cpu limit: %w", err)
|
|
}
|
|
} else {
|
|
err := e.Dokku.ClearAppProcessResourceLimit(req.Name, req.Process, dokku.ResourceCPU)
|
|
if err != nil {
|
|
return fmt.Errorf("clearing app cpu limit: %w", err)
|
|
}
|
|
}
|
|
|
|
if limits.Memory != nil && limits.MemoryUnit != nil {
|
|
resSpec := dokku.ResourceSpec{
|
|
Name: "memory",
|
|
Suffix: *limits.MemoryUnit,
|
|
}
|
|
err := e.Dokku.SetAppProcessResourceLimit(req.Name, req.Process, resSpec, *limits.Memory)
|
|
if err != nil {
|
|
return fmt.Errorf("setting app mem limit: %w", err)
|
|
}
|
|
} else {
|
|
err := e.Dokku.ClearAppProcessResourceLimit(req.Name, req.Process, dokku.ResourceMemoryBytes)
|
|
if err != nil {
|
|
return fmt.Errorf("clearing app mem limit: %w", err)
|
|
}
|
|
}
|
|
|
|
if reservations.Memory != nil && reservations.MemoryUnit != nil {
|
|
resSpec := dokku.ResourceSpec{
|
|
Name: "memory",
|
|
Suffix: *reservations.MemoryUnit,
|
|
}
|
|
err := e.Dokku.SetAppProcessResourceReservation(req.Name, req.Process, resSpec,
|
|
*reservations.Memory)
|
|
if err != nil {
|
|
return fmt.Errorf("setting app mem reservation: %w", err)
|
|
}
|
|
} else {
|
|
err := e.Dokku.ClearAppProcessResourceReservation(req.Name, req.Process,
|
|
dokku.ResourceMemoryBytes)
|
|
if err != nil {
|
|
return fmt.Errorf("clearing app mem reservation: %w", err)
|
|
}
|
|
}
|
|
|
|
return c.NoContent(http.StatusOK)
|
|
}
|
|
|
|
func GetAppProcessScale(e *env.Env, c echo.Context) error {
|
|
var req dto.GetAppProcessScaleRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
scale, err := e.Dokku.GetAppProcessScale(req.Name)
|
|
if err != nil {
|
|
return fmt.Errorf("getting app process scale: %w", err)
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, dto.GetAppProcessScaleResponse{
|
|
ProcessScale: scale,
|
|
})
|
|
}
|
|
|
|
func SetAppProcessDeployChecks(e *env.Env, c echo.Context) error {
|
|
var req dto.SetAppProcessDeployChecksRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
processes := []string{req.Process}
|
|
var err error
|
|
switch req.State {
|
|
case "enabled":
|
|
err = e.Dokku.EnableAppProcessesDeployChecks(req.Name, processes)
|
|
case "disabled":
|
|
err = e.Dokku.DisableAppProcessesDeployChecks(req.Name, processes)
|
|
case "skipped":
|
|
err = e.Dokku.SetAppProcessesDeployChecksSkipped(req.Name, processes)
|
|
default:
|
|
return echo.NewHTTPError(http.StatusBadRequest, "unknown state")
|
|
}
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("setting app deploy checks to " + req.State)
|
|
}
|
|
|
|
return c.NoContent(http.StatusOK)
|
|
}
|
|
|
|
func SetAppProcessScale(e *env.Env, c echo.Context) error {
|
|
var req dto.SetAppProcessScaleRequest
|
|
if err := dto.BindRequest(c, &req); err != nil {
|
|
return err.ToHTTP()
|
|
}
|
|
|
|
_, err := e.Auth.GetUserFromContext(c)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("failed to retrieve user from context")
|
|
return echo.ErrInternalServerError
|
|
}
|
|
|
|
cmd := func() (*dokku.CommandOutputStream, error) {
|
|
return e.Dokku.SetAppProcessScale(req.Name, req.Process, req.Scale, req.SkipDeploy)
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, dto.CommandExecutionResponse{
|
|
ExecutionID: commands.RequestExecution(cmd, nil),
|
|
})
|
|
}
|