albatros/pkg/job.go
2023-04-17 11:25:26 +02:00

84 lines
2.3 KiB
Go

package pkg
import (
"log"
"code.gitea.io/sdk/gitea"
nomad "github.com/hashicorp/nomad/api"
)
type Job struct {
Cluster *Cluster
Config *Config
Notification *GiteaNotification
Dispatch *nomad.JobDispatchResponse
Creds *SecretGitea
Flavor string
}
func (j *Job) follow() {
notifInfo := notifSummary(j.Notification)
log.Printf("[lifecycle] Commit to build: %s, Gitea URL: %s\n", notifInfo, j.Creds.Url)
// init Gitea
forge, err := gitea.NewClient(j.Creds.Url, gitea.SetToken(j.Creds.Token))
if err != nil {
log.Printf("Unable to create gitea client for %s: %+v\n", notifInfo, err)
return
}
// get job's deployment
jobs := j.Cluster.Nomad.Jobs()
queryOpt := nomad.QueryOptions{
AllowStale: false,
}
safeguard := 1000
for ; safeguard > 0; safeguard-- {
// Blocking fetch on deployment info
job, meta, err := jobs.Summary(j.Dispatch.DispatchedJobID, &queryOpt)
if err != nil {
log.Printf("[lifecycle] can't fetch job for %s: %+v\n", notifInfo, err)
break
}
queryOpt.WaitIndex = meta.LastIndex
summary, ok := job.Summary["runner"]
if !ok {
log.Printf("[lifecycle] Job %s for %s must contain a 'runner' task\n", job.JobID, notifInfo)
break
}
log.Printf("[lifecycle] Task status for job %s on %s: %+v\n", job.JobID, notifInfo, summary)
// Compute new job state
state := nomadToGiteaStatus(&summary)
// Try updating Gitea commit status
_, _, err = forge.CreateStatus(
j.Notification.Repository.Owner.Username,
j.Notification.Repository.Name,
j.Notification.After,
gitea.CreateStatusOption{
State: state,
TargetURL: j.Config.AlbatrosURL + "/build?log=stderr&job=" + j.Dispatch.DispatchedJobID,
Description: j.Flavor,
Context: "Albatros",
})
if err != nil {
log.Printf("[lifecycle] can't update gitea repo %s for job %s: %+v\n", notifInfo, job.JobID, err)
}
// Continue the loop only if the job is pending
if state != gitea.StatusPending {
log.Printf("Job %s for %s terminated with status %s\n", job.JobID, notifInfo, state)
break
}
}
if safeguard == 0 {
// To avoid dangerous infinite loops, we put an upperbound here
// of 1k refresh here. Reaching this limit will allow us to know
// that something did not work as expected...
log.Printf("!!! [lifecycle] we refreshed 1k times the job of %s and it's still running, giving up...\n", notifInfo)
}
}