feat: 完成镜像仓库管理

This commit is contained in:
ssongliu
2022-10-19 15:06:32 +08:00
committed by ssongliu
parent a79ba71ef4
commit dcbf92ac12
22 changed files with 848 additions and 50 deletions
+1
View File
@@ -14,6 +14,7 @@ var (
backupService = service.ServiceGroupApp.BackupService
groupService = service.ServiceGroupApp.GroupService
containerService = service.ServiceGroupApp.ContainerService
imageRepoService = service.ServiceGroupApp.ImageRepoService
commandService = service.ServiceGroupApp.CommandService
operationService = service.ServiceGroupApp.OperationService
fileService = service.ServiceGroupApp.FileService
+92
View File
@@ -0,0 +1,92 @@
package v1
import (
"github.com/1Panel-dev/1Panel/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/app/dto"
"github.com/1Panel-dev/1Panel/constant"
"github.com/1Panel-dev/1Panel/global"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) GetRepoList(c *gin.Context) {
var req dto.PageInfo
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, list, err := imageRepoService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
func (b *BaseApi) CreateRepo(c *gin.Context) {
var req dto.ImageRepoCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := imageRepoService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) DeleteRepo(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := imageRepoService.BatchDelete(req.Ids); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) UpdateRepo(c *gin.Context) {
var req dto.ImageRepoUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
id, err := helper.GetParamID(c)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
upMap := make(map[string]interface{})
upMap["download_url"] = req.DownloadUrl
upMap["repo_name"] = req.RepoName
upMap["username"] = req.Username
upMap["password"] = req.Password
upMap["auth"] = req.Auth
if err := imageRepoService.Update(id, upMap); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+31
View File
@@ -0,0 +1,31 @@
package dto
import "time"
type ImageRepoCreate struct {
Name string `json:"name" validate:"required"`
DownloadUrl string `json:"downloadUrl"`
RepoName string `json:"repoName"`
Username string `json:"username"`
Password string `json:"password"`
Auth bool `json:"auth"`
}
type ImageRepoUpdate struct {
ID uint `json:"id"`
DownloadUrl string `json:"downloadUrl"`
RepoName string `json:"repoName"`
Username string `json:"username"`
Password string `json:"password"`
Auth bool `json:"auth"`
}
type ImageRepoInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
DownloadUrl string `json:"downloadUrl"`
RepoName string `json:"repoName"`
Username string `json:"username"`
Auth bool `json:"auth"`
}
+12
View File
@@ -0,0 +1,12 @@
package model
type ImageRepo struct {
BaseModel
Name string `gorm:"type:varchar(64);not null" json:"name"`
DownloadUrl string `gorm:"type:varchar(256)" json:"downloadUrl"`
RepoName string `gorm:"type:varchar(256)" json:"repoName"`
Username string `gorm:"type:varchar(256)" json:"username"`
Password string `gorm:"type:varchar(256)" json:"password"`
Auth bool `gorm:"type:varchar(256)" json:"auth"`
}
+1
View File
@@ -4,6 +4,7 @@ type RepoGroup struct {
HostRepo
BackupRepo
GroupRepo
ImageRepoRepo
CommandRepo
OperationRepo
CommonRepo
+58
View File
@@ -0,0 +1,58 @@
package repo
import (
"github.com/1Panel-dev/1Panel/app/model"
"github.com/1Panel-dev/1Panel/global"
)
type ImageRepoRepo struct{}
type IImageRepoRepo interface {
Get(opts ...DBOption) (model.ImageRepo, error)
Page(limit, offset int, opts ...DBOption) (int64, []model.ImageRepo, error)
Create(imageRepo *model.ImageRepo) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
}
func NewIImageRepoRepo() IImageRepoRepo {
return &ImageRepoRepo{}
}
func (u *ImageRepoRepo) Get(opts ...DBOption) (model.ImageRepo, error) {
var imageRepo model.ImageRepo
db := global.DB
for _, opt := range opts {
db = opt(db)
}
err := db.First(&imageRepo).Error
return imageRepo, err
}
func (u *ImageRepoRepo) Page(page, size int, opts ...DBOption) (int64, []model.ImageRepo, error) {
var ops []model.ImageRepo
db := global.DB.Model(&model.ImageRepo{})
for _, opt := range opts {
db = opt(db)
}
count := int64(0)
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Find(&ops).Error
return count, ops, err
}
func (u *ImageRepoRepo) Create(imageRepo *model.ImageRepo) error {
return global.DB.Create(imageRepo).Error
}
func (u *ImageRepoRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.ImageRepo{}).Where("id = ?", id).Updates(vars).Error
}
func (u *ImageRepoRepo) Delete(opts ...DBOption) error {
db := global.DB
for _, opt := range opts {
db = opt(db)
}
return db.Delete(&model.ImageRepo{}).Error
}
+2
View File
@@ -7,6 +7,7 @@ type ServiceGroup struct {
HostService
BackupService
GroupService
ImageRepoService
ContainerService
CommandService
OperationService
@@ -25,6 +26,7 @@ var (
commandRepo = repo.RepoGroupApp.CommandRepo
operationRepo = repo.RepoGroupApp.OperationRepo
commonRepo = repo.RepoGroupApp.CommonRepo
imageRepoRepo = repo.RepoGroupApp.ImageRepoRepo
cronjobRepo = repo.RepoGroupApp.CronjobRepo
settingRepo = repo.RepoGroupApp.SettingRepo
appRepo = repo.RepoGroupApp.AppRepo
+56
View File
@@ -0,0 +1,56 @@
package service
import (
"github.com/1Panel-dev/1Panel/app/dto"
"github.com/1Panel-dev/1Panel/constant"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
)
type ImageRepoService struct{}
type IImageRepoService interface {
Page(search dto.PageInfo) (int64, interface{}, error)
Create(imageRepoDto dto.ImageRepoCreate) error
Update(id uint, upMap map[string]interface{}) error
BatchDelete(ids []uint) error
}
func NewIImageRepoService() IImageRepoService {
return &ImageRepoService{}
}
func (u *ImageRepoService) Page(search dto.PageInfo) (int64, interface{}, error) {
total, ops, err := imageRepoRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc"))
var dtoOps []dto.ImageRepoInfo
for _, op := range ops {
var item dto.ImageRepoInfo
if err := copier.Copy(&item, &op); err != nil {
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
dtoOps = append(dtoOps, item)
}
return total, dtoOps, err
}
func (u *ImageRepoService) Create(imageRepoDto dto.ImageRepoCreate) error {
imageRepo, _ := imageRepoRepo.Get(commonRepo.WithByName(imageRepoDto.RepoName))
if imageRepo.ID != 0 {
return constant.ErrRecordExist
}
if err := copier.Copy(&imageRepo, &imageRepoDto); err != nil {
return errors.WithMessage(constant.ErrStructTransform, err.Error())
}
if err := imageRepoRepo.Create(&imageRepo); err != nil {
return err
}
return nil
}
func (u *ImageRepoService) BatchDelete(ids []uint) error {
return imageRepoRepo.Delete(commonRepo.WithIdsIn(ids))
}
func (u *ImageRepoService) Update(id uint, upMap map[string]interface{}) error {
return imageRepoRepo.Update(id, upMap)
}
+1
View File
@@ -16,6 +16,7 @@ func Init() {
migrations.AddTableBackupAccount,
migrations.AddTableCronjob,
migrations.AddTableApp,
migrations.AddTableImageRepo,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
+17
View File
@@ -153,3 +153,20 @@ var AddTableApp = &gormigrate.Migration{
return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppInstallResource{}, &model.Database{}, &model.AppInstallBackup{})
},
}
var AddTableImageRepo = &gormigrate.Migration{
ID: "20201009-add-table-imagerepo",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.ImageRepo{}); err != nil {
return err
}
item := &model.ImageRepo{
Name: "Docker Hub",
DownloadUrl: "docker.io",
}
if err := tx.Create(item).Error; err != nil {
return err
}
return nil
},
}
@@ -24,5 +24,10 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
baRouter.GET("/detail/:id", baseApi.ContainerDetail)
withRecordRouter.POST("operate", baseApi.ContainerOperation)
withRecordRouter.POST("/log", baseApi.ContainerLogs)
baRouter.POST("/repo/search", baseApi.GetRepoList)
baRouter.PUT("/repo/:id", baseApi.UpdateRepo)
withRecordRouter.POST("/repo", baseApi.CreateRepo)
withRecordRouter.POST("/repo/del", baseApi.DeleteRepo)
}
}