feat(master): suggest newer version tags for third-party images (#11)
This commit is contained in:
@@ -175,7 +175,7 @@ const serviceColumns = `s.id, s.kind, s.location_key, s.agent_id, COALESCE(a.nam
|
||||
s.compose_project, s.compose_service, s.working_dir, s.config_files, s.built, s.swarm_cluster_id,
|
||||
s.swarm_service, s.container_name, s.image_repo, s.desired_ref, s.actual_ref, s.actual_digest,
|
||||
s.status, s.self, s.update_mode, s.available_ref, s.available_digest, s.available_source, s.available_at,
|
||||
s.last_poll_error, s.last_tag_digest, s.awaiting_inventory, s.first_seen_at, s.updated_at, s.removed_at`
|
||||
s.last_poll_error, s.newer_ref, s.newer_at, s.last_tag_digest, s.awaiting_inventory, s.first_seen_at, s.updated_at, s.removed_at`
|
||||
|
||||
func scanService(row pgx.Row) (model.Service, error) {
|
||||
var m model.Service
|
||||
@@ -184,7 +184,7 @@ func scanService(row pgx.Row) (model.Service, error) {
|
||||
&m.ComposeProject, &m.ComposeService, &m.WorkingDir, &m.ConfigFiles, &m.Built, &m.SwarmClusterID,
|
||||
&m.SwarmService, &m.ContainerName, &m.ImageRepo, &m.DesiredRef, &m.ActualRef, &m.ActualDigest,
|
||||
&m.Status, &m.Self, &m.UpdateMode, &m.AvailableRef, &m.AvailableDigest, &m.AvailableSource, &m.AvailableAt,
|
||||
&m.LastPollError, &m.LastTagDigest, &m.AwaitingInventory, &m.FirstSeenAt, &m.UpdatedAt, &m.RemovedAt)
|
||||
&m.LastPollError, &m.NewerRef, &m.NewerAt, &m.LastTagDigest, &m.AwaitingInventory, &m.FirstSeenAt, &m.UpdatedAt, &m.RemovedAt)
|
||||
m.Kind = protocol.Kind(kind)
|
||||
return m, err
|
||||
}
|
||||
@@ -246,6 +246,33 @@ func (s *Store) SetAvailable(ctx context.Context, id int64, a model.Available) e
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetNewer sets the service's newer-tag suggestion (model.Service.NewerRef);
|
||||
// ref "" clears it. A non-empty ref is also recorded in image_versions with
|
||||
// source "tags", in the same transaction, unless that (repo, tag) is already
|
||||
// there. The digest is unknown, so the row has none.
|
||||
func (s *Store) SetNewer(ctx context.Context, id int64, ref string, at time.Time) error {
|
||||
tx, err := s.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("set newer: begin: %w", err)
|
||||
}
|
||||
defer func() { _ = tx.Rollback(ctx) }()
|
||||
if _, err := tx.Exec(ctx, `
|
||||
UPDATE services SET newer_ref = $2, newer_at = CASE WHEN $2 = '' THEN NULL ELSE $3::timestamptz END
|
||||
WHERE id = $1`, id, ref, at); err != nil {
|
||||
return fmt.Errorf("set newer: %w", err)
|
||||
}
|
||||
if ref != "" {
|
||||
p := imageref.Parse(ref)
|
||||
if err := insertVersion(ctx, tx, p.Repo, p.Tag, "", model.SourceTags, at); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return fmt.Errorf("set newer: commit: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPollError sets last_poll_error on the given services; msg "" clears it.
|
||||
func (s *Store) SetPollError(ctx context.Context, ids []int64, msg string) error {
|
||||
if len(ids) == 0 {
|
||||
@@ -313,6 +340,23 @@ func (s *Store) GetImageVersion(ctx context.Context, id int64) (model.ImageVersi
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// GetTagVersion returns the digest-less version row with an empty digest, which
|
||||
// SetNewer and the webhook create. Returns model.ErrNotFound if there is none.
|
||||
func (s *Store) GetTagVersion(ctx context.Context, repo, tag string) (model.ImageVersion, error) {
|
||||
var v model.ImageVersion
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
SELECT id, repo, tag, digest, source, first_seen_at FROM image_versions
|
||||
WHERE repo = $1 AND tag = $2 AND digest = ''`, repo, tag,
|
||||
).Scan(&v.ID, &v.Repo, &v.Tag, &v.Digest, &v.Source, &v.FirstSeenAt)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return model.ImageVersion{}, model.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return model.ImageVersion{}, fmt.Errorf("get tag version: %w", err)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// SetUpdateMode sets the service's update mode (model.ModeManual or
|
||||
// model.ModeAuto). Returns model.ErrNotFound if the service does not exist
|
||||
// or is marked removed.
|
||||
|
||||
Reference in New Issue
Block a user