mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
WebDAV: Skip download sync if storage is full or quota is exceeded #4266
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -56,7 +56,7 @@ func StartImport(router *gin.RouterGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Abort if there is not enough free storage to import new files.
|
// Abort if there is not enough free storage to import new files.
|
||||||
if conf.FilesQuotaReached() {
|
if conf.FilesQuotaExceeded() {
|
||||||
event.AuditErr([]string{ClientIP(c), "session %s", "import files", "insufficient storage"}, s.RefID)
|
event.AuditErr([]string{ClientIP(c), "session %s", "import files", "insufficient storage"}, s.RefID)
|
||||||
Abort(c, http.StatusInsufficientStorage, i18n.ErrInsufficientStorage)
|
Abort(c, http.StatusInsufficientStorage, i18n.ErrInsufficientStorage)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Abort if there is not enough free storage to upload new files.
|
// Abort if there is not enough free storage to upload new files.
|
||||||
if conf.FilesQuotaReached() {
|
if conf.FilesQuotaExceeded() {
|
||||||
event.AuditErr([]string{ClientIP(c), "session %s", "upload files", "insufficient storage"}, s.RefID)
|
event.AuditErr([]string{ClientIP(c), "session %s", "upload files", "insufficient storage"}, s.RefID)
|
||||||
Abort(c, http.StatusInsufficientStorage, i18n.ErrInsufficientStorage)
|
Abort(c, http.StatusInsufficientStorage, i18n.ErrInsufficientStorage)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ func (c *Config) FilesQuotaBytes() uint64 {
|
|||||||
return c.options.FilesQuota * fs.GB
|
return c.options.FilesQuota * fs.GB
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilesQuotaReached checks if the filesystem usage has been reached or exceeded.
|
// FilesQuotaExceeded checks if the filesystem usage has been reached or exceeded.
|
||||||
func (c *Config) FilesQuotaReached() bool {
|
func (c *Config) FilesQuotaExceeded() bool {
|
||||||
return c.Usage().FilesUsedPct >= 100
|
return c.Usage().FilesUsedPct >= 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,19 +56,19 @@ func TestConfig_Quota(t *testing.T) {
|
|||||||
c.options.UsersQuota = 0
|
c.options.UsersQuota = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfig_FilesQuotaReached(t *testing.T) {
|
func TestConfig_FilesQuotaExceeded(t *testing.T) {
|
||||||
c := TestConfig()
|
c := TestConfig()
|
||||||
|
|
||||||
FlushUsageCache()
|
FlushUsageCache()
|
||||||
assert.False(t, c.FilesQuotaReached())
|
assert.False(t, c.FilesQuotaExceeded())
|
||||||
|
|
||||||
c.options.FilesQuota = uint64(1)
|
c.options.FilesQuota = uint64(1)
|
||||||
FlushUsageCache()
|
FlushUsageCache()
|
||||||
assert.True(t, c.FilesQuotaReached())
|
assert.True(t, c.FilesQuotaExceeded())
|
||||||
|
|
||||||
c.options.FilesQuota = uint64(5)
|
c.options.FilesQuota = uint64(5)
|
||||||
FlushUsageCache()
|
FlushUsageCache()
|
||||||
assert.False(t, c.FilesQuotaReached())
|
assert.False(t, c.FilesQuotaExceeded())
|
||||||
|
|
||||||
c.options.FilesQuota = uint64(0)
|
c.options.FilesQuota = uint64(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func WebDAV(dir string, router *gin.RouterGroup, conf *config.Config) {
|
|||||||
// is not enough free storage to upload new files.
|
// is not enough free storage to upload new files.
|
||||||
switch c.Request.Method {
|
switch c.Request.Method {
|
||||||
case MethodPut, MethodPost, MethodPatch, MethodCopy:
|
case MethodPut, MethodPost, MethodPatch, MethodCopy:
|
||||||
if conf.FilesQuotaReached() {
|
if conf.FilesQuotaExceeded() {
|
||||||
c.AbortWithStatus(http.StatusInsufficientStorage)
|
c.AbortWithStatus(http.StatusInsufficientStorage)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ func (w *Sync) Start() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case entity.SyncStatusDownload:
|
case entity.SyncStatusDownload:
|
||||||
if complete, err := w.download(a); err != nil {
|
if complete, downloadErr := w.download(a); downloadErr != nil {
|
||||||
accErrors++
|
accErrors++
|
||||||
accError = err.Error()
|
accError = downloadErr.Error()
|
||||||
syncStatus = entity.SyncStatusRefresh
|
syncStatus = entity.SyncStatusRefresh
|
||||||
} else if complete {
|
} else if complete {
|
||||||
if a.SyncUpload {
|
if a.SyncUpload {
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ func (w *Sync) download(a entity.Service) (complete bool, err error) {
|
|||||||
done := make(map[string]bool)
|
done := make(map[string]bool)
|
||||||
|
|
||||||
for _, files := range relatedFiles {
|
for _, files := range relatedFiles {
|
||||||
|
if w.conf.FilesQuotaExceeded() {
|
||||||
|
log.Warnf("sync: skipped downloading files from %s due to insufficient storage", clean.Log(a.AccName))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
for i, file := range files {
|
for i, file := range files {
|
||||||
if mutex.SyncWorker.Canceled() {
|
if mutex.SyncWorker.Canceled() {
|
||||||
return false, nil
|
return false, nil
|
||||||
@@ -112,14 +117,14 @@ func (w *Sync) download(a entity.Service) (complete bool, err error) {
|
|||||||
|
|
||||||
// Failed too often?
|
// Failed too often?
|
||||||
if a.RetryLimit > 0 && file.Errors > a.RetryLimit {
|
if a.RetryLimit > 0 && file.Errors > a.RetryLimit {
|
||||||
log.Debugf("sync: downloading %s failed more than %d times", file.RemoteName, a.RetryLimit)
|
log.Debugf("sync: downloading %s from %s failed more than %d times", file.RemoteName, clean.Log(a.AccName), a.RetryLimit)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
localName := baseDir + file.RemoteName
|
localName := baseDir + file.RemoteName
|
||||||
|
|
||||||
if _, err = os.Stat(localName); err == nil {
|
if _, err = os.Stat(localName); err == nil {
|
||||||
log.Warnf("sync: download skipped, %s already exists", localName)
|
log.Warnf("sync: skipped download of %s from %s because local file %s already exists", file.RemoteName, clean.Log(a.AccName), localName)
|
||||||
file.Status = entity.FileSyncExists
|
file.Status = entity.FileSyncExists
|
||||||
file.Error = ""
|
file.Error = ""
|
||||||
file.Errors = 0
|
file.Errors = 0
|
||||||
@@ -128,7 +133,7 @@ func (w *Sync) download(a entity.Service) (complete bool, err error) {
|
|||||||
file.Errors++
|
file.Errors++
|
||||||
file.Error = err.Error()
|
file.Error = err.Error()
|
||||||
} else {
|
} else {
|
||||||
log.Infof("sync: downloaded %s from %s", file.RemoteName, a.AccName)
|
log.Infof("sync: downloaded %s from %s", file.RemoteName, clean.Log(a.AccName))
|
||||||
file.Status = entity.FileSyncDownloaded
|
file.Status = entity.FileSyncDownloaded
|
||||||
file.Error = ""
|
file.Error = ""
|
||||||
file.Errors = 0
|
file.Errors = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user