feat: CPU/RAM limits per stage, NPM access list (global + per-project)
Resource limits: - Add cpu_limit (cores) and memory_limit (MB) fields to Stage model - Pass limits to Docker container via NanoCPUs and Memory in HostConfig - Add CPU/Memory fields to stage creation form in project detail - 0 = unlimited (default) NPM access list: - Add npm_access_list_id to Settings (global default) and Project (per-project override) - Per-project overrides global when > 0 - NPM provider passes access_list_id when configuring proxy hosts - Add GET /api/settings/npm-access-lists endpoint to list NPM access lists - Add access list picker on NPM settings page (global) - Add access list ID field on project edit form (per-project) - DB migrations for all new columns
This commit is contained in:
+27
-8
@@ -13,14 +13,16 @@ import (
|
||||
|
||||
// stageRequest is the expected JSON body for creating/updating a stage.
|
||||
type stageRequest struct {
|
||||
Name string `json:"name"`
|
||||
TagPattern string `json:"tag_pattern"`
|
||||
AutoDeploy *bool `json:"auto_deploy"`
|
||||
MaxInstances *int `json:"max_instances"`
|
||||
Confirm *bool `json:"confirm"`
|
||||
PromoteFrom string `json:"promote_from"`
|
||||
Subdomain string `json:"subdomain"`
|
||||
NotificationURL string `json:"notification_url"`
|
||||
Name string `json:"name"`
|
||||
TagPattern string `json:"tag_pattern"`
|
||||
AutoDeploy *bool `json:"auto_deploy"`
|
||||
MaxInstances *int `json:"max_instances"`
|
||||
Confirm *bool `json:"confirm"`
|
||||
PromoteFrom string `json:"promote_from"`
|
||||
Subdomain string `json:"subdomain"`
|
||||
NotificationURL string `json:"notification_url"`
|
||||
CpuLimit *float64 `json:"cpu_limit"`
|
||||
MemoryLimit *int `json:"memory_limit"`
|
||||
}
|
||||
|
||||
// createStage handles POST /api/projects/{id}/stages.
|
||||
@@ -64,6 +66,15 @@ func (s *Server) createStage(w http.ResponseWriter, r *http.Request) {
|
||||
confirm = *req.Confirm
|
||||
}
|
||||
|
||||
var cpuLimit float64
|
||||
if req.CpuLimit != nil {
|
||||
cpuLimit = *req.CpuLimit
|
||||
}
|
||||
var memoryLimit int
|
||||
if req.MemoryLimit != nil {
|
||||
memoryLimit = *req.MemoryLimit
|
||||
}
|
||||
|
||||
stage, err := s.store.CreateStage(store.Stage{
|
||||
ProjectID: projectID,
|
||||
Name: req.Name,
|
||||
@@ -74,6 +85,8 @@ func (s *Server) createStage(w http.ResponseWriter, r *http.Request) {
|
||||
PromoteFrom: req.PromoteFrom,
|
||||
Subdomain: req.Subdomain,
|
||||
NotificationURL: req.NotificationURL,
|
||||
CpuLimit: cpuLimit,
|
||||
MemoryLimit: memoryLimit,
|
||||
})
|
||||
if err != nil {
|
||||
slog.Error("failed to create stage", "error", err)
|
||||
@@ -131,6 +144,12 @@ func (s *Server) updateStage(w http.ResponseWriter, r *http.Request) {
|
||||
updated.PromoteFrom = req.PromoteFrom
|
||||
updated.Subdomain = req.Subdomain
|
||||
updated.NotificationURL = req.NotificationURL
|
||||
if req.CpuLimit != nil {
|
||||
updated.CpuLimit = *req.CpuLimit
|
||||
}
|
||||
if req.MemoryLimit != nil {
|
||||
updated.MemoryLimit = *req.MemoryLimit
|
||||
}
|
||||
|
||||
if err := s.store.UpdateStage(updated); err != nil {
|
||||
slog.Error("failed to update stage", "error", err)
|
||||
|
||||
Reference in New Issue
Block a user