From 48dc0da6ef8b7e295a0baa5fdc1218cc9459cde0 Mon Sep 17 00:00:00 2001 From: Giovanni Harting <539@idlegandalf.com> Date: Tue, 13 Jul 2021 16:51:08 +0200 Subject: [PATCH] added status page --- ent/schema/dbpackage.go | 2 +- main.go | 119 ++++++++++++++++++++++++++++++++++++++-- tpl/status.html | 72 ++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 tpl/status.html diff --git a/ent/schema/dbpackage.go b/ent/schema/dbpackage.go index d173938..2b5081b 100644 --- a/ent/schema/dbpackage.go +++ b/ent/schema/dbpackage.go @@ -15,7 +15,7 @@ func (DbPackage) Fields() []ent.Field { return []ent.Field{ field.String("pkgbase").NotEmpty().Immutable().Unique(), field.Strings("packages").Optional(), - field.Int("status").Optional().Positive(), + field.Int("status").Optional().Min(0), field.String("skip_reason").Optional(), field.String("repository").NotEmpty(), field.String("march").NotEmpty(), diff --git a/main.go b/main.go index 292847a..ea91abe 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( "github.com/wercker/journalhook" "github.com/yargevad/filepathx" "gopkg.in/yaml.v2" + "html/template" "io" "math/rand" "os" @@ -38,7 +39,7 @@ const ( ) const ( - UNKNOWN = iota + SKIPPED = iota FAILED = iota BUILD = iota QUEUED = iota @@ -469,13 +470,13 @@ func (b *BuildManager) parseWorker() { if contains(info.Arch, "any") { log.Infof("Skipped %s: any-Package", info.Pkgbase) dbLock.Lock() - dbPkg = dbPkg.Update().SetSkipReason("arch = any").SaveX(context.Background()) + dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("arch = any").SaveX(context.Background()) dbLock.Unlock() skipping = true } else if contains(conf.Blacklist, info.Pkgbase) { log.Infof("Skipped %s: blacklisted package", info.Pkgbase) dbLock.Lock() - dbPkg = dbPkg.Update().SetSkipReason("blacklisted").SaveX(context.Background()) + dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("blacklisted").SaveX(context.Background()) dbLock.Unlock() skipping = true } else if contains(info.MakeDepends, "ghc") || contains(info.MakeDepends, "haskell-ghc") || contains(info.Depends, "ghc") || contains(info.Depends, "haskell-ghc") { @@ -484,13 +485,13 @@ func (b *BuildManager) parseWorker() { // https://git.harting.dev/anonfunc/ALHP.GO/issues/11 log.Infof("Skipped %s: haskell package", info.Pkgbase) dbLock.Lock() - dbPkg = dbPkg.Update().SetSkipReason("blacklisted (haskell)").SaveX(context.Background()) + dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("blacklisted (haskell)").SaveX(context.Background()) dbLock.Unlock() skipping = true } else if isPkgFailed(pkg) { log.Infof("Skipped %s: failed build", info.Pkgbase) dbLock.Lock() - dbPkg = dbPkg.Update().SetStatus(FAILED).SetSkipReason("failed").SaveX(context.Background()) + dbPkg = dbPkg.Update().SetStatus(FAILED).SetSkipReason("").SaveX(context.Background()) dbLock.Unlock() skipping = true } @@ -607,6 +608,113 @@ func isPkgFailed(pkg *BuildPackage) bool { return failed } +func statusId2string(status int) (string, string) { + switch status { + case SKIPPED: + return "SKIPPED", "table-secondary" + case QUEUED: + return "QUEUED", "table-warning" + case LATEST: + return "LATEST", "table-primary" + case FAILED: + return "FAILED", "table-danger" + case BUILD: + return "SIGNING", "table-success" + case BUILDING: + return "BUILDING", "table-info" + default: + return "UNKNOWN", "table-dark" + } +} + +func (b *BuildManager) htmlWorker() { + type Pkg struct { + Pkgbase string + Status string + Class string + Skip string + Version string + Svn2GitVersion string + BuildDate string + BuildDuration time.Duration + Checked string + } + + type Repo struct { + Name string + Packages []Pkg + } + + type March struct { + Name string + Repos []Repo + } + + type tpl struct { + March []March + } + + for { + gen := &tpl{} + + for _, march := range conf.March { + addMarch := March{ + Name: march, + } + + for _, repo := range conf.Repos { + addRepo := Repo{ + Name: repo, + } + + dbLock.RLock() + pkgs := db.DbPackage.Query().Where(dbpackage.MarchEQ(march), dbpackage.RepositoryEQ(repo)).AllX(context.Background()) + dbLock.RUnlock() + + for _, pkg := range pkgs { + status, class := statusId2string(pkg.Status) + + addPkg := Pkg{ + Pkgbase: pkg.Pkgbase, + Status: status, + Class: class, + Skip: pkg.SkipReason, + Version: pkg.RepoVersion, + Svn2GitVersion: pkg.Version, + } + + if pkg.BuildDuration > 0 { + duration, err := time.ParseDuration(strconv.Itoa(int(pkg.BuildDuration)) + "ms") + check(err) + addPkg.BuildDuration = duration + } + + if !pkg.BuildTime.IsZero() { + addPkg.BuildDate = pkg.BuildTime.Format(time.RFC3339) + } + + if !pkg.Updated.IsZero() { + addPkg.Checked = pkg.Updated.Format(time.RFC3339) + } + + addRepo.Packages = append(addRepo.Packages, addPkg) + } + addMarch.Repos = append(addMarch.Repos, addRepo) + } + gen.March = append(gen.March, addMarch) + } + + statusTpl, err := template.ParseFiles("tpl/status.html") + check(err) + + f, err := os.OpenFile(filepath.Join(conf.Basedir.Repo, "status.html"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) + check(statusTpl.Execute(f, gen)) + check(f.Close()) + + time.Sleep(time.Minute) + } +} + func setupChroot() { if _, err := os.Stat(filepath.Join(conf.Basedir.Chroot, orgChrootName)); err == nil { //goland:noinspection SpellCheckingInspection @@ -813,6 +921,7 @@ func main() { syncMarchs() go buildManager.syncWorker() + go buildManager.htmlWorker() <-killSignals diff --git a/tpl/status.html b/tpl/status.html new file mode 100644 index 0000000..dd8feae --- /dev/null +++ b/tpl/status.html @@ -0,0 +1,72 @@ + + + + + + + + + + ALHP Status + + + +
+ {{range $march := .March}}

{{$march.Name}}

+
+ {{range $repo := $march.Repos}} +
+

+ +

+
+
+ + + + + + + + + + + + + + + {{range $pkg := $repo.Packages}} + + + + + + + + + + + {{end}} + +
PkgbaseStatusSkippedSVN2GIT VersionVersionBuild DateBuild DurationCheck date
{{$pkg.Pkgbase}}{{$pkg.Status}}{{$pkg.Skip}}{{$pkg.Svn2GitVersion}}{{$pkg.Version}}{{$pkg.BuildDate}}{{if $pkg.BuildDuration}}{{$pkg.BuildDuration}}{{end}}{{$pkg.Checked}}
+
+
+
+ {{end}} +
+ {{end}} +
+ + + + + \ No newline at end of file