Files
cluster/internal/module/registry/handler.config.go
loveuer 9780a2b028 feat: add registry config, image upload/download, and OCI format support
Backend:
- Add registry_address configuration API (GET/POST)
- Add tar image upload with OCI and Docker format support
- Add image download with streaming optimization
- Fix blob download using c.Send (Fiber v3 SendStream bug)
- Add registry_address prefix stripping for all OCI v2 endpoints
- Add AGENTS.md for project documentation

Frontend:
- Add settings store with Snackbar notifications
- Add image upload dialog with progress bar
- Add download state tracking with multi-stage feedback
- Replace alert() with MUI Snackbar messages
- Display image names without registry_address prefix

🤖 Generated with [Qoder](https://qoder.com)
2025-11-10 16:28:58 +08:00

82 lines
2.0 KiB
Go

package registry
import (
"context"
"encoding/json"
"gitea.loveuer.com/loveuer/cluster/internal/model"
"gitea.loveuer.com/loveuer/cluster/pkg/resp"
"gitea.loveuer.com/loveuer/cluster/pkg/store"
"github.com/gofiber/fiber/v3"
"gorm.io/gorm"
)
// RegistryConfigGet returns the registry configuration
func RegistryConfigGet(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
var configs []model.RegistryConfig
if err := db.Find(&configs).Error; err != nil {
return resp.R500(c, "", nil, err)
}
// Convert to map for easier frontend access
configMap := make(map[string]string)
for _, config := range configs {
configMap[config.Key] = config.Value
}
return resp.R200(c, map[string]interface{}{
"configs": configMap,
})
}
}
// RegistryConfigSet sets a registry configuration value
func RegistryConfigSet(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
var req struct {
Key string `json:"key"`
Value string `json:"value"`
}
// Parse JSON body
body := c.Body()
if len(body) == 0 {
return resp.R400(c, "EMPTY_BODY", nil, "request body is empty")
}
if err := json.Unmarshal(body, &req); err != nil {
return resp.R400(c, "INVALID_REQUEST", nil, "invalid request body")
}
if req.Key == "" {
return resp.R400(c, "MISSING_KEY", nil, "key is required")
}
// Find or create config
var config model.RegistryConfig
err := db.Where("key = ?", req.Key).First(&config).Error
if err == gorm.ErrRecordNotFound {
// Create new config
config = model.RegistryConfig{
Key: req.Key,
Value: req.Value,
}
if err := db.Create(&config).Error; err != nil {
return resp.R500(c, "", nil, err)
}
} else if err != nil {
return resp.R500(c, "", nil, err)
} else {
// Update existing config
config.Value = req.Value
if err := db.Save(&config).Error; err != nil {
return resp.R500(c, "", nil, err)
}
}
return resp.R200(c, map[string]interface{}{
"config": config,
})
}
}