carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "log"
5 "sync"
6
7 "github.com/carlosframework/platform/internal/release"
8 "github.com/carlosframework/platform/internal/rollout"
9)
10
11// updatesPassOption arms the instance update settings on an adoption pass
12// (settings spec §4). root is set on carlos-adopt's pass only: root resolves
13// install requests and writes the consumed file; the agent's passes apply
14// the same decisions and write nothing.
15//
16// The failure book is the zero-downtime plans' (§4.3: failure records
17// outrank every rule), read from dd's swap-failures.json at the start of
18// every pass, never once per process: the fast loop's options are built once
19// per agent run. A build is failed for a host when the book blocks it
20// (Blocks: a record the host has not served or been retried past) or holds
21// the host down on it (HeldDown: a hold attempt onto it failed there). An
22// unreadable book holds every route with settings and every managed route
23// (rollout.Managed), as refuseManaged does; a default unmanaged route keeps
24// today's adoption, which never read the book.
25//
26// The pass prints the unreadable-book line on root's pass only. The agent's
27// opener logs it here once per distinct error, since the fast loop runs a
28// pass every few seconds with options built once.
29func updatesPassOption(dd string, root bool, providers ...release.RootUpdateOpener) release.PassOption {
30 var (
31 mu sync.Mutex
32 lastErr string
33 )
34 open := func() (release.FailedBuild, error) {
35 book, err := rollout.OpenFailureBook(dd)
36 mu.Lock()
37 said := ""
38 if err != nil {
39 said = err.Error()
40 }
41 if !root && err != nil && said != lastErr {
42 log.Printf("agent: failure book unreadable (%v): routes with update settings and managed routes install nothing", err)
43 }
44 lastErr = said
45 mu.Unlock()
46 if err != nil {
47 return nil, err
48 }
49 return func(acct, app, build, host string, served bool) bool {
50 return book.Blocks(acct, app, build, host, served) || book.HeldDown(acct, app, build, host)
51 }, nil
52 }
53 legacy := release.WithUpdateSettings(open, rollout.Managed, root)
54 if !root {
55 return legacy
56 }
57 provider := productionRootUpdates(dd)
58 if len(providers) == 1 {
59 provider = providers[0]
60 }
61 return release.CombinePassOptions(legacy, release.WithRootUpdateInputs(provider))
62}
63