Delete releases attachments if release is deleted (#6068)
* delete attachments from the database and file system * add migration * fix import statements * fix package name * remove conditional should in case the confi has been changed and the server restarted * simplify deletion of attachments in DB * fix CI build * fix review * add copyright in the proper place * fix review
This commit is contained in:
		
							parent
							
								
									6322d254e7
								
							
						
					
					
						commit
						63ff61615e
					
				
					 4 changed files with 63 additions and 1 deletions
				
			
		|  | @ -246,6 +246,8 @@ var migrations = []Migration{ | |||
| 	NewMigration("add enable_status_check, status_check_contexts to protected_branch", addStatusCheckColumnsForProtectedBranches), | ||||
| 	// v95 -> v96
 | ||||
| 	NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns), | ||||
| 	// v96 -> v97
 | ||||
| 	NewMigration("delete orphaned attachments", deleteOrphanedAttachments), | ||||
| } | ||||
| 
 | ||||
| // Migrate database to current version
 | ||||
|  |  | |||
|  | @ -14,5 +14,4 @@ func addIsLockedToIssues(x *xorm.Engine) error { | |||
| 	} | ||||
| 
 | ||||
| 	return x.Sync2(new(Issue)) | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										48
									
								
								models/migrations/v96.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								models/migrations/v96.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package migrations | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 
 | ||||
| 	"github.com/go-xorm/xorm" | ||||
| ) | ||||
| 
 | ||||
| func deleteOrphanedAttachments(x *xorm.Engine) error { | ||||
| 
 | ||||
| 	type Attachment struct { | ||||
| 		ID        int64  `xorm:"pk autoincr"` | ||||
| 		UUID      string `xorm:"uuid UNIQUE"` | ||||
| 		IssueID   int64  `xorm:"INDEX"` | ||||
| 		ReleaseID int64  `xorm:"INDEX"` | ||||
| 		CommentID int64 | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sess.Close() | ||||
| 
 | ||||
| 	err := sess.BufferSize(setting.Database.IterateBufferSize). | ||||
| 		Where("`comment_id` = 0 and (`release_id` = 0 or `release_id` not in (select `id` from `release`))").Cols("uuid"). | ||||
| 		Iterate(new(Attachment), | ||||
| 			func(idx int, bean interface{}) error { | ||||
| 				attachment := bean.(*Attachment) | ||||
| 
 | ||||
| 				if err := os.RemoveAll(models.AttachmentLocalPath(attachment.UUID)); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 
 | ||||
| 				_, err := sess.ID(attachment.ID).NoAutoCondition().Delete(attachment) | ||||
| 				return err | ||||
| 			}) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return sess.Commit() | ||||
| } | ||||
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -6,6 +7,7 @@ package models | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 
 | ||||
|  | @ -357,6 +359,17 @@ func DeleteReleaseByID(id int64, doer *User, delTag bool) error { | |||
| 		return fmt.Errorf("LoadAttributes: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := x.Delete(&Attachment{ReleaseID: id}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	for i := range rel.Attachments { | ||||
| 		attachment := rel.Attachments[i] | ||||
| 		if err := os.RemoveAll(attachment.LocalPath()); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	mode, _ := AccessLevel(doer, rel.Repo) | ||||
| 	if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{ | ||||
| 		Action:     api.HookReleaseDeleted, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue