package registry import ( "context" "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" ) // RegistryImageList returns the list of images/repositories func RegistryImageList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler { return func(c fiber.Ctx) error { // Get filter parameter from query string filter := c.Query("filter", "") // Get current registry_address setting var registryConfig model.RegistryConfig registryAddress := "" if err := db.Where("key = ?", "registry_address").First(®istryConfig).Error; err == nil { registryAddress = registryConfig.Value } if registryAddress == "" { registryAddress = "localhost:9119" } var repositories []model.Repository // Query all repositories from the database query := db if filter != "" { query = query.Where("name LIKE ?", "%"+filter+"%") } if err := query.Find(&repositories).Error; err != nil { return resp.R500(c, "", nil, err) } // Convert to the expected format for the frontend var result []map[string]interface{} for _, repo := range repositories { // Get all tags for this repository var tags []model.Tag if err := db.Where("repository = ?", repo.Name).Find(&tags).Error; err != nil { continue // Skip this repository if we can't get tags } // If no tags, skip this repository if len(tags) == 0 { continue } // Calculate total size of all blobs for this repository var totalSize int64 var sizeResult struct { Total int64 } err := db.Model(&model.Blob{}). Where("repository = ?", repo.Name). Select("COALESCE(SUM(size), 0) as total"). Scan(&sizeResult).Error if err == nil { totalSize = sizeResult.Total } // Format updated_at to second precision uploadTime := repo.UpdatedAt.Format("2006-01-02 15:04:05") // Create an entry for each tag with full image name // Dynamically prepend registry_address to the repository name for _, tag := range tags { fullRepoName := registryAddress + "/" + repo.Name fullImageName := fullRepoName + ":" + tag.Tag repoMap := map[string]interface{}{ "id": repo.ID, "name": fullImageName, // Full image name: registry_address/repo:tag "repository": repo.Name, // Original repository name (without registry_address) "tag": tag.Tag, // Tag name "upload_time": uploadTime, "size": totalSize, } result = append(result, repoMap) } } return resp.R200(c, map[string]interface{}{ "images": result, }) } }