2023-03-14 00:39:15 +01:00
package main
import (
"context"
log "github.com/sirupsen/logrus"
"os"
"path/filepath"
"somegit.dev/ALHP/ALHP.GO/ent"
"somegit.dev/ALHP/ALHP.GO/ent/dbpackage"
"strings"
"sync"
"time"
)
func housekeeping ( repo , march string , wg * sync . WaitGroup ) error {
defer wg . Done ( )
fullRepo := repo + "-" + march
2023-05-21 20:28:23 +02:00
log . Debugf ( "[%s] start housekeeping" , fullRepo )
2023-03-14 00:39:15 +01:00
packages , err := Glob ( filepath . Join ( conf . Basedir . Repo , fullRepo , "/**/*.pkg.tar.zst" ) )
if err != nil {
return err
}
log . Debugf ( "[HK/%s] removing orphans, signature check" , fullRepo )
for _ , path := range packages {
mPackage := Package ( path )
dbPkg , err := mPackage . DBPackage ( db )
if ent . IsNotFound ( err ) {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] removing orphan %s->%s" , fullRepo , filepath . Base ( path ) )
2023-03-14 00:39:15 +01:00
pkg := & ProtoPackage {
2023-05-21 20:28:23 +02:00
FullRepo : * mPackage . FullRepo ( ) ,
2023-03-14 00:39:15 +01:00
PkgFiles : [ ] string { path } ,
2023-05-21 20:28:23 +02:00
March : * mPackage . MArch ( ) ,
2023-03-14 00:39:15 +01:00
}
buildManager . repoPurge [ pkg . FullRepo ] <- [ ] * ProtoPackage { pkg }
continue
} else if err != nil {
2023-06-21 12:54:45 +02:00
log . Warningf ( "[HK] error fetching %s->%q from db: %v" , fullRepo , path , err )
2023-03-14 00:39:15 +01:00
continue
}
pkg := & ProtoPackage {
Pkgbase : dbPkg . Pkgbase ,
Repo : mPackage . Repo ( ) ,
2023-05-21 20:28:23 +02:00
FullRepo : * mPackage . FullRepo ( ) ,
2023-03-14 00:39:15 +01:00
DBPackage : dbPkg ,
2023-05-21 20:28:23 +02:00
March : * mPackage . MArch ( ) ,
Arch : * mPackage . Arch ( ) ,
2023-03-14 00:39:15 +01:00
}
// check if package is still part of repo
dbs , err := alpmHandle . SyncDBs ( )
if err != nil {
return err
}
buildManager . alpmMutex . Lock ( )
pkgResolved , err := dbs . FindSatisfier ( mPackage . Name ( ) )
buildManager . alpmMutex . Unlock ( )
if err != nil || pkgResolved . DB ( ) . Name ( ) != pkg . DBPackage . Repository . String ( ) || pkgResolved . DB ( ) . Name ( ) != pkg . Repo . String ( ) ||
pkgResolved . Architecture ( ) != pkg . Arch || pkgResolved . Name ( ) != mPackage . Name ( ) {
2023-12-13 02:26:03 +01:00
switch {
case pkgResolved . DB ( ) . Name ( ) != pkg . DBPackage . Repository . String ( ) :
log . Infof ( "[HK] %s->%s not included in repo (repo mismatch: repo:%s != db:%s)" , pkg . FullRepo , mPackage . Name ( ) , pkgResolved . DB ( ) . Name ( ) , pkg . DBPackage . Repository . String ( ) )
case pkgResolved . DB ( ) . Name ( ) != pkg . Repo . String ( ) :
log . Infof ( "[HK] %s->%s not included in repo (repo mismatch: repo:%s != pkg:%s)" , pkg . FullRepo , mPackage . Name ( ) , pkgResolved . DB ( ) . Name ( ) , pkg . Repo . String ( ) )
case pkgResolved . Architecture ( ) != pkg . Arch :
log . Infof ( "[HK] %s->%s not included in repo (arch mismatch: repo:%s != pkg:%s)" , pkg . FullRepo , mPackage . Name ( ) , pkgResolved . Architecture ( ) , pkg . Arch )
case pkgResolved . Name ( ) != mPackage . Name ( ) :
log . Infof ( "[HK] %s->%s not included in repo (name mismatch: repo:%s != pkg:%s)" , pkg . FullRepo , mPackage . Name ( ) , pkgResolved . Name ( ) , mPackage . Name ( ) )
default :
log . Infof ( "[HK] %s->%s not included in repo (resolve error: %v)" , pkg . FullRepo , mPackage . Name ( ) , err )
}
2023-03-14 00:39:15 +01:00
// package not found on mirror/db -> not part of any repo anymore
2023-09-23 12:52:51 +02:00
err = pkg . findPkgFiles ( )
if err != nil {
log . Errorf ( "[HK] %s->%s unable to get pkg-files: %v" , pkg . FullRepo , mPackage . Name ( ) , err )
continue
}
2023-05-21 20:28:23 +02:00
err = db . DBPackage . DeleteOne ( pkg . DBPackage ) . Exec ( context . Background ( ) )
2023-09-23 12:52:51 +02:00
pkg . DBPackage = nil
buildManager . repoPurge [ pkg . FullRepo ] <- [ ] * ProtoPackage { pkg }
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
continue
}
if pkg . DBPackage . LastVerified . Before ( pkg . DBPackage . BuildTimeStart ) {
err := pkg . DBPackage . Update ( ) . SetLastVerified ( time . Now ( ) . UTC ( ) ) . Exec ( context . Background ( ) )
if err != nil {
return err
}
// check if pkg signature is valid
valid , err := mPackage . HasValidSignature ( )
if err != nil {
return err
}
if ! valid {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] %s->%s invalid package signature" , pkg . FullRepo , pkg . Pkgbase )
2023-03-14 00:39:15 +01:00
buildManager . repoPurge [ pkg . FullRepo ] <- [ ] * ProtoPackage { pkg }
continue
}
}
// compare db-version with repo version
repoVer , err := pkg . repoVersion ( )
if err == nil && repoVer != dbPkg . RepoVersion {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] %s->%s update repoVersion %s->%s" , pkg . FullRepo , pkg . Pkgbase , dbPkg . RepoVersion , repoVer )
2023-05-21 20:28:23 +02:00
pkg . DBPackage , err = pkg . DBPackage . Update ( ) . SetRepoVersion ( repoVer ) . ClearTagRev ( ) . Save ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
}
}
// check all packages from db for existence
2023-05-21 20:28:23 +02:00
dbPackages , err := db . DBPackage . Query ( ) . Where (
2023-03-14 00:39:15 +01:00
dbpackage . And (
dbpackage . RepositoryEQ ( dbpackage . Repository ( repo ) ) ,
dbpackage . March ( march ) ,
) ) . All ( context . Background ( ) )
if err != nil {
return err
}
2023-05-26 12:59:59 +02:00
log . Debugf ( "[HK/%s] checking %d packages from database" , fullRepo , len ( dbPackages ) )
2023-03-14 00:39:15 +01:00
for _ , dbPkg := range dbPackages {
pkg := & ProtoPackage {
Pkgbase : dbPkg . Pkgbase ,
Repo : dbPkg . Repository ,
March : dbPkg . March ,
FullRepo : dbPkg . Repository . String ( ) + "-" + dbPkg . March ,
DBPackage : dbPkg ,
}
if ! pkg . isAvailable ( alpmHandle ) {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] %s->%s not found on mirror, removing" , pkg . FullRepo , pkg . Pkgbase )
2023-05-21 20:28:23 +02:00
err = db . DBPackage . DeleteOne ( dbPkg ) . Exec ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
2023-05-21 20:28:23 +02:00
log . Errorf ( "[HK] error deleting package %s->%s: %v" , pkg . FullRepo , dbPkg . Pkgbase , err )
2023-03-14 00:39:15 +01:00
}
continue
}
switch {
case dbPkg . Status == dbpackage . StatusLatest && dbPkg . RepoVersion != "" :
2023-05-13 18:16:17 +02:00
// check lastVersionBuild
if dbPkg . LastVersionBuild != dbPkg . RepoVersion {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] %s->%s updating lastVersionBuild %s -> %s" , fullRepo , dbPkg . Pkgbase , dbPkg . LastVersionBuild , dbPkg . RepoVersion )
2023-05-13 18:17:46 +02:00
dbPkg , err = dbPkg . Update ( ) . SetLastVersionBuild ( dbPkg . RepoVersion ) . Save ( context . Background ( ) )
2023-05-13 18:16:17 +02:00
if err != nil {
2023-05-15 15:56:34 +02:00
log . Warningf ( "[HK] error updating lastVersionBuild for %s->%s: %v" , fullRepo , dbPkg . Pkgbase , err )
2023-05-13 18:16:17 +02:00
}
}
2023-03-14 00:39:15 +01:00
var existingSplits [ ] string
var missingSplits [ ] string
for _ , splitPkg := range dbPkg . Packages {
pkgFile := filepath . Join ( conf . Basedir . Repo , fullRepo , "os" , conf . Arch ,
splitPkg + "-" + dbPkg . RepoVersion + "-" + conf . Arch + ".pkg.tar.zst" )
_ , err = os . Stat ( pkgFile )
switch {
case os . IsNotExist ( err ) :
missingSplits = append ( missingSplits , splitPkg )
case err != nil :
log . Warningf ( "[HK] error reading package-file %s: %v" , splitPkg , err )
default :
existingSplits = append ( existingSplits , pkgFile )
}
}
if len ( missingSplits ) > 0 {
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] %s->%s missing split-package(s): %s" , fullRepo , dbPkg . Pkgbase , missingSplits )
2023-06-05 15:33:02 +02:00
pkg . DBPackage , err = pkg . DBPackage . Update ( ) .
ClearRepoVersion ( ) .
ClearTagRev ( ) .
SetStatus ( dbpackage . StatusQueued ) .
Save ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
pkg := & ProtoPackage {
FullRepo : fullRepo ,
PkgFiles : existingSplits ,
March : march ,
DBPackage : dbPkg ,
}
buildManager . repoPurge [ fullRepo ] <- [ ] * ProtoPackage { pkg }
}
case dbPkg . Status == dbpackage . StatusLatest && dbPkg . RepoVersion == "" :
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] reseting missing package %s->%s with no repo version" , fullRepo , dbPkg . Pkgbase )
2023-05-21 20:28:23 +02:00
err = dbPkg . Update ( ) . SetStatus ( dbpackage . StatusQueued ) . ClearTagRev ( ) . ClearRepoVersion ( ) . Exec ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
case dbPkg . Status == dbpackage . StatusSkipped && dbPkg . RepoVersion != "" && strings . HasPrefix ( dbPkg . SkipReason , "blacklisted" ) :
2023-05-15 15:56:34 +02:00
log . Infof ( "[HK] delete blacklisted package %s->%s" , fullRepo , dbPkg . Pkgbase )
2023-03-14 00:39:15 +01:00
pkg := & ProtoPackage {
FullRepo : fullRepo ,
March : march ,
DBPackage : dbPkg ,
}
buildManager . repoPurge [ fullRepo ] <- [ ] * ProtoPackage { pkg }
2023-09-04 18:26:17 +02:00
case dbPkg . Status == dbpackage . StatusFailed && dbPkg . RepoVersion != "" :
log . Infof ( "[HK] package %s->%s failed but still present in repo, removing" , fullRepo , dbPkg . Pkgbase )
pkg := & ProtoPackage {
FullRepo : fullRepo ,
March : march ,
DBPackage : dbPkg ,
}
buildManager . repoPurge [ fullRepo ] <- [ ] * ProtoPackage { pkg }
2023-03-14 00:39:15 +01:00
}
}
log . Debugf ( "[HK/%s] all tasks finished" , fullRepo )
return nil
}
func logHK ( ) error {
// check if package for log exists and if error can be fixed by rebuild
logFiles , err := Glob ( filepath . Join ( conf . Basedir . Repo , logDir , "/**/*.log" ) )
if err != nil {
return err
}
for _ , logFile := range logFiles {
pathSplit := strings . Split ( logFile , string ( filepath . Separator ) )
extSplit := strings . Split ( filepath . Base ( logFile ) , "." )
pkgbase := strings . Join ( extSplit [ : len ( extSplit ) - 1 ] , "." )
march := pathSplit [ len ( pathSplit ) - 2 ]
pkg := ProtoPackage {
Pkgbase : pkgbase ,
March : march ,
}
if exists , err := pkg . exists ( ) ; err != nil {
return err
} else if ! exists {
_ = os . Remove ( logFile )
continue
}
2023-05-21 20:28:23 +02:00
pkgSkipped , err := db . DBPackage . Query ( ) . Where (
2023-03-14 00:39:15 +01:00
dbpackage . Pkgbase ( pkg . Pkgbase ) ,
dbpackage . March ( pkg . March ) ,
dbpackage . StatusEQ ( dbpackage . StatusSkipped ) ,
) . Exist ( context . Background ( ) )
if err != nil {
return err
}
if pkgSkipped {
_ = os . Remove ( logFile )
continue
}
logContent , err := os . ReadFile ( logFile )
if err != nil {
return err
}
sLogContent := string ( logContent )
2023-05-28 13:08:01 +02:00
if rePortError . MatchString ( sLogContent ) || reSigError . MatchString ( sLogContent ) || reDownloadError . MatchString ( sLogContent ) ||
reDownloadError2 . MatchString ( sLogContent ) {
rows , err := db . DBPackage . Update ( ) . Where ( dbpackage . Pkgbase ( pkg . Pkgbase ) , dbpackage . March ( pkg . March ) ,
dbpackage . StatusEQ ( dbpackage . StatusFailed ) ) . ClearTagRev ( ) . SetStatus ( dbpackage . StatusQueued ) . Save ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
if rows > 0 {
log . Infof ( "[HK/%s/%s] fixable build-error detected, requeueing package (%d)" , pkg . March , pkg . Pkgbase , rows )
}
} else if reLdError . MatchString ( sLogContent ) || reRustLTOError . MatchString ( sLogContent ) {
2023-05-21 20:28:23 +02:00
rows , err := db . DBPackage . Update ( ) . Where (
2023-03-14 00:39:15 +01:00
dbpackage . Pkgbase ( pkg . Pkgbase ) ,
dbpackage . March ( pkg . March ) ,
dbpackage . StatusEQ ( dbpackage . StatusFailed ) ,
dbpackage . LtoNotIn ( dbpackage . LtoAutoDisabled , dbpackage . LtoDisabled ) ,
2023-05-21 20:28:23 +02:00
) . ClearTagRev ( ) . SetStatus ( dbpackage . StatusQueued ) . SetLto ( dbpackage . LtoAutoDisabled ) . Save ( context . Background ( ) )
2023-03-14 00:39:15 +01:00
if err != nil {
return err
}
if rows > 0 {
log . Infof ( "[HK/%s/%s] fixable build-error detected (linker-error), requeueing package (%d)" , pkg . March , pkg . Pkgbase , rows )
}
}
}
return nil
}