2023-04-17 09:25:26 +00:00
|
|
|
package pkg
|
|
|
|
|
|
|
|
import (
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
|
|
nomad "github.com/hashicorp/nomad/api"
|
2023-05-03 08:52:34 +00:00
|
|
|
"log"
|
2023-04-17 09:25:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Job struct {
|
2023-05-03 08:52:34 +00:00
|
|
|
Cluster *Cluster
|
|
|
|
Config *Config
|
2023-04-17 09:25:26 +00:00
|
|
|
Notification *GiteaNotification
|
2023-05-03 08:52:34 +00:00
|
|
|
Dispatch *nomad.JobDispatchResponse
|
|
|
|
Creds *SecretGitea
|
|
|
|
Flavor string
|
2023-04-17 09:25:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|