mirror of
https://github.com/hanzoai/ci.git
synced 2026-10-20 15:28:05 +00:00
the board answers on a phone, and a pinned-back sidecar is not the service
The table is wider than a phone and had no box to scroll in, so the page itself scrolled sideways and carried the header and nav with it: a reader could see that something was wrong but not what, which is the one thing the four columns exist to say. And two containers can share a repository at different versions on purpose — a sidecar held back while the app moves on. Reading whichever came last reported the pin unapplied on a service whose app container was carrying it, so the board named drift where there was none. A workload runs the declared version if any of its containers does.
This commit is contained in:
@@ -189,6 +189,7 @@ var fleetTmpl = template.Must(template.New("fleet").Funcs(template.FuncMap{
|
||||
</div>{{end}}
|
||||
|
||||
{{if .Services}}
|
||||
<div class="scroll">
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>Service</th>
|
||||
@@ -233,6 +234,7 @@ var fleetTmpl = template.Must(template.New("fleet").Funcs(template.FuncMap{
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody></table>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="empty">
|
||||
No services visible.<br>
|
||||
|
||||
@@ -39,6 +39,11 @@ nav .who{margin-left:auto;align-self:center;color:var(--text-muted);font-size:va
|
||||
background:color-mix(in srgb, var(--warning) 10%, transparent);
|
||||
color:var(--warning-light);font-size:var(--font-size-sm)}
|
||||
|
||||
/* The four versions are the answer, so they must survive a narrow screen. The
|
||||
table scrolls inside its own box; without one the page scrolls sideways and
|
||||
takes the header and nav with it, leaving a reader able to see that something
|
||||
is wrong but not what. */
|
||||
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
|
||||
table{width:100%;border-collapse:collapse}
|
||||
th{position:sticky;top:0;background:var(--surface-1);text-align:left;
|
||||
font-size:var(--font-size-xs);text-transform:uppercase;letter-spacing:.06em;
|
||||
|
||||
@@ -277,6 +277,16 @@ func assemble(pins []pin, lives []live, links map[string]link) []Service {
|
||||
// service declares; its sidecars are not the service.
|
||||
continue
|
||||
}
|
||||
// A workload runs the declared version if ANY of its containers does.
|
||||
// Two containers can share the repository and hold different versions on
|
||||
// purpose — a sidecar pinned back while the app moves on — and taking
|
||||
// whichever the loop reached last reported the pin unapplied on a service
|
||||
// whose app container was carrying it. Preferring the match answers the
|
||||
// question the column asks: is what we declared running here. For the
|
||||
// single-container case, which is nearly every row, nothing changes.
|
||||
if same, decided := alike(s.Running, s.Declared); decided && same {
|
||||
continue
|
||||
}
|
||||
s.Running, s.Ready, s.Want = l.Version, l.Ready, l.Want
|
||||
}
|
||||
for _, s := range byName {
|
||||
|
||||
@@ -337,6 +337,35 @@ func TestOneImageIsSeveralServices(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestSidecarOnTheSameImageDoesNotHideThePin — two containers can share the
|
||||
// repository and hold different versions deliberately, and taking whichever the
|
||||
// loop reached last reported the pin unapplied on a service whose app container
|
||||
// was carrying it. studio pins its build-manifest sidecar back to v0.19.26 while
|
||||
// the app runs v0.19.31; the board called that drift and named a service that was
|
||||
// in fact current.
|
||||
func TestSidecarOnTheSameImageDoesNotHideThePin(t *testing.T) {
|
||||
studio := "ghcr.io/hanzoai/studio"
|
||||
pins := []pin{{Name: "studio", Namespace: "hanzo", Image: studio,
|
||||
Version: Version{Tag: "v0.19.31"}}}
|
||||
// Sidecar last, so a last-writer-wins read takes the pinned-back one.
|
||||
lives := []live{
|
||||
{Name: "studio", Namespace: "hanzo", Image: studio, Version: Version{Tag: "v0.19.31"}, Ready: 1, Want: 1},
|
||||
{Name: "studio", Namespace: "hanzo", Image: studio, Version: Version{Tag: "v0.19.26"}, Ready: 1, Want: 1},
|
||||
}
|
||||
|
||||
got := assemble(pins, lives, map[string]link{})
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("assembled %d rows from one declaration: %+v", len(got), got)
|
||||
}
|
||||
if got[0].Running.Tag != "v0.19.31" {
|
||||
t.Errorf("running = %q; a workload runs the declared version if any container does",
|
||||
got[0].Running.Tag)
|
||||
}
|
||||
if !got[0].current() {
|
||||
t.Errorf("drift = %v; the pin was applied and the app container carries it", got[0].Drift)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRunningMatchesOnNameAndImage — a workload of the right name still has to be
|
||||
// running the image the service declares, so a sidecar is never read as the
|
||||
// service.
|
||||
|
||||
Reference in New Issue
Block a user