wip: oci image management
This commit is contained in:
99
handler/upload_handler.go
Normal file
99
handler/upload_handler.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"gitea.loveuer.com/loveuer/cluster/internal/database"
|
||||
"gitea.loveuer.com/loveuer/cluster/internal/model"
|
||||
"gitea.loveuer.com/loveuer/cluster/internal/rerr"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type uploadHandlerImpl struct{}
|
||||
|
||||
// NewUploadHandler creates a new upload handler
|
||||
func NewUploadHandler() UploadHandler {
|
||||
return &uploadHandlerImpl{}
|
||||
}
|
||||
|
||||
func (u *uploadHandlerImpl) UploadId() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
func (u *uploadHandlerImpl) Write(ctx context.Context, sessionID string, r io.Reader, start, end int) (int, *rerr.RepositoryError) {
|
||||
// Get upload session
|
||||
var session model.RegistryUploadSession
|
||||
if err := database.DB.Where("session_id = ?", sessionID).First(&session).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return 0, &rerr.RepositoryError{
|
||||
Status: 404,
|
||||
Code: "BLOB_UPLOAD_UNKNOWN",
|
||||
Message: "upload session not found",
|
||||
}
|
||||
}
|
||||
return 0, rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
// Open file for writing
|
||||
file, err := os.OpenFile(session.Path, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return 0, rerr.ErrInternal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Seek to start position
|
||||
if _, err := file.Seek(int64(start), 0); err != nil {
|
||||
return 0, rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
// Write data
|
||||
n, err := io.CopyN(file, r, int64(end-start+1))
|
||||
if err != nil && err != io.EOF {
|
||||
return 0, rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
// Update session size
|
||||
session.Size = int64(start) + n
|
||||
if err := database.DB.Save(&session).Error; err != nil {
|
||||
return 0, rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
func (u *uploadHandlerImpl) Done(ctx context.Context, blobHandler BlobHandler, sessionID string, r io.Reader, contentLength int, repo string, h model.Hash) *rerr.RepositoryError {
|
||||
// Get upload session
|
||||
var session model.RegistryUploadSession
|
||||
if err := database.DB.Where("session_id = ?", sessionID).First(&session).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return &rerr.RepositoryError{
|
||||
Status: 404,
|
||||
Code: "BLOB_UPLOAD_UNKNOWN",
|
||||
Message: "upload session not found",
|
||||
}
|
||||
}
|
||||
return rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
// Read from the uploaded file instead of the request body
|
||||
file, err := os.Open(session.Path)
|
||||
if err != nil {
|
||||
return rerr.ErrInternal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Store blob
|
||||
if err := blobHandler.Put(ctx, repo, h, file); err != nil {
|
||||
return rerr.ErrInternal(err)
|
||||
}
|
||||
|
||||
// Clean up upload session
|
||||
os.Remove(session.Path)
|
||||
database.DB.Delete(&session)
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user