feat(master): record image versions and track poll suggestions in the store (#9)
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/shcizo/package-updater/internal/imageref"
|
||||
"github.com/shcizo/package-updater/internal/protocol"
|
||||
)
|
||||
|
||||
@@ -56,8 +57,10 @@ type Service struct {
|
||||
// AvailableRef is the newest ref a webhook or poll reported for this
|
||||
// service; "" if none, or if a later job already deployed it.
|
||||
AvailableRef string
|
||||
AvailableSource string // SourceWebhook; "" when AvailableRef is empty
|
||||
AvailableDigest string // digest of AvailableRef when known (poll); "" from the webhook
|
||||
AvailableSource string // SourceWebhook or SourcePoll; "" when AvailableRef is empty
|
||||
AvailableAt *time.Time
|
||||
LastPollError string // last registry error for the followed ref; "" when fine
|
||||
FirstSeenAt time.Time
|
||||
UpdatedAt time.Time
|
||||
RemovedAt *time.Time
|
||||
@@ -69,18 +72,40 @@ const (
|
||||
ModeAuto = "auto"
|
||||
)
|
||||
|
||||
// Sources of an available ref.
|
||||
// Sources of an available ref and of an ImageVersion.
|
||||
const (
|
||||
SourceWebhook = "webhook"
|
||||
SourcePoll = "poll"
|
||||
// SourceRunning is used by image_versions only: an agent reported the
|
||||
// version as running.
|
||||
SourceRunning = "running"
|
||||
)
|
||||
|
||||
// Available is a newer ref reported for a service.
|
||||
type Available struct {
|
||||
Ref string
|
||||
Source string // SourceWebhook
|
||||
Digest string // "" when unknown (webhook)
|
||||
Source string // SourceWebhook or SourcePoll
|
||||
At time.Time
|
||||
}
|
||||
|
||||
// ImageVersion is one version of an image repo the master has seen. Tag and
|
||||
// Digest are "" when the version has no tag or its digest is unknown; they
|
||||
// are never both empty.
|
||||
type ImageVersion struct {
|
||||
ID int64
|
||||
Repo string
|
||||
Tag string
|
||||
Digest string
|
||||
Source string // SourceWebhook, SourcePoll or SourceRunning: the first source that saw it
|
||||
FirstSeenAt time.Time
|
||||
}
|
||||
|
||||
// Ref returns "repo:tag@digest", "repo:tag" or "repo@digest".
|
||||
func (v ImageVersion) Ref() string {
|
||||
return imageref.Ref{Repo: v.Repo, Tag: v.Tag, Digest: v.Digest}.String()
|
||||
}
|
||||
|
||||
// DisplayName is the human-facing name of the service.
|
||||
func (s Service) DisplayName() string {
|
||||
switch s.Kind {
|
||||
|
||||
@@ -40,6 +40,24 @@ func TestDisplayName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageVersionRef(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
v ImageVersion
|
||||
want string
|
||||
}{
|
||||
{"tag and digest", ImageVersion{Repo: "r/x", Tag: "1", Digest: "sha256:a"}, "r/x:1@sha256:a"},
|
||||
{"tag only", ImageVersion{Repo: "r/x", Tag: "1"}, "r/x:1"},
|
||||
{"digest only", ImageVersion{Repo: "r/x", Digest: "sha256:a"}, "r/x@sha256:a"},
|
||||
{"registry port", ImageVersion{Repo: "localhost:5000/x", Tag: "1"}, "localhost:5000/x:1"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
assert.Equal(t, c.want, c.v.Ref())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJob_Active(t *testing.T) {
|
||||
cases := []struct {
|
||||
status JobStatus
|
||||
|
||||
Reference in New Issue
Block a user