73 lines
2.3 KiB
Go
73 lines
2.3 KiB
Go
package inventory
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
// BusStep is one planned bus upgrade (novox/hq to-be 45 §8, ADR 0236).
|
|
type BusStep struct {
|
|
ID int64
|
|
Module string
|
|
Machines []string
|
|
From, To string
|
|
Snapshot string
|
|
Reversible bool
|
|
By, Why string
|
|
Started time.Time
|
|
Ended *time.Time
|
|
Outcome string
|
|
Found string
|
|
}
|
|
|
|
// StartBusStep records a bus upgrade starting. Refused while another runs.
|
|
func (i *Inventory) StartBusStep(ctx context.Context, s BusStep) (BusStep, error) {
|
|
if _, err := i.actingEpoch(ctx); err != nil {
|
|
return s, err
|
|
}
|
|
if open, found, err := i.LatestBusStep(ctx); err != nil {
|
|
return s, err
|
|
} else if found && open.Ended == nil {
|
|
return s, ErrBusStepRunning
|
|
}
|
|
if s.Machines == nil {
|
|
s.Machines = []string{}
|
|
}
|
|
err := i.store.Pool().QueryRow(ctx,
|
|
`insert into bus_step (module, machines, from_build, to_build, snapshot, reversible, by_whom, why)
|
|
values ($1, $2, $3, $4, $5, $6, $7, $8) returning id, started`,
|
|
s.Module, s.Machines, s.From, s.To, s.Snapshot, s.Reversible, s.By, s.Why).Scan(&s.ID, &s.Started)
|
|
return s, err
|
|
}
|
|
|
|
// ErrBusStepRunning is a bus upgrade asked while one runs.
|
|
var ErrBusStepRunning = errors.New("a bus upgrade is already running")
|
|
|
|
// EndBusStep records how a bus upgrade ended: done or failed, with what was found.
|
|
func (i *Inventory) EndBusStep(ctx context.Context, id int64, outcome, found string) error {
|
|
if _, err := i.actingEpoch(ctx); err != nil {
|
|
return err
|
|
}
|
|
_, err := i.store.Pool().Exec(ctx,
|
|
`update bus_step set ended = now(), outcome = $2, found = $3 where id = $1 and ended is null`, id, outcome, found)
|
|
return err
|
|
}
|
|
|
|
// LatestBusStep is the newest bus upgrade, and whether there is any.
|
|
func (i *Inventory) LatestBusStep(ctx context.Context) (BusStep, bool, error) {
|
|
var s BusStep
|
|
err := i.store.Pool().QueryRow(ctx,
|
|
`select id, module, machines, from_build, to_build, snapshot, reversible, by_whom, why, started, ended,
|
|
outcome, found
|
|
from bus_step order by id desc limit 1`).
|
|
Scan(&s.ID, &s.Module, &s.Machines, &s.From, &s.To, &s.Snapshot, &s.Reversible, &s.By, &s.Why, &s.Started,
|
|
&s.Ended, &s.Outcome, &s.Found)
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return s, false, nil
|
|
}
|
|
return s, err == nil, err
|
|
}
|