Implement archive cleanup (#885)
* Implement archive cleanup Fixes #769 Signed-off-by: Andrew <write@imaginarycode.com> * Make sure to close the directory file * Resolve issues noted by @strk * edit cheatsheet app.ini [ci skip] * oops [ci skip]
This commit is contained in:
parent
cf0f451c37
commit
42835c7f82
4 changed files with 92 additions and 3 deletions
7
conf/app.ini
vendored
7
conf/app.ini
vendored
|
@ -391,6 +391,13 @@ ARGS =
|
||||||
RUN_AT_START = true
|
RUN_AT_START = true
|
||||||
SCHEDULE = @every 24h
|
SCHEDULE = @every 24h
|
||||||
|
|
||||||
|
; Clean up old repository archives
|
||||||
|
[cron.archive_cleanup]
|
||||||
|
RUN_AT_START = true
|
||||||
|
SCHEDULE = @every 24h
|
||||||
|
; Archives created more than OLDER_THAN ago are subject to deletion
|
||||||
|
OLDER_THAN = 24h
|
||||||
|
|
||||||
[git]
|
[git]
|
||||||
; Disables highlight of added and removed changes
|
; Disables highlight of added and removed changes
|
||||||
DISABLE_DIFF_HIGHLIGHT = false
|
DISABLE_DIFF_HIGHLIGHT = false
|
||||||
|
|
|
@ -1837,6 +1837,60 @@ func DeleteRepositoryArchives() error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteOldRepositoryArchives deletes old repository archives.
|
||||||
|
func DeleteOldRepositoryArchives() {
|
||||||
|
if taskStatusTable.IsRunning(archiveCleanup) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
taskStatusTable.Start(archiveCleanup)
|
||||||
|
defer taskStatusTable.Stop(archiveCleanup)
|
||||||
|
|
||||||
|
log.Trace("Doing: ArchiveCleanup")
|
||||||
|
|
||||||
|
if err := x.Where("id > 0").Iterate(new(Repository), deleteOldRepositoryArchives); err != nil {
|
||||||
|
log.Error(4, "ArchiveClean: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteOldRepositoryArchives(idx int, bean interface{}) error {
|
||||||
|
repo := bean.(*Repository)
|
||||||
|
basePath := filepath.Join(repo.RepoPath(), "archives")
|
||||||
|
|
||||||
|
for _, ty := range []string{"zip", "targz"} {
|
||||||
|
path := filepath.Join(basePath, ty)
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
log.Warn("Unable to open directory %s: %v", path, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the directory doesn't exist, that's okay.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := file.Readdir(0)
|
||||||
|
file.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Unable to read directory %s: %v", path, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
minimumOldestTime := time.Now().Add(-setting.Cron.ArchiveCleanup.OlderThan)
|
||||||
|
for _, info := range files {
|
||||||
|
if info.ModTime().Before(minimumOldestTime) && !info.IsDir() {
|
||||||
|
toDelete := filepath.Join(path, info.Name())
|
||||||
|
// This is a best-effort purge, so we do not check error codes to confirm removal.
|
||||||
|
if err = os.Remove(toDelete); err != nil {
|
||||||
|
log.Trace("Unable to delete %s, but proceeding: %v", toDelete, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func gatherMissingRepoRecords() ([]*Repository, error) {
|
func gatherMissingRepoRecords() ([]*Repository, error) {
|
||||||
repos := make([]*Repository, 0, 10)
|
repos := make([]*Repository, 0, 10)
|
||||||
if err := x.
|
if err := x.
|
||||||
|
@ -1915,9 +1969,10 @@ func RewriteRepositoryUpdateHook() error {
|
||||||
var taskStatusTable = sync.NewStatusTable()
|
var taskStatusTable = sync.NewStatusTable()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mirrorUpdate = "mirror_update"
|
mirrorUpdate = "mirror_update"
|
||||||
gitFsck = "git_fsck"
|
gitFsck = "git_fsck"
|
||||||
checkRepos = "check_repos"
|
checkRepos = "check_repos"
|
||||||
|
archiveCleanup = "archive_cleanup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GitFsck calls 'git fsck' to check repository health.
|
// GitFsck calls 'git fsck' to check repository health.
|
||||||
|
|
|
@ -55,6 +55,17 @@ func NewContext() {
|
||||||
go models.CheckRepoStats()
|
go models.CheckRepoStats()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if setting.Cron.ArchiveCleanup.Enabled {
|
||||||
|
entry, err = c.AddFunc("Clean up old repository archives", setting.Cron.ArchiveCleanup.Schedule, models.DeleteOldRepositoryArchives)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(4, "Cron[Clean up old repository archives]: %v", err)
|
||||||
|
}
|
||||||
|
if setting.Cron.ArchiveCleanup.RunAtStart {
|
||||||
|
entry.Prev = time.Now()
|
||||||
|
entry.ExecTimes++
|
||||||
|
go models.DeleteOldRepositoryArchives()
|
||||||
|
}
|
||||||
|
}
|
||||||
c.Start()
|
c.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,6 +307,12 @@ var (
|
||||||
RunAtStart bool
|
RunAtStart bool
|
||||||
Schedule string
|
Schedule string
|
||||||
} `ini:"cron.check_repo_stats"`
|
} `ini:"cron.check_repo_stats"`
|
||||||
|
ArchiveCleanup struct {
|
||||||
|
Enabled bool
|
||||||
|
RunAtStart bool
|
||||||
|
Schedule string
|
||||||
|
OlderThan time.Duration
|
||||||
|
} `ini:"cron.archive_cleanup"`
|
||||||
}{
|
}{
|
||||||
UpdateMirror: struct {
|
UpdateMirror: struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
@ -334,6 +340,16 @@ var (
|
||||||
RunAtStart: true,
|
RunAtStart: true,
|
||||||
Schedule: "@every 24h",
|
Schedule: "@every 24h",
|
||||||
},
|
},
|
||||||
|
ArchiveCleanup: struct {
|
||||||
|
Enabled bool
|
||||||
|
RunAtStart bool
|
||||||
|
Schedule string
|
||||||
|
OlderThan time.Duration
|
||||||
|
}{
|
||||||
|
RunAtStart: true,
|
||||||
|
Schedule: "@every 24h",
|
||||||
|
OlderThan: 24 * time.Hour,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Git settings
|
// Git settings
|
||||||
|
|
Reference in a new issue