Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
feat: #164 implemented working rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
blackandred committed Feb 18, 2022
1 parent 4782fca commit 9d3fac3
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 11 deletions.
3 changes: 2 additions & 1 deletion server-go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ build:

test_login:
curl -s -X POST -d '{"username":"admin","password":"admin"}' -H 'Content-Type: application/json' 'http://localhost:8080/api/stable/auth/login'
@echo "Now do export TOKEN=..."

test_login_some_user:
curl -s -X POST -d '{"username":"some-user","password":"admin"}' -H 'Content-Type: application/json' 'http://localhost:8080/api/stable/auth/login'
Expand Down Expand Up @@ -52,4 +53,4 @@ minio:
-v /tmp/br_minio:/data \
-e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_ROOT_PASSWORD=wJaFuCKtnFEMI/CApItaliSM/bPxRfiCYEXAMPLEKEY" \
quay.io/minio/minio:RELEASE.2022-02-16T00-35-27Z server /data
quay.io/minio/minio:RELEASE.2022-02-16T00-35-27Z server /data --console-address 0.0.0.0:9001
2 changes: 1 addition & 1 deletion server-go/docs/examples/collection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
duration: 1h

# fifo, fifo-plus-older
strategyName: fifo-plus-older
strategyName: fifo
strategySpec:
keepLastOlderNotMoreThan: 5d
maxOlderCopies: 2
Expand Down
14 changes: 7 additions & 7 deletions server-go/http/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (

func addUploadRoute(r *gin.RouterGroup, ctx *core.ApplicationContainer) {
r.POST("/repository/collection/:collectionId/version", func(c *gin.Context) {
// todo: check if rotation strategy allows uploading
// todo: deactivate token if temporary token is used
// todo: check uploaded file size, respect quotas and additional space
// todo: handle upload interruptions
Expand Down Expand Up @@ -55,6 +54,7 @@ func addUploadRoute(r *gin.RouterGroup, ctx *core.ApplicationContainer) {
if strategyFactorialError != nil {
logrus.Errorf(fmt.Sprintf("Cannot create collection strategy for collectionId=%v, error: %v", collection.Metadata.Name, strategyFactorialError))
ServerErrorResponse(c, errors.New("internal error while trying to create rotation strategy. Check server logs"))
return
}
if err := rotationStrategyCase.CanUpload(version); err != nil {
UnauthorizedResponse(c, errors.New(fmt.Sprintf("backup collection strategy declined a possibility to upload, %v", err)))
Expand Down Expand Up @@ -84,7 +84,7 @@ func addUploadRoute(r *gin.RouterGroup, ctx *core.ApplicationContainer) {
// Upload a file from selected source, then handle errors - delete file from storage if not uploaded successfully
wroteLen, uploadError := ctx.Storage.UploadFile(stream, &version)
if uploadError != nil {
// todo: make sure the uploaded file will be deleted
_ = ctx.Storage.Delete(&version)

ServerErrorResponse(c, errors.New(fmt.Sprintf("cannot upload version. %v", uploadError)))
return
Expand All @@ -94,12 +94,12 @@ func addUploadRoute(r *gin.RouterGroup, ctx *core.ApplicationContainer) {
version.Filesize = wroteLen

// Append version to the registry
// todo
//ctx.Storage.SubmitVersion(version)
//ctx.Storage.CleanUpOlderVersions(rotationStrategyCase.GetVersionsThatShouldBeDeletedIfThisVersionUploaded(version))
if err := ctx.Storage.RegisterVersion(&version); err != nil {
_ = ctx.Storage.Delete(&version)
}
ctx.Storage.CleanUpOlderVersions(rotationStrategyCase.GetVersionsThatShouldBeDeletedIfThisVersionUploaded(version))
logrus.Infof("Uploaded v%v for collectionId=%v, size=%v", version.VersionNumber, version.CollectionId, version.Filesize)

// todo: Rotate collection
// todo: add UploadedVersion to database
OKResponse(c, gin.H{
"version": version,
})
Expand Down
9 changes: 9 additions & 0 deletions server-go/storage/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ func (vr VersionsRepository) findAllVersionsForCollectionId(collectionId string)
return foundVersions, nil
}

func (vr VersionsRepository) delete(version *UploadedVersion) (error, bool) {
var result bool
return vr.db.Model(&UploadedVersion{}).Where("uploaded_versions.id = ?", version.Id).Delete(&result).Error, result
}

func (vr VersionsRepository) create(version *UploadedVersion) error {
return vr.db.Create(version).Error
}

func InitializeModel(db *gorm.DB) error {
return db.AutoMigrate(&UploadedVersion{})
}
4 changes: 2 additions & 2 deletions server-go/storage/rotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func (frs *FifoRotationStrategy) GetVersionsThatShouldBeDeletedIfThisVersionUplo
}

// order by version number DESCENDING
sort.SliceStable(&existingVersions, func(i, j int) bool {
return existingVersions[i].VersionNumber > existingVersions[j].VersionNumber
sort.SliceStable(existingVersions, func(i, j int) bool {
return existingVersions[i].VersionNumber < existingVersions[j].VersionNumber
})

// oldest element
Expand Down
30 changes: 30 additions & 0 deletions server-go/storage/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,36 @@ func (s *Service) CreateRotationStrategyCase(collection *collections.Collection)
return &FifoRotationStrategy{}, errors.New(fmt.Sprintf("collection configuration error: unrecognized backup strategy type '%v'", collection.Spec.StrategyName))
}

func (s *Service) CleanUpOlderVersions(versions []UploadedVersion) bool {
logrus.Infof("Cleaning up older versions")
isError := false

for _, version := range versions {
if err := s.Delete(&version); err != nil {
logrus.Errorf("Consistency error! Cannot delete version id=%v, of collectionId=%v, error: %v", version.Id, version.CollectionId, err)
isError = true
} else {
logrus.Debugf("Deleted version: id=%v, version=%v, of collectionId=%v", version.Id, version.VersionNumber, version.CollectionId)
}
}

return isError
}

func (s *Service) Delete(version *UploadedVersion) error {
if err := s.storage.Delete(context.TODO(), version.GetTargetPath()); err != nil {
return errors.New(fmt.Sprintf("cannot delete from storage at path '%v', error: %v", version.GetTargetPath(), err))
}
if err, _ := s.repository.delete(version); err != nil {
return errors.New(fmt.Sprintf("cannot delete version from database - id=%v, version=%v, error=%v", version.Id, version.VersionNumber, err))
}
return nil
}

func (s *Service) RegisterVersion(version *UploadedVersion) error {
return s.repository.create(version)
}

// NewService is a factory method that knows how to construct a Storage provider, distincting multiple types of providers
func NewService(db *gorm.DB, driverUrl string, isUsingGCS bool) (Service, error) {
repository := VersionsRepository{db: db}
Expand Down

0 comments on commit 9d3fac3

Please sign in to comment.