2021-06-10 21:32:11 +02:00
package main
import (
2021-06-14 15:52:53 +02:00
"bytes"
2021-07-13 18:07:29 +02:00
"context"
2021-10-25 06:20:03 +02:00
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
2021-09-12 17:25:33 +02:00
"flag"
2021-06-10 21:32:11 +02:00
"fmt"
2022-02-11 21:33:44 +01:00
"git.harting.dev/ALHP/ALHP.GO/ent"
"git.harting.dev/ALHP/ALHP.GO/ent/dbpackage"
"git.harting.dev/ALHP/ALHP.GO/ent/migrate"
2021-06-10 21:32:11 +02:00
"github.com/Jguer/go-alpm/v2"
2021-10-25 06:20:03 +02:00
_ "github.com/jackc/pgx/v4/stdlib"
2021-06-10 21:32:11 +02:00
log "github.com/sirupsen/logrus"
2021-08-30 11:05:11 +02:00
"github.com/wercker/journalhook"
2021-06-10 21:32:11 +02:00
"gopkg.in/yaml.v2"
2021-07-13 18:07:29 +02:00
"html/template"
2021-12-14 10:29:24 +01:00
"math/rand"
2021-06-10 21:32:11 +02:00
"os"
"os/exec"
"os/signal"
"path/filepath"
2021-07-01 21:40:49 +02:00
"runtime"
2021-06-10 21:32:11 +02:00
"strconv"
"strings"
2021-11-19 23:01:19 +01:00
"sync"
2021-06-10 21:32:11 +02:00
"syscall"
"time"
)
var (
2021-11-04 11:59:57 +01:00
conf * Conf
2021-09-12 17:35:45 +02:00
repos [ ] string
alpmHandle * alpm . Handle
2021-11-04 11:59:57 +01:00
buildManager * BuildManager
2021-09-12 17:35:45 +02:00
db * ent . Client
journalLog = flag . Bool ( "journal" , false , "Log to systemd journal instead of stdout" )
checkInterval = flag . Int ( "interval" , 5 , "How often svn2git should be checked in minutes (default: 5)" )
2021-06-10 21:32:11 +02:00
)
2021-11-29 10:48:29 +01:00
func ( b * BuildManager ) buildWorker ( id int , march string ) {
2021-06-30 17:41:50 +02:00
err := syscall . Setpriority ( syscall . PRIO_PROCESS , 0 , 18 )
if err != nil {
2021-11-29 10:48:29 +01:00
log . Warningf ( "[%s/worker-%d] Failed to drop priority: %v" , march , id , err )
2021-06-30 17:41:50 +02:00
}
2021-06-14 16:28:00 +02:00
2021-06-10 21:32:11 +02:00
for {
select {
2021-11-29 10:48:29 +01:00
case pkg := <- b . build [ march ] :
2021-06-10 21:32:11 +02:00
if b . exit {
2021-11-29 10:48:29 +01:00
log . Infof ( "Worker %s/%d exited..." , march , id )
2021-06-14 15:52:53 +02:00
return
2021-06-10 21:32:11 +02:00
} else {
2021-07-01 21:13:48 +02:00
b . buildWG . Add ( 1 )
2022-01-21 13:02:22 +01:00
b . parseWG . Done ( )
2021-06-10 21:32:11 +02:00
}
2021-12-20 01:14:55 +01:00
rand . Seed ( time . Now ( ) . UnixNano ( ) )
time . Sleep ( time . Duration ( rand . Float32 ( ) * 60 ) * time . Second )
2021-11-18 13:46:56 +01:00
start := time . Now ( ) . UTC ( )
2021-06-10 21:32:11 +02:00
2021-11-29 10:48:29 +01:00
log . Infof ( "[%s/%s/%s] Build starting" , pkg . FullRepo , pkg . Pkgbase , pkg . Version )
2021-06-10 21:32:11 +02:00
2021-11-20 00:02:53 +01:00
pkg . toDbPackage ( true )
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusBuilding ) . ClearSkipReason ( ) . SaveX ( context . Background ( ) )
2021-07-13 18:07:29 +02:00
2021-11-25 01:50:49 +01:00
err := pkg . importKeys ( )
2021-07-27 02:43:30 +02:00
if err != nil {
2021-11-29 10:48:29 +01:00
log . Warningf ( "[%s/%s/%s] Failed to import pgp keys: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
2021-07-27 02:43:30 +02:00
}
2021-11-29 15:02:14 +01:00
buildDir , err := pkg . setupBuildDir ( )
if err != nil {
log . Errorf ( "[%s/%s/%s] Error setting up builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
b . buildWG . Done ( )
continue
}
2021-11-27 01:28:42 +01:00
buildNo := 1
2021-11-27 01:34:15 +01:00
versionSlice := strings . Split ( pkg . DbPackage . LastVersionBuild , "." )
2021-11-27 02:01:43 +01:00
if strings . Join ( versionSlice [ : len ( versionSlice ) - 1 ] , "." ) == pkg . Version {
2021-11-27 01:28:42 +01:00
buildNo , err = strconv . Atoi ( versionSlice [ len ( versionSlice ) - 1 ] )
if err != nil {
2021-11-29 10:48:29 +01:00
log . Errorf ( "[%s/%s/%s] Failed to read build from pkgrel: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-11-27 01:28:42 +01:00
b . buildWG . Done ( )
continue
}
buildNo ++
}
err = pkg . increasePkgRel ( buildNo )
2021-07-27 02:43:30 +02:00
if err != nil {
2021-11-29 10:48:29 +01:00
log . Errorf ( "[%s/%s/%s] Failed to increase pkgrel: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-07-27 02:43:30 +02:00
b . buildWG . Done ( )
continue
}
2021-11-21 23:46:21 +01:00
if contains ( conf . KernelToPatch , pkg . Pkgbase ) {
err = pkg . prepareKernelPatches ( )
if err != nil {
2021-11-29 10:48:29 +01:00
log . Warningf ( "[%s/%s/%s] Failed to modify PKGBUILD for kernel patch: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
2021-11-21 23:46:21 +01:00
pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusFailed ) . SetSkipReason ( "failed to apply patch" ) . SetHash ( pkg . Hash ) . ExecX ( context . Background ( ) )
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-11-21 23:46:21 +01:00
b . buildWG . Done ( )
continue
}
}
2021-06-10 21:32:11 +02:00
pkg . PkgFiles = [ ] string { }
2021-11-13 20:45:47 +01:00
// default to LTO
2021-12-21 22:33:42 +01:00
makepkgFile := makepkg
2021-11-25 01:50:49 +01:00
if pkg . DbPackage . Lto == dbpackage . LtoDisabled || pkg . DbPackage . Lto == dbpackage . LtoAutoDisabled {
2021-11-13 20:45:47 +01:00
// use non-lto makepkg.conf if LTO is blacklisted for this package
2021-12-21 22:33:42 +01:00
makepkgFile = makepkgLTO
2021-11-13 20:45:47 +01:00
}
2021-07-08 16:30:03 +02:00
cmd := exec . Command ( "sh" , "-c" ,
2021-12-19 16:37:10 +01:00
"cd " + filepath . Dir ( pkg . Pkgbuild ) + "&&makechrootpkg -c -D " + filepath . Join ( conf . Basedir . Work , makepkgDir ) + " -l worker-" + march + "-" + strconv . Itoa ( id ) + " -r " + filepath . Join ( conf . Basedir . Work , chrootDir ) + " -- " +
"-m --noprogressbar --config " + filepath . Join ( conf . Basedir . Work , makepkgDir , fmt . Sprintf ( makepkgFile , pkg . March ) ) )
2021-06-14 15:52:53 +02:00
var out bytes . Buffer
cmd . Stdout = & out
cmd . Stderr = & out
check ( cmd . Start ( ) )
b . buildProcMutex . Lock ( )
2021-06-14 16:14:17 +02:00
b . buildProcesses = append ( b . buildProcesses , cmd . Process )
2021-06-14 15:52:53 +02:00
b . buildProcMutex . Unlock ( )
2021-07-13 18:07:29 +02:00
err = cmd . Wait ( )
2021-06-14 15:52:53 +02:00
b . buildProcMutex . Lock ( )
for i := range b . buildProcesses {
2021-06-14 16:14:17 +02:00
if b . buildProcesses [ i ] . Pid == cmd . Process . Pid {
2021-06-14 15:52:53 +02:00
b . buildProcesses = append ( b . buildProcesses [ : i ] , b . buildProcesses [ i + 1 : ] ... )
break
}
}
b . buildProcMutex . Unlock ( )
2021-06-10 21:32:11 +02:00
if err != nil {
2021-06-12 00:04:33 +02:00
if b . exit {
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-07-01 21:13:48 +02:00
b . buildWG . Done ( )
2021-06-12 00:04:33 +02:00
continue
}
2021-11-25 01:50:49 +01:00
if pkg . DbPackage . Lto != dbpackage . LtoAutoDisabled && pkg . DbPackage . Lto != dbpackage . LtoDisabled && reLdError . Match ( out . Bytes ( ) ) {
2021-11-29 10:48:29 +01:00
log . Infof ( "[%s/%s/%s] ld error detected, disabling LTO" , pkg . FullRepo , pkg . Pkgbase , pkg . Version )
2021-11-25 01:50:49 +01:00
pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusQueued ) . SetSkipReason ( "non-LTO rebuild" ) . SetLto ( dbpackage . LtoAutoDisabled ) . ExecX ( context . Background ( ) )
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-11-25 01:50:49 +01:00
b . buildWG . Done ( )
continue
}
2021-12-20 00:44:32 +01:00
if reDownloadError . Match ( out . Bytes ( ) ) || rePortError . Match ( out . Bytes ( ) ) || reSigError . Match ( out . Bytes ( ) ) {
log . Infof ( "[%s/%s/%s] detected fixable error, rebuilding later" , pkg . FullRepo , pkg . Pkgbase , pkg . Version )
2021-12-19 17:39:33 +01:00
pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusQueued ) . ExecX ( context . Background ( ) )
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
b . buildWG . Done ( )
continue
}
2021-11-29 10:48:29 +01:00
log . Warningf ( "[%s/%s/%s] Build failed (%d)" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , cmd . ProcessState . ExitCode ( ) )
2021-06-10 21:32:11 +02:00
2021-11-29 13:29:43 +01:00
check ( os . MkdirAll ( filepath . Join ( conf . Basedir . Repo , logDir , march ) , 0755 ) )
check ( os . WriteFile ( filepath . Join ( conf . Basedir . Repo , logDir , march , pkg . Pkgbase + ".log" ) , out . Bytes ( ) , 0644 ) )
2021-06-10 21:32:11 +02:00
2021-11-20 00:02:53 +01:00
pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusFailed ) . ClearSkipReason ( ) . SetBuildTimeStart ( start ) . SetBuildTimeEnd ( time . Now ( ) . UTC ( ) ) . SetHash ( pkg . Hash ) . ExecX ( context . Background ( ) )
2021-07-13 18:07:29 +02:00
2021-09-07 12:49:01 +02:00
// purge failed package from repo
2021-12-20 16:04:13 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
2021-09-07 12:49:01 +02:00
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-07-01 21:13:48 +02:00
b . buildWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
pkgFiles , err := filepath . Glob ( filepath . Join ( filepath . Dir ( pkg . Pkgbuild ) , "*.pkg.tar.zst" ) )
check ( err )
if len ( pkgFiles ) == 0 {
log . Warningf ( "No packages found after building %s. Abort build." , pkg . Pkgbase )
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-07-01 21:13:48 +02:00
b . buildWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
for _ , file := range pkgFiles {
2021-07-08 16:30:03 +02:00
cmd = exec . Command ( "gpg" , "--batch" , "--detach-sign" , file )
2021-06-10 21:32:11 +02:00
res , err := cmd . CombinedOutput ( )
if err != nil {
2021-12-20 18:40:20 +01:00
log . Warningf ( "Failed to sign %s (%s): %s" , pkg . Pkgbase , err , string ( res ) )
2021-07-01 21:13:48 +02:00
b . buildWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
}
copyFiles , err := filepath . Glob ( filepath . Join ( filepath . Dir ( pkg . Pkgbuild ) , "*.pkg.tar.zst*" ) )
check ( err )
for _ , file := range copyFiles {
2021-12-20 18:40:20 +01:00
check ( os . MkdirAll ( filepath . Join ( conf . Basedir . Work , waitingDir , pkg . FullRepo ) , 0755 ) )
2021-12-20 17:20:06 +01:00
_ , err = copyFile ( file , filepath . Join ( conf . Basedir . Work , waitingDir , pkg . FullRepo , filepath . Base ( file ) ) )
2021-06-10 21:32:11 +02:00
if err != nil {
check ( err )
2021-07-01 21:13:48 +02:00
b . buildWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
if filepath . Ext ( file ) != ".sig" {
2021-12-20 17:20:06 +01:00
pkg . PkgFiles = append ( pkg . PkgFiles , filepath . Join ( conf . Basedir . Work , waitingDir , pkg . FullRepo , filepath . Base ( file ) ) )
2021-06-10 21:32:11 +02:00
}
}
2021-11-29 13:29:43 +01:00
if _ , err := os . Stat ( filepath . Join ( conf . Basedir . Repo , logDir , march , pkg . Pkgbase + ".log" ) ) ; err == nil {
check ( os . Remove ( filepath . Join ( conf . Basedir . Repo , logDir , march , pkg . Pkgbase + ".log" ) ) )
2021-06-10 21:32:11 +02:00
}
2021-11-25 01:50:49 +01:00
if pkg . DbPackage . Lto != dbpackage . LtoDisabled && pkg . DbPackage . Lto != dbpackage . LtoAutoDisabled {
2021-12-20 17:20:06 +01:00
pkg . DbPackage . Update ( ) .
SetStatus ( dbpackage . StatusBuild ) .
SetLto ( dbpackage . LtoEnabled ) .
SetBuildTimeStart ( start ) .
SetLastVersionBuild ( pkg . Version ) .
SetBuildTimeEnd ( time . Now ( ) . UTC ( ) ) .
SetHash ( pkg . Hash ) .
ExecX ( context . Background ( ) )
2021-11-16 23:30:31 +01:00
} else {
2021-12-20 17:20:06 +01:00
pkg . DbPackage . Update ( ) .
SetStatus ( dbpackage . StatusBuild ) .
SetBuildTimeStart ( start ) .
SetBuildTimeEnd ( time . Now ( ) . UTC ( ) ) .
SetLastVersionBuild ( pkg . Version ) .
SetHash ( pkg . Hash ) . ExecX ( context . Background ( ) )
2021-11-16 23:30:31 +01:00
}
2021-07-13 18:07:29 +02:00
2021-11-27 01:28:42 +01:00
log . Infof ( "[%s/%s/%s] Build successful (%s)" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , time . Since ( start ) )
2021-07-13 18:07:29 +02:00
2021-11-29 15:02:14 +01:00
err = cleanBuildDir ( buildDir )
if err != nil {
log . Warningf ( "[%s/%s/%s] Error removing builddir: %v" , pkg . FullRepo , pkg . Pkgbase , pkg . Version , err )
}
2021-12-20 17:20:06 +01:00
b . buildWG . Done ( )
2021-06-10 21:32:11 +02:00
}
}
}
func ( b * BuildManager ) parseWorker ( ) {
for {
if b . exit {
return
}
select {
2021-07-09 20:37:00 +02:00
case pkg := <- b . parse :
2021-11-19 22:32:11 +01:00
if err := pkg . genSrcinfo ( ) ; err != nil {
2021-10-24 06:10:55 +02:00
log . Warningf ( "Failed to generate SRCINFO for %s: %v" , pkg . Pkgbase , err )
2021-07-01 21:13:48 +02:00
b . parseWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
2021-07-27 02:43:30 +02:00
pkg . Version = constructVersion ( pkg . Srcinfo . Pkgver , pkg . Srcinfo . Pkgrel , pkg . Srcinfo . Epoch )
2021-06-10 21:32:11 +02:00
2021-11-20 01:02:37 +01:00
if ! pkg . isAvailable ( alpmHandle ) {
log . Debugf ( "[%s/%s] Not available on mirror, skipping build" , pkg . FullRepo , pkg . Pkgbase )
2021-11-20 15:24:07 +01:00
b . parseWG . Done ( )
2021-11-20 01:02:37 +01:00
continue
}
2021-07-13 18:07:29 +02:00
2021-11-20 01:02:37 +01:00
pkg . toDbPackage ( true )
2021-07-13 18:07:29 +02:00
skipping := false
2021-11-19 22:32:11 +01:00
if contains ( pkg . Srcinfo . Arch , "any" ) {
log . Debugf ( "Skipped %s: any-Package" , pkg . Srcinfo . Pkgbase )
2021-11-20 00:02:53 +01:00
pkg . DbPackage . SkipReason = "arch = any"
pkg . DbPackage . Status = dbpackage . StatusSkipped
2021-07-13 18:07:29 +02:00
skipping = true
2021-11-19 22:32:11 +01:00
} else if contains ( conf . Blacklist . Packages , pkg . Srcinfo . Pkgbase ) {
log . Debugf ( "Skipped %s: blacklisted package" , pkg . Srcinfo . Pkgbase )
2021-11-20 00:02:53 +01:00
pkg . DbPackage . SkipReason = "blacklisted"
pkg . DbPackage . Status = dbpackage . StatusSkipped
2021-07-13 18:07:29 +02:00
skipping = true
2021-11-19 22:32:11 +01:00
} else if contains ( pkg . Srcinfo . MakeDepends , "ghc" ) || contains ( pkg . Srcinfo . MakeDepends , "haskell-ghc" ) || contains ( pkg . Srcinfo . Depends , "ghc" ) || contains ( pkg . Srcinfo . Depends , "haskell-ghc" ) {
2021-07-13 18:07:29 +02:00
// Skip Haskell packages for now, as we are facing linking problems with them,
2021-07-27 16:24:30 +02:00
// most likely caused by not having a dependency check implemented yet and building at random.
2021-07-13 18:07:29 +02:00
// https://git.harting.dev/anonfunc/ALHP.GO/issues/11
2021-11-19 22:32:11 +01:00
log . Debugf ( "Skipped %s: haskell package" , pkg . Srcinfo . Pkgbase )
2021-11-20 00:02:53 +01:00
pkg . DbPackage . SkipReason = "blacklisted (haskell)"
pkg . DbPackage . Status = dbpackage . StatusSkipped
2021-07-13 18:07:29 +02:00
skipping = true
2021-11-20 00:02:53 +01:00
} else if isPkgFailed ( pkg ) {
2021-11-19 22:32:11 +01:00
log . Debugf ( "Skipped %s: failed build" , pkg . Srcinfo . Pkgbase )
2021-07-13 18:07:29 +02:00
skipping = true
2021-07-09 14:46:50 +02:00
}
2021-07-13 18:07:29 +02:00
if skipping {
2021-11-25 01:50:49 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetUpdated ( time . Now ( ) ) . SetVersion ( pkg . Version ) .
2021-11-20 00:02:53 +01:00
SetPackages ( packages2slice ( pkg . Srcinfo . Packages ) ) . SetStatus ( pkg . DbPackage . Status ) .
2021-11-25 01:50:49 +01:00
SetSkipReason ( pkg . DbPackage . SkipReason ) . SetHash ( pkg . Hash ) . SaveX ( context . Background ( ) )
2021-12-20 16:04:13 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
2021-07-01 21:13:48 +02:00
b . parseWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
2021-11-18 13:22:10 +01:00
} else {
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetUpdated ( time . Now ( ) ) . SetPackages ( packages2slice ( pkg . Srcinfo . Packages ) ) . SetVersion ( pkg . Version ) . SaveX ( context . Background ( ) )
2021-06-10 21:32:11 +02:00
}
2021-11-25 01:50:49 +01:00
if contains ( conf . Blacklist . LTO , pkg . Pkgbase ) {
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetLto ( dbpackage . LtoDisabled ) . SaveX ( context . Background ( ) )
}
2021-11-19 22:32:11 +01:00
repoVer , err := pkg . repoVersion ( )
2021-11-18 13:22:10 +01:00
if err != nil {
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . ClearRepoVersion ( ) . SaveX ( context . Background ( ) )
2021-11-18 13:22:10 +01:00
} else if err == nil && alpm . VerCmp ( repoVer , pkg . Version ) > 0 {
2021-11-19 22:32:11 +01:00
log . Debugf ( "Skipped %s: Version in repo higher than in PKGBUILD (%s < %s)" , pkg . Srcinfo . Pkgbase , pkg . Version , repoVer )
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusLatest ) . ClearSkipReason ( ) . SetHash ( pkg . Hash ) . SaveX ( context . Background ( ) )
2021-07-01 21:13:48 +02:00
b . parseWG . Done ( )
2021-06-10 21:32:11 +02:00
continue
}
2021-11-19 22:32:11 +01:00
isLatest , local , syncVersion , err := pkg . isMirrorLatest ( alpmHandle )
2021-07-27 18:42:37 +02:00
if err != nil {
2021-08-26 12:21:20 +02:00
switch err . ( type ) {
default :
2021-11-19 22:32:11 +01:00
log . Warningf ( "[%s/%s] Problem solving dependencies: %v" , pkg . FullRepo , pkg . Srcinfo . Pkgbase , err )
2022-01-21 12:33:45 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
b . parseWG . Done ( )
continue
2021-08-26 12:21:20 +02:00
case MultiplePKGBUILDError :
2021-11-19 22:32:11 +01:00
log . Infof ( "Skipped %s: Multiple PKGBUILDs for dependency found: %v" , pkg . Srcinfo . Pkgbase , err )
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusSkipped ) . SetSkipReason ( "multiple PKGBUILD for dep. found" ) . SaveX ( context . Background ( ) )
2021-12-20 16:04:13 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
2021-08-26 12:21:20 +02:00
b . parseWG . Done ( )
continue
2021-08-26 12:59:23 +02:00
case UnableToSatisfyError :
2021-11-19 22:32:11 +01:00
log . Infof ( "Skipped %s: unable to resolve dependencies: %v" , pkg . Srcinfo . Pkgbase , err )
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusSkipped ) . SetSkipReason ( "unable to resolve dependencies" ) . SaveX ( context . Background ( ) )
2021-12-20 16:04:13 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
2021-08-26 12:59:23 +02:00
b . parseWG . Done ( )
continue
2021-08-26 12:21:20 +02:00
}
2021-07-27 18:42:37 +02:00
}
2021-11-20 00:02:53 +01:00
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusQueued ) . SaveX ( context . Background ( ) )
2021-07-13 18:07:29 +02:00
2021-07-27 02:43:30 +02:00
if ! isLatest {
2021-07-29 16:53:15 +02:00
if local != nil {
2021-11-19 22:32:11 +01:00
log . Infof ( "Delayed %s: not all dependencies are up to date (local: %s==%s, sync: %s==%s)" , pkg . Srcinfo . Pkgbase , local . Name ( ) , local . Version ( ) , local . Name ( ) , syncVersion )
2021-11-20 00:02:53 +01:00
pkg . DbPackage . Update ( ) . SetSkipReason ( fmt . Sprintf ( "waiting for %s==%s" , local . Name ( ) , syncVersion ) ) . ExecX ( context . Background ( ) )
2021-07-27 18:51:35 +02:00
} else {
2021-11-19 22:32:11 +01:00
log . Infof ( "Delayed %s: not all dependencies are up to date or resolvable" , pkg . Srcinfo . Pkgbase )
2021-11-20 00:02:53 +01:00
pkg . DbPackage . Update ( ) . SetSkipReason ( "waiting for mirror" ) . ExecX ( context . Background ( ) )
2021-07-27 18:51:35 +02:00
}
2021-07-29 20:45:45 +02:00
2021-09-12 17:40:17 +02:00
// Purge delayed packages in case delay is caused by inconsistencies in svn2git.
// Worst case would be clients downloading a package update twice, once from their official mirror,
// and then after build from ALHP. Best case we prevent a not buildable package from staying in the repos
// in an outdated version.
2021-12-20 16:04:13 +01:00
b . repoPurge [ pkg . FullRepo ] <- [ ] * BuildPackage { pkg }
2021-07-27 02:43:30 +02:00
b . parseWG . Done ( )
continue
2021-06-10 21:32:11 +02:00
}
2021-11-29 10:48:29 +01:00
b . build [ pkg . March ] <- pkg
2021-06-10 21:32:11 +02:00
}
}
2021-07-13 18:07:29 +02:00
}
func ( b * BuildManager ) htmlWorker ( ) {
type Pkg struct {
2021-11-25 01:50:49 +01:00
Pkgbase string
Status string
Class string
Skip string
Version string
Svn2GitVersion string
BuildDate string
BuildDuration time . Duration
Checked string
Log string
LTO bool
LTOUnknown bool
LTODisabled bool
LTOAutoDisabled bool
2021-07-13 18:07:29 +02:00
}
type Repo struct {
Name string
Packages [ ] Pkg
}
type March struct {
Name string
Repos [ ] Repo
}
type tpl struct {
2021-11-25 02:10:39 +01:00
March [ ] March
Generated string
Latest int
Failed int
Skipped int
Queued int
LTOEnabled int
LTOUnknown int
LTODisabled int
2021-07-13 18:07:29 +02:00
}
for {
gen := & tpl { }
for _ , march := range conf . March {
addMarch := March {
Name : march ,
}
for _ , repo := range conf . Repos {
addRepo := Repo {
Name : repo ,
}
2021-10-25 05:57:43 +02:00
pkgs := db . DbPackage . Query ( ) . Order ( ent . Asc ( dbpackage . FieldPkgbase ) ) . Where ( dbpackage . MarchEQ ( march ) , dbpackage . RepositoryEQ ( dbpackage . Repository ( repo ) ) ) . AllX ( context . Background ( ) )
2021-07-13 18:07:29 +02:00
for _ , pkg := range pkgs {
addPkg := Pkg {
Pkgbase : pkg . Pkgbase ,
2021-11-21 15:24:27 +01:00
Status : strings . ToUpper ( pkg . Status . String ( ) ) ,
2021-11-21 18:27:03 +01:00
Class : statusId2string ( pkg . Status ) ,
2021-07-13 18:07:29 +02:00
Skip : pkg . SkipReason ,
Version : pkg . RepoVersion ,
Svn2GitVersion : pkg . Version ,
}
2021-11-18 13:46:56 +01:00
if ! pkg . BuildTimeEnd . IsZero ( ) && ! pkg . BuildTimeStart . IsZero ( ) && pkg . BuildTimeStart . Before ( pkg . BuildTimeEnd ) {
2021-11-13 15:36:28 +01:00
addPkg . BuildDuration = pkg . BuildTimeEnd . Sub ( pkg . BuildTimeStart )
2021-07-13 18:07:29 +02:00
}
2021-10-25 05:57:43 +02:00
if ! pkg . BuildTimeStart . IsZero ( ) {
2021-11-02 10:59:58 +01:00
addPkg . BuildDate = pkg . BuildTimeStart . UTC ( ) . Format ( time . RFC1123 )
2021-07-13 18:07:29 +02:00
}
if ! pkg . Updated . IsZero ( ) {
2021-11-02 10:59:58 +01:00
addPkg . Checked = pkg . Updated . UTC ( ) . Format ( time . RFC1123 )
2021-07-13 18:07:29 +02:00
}
2021-10-25 05:57:43 +02:00
if pkg . Status == dbpackage . StatusFailed {
2021-11-29 13:29:43 +01:00
addPkg . Log = fmt . Sprintf ( "%s/%s/%s.log" , logDir , pkg . March , pkg . Pkgbase )
2021-07-14 19:21:58 +02:00
}
2021-11-16 23:30:31 +01:00
switch pkg . Lto {
case dbpackage . LtoUnknown :
2021-11-20 01:25:32 +01:00
if pkg . Status != dbpackage . StatusSkipped && pkg . Status != dbpackage . StatusFailed {
2021-11-19 22:32:11 +01:00
addPkg . LTOUnknown = true
}
2021-11-16 23:30:31 +01:00
case dbpackage . LtoEnabled :
2021-11-16 23:42:54 +01:00
addPkg . LTO = true
2021-11-16 23:30:31 +01:00
case dbpackage . LtoDisabled :
2021-11-16 23:42:54 +01:00
addPkg . LTODisabled = true
2021-11-25 01:50:49 +01:00
case dbpackage . LtoAutoDisabled :
addPkg . LTOAutoDisabled = true
2021-11-16 23:30:31 +01:00
}
2021-07-13 18:07:29 +02:00
addRepo . Packages = append ( addRepo . Packages , addPkg )
}
addMarch . Repos = append ( addMarch . Repos , addRepo )
}
gen . March = append ( gen . March , addMarch )
}
2021-11-02 10:59:58 +01:00
gen . Generated = time . Now ( ) . UTC ( ) . Format ( time . RFC1123 )
2021-07-14 19:21:58 +02:00
2021-11-23 22:04:50 +01:00
var v [ ] struct {
Status dbpackage . Status ` json:"status" `
Count int ` json:"count" `
}
db . DbPackage . Query ( ) . GroupBy ( dbpackage . FieldStatus ) . Aggregate ( ent . Count ( ) ) . ScanX ( context . Background ( ) , & v )
for _ , c := range v {
switch c . Status {
case dbpackage . StatusFailed :
gen . Failed = c . Count
case dbpackage . StatusSkipped :
gen . Skipped = c . Count
case dbpackage . StatusLatest :
gen . Latest = c . Count
2021-11-24 13:24:41 +01:00
case dbpackage . StatusQueued :
gen . Queued = c . Count
2021-11-23 22:04:50 +01:00
}
}
2021-11-25 02:10:39 +01:00
var v2 [ ] struct {
Status dbpackage . Lto ` json:"lto" `
Count int ` json:"count" `
}
2021-11-25 13:51:59 +01:00
db . DbPackage . Query ( ) . Where ( dbpackage . StatusNEQ ( dbpackage . StatusSkipped ) ) . GroupBy ( dbpackage . FieldLto ) . Aggregate ( ent . Count ( ) ) . ScanX ( context . Background ( ) , & v2 )
2021-11-25 02:10:39 +01:00
for _ , c := range v2 {
switch c . Status {
case dbpackage . LtoUnknown :
gen . LTOUnknown = c . Count
case dbpackage . LtoDisabled , dbpackage . LtoAutoDisabled :
gen . LTODisabled += c . Count
case dbpackage . LtoEnabled :
gen . LTOEnabled = c . Count
}
}
2021-07-22 23:41:24 +02:00
statusTpl , err := template . ParseFiles ( "tpl/packages.html" )
2021-07-13 18:07:29 +02:00
check ( err )
2021-12-20 00:38:47 +01:00
f , err := os . OpenFile ( filepath . Join ( conf . Basedir . Repo , "packages.html" ) , os . O_WRONLY | os . O_CREATE | os . O_TRUNC , 0644 )
2021-07-13 18:07:29 +02:00
check ( statusTpl . Execute ( f , gen ) )
check ( f . Close ( ) )
2021-12-20 00:38:47 +01:00
time . Sleep ( time . Minute * 5 )
2021-07-13 18:07:29 +02:00
}
}
2021-07-09 20:37:00 +02:00
func ( b * BuildManager ) repoWorker ( repo string ) {
2021-06-10 21:32:11 +02:00
for {
select {
2021-12-20 16:04:13 +01:00
case pkgL := <- b . repoAdd [ repo ] :
2021-12-20 17:20:06 +01:00
toAdd := make ( [ ] string , 0 )
2021-12-20 16:04:13 +01:00
for _ , pkg := range pkgL {
2021-12-20 17:20:06 +01:00
toAdd = append ( toAdd , pkg . PkgFiles ... )
}
args := [ ] string { "-s" , "-v" , "-p" , "-n" , filepath . Join ( conf . Basedir . Repo , repo , "os" , conf . Arch , repo ) + ".db.tar.xz" }
args = append ( args , toAdd ... )
cmd := exec . Command ( "repo-add" , args ... )
res , err := cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
if err != nil && cmd . ProcessState . ExitCode ( ) != 1 {
log . Panicf ( "%s while repo-add: %v" , string ( res ) , err )
}
2021-06-10 21:32:11 +02:00
2021-12-20 17:20:06 +01:00
for _ , pkg := range pkgL {
2021-12-20 16:04:13 +01:00
pkg . toDbPackage ( true )
pkg . DbPackage = pkg . DbPackage . Update ( ) . SetStatus ( dbpackage . StatusLatest ) . ClearSkipReason ( ) . SetRepoVersion ( pkg . Version ) . SetHash ( pkg . Hash ) . SaveX ( context . Background ( ) )
2021-06-10 21:32:11 +02:00
}
2021-12-20 17:20:06 +01:00
cmd = exec . Command ( "paccache" , "-rc" , filepath . Join ( conf . Basedir . Repo , repo , "os" , conf . Arch ) , "-k" , "1" )
res , err = cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
check ( err )
updateLastUpdated ( )
2021-12-20 16:04:13 +01:00
case pkgL := <- b . repoPurge [ repo ] :
for _ , pkg := range pkgL {
if _ , err := os . Stat ( filepath . Join ( conf . Basedir . Repo , pkg . FullRepo , "os" , conf . Arch , pkg . FullRepo ) + ".db.tar.xz" ) ; err != nil {
2021-07-13 20:01:42 +02:00
continue
}
2021-12-20 16:04:13 +01:00
if len ( pkg . PkgFiles ) == 0 {
if err := pkg . findPkgFiles ( ) ; err != nil {
log . Warningf ( "[%s/%s] Unable to find files: %v" , pkg . FullRepo , pkg . Pkgbase , err )
continue
} else if len ( pkg . PkgFiles ) == 0 {
continue
}
}
2021-06-10 21:32:11 +02:00
2021-12-20 16:04:13 +01:00
var realPkgs [ ] string
for _ , filePath := range pkg . PkgFiles {
realPkgs = append ( realPkgs , Package ( filePath ) . Name ( ) )
}
2021-06-10 21:32:11 +02:00
2021-12-20 16:04:13 +01:00
b . repoWG . Add ( 1 )
args := [ ] string { "-s" , "-v" , filepath . Join ( conf . Basedir . Repo , pkg . FullRepo , "os" , conf . Arch , pkg . FullRepo ) + ".db.tar.xz" }
args = append ( args , realPkgs ... )
cmd := exec . Command ( "repo-remove" , args ... )
res , err := cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
if err != nil && cmd . ProcessState . ExitCode ( ) == 1 {
log . Warningf ( "Error while deleting package %s: %s" , pkg . Pkgbase , string ( res ) )
}
2021-06-10 21:32:11 +02:00
2021-12-20 16:04:13 +01:00
if pkg . DbPackage != nil {
_ = pkg . DbPackage . Update ( ) . ClearRepoVersion ( ) . Exec ( context . Background ( ) )
}
2021-07-18 23:33:16 +02:00
2021-12-20 16:04:13 +01:00
for _ , file := range pkg . PkgFiles {
_ = os . Remove ( file )
_ = os . Remove ( file + ".sig" )
}
updateLastUpdated ( )
b . repoWG . Done ( )
2021-06-10 21:32:11 +02:00
}
}
}
}
func ( b * BuildManager ) syncWorker ( ) {
2021-12-19 16:37:10 +01:00
check ( os . MkdirAll ( filepath . Join ( conf . Basedir . Work , upstreamDir ) , 0755 ) )
2021-06-10 21:32:11 +02:00
2021-07-01 21:40:49 +02:00
for i := 0 ; i < runtime . NumCPU ( ) ; i ++ {
2021-06-10 21:32:11 +02:00
go b . parseWorker ( )
}
for {
for gitDir , gitURL := range conf . Svn2git {
2021-12-19 16:37:10 +01:00
gitPath := filepath . Join ( conf . Basedir . Work , upstreamDir , gitDir )
2021-06-10 21:32:11 +02:00
if _ , err := os . Stat ( gitPath ) ; os . IsNotExist ( err ) {
2021-07-08 16:30:03 +02:00
cmd := exec . Command ( "git" , "clone" , "--depth=1" , gitURL , gitPath )
2021-06-10 21:32:11 +02:00
res , err := cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
check ( err )
} else if err == nil {
2021-11-29 15:02:14 +01:00
cmd := exec . Command ( "sh" , "-c" , "cd " + gitPath + " && git reset --hard" )
2021-06-10 21:32:11 +02:00
res , err := cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
check ( err )
2021-07-08 16:30:03 +02:00
cmd = exec . Command ( "sh" , "-c" , "cd " + gitPath + " && git pull" )
2021-06-10 21:32:11 +02:00
res , err = cmd . CombinedOutput ( )
log . Debug ( string ( res ) )
2021-11-20 16:15:00 +01:00
if err != nil {
log . Warningf ( "Failed to update git repo %s: %v" , gitDir , err )
}
2021-06-10 21:32:11 +02:00
}
}
2021-11-19 22:32:11 +01:00
// housekeeping
2021-11-20 00:02:53 +01:00
wg := new ( sync . WaitGroup )
for _ , repo := range repos {
wg . Add ( 1 )
2022-02-07 17:46:16 +01:00
splitRepo := strings . Split ( repo , "-" )
2021-11-20 00:02:53 +01:00
repo := repo
go func ( ) {
2022-02-07 17:46:16 +01:00
err := housekeeping ( splitRepo [ 0 ] , strings . Join ( splitRepo [ 1 : ] , "-" ) , wg )
2021-11-20 00:02:53 +01:00
if err != nil {
log . Warningf ( "[%s] housekeeping failed: %v" , repo , err )
}
} ( )
2021-11-19 22:32:11 +01:00
}
2021-11-20 00:02:53 +01:00
wg . Wait ( )
2021-11-19 22:32:11 +01:00
2022-01-21 01:41:17 +01:00
err := logHK ( )
if err != nil {
log . Warningf ( "log-housekeeping failed: %v" , err )
}
2021-07-03 22:13:39 +02:00
// fetch updates between sync runs
2021-08-31 21:13:22 +02:00
b . alpmMutex . Lock ( )
2021-07-29 00:45:45 +02:00
check ( alpmHandle . Release ( ) )
2022-01-21 01:41:17 +01:00
err = setupChroot ( )
2021-11-02 08:43:50 +01:00
for err != nil {
log . Warningf ( "Unable to upgrade chroot, trying again later." )
time . Sleep ( time . Minute )
err = setupChroot ( )
}
2021-12-19 16:37:10 +01:00
alpmHandle , err = initALPM ( filepath . Join ( conf . Basedir . Work , chrootDir , pristineChroot ) , filepath . Join ( conf . Basedir . Work , chrootDir , pristineChroot , "/var/lib/pacman" ) )
2021-07-29 00:43:22 +02:00
check ( err )
2021-08-31 21:13:22 +02:00
b . alpmMutex . Unlock ( )
2021-07-03 22:13:39 +02:00
2021-12-19 16:37:10 +01:00
pkgBuilds , err := Glob ( filepath . Join ( conf . Basedir . Work , upstreamDir , "/**/PKGBUILD" ) )
2021-06-10 21:32:11 +02:00
check ( err )
2021-12-14 10:29:24 +01:00
// Shuffle pkgbuilds to spread out long-running builds, otherwise pkgBuilds is alphabetically-sorted
rand . Seed ( time . Now ( ) . UnixNano ( ) )
rand . Shuffle ( len ( pkgBuilds ) , func ( i , j int ) { pkgBuilds [ i ] , pkgBuilds [ j ] = pkgBuilds [ j ] , pkgBuilds [ i ] } )
2021-06-10 21:32:11 +02:00
for _ , pkgbuild := range pkgBuilds {
if b . exit {
return
}
2021-12-10 09:26:51 +01:00
mPkgbuild := PKGBUILD ( pkgbuild )
if mPkgbuild . FullRepo ( ) == "trunk" || ! contains ( conf . Repos , mPkgbuild . Repo ( ) ) || containsSubStr ( mPkgbuild . FullRepo ( ) , conf . Blacklist . Repo ) {
2021-06-10 21:32:11 +02:00
continue
}
2021-11-29 15:02:14 +01:00
for _ , march := range conf . March {
2021-12-10 09:26:51 +01:00
dbPkg , dbErr := db . DbPackage . Query ( ) . Where (
dbpackage . And (
dbpackage . Pkgbase ( mPkgbuild . PkgBase ( ) ) ,
dbpackage . RepositoryEQ ( dbpackage . Repository ( mPkgbuild . Repo ( ) ) ) ,
dbpackage . March ( march ) ,
) ,
2021-11-29 15:02:14 +01:00
) . Only ( context . Background ( ) )
2022-02-07 15:55:33 +01:00
if ent . IsNotFound ( dbErr ) {
log . Debugf ( "[%s/%s] Package not found in database" , mPkgbuild . Repo ( ) , mPkgbuild . PkgBase ( ) )
} else if err != nil {
log . Errorf ( "[%s/%s] Problem querying db for package: %v" , mPkgbuild . Repo ( ) , mPkgbuild . PkgBase ( ) , dbErr )
2021-08-30 11:02:06 +02:00
}
2021-12-10 09:26:51 +01:00
// compare b3sum of PKGBUILD file to hash in database, only proceed if hash differs
// reduces the amount of PKGBUILDs that need to be parsed with makepkg, which is _really_ slow, significantly
2021-11-29 15:02:14 +01:00
b3s , err := b3sum ( pkgbuild )
check ( err )
2021-08-30 11:02:06 +02:00
2021-11-29 15:02:14 +01:00
if dbPkg != nil && b3s == dbPkg . Hash {
2021-12-10 09:26:51 +01:00
log . Debugf ( "[%s/%s] Skipped: PKGBUILD hash matches db (%s)" , mPkgbuild . Repo ( ) , mPkgbuild . PkgBase ( ) , b3s )
2021-11-29 15:02:14 +01:00
continue
}
2021-08-30 11:02:06 +02:00
2021-11-29 15:02:14 +01:00
// send to parse
2021-07-01 21:13:48 +02:00
b . parseWG . Add ( 1 )
2021-07-09 20:37:00 +02:00
b . parse <- & BuildPackage {
2021-06-10 21:32:11 +02:00
Pkgbuild : pkgbuild ,
2021-12-10 09:26:51 +01:00
Pkgbase : mPkgbuild . PkgBase ( ) ,
Repo : dbpackage . Repository ( mPkgbuild . Repo ( ) ) ,
2021-06-10 21:32:11 +02:00
March : march ,
2021-12-10 09:26:51 +01:00
FullRepo : mPkgbuild . Repo ( ) + "-" + march ,
2021-08-30 11:02:06 +02:00
Hash : b3s ,
2021-06-10 21:32:11 +02:00
}
}
}
2021-07-01 21:13:48 +02:00
b . parseWG . Wait ( )
2021-12-20 17:20:06 +01:00
b . buildWG . Wait ( )
2021-12-20 18:40:20 +01:00
if ! b . exit {
for _ , repo := range repos {
err = movePackagesLive ( repo )
if err != nil {
log . Errorf ( "[%s] Error moving packages live: %v" , repo , err )
}
2021-12-20 17:20:06 +01:00
}
}
2022-01-21 13:02:22 +01:00
time . Sleep ( time . Duration ( * checkInterval ) * time . Minute )
2021-06-10 21:32:11 +02:00
}
}
func main ( ) {
killSignals := make ( chan os . Signal , 1 )
signal . Notify ( killSignals , syscall . SIGINT , syscall . SIGTERM )
2021-11-22 16:50:12 +01:00
reloadSignals := make ( chan os . Signal , 1 )
signal . Notify ( reloadSignals , syscall . SIGUSR1 )
2021-09-12 17:25:33 +02:00
flag . Parse ( )
2021-06-10 21:32:11 +02:00
confStr , err := os . ReadFile ( "config.yaml" )
check ( err )
err = yaml . Unmarshal ( confStr , & conf )
check ( err )
lvl , err := log . ParseLevel ( conf . Logging . Level )
check ( err )
log . SetLevel ( lvl )
2021-09-12 17:25:33 +02:00
if * journalLog {
journalhook . Enable ( )
}
2021-06-10 21:32:11 +02:00
2021-06-30 17:41:50 +02:00
err = syscall . Setpriority ( syscall . PRIO_PROCESS , 0 , 5 )
if err != nil {
log . Warningf ( "Failed to drop priority: %v" , err )
}
2021-06-14 13:04:06 +02:00
2021-11-04 11:59:57 +01:00
err = os . MkdirAll ( conf . Basedir . Repo , 0755 )
2021-07-14 19:21:58 +02:00
check ( err )
2021-10-25 06:20:03 +02:00
if conf . Db . Driver == "pgx" {
pdb , err := sql . Open ( "pgx" , conf . Db . ConnectTo )
if err != nil {
log . Fatalf ( "Failed to open database %s: %v" , conf . Db . ConnectTo , err )
}
drv := sql . OpenDB ( dialect . Postgres , pdb . DB ( ) )
db = ent . NewClient ( ent . Driver ( drv ) )
} else {
db , err = ent . Open ( conf . Db . Driver , conf . Db . ConnectTo )
if err != nil {
log . Panicf ( "Failed to open database %s: %v" , conf . Db . ConnectTo , err )
}
defer func ( Client * ent . Client ) {
_ = Client . Close ( )
} ( db )
2021-07-13 18:07:29 +02:00
}
2021-07-26 16:38:12 +02:00
if err := db . Schema . Create ( context . Background ( ) , migrate . WithDropIndex ( true ) , migrate . WithDropColumn ( true ) ) ; err != nil {
2021-07-13 18:07:29 +02:00
log . Panicf ( "Automigrate failed: %v" , err )
}
2021-11-04 11:59:57 +01:00
buildManager = & BuildManager {
2021-11-29 10:48:29 +01:00
build : make ( map [ string ] chan * BuildPackage ) ,
2021-07-09 20:44:37 +02:00
parse : make ( chan * BuildPackage , 10000 ) ,
2021-12-20 16:04:13 +01:00
repoPurge : make ( map [ string ] chan [ ] * BuildPackage ) ,
repoAdd : make ( map [ string ] chan [ ] * BuildPackage ) ,
2021-07-09 20:44:37 +02:00
exit : false ,
2021-06-10 21:32:11 +02:00
}
2021-11-02 08:43:50 +01:00
err = setupChroot ( )
if err != nil {
log . Fatalf ( "Unable to setup chroot: %v" , err )
}
2021-06-10 21:32:11 +02:00
syncMarchs ( )
2021-12-19 16:37:10 +01:00
alpmHandle , err = initALPM ( filepath . Join ( conf . Basedir . Work , chrootDir , pristineChroot ) , filepath . Join ( conf . Basedir . Work , chrootDir , pristineChroot , "/var/lib/pacman" ) )
2021-07-27 02:43:30 +02:00
check ( err )
2021-06-10 21:32:11 +02:00
go buildManager . syncWorker ( )
2021-07-13 18:07:29 +02:00
go buildManager . htmlWorker ( )
2021-06-10 21:32:11 +02:00
2021-11-22 16:50:12 +01:00
killLoop :
for {
select {
case <- killSignals :
break killLoop
case <- reloadSignals :
confStr , err := os . ReadFile ( "config.yaml" )
if err != nil {
log . Fatalf ( "Unable to open config: %v" , err )
}
err = yaml . Unmarshal ( confStr , & conf )
if err != nil {
log . Fatalf ( "Unable to parse config: %v" , err )
}
lvl , err := log . ParseLevel ( conf . Logging . Level )
if err != nil {
log . Fatalf ( "Failure setting logging level: %v" , err )
}
log . SetLevel ( lvl )
2021-11-23 01:13:50 +01:00
log . Infof ( "Config reloaded" )
2021-11-22 16:50:12 +01:00
}
}
2021-06-10 21:32:11 +02:00
buildManager . exit = true
2021-06-14 15:56:21 +02:00
buildManager . buildProcMutex . RLock ( )
2021-06-14 15:52:53 +02:00
for _ , p := range buildManager . buildProcesses {
2021-06-14 16:14:17 +02:00
pgid , err := syscall . Getpgid ( p . Pid )
check ( err )
check ( syscall . Kill ( - pgid , syscall . SIGTERM ) )
2021-06-14 15:52:53 +02:00
}
2021-06-14 15:56:21 +02:00
buildManager . buildProcMutex . RUnlock ( )
2021-07-01 21:13:48 +02:00
buildManager . buildWG . Wait ( )
2021-07-09 14:12:43 +02:00
buildManager . repoWG . Wait ( )
2021-07-27 02:43:30 +02:00
check ( alpmHandle . Release ( ) )
2021-06-10 21:32:11 +02:00
}