Files
dokku-ui/internal/server/api/apps/processes.go
2023-04-25 14:33:14 +08:00

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),
})
}