added status page
This commit is contained in:
@@ -15,7 +15,7 @@ func (DbPackage) Fields() []ent.Field {
|
|||||||
return []ent.Field{
|
return []ent.Field{
|
||||||
field.String("pkgbase").NotEmpty().Immutable().Unique(),
|
field.String("pkgbase").NotEmpty().Immutable().Unique(),
|
||||||
field.Strings("packages").Optional(),
|
field.Strings("packages").Optional(),
|
||||||
field.Int("status").Optional().Positive(),
|
field.Int("status").Optional().Min(0),
|
||||||
field.String("skip_reason").Optional(),
|
field.String("skip_reason").Optional(),
|
||||||
field.String("repository").NotEmpty(),
|
field.String("repository").NotEmpty(),
|
||||||
field.String("march").NotEmpty(),
|
field.String("march").NotEmpty(),
|
||||||
|
|||||||
119
main.go
119
main.go
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/wercker/journalhook"
|
"github.com/wercker/journalhook"
|
||||||
"github.com/yargevad/filepathx"
|
"github.com/yargevad/filepathx"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
@@ -38,7 +39,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UNKNOWN = iota
|
SKIPPED = iota
|
||||||
FAILED = iota
|
FAILED = iota
|
||||||
BUILD = iota
|
BUILD = iota
|
||||||
QUEUED = iota
|
QUEUED = iota
|
||||||
@@ -469,13 +470,13 @@ func (b *BuildManager) parseWorker() {
|
|||||||
if contains(info.Arch, "any") {
|
if contains(info.Arch, "any") {
|
||||||
log.Infof("Skipped %s: any-Package", info.Pkgbase)
|
log.Infof("Skipped %s: any-Package", info.Pkgbase)
|
||||||
dbLock.Lock()
|
dbLock.Lock()
|
||||||
dbPkg = dbPkg.Update().SetSkipReason("arch = any").SaveX(context.Background())
|
dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("arch = any").SaveX(context.Background())
|
||||||
dbLock.Unlock()
|
dbLock.Unlock()
|
||||||
skipping = true
|
skipping = true
|
||||||
} else if contains(conf.Blacklist, info.Pkgbase) {
|
} else if contains(conf.Blacklist, info.Pkgbase) {
|
||||||
log.Infof("Skipped %s: blacklisted package", info.Pkgbase)
|
log.Infof("Skipped %s: blacklisted package", info.Pkgbase)
|
||||||
dbLock.Lock()
|
dbLock.Lock()
|
||||||
dbPkg = dbPkg.Update().SetSkipReason("blacklisted").SaveX(context.Background())
|
dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("blacklisted").SaveX(context.Background())
|
||||||
dbLock.Unlock()
|
dbLock.Unlock()
|
||||||
skipping = true
|
skipping = true
|
||||||
} else if contains(info.MakeDepends, "ghc") || contains(info.MakeDepends, "haskell-ghc") || contains(info.Depends, "ghc") || contains(info.Depends, "haskell-ghc") {
|
} 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
|
// https://git.harting.dev/anonfunc/ALHP.GO/issues/11
|
||||||
log.Infof("Skipped %s: haskell package", info.Pkgbase)
|
log.Infof("Skipped %s: haskell package", info.Pkgbase)
|
||||||
dbLock.Lock()
|
dbLock.Lock()
|
||||||
dbPkg = dbPkg.Update().SetSkipReason("blacklisted (haskell)").SaveX(context.Background())
|
dbPkg = dbPkg.Update().SetStatus(SKIPPED).SetSkipReason("blacklisted (haskell)").SaveX(context.Background())
|
||||||
dbLock.Unlock()
|
dbLock.Unlock()
|
||||||
skipping = true
|
skipping = true
|
||||||
} else if isPkgFailed(pkg) {
|
} else if isPkgFailed(pkg) {
|
||||||
log.Infof("Skipped %s: failed build", info.Pkgbase)
|
log.Infof("Skipped %s: failed build", info.Pkgbase)
|
||||||
dbLock.Lock()
|
dbLock.Lock()
|
||||||
dbPkg = dbPkg.Update().SetStatus(FAILED).SetSkipReason("failed").SaveX(context.Background())
|
dbPkg = dbPkg.Update().SetStatus(FAILED).SetSkipReason("").SaveX(context.Background())
|
||||||
dbLock.Unlock()
|
dbLock.Unlock()
|
||||||
skipping = true
|
skipping = true
|
||||||
}
|
}
|
||||||
@@ -607,6 +608,113 @@ func isPkgFailed(pkg *BuildPackage) bool {
|
|||||||
return failed
|
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() {
|
func setupChroot() {
|
||||||
if _, err := os.Stat(filepath.Join(conf.Basedir.Chroot, orgChrootName)); err == nil {
|
if _, err := os.Stat(filepath.Join(conf.Basedir.Chroot, orgChrootName)); err == nil {
|
||||||
//goland:noinspection SpellCheckingInspection
|
//goland:noinspection SpellCheckingInspection
|
||||||
@@ -813,6 +921,7 @@ func main() {
|
|||||||
syncMarchs()
|
syncMarchs()
|
||||||
|
|
||||||
go buildManager.syncWorker()
|
go buildManager.syncWorker()
|
||||||
|
go buildManager.htmlWorker()
|
||||||
|
|
||||||
<-killSignals
|
<-killSignals
|
||||||
|
|
||||||
|
|||||||
72
tpl/status.html
Normal file
72
tpl/status.html
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>ALHP Status</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{{range $march := .March}}<h3>{{$march.Name}}</h3>
|
||||||
|
<div class="accordion" id="accordion-{{$march.Name}}">
|
||||||
|
{{range $repo := $march.Repos}}
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="heading-{{$march.Name}}-{{$repo.Name}}">
|
||||||
|
<button aria-controls="collapse-{{$march.Name}}-{{$repo.Name}}" aria-expanded="false"
|
||||||
|
class="accordion-button"
|
||||||
|
data-bs-target="#collapse-{{$march.Name}}-{{$repo.Name}}"
|
||||||
|
data-bs-toggle="collapse" type="button">
|
||||||
|
{{$march.Name}}-{{$repo.Name}}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div aria-labelledby="heading-{{$march.Name}}-{{$repo.Name}}" class="accordion-collapse collapse show"
|
||||||
|
data-bs-parent="#accordion-{{$march.Name}}" id="collapse-{{$march.Name}}-{{$repo.Name}}">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Pkgbase</th>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<th scope="col">Skipped</th>
|
||||||
|
<th scope="col">SVN2GIT Version</th>
|
||||||
|
<th scope="col">Version</th>
|
||||||
|
<th scope="col">Build Date</th>
|
||||||
|
<th scope="col">Build Duration</th>
|
||||||
|
<th scope="col">Check date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range $pkg := $repo.Packages}}
|
||||||
|
<tr class="{{$pkg.Class}}">
|
||||||
|
<td>{{$pkg.Pkgbase}}</td>
|
||||||
|
<td>{{$pkg.Status}}</td>
|
||||||
|
<td>{{$pkg.Skip}}</td>
|
||||||
|
<td>{{$pkg.Svn2GitVersion}}</td>
|
||||||
|
<td>{{$pkg.Version}}</td>
|
||||||
|
<td>{{$pkg.BuildDate}}</td>
|
||||||
|
<td>{{if $pkg.BuildDuration}}{{$pkg.BuildDuration}}{{end}}</td>
|
||||||
|
<td>{{$pkg.Checked}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script crossorigin="anonymous"
|
||||||
|
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user