7 Commits
1.0.1 ... 1.0.7

4 changed files with 133 additions and 19 deletions

View File

@@ -1,3 +1,3 @@
# ALHP.NOGO
# ALHP.utils
Utility to check if one of your packages is building

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.24
require (
github.com/Jguer/go-alpm/v2 v2.2.2
github.com/deckarep/golang-set/v2 v2.8.0
github.com/Morganamilo/go-pacmanconf v0.0.0-20210502114700-cff030e927a5
github.com/sirupsen/logrus v1.9.3
somegit.dev/ALHP/ALHP.GO v0.0.0-20250322224907-01404adad53a
)

2
go.sum
View File

@@ -9,8 +9,6 @@ github.com/Morganamilo/go-pacmanconf v0.0.0-20210502114700-cff030e927a5/go.mod h
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

146
main.go
View File

@@ -5,12 +5,16 @@ import (
"flag"
"fmt"
"github.com/Jguer/go-alpm/v2"
"github.com/deckarep/golang-set/v2"
paconf "github.com/Morganamilo/go-pacmanconf"
log "github.com/sirupsen/logrus"
"io"
"net/http"
"net/url"
"os"
"path"
"regexp"
"somegit.dev/ALHP/ALHP.GO/ent/dbpackage"
"strconv"
"strings"
)
@@ -19,14 +23,17 @@ const (
)
var (
jsonFlag = flag.Bool("j", false, "output as JSON")
debugFlag = flag.Bool("d", false, "enable debug output")
exitCodeFlag = flag.Bool("e", false, "exit with non-zero if one of your packages is in queue")
jsonFlag = flag.Bool("j", false, "output as JSON")
debugFlag = flag.Bool("d", false, "enable debug output")
exitCodePackageFlag = flag.Bool("e", false, "exit with non-zero if one of your packages is in queue")
exitCodeMirrorFlag = flag.Bool("m", false, "exit with non-zero if your main mirror is out of sync")
repoRegex = regexp.MustCompile(`^\w+-x86-64-v\d$`)
)
type JSONOut struct {
InQueue int `json:"in_queue"`
PackageBases []string `json:"package_base"`
Total int `json:"total"`
Packages []string `json:"packages"`
MirrorOutOfDate bool `json:"mirror_out_of_date"`
}
func main() {
@@ -61,30 +68,97 @@ func main() {
}
log.Debugf("alhp build queue length: %d", len(alhpQueue))
packagesInQueue := mapset.NewSet[string]()
var packagesInQueue []string
for _, pkg := range db.PkgCache().Slice() {
if Find(alhpQueue, pkg.Base()) != -1 {
log.Debugf("found package in queue: %s", pkg.Base())
packagesInQueue.Add(pkg.Base())
log.Debugf("found package in queue: %s", pkg.Name())
packagesInQueue = append(packagesInQueue, pkg.Name())
}
}
if !packagesInQueue.IsEmpty() {
log.Debugf("found %d of your local packages in queue", packagesInQueue.Cardinality())
stats, err := ALHPStats()
if err != nil {
log.Errorf("error getting stats from ALHP api: %v", err)
os.Exit(2)
}
pacmanConfig, _, err := paconf.ParseFile("/etc/pacman.conf")
if err != nil {
log.Errorf("error parsing pacman.conf: %v", err)
os.Exit(2)
}
mirrorOutOfDate := false
for _, repo := range pacmanConfig.Repos {
if !repoRegex.MatchString(repo.Name) || len(repo.Servers) == 0 {
continue
}
pURL, err := url.Parse(repo.Servers[0])
if err != nil {
log.Warnf("error parsing mirror url: %v", err)
}
pURL.Path = path.Join(pURL.Path, "../../../lastupdate")
log.Debugf("checking mirror %s (%s)", repo.Servers[0], pURL.String())
resp, err := http.Get(pURL.String())
if err != nil {
log.Warnf("error getting mirror lastupdate: %v", err)
continue
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Warnf("mirror lastupdate returned %d", resp.StatusCode)
continue
}
bResp, err := io.ReadAll(resp.Body)
if err != nil {
log.Warnf("error reading mirror lastupdate: %v", err)
}
timestamp, err := strconv.ParseInt(string(bResp), 10, 64)
if err != nil {
log.Warnf("error parsing mirror lastupdate: %v", err)
}
if timestamp < stats.LastMirrorTimestamp {
log.Debugf("mirror %s is out of date", repo.Servers[0])
mirrorOutOfDate = true
}
}
if len(packagesInQueue) > 0 {
log.Debugf("found %d of your local packages in queue", len(packagesInQueue))
if *jsonFlag {
err = json.NewEncoder(os.Stdout).Encode(JSONOut{
InQueue: packagesInQueue.Cardinality(),
PackageBases: packagesInQueue.ToSlice(),
Total: len(packagesInQueue),
Packages: packagesInQueue,
MirrorOutOfDate: mirrorOutOfDate,
})
if err != nil {
log.Errorf("error encoding JSON: %v", err)
os.Exit(1)
}
} else {
fmt.Println(strings.Join(packagesInQueue.ToSlice(), "\n"))
fmt.Println(strings.Join(packagesInQueue, "\n"))
}
if *exitCodeFlag {
if *exitCodePackageFlag {
os.Exit(20)
}
} else {
log.Debugf("no packages in queue")
if *jsonFlag {
err = json.NewEncoder(os.Stdout).Encode(JSONOut{
Total: len(packagesInQueue),
Packages: packagesInQueue,
MirrorOutOfDate: mirrorOutOfDate,
})
}
if *exitCodeMirrorFlag && mirrorOutOfDate {
os.Exit(20)
}
}
@@ -121,6 +195,20 @@ type PackageResponse struct {
Limit int `json:"limit"`
}
type StatsResponse struct {
Failed int `json:"failed"`
Skipped int `json:"skipped"`
Latest int `json:"latest"`
Queued int `json:"queued"`
Building int `json:"building"`
LastMirrorTimestamp int64 `json:"last_mirror_timestamp"`
Lto struct {
Enabled int `json:"enabled"`
Disabled int `json:"disabled"`
Unknown int `json:"unknown"`
} `json:"lto"`
}
func ALHPBuildQueuePkgbase() ([]string, error) {
resp, err := http.Get(fmt.Sprintf("%spackages?status=built&status=building&status=queued&limit=0&offset=0", APIBase))
if err != nil {
@@ -128,6 +216,12 @@ func ALHPBuildQueuePkgbase() ([]string, error) {
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
return nil, nil
} else if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("ALHP api returned HTTP %d", resp.StatusCode)
}
bResp, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
@@ -144,3 +238,25 @@ func ALHPBuildQueuePkgbase() ([]string, error) {
}
return respArray, nil
}
func ALHPStats() (*StatsResponse, error) {
resp, err := http.Get(fmt.Sprintf("%sstats", APIBase))
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
bResp, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
jResp := new(StatsResponse)
if err = json.Unmarshal(bResp, jResp); err != nil {
return nil, err
}
return jResp, nil
}