mirror of
https://github.com/safing/portbase
synced 2025-09-01 18:19:57 +00:00
Improve version purging
This commit is contained in:
parent
eb17a5e6b8
commit
823b05d239
1 changed files with 71 additions and 35 deletions
|
@ -338,65 +338,101 @@ func (res *Resource) Blacklist(version string) error {
|
||||||
|
|
||||||
// Purge deletes old updates, retaining a certain amount, specified by
|
// Purge deletes old updates, retaining a certain amount, specified by
|
||||||
// the keep parameter. Purge will always keep at least 2 versions so
|
// the keep parameter. Purge will always keep at least 2 versions so
|
||||||
// specifying a smaller keep value will have no effect. Note that
|
// specifying a smaller keep value will have no effect.
|
||||||
// blacklisted versions are not counted for the keep parameter.
|
func (res *Resource) Purge(keepExtra int) { //nolint:gocognit
|
||||||
// After purging a new version will be selected.
|
|
||||||
func (res *Resource) Purge(keep int) {
|
|
||||||
res.Lock()
|
res.Lock()
|
||||||
defer res.Unlock()
|
defer res.Unlock()
|
||||||
|
|
||||||
// safeguard
|
// If there is any blacklisted version within the resource, pause purging.
|
||||||
if keep < 2 {
|
// In this case we may need extra available versions beyond what would be
|
||||||
keep = 2
|
// available after purging.
|
||||||
|
for _, rv := range res.Versions {
|
||||||
|
if rv.Blacklisted {
|
||||||
|
log.Debugf(
|
||||||
|
"%s: pausing purging of resource %s, as it contains blacklisted items",
|
||||||
|
res.registry.Name,
|
||||||
|
rv.resource.Identifier,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep versions
|
// Safeguard the amount of extra version to keep.
|
||||||
var validVersions int
|
if keepExtra < 2 {
|
||||||
|
keepExtra = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for purge boundary.
|
||||||
|
var purgeBoundary int
|
||||||
var skippedActiveVersion bool
|
var skippedActiveVersion bool
|
||||||
var skippedSelectedVersion bool
|
var skippedSelectedVersion bool
|
||||||
var purgeFrom int
|
var skippedStableVersion bool
|
||||||
|
boundarySearch:
|
||||||
for i, rv := range res.Versions {
|
for i, rv := range res.Versions {
|
||||||
// continue to purging?
|
// Check if required versions are already skipped.
|
||||||
if validVersions >= keep && // skip at least <keep> versions
|
switch {
|
||||||
skippedActiveVersion && // skip until active version
|
case !skippedActiveVersion && res.ActiveVersion != nil:
|
||||||
skippedSelectedVersion { // skip until selected version
|
// Skip versions until the active version, if it's set.
|
||||||
purgeFrom = i
|
case !skippedSelectedVersion && res.SelectedVersion != nil:
|
||||||
break
|
// Skip versions until the selected version, if it's set.
|
||||||
|
case !skippedStableVersion:
|
||||||
|
// Skip versions until the stable version.
|
||||||
|
default:
|
||||||
|
// All required version skipped, set purge boundary.
|
||||||
|
purgeBoundary = i + keepExtra
|
||||||
|
break boundarySearch
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep active version
|
// Check if current instance is a required version.
|
||||||
if !skippedActiveVersion && rv == res.ActiveVersion {
|
if rv == res.ActiveVersion {
|
||||||
skippedActiveVersion = true
|
skippedActiveVersion = true
|
||||||
}
|
}
|
||||||
|
if rv == res.SelectedVersion {
|
||||||
// keep selected version
|
|
||||||
if !skippedSelectedVersion && rv == res.SelectedVersion {
|
|
||||||
skippedSelectedVersion = true
|
skippedSelectedVersion = true
|
||||||
}
|
}
|
||||||
|
if rv.StableRelease {
|
||||||
// count valid (not blacklisted) versions
|
skippedStableVersion = true
|
||||||
if !rv.Blacklisted {
|
|
||||||
validVersions++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there is anything to purge
|
// Check if there is anything to purge at all.
|
||||||
if purgeFrom < keep || purgeFrom > len(res.Versions) {
|
if purgeBoundary <= keepExtra || purgeBoundary >= len(res.Versions) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// purge phase
|
// Purge everything beyond the purge boundary.
|
||||||
for _, rv := range res.Versions[purgeFrom:] {
|
for _, rv := range res.Versions[purgeBoundary:] {
|
||||||
// delete
|
storagePath := rv.storagePath()
|
||||||
err := os.Remove(rv.storagePath())
|
// Remove resource file.
|
||||||
|
err := os.Remove(storagePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("%s: failed to purge old resource %s: %s", res.registry.Name, rv.storagePath(), err)
|
log.Warningf("%s: failed to purge resource %s v%s: %s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber, err)
|
||||||
|
} else {
|
||||||
|
log.Tracef("%s: purged resource %s v%s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unpacked version of resource.
|
||||||
|
ext := filepath.Ext(storagePath)
|
||||||
|
if ext == "" {
|
||||||
|
// Nothing to do if file does not have an extension.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
unpackedPath := strings.TrimSuffix(storagePath, ext)
|
||||||
|
|
||||||
|
// Remove if it exists, or an error occurs on access.
|
||||||
|
_, err = os.Stat(unpackedPath)
|
||||||
|
if err == nil || !os.IsNotExist(err) {
|
||||||
|
err = os.Remove(unpackedPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("%s: failed to purge unpacked resource %s v%s: %s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber, err)
|
||||||
|
} else {
|
||||||
|
log.Tracef("%s: purged unpacked resource %s v%s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove entries of deleted files
|
|
||||||
res.Versions = res.Versions[purgeFrom:]
|
|
||||||
|
|
||||||
res.selectVersion()
|
// remove entries of deleted files
|
||||||
|
res.Versions = res.Versions[purgeBoundary:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rv *ResourceVersion) versionedPath() string {
|
func (rv *ResourceVersion) versionedPath() string {
|
||||||
|
|
Loading…
Add table
Reference in a new issue