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 "strings"
5
6 "github.com/carlosframework/platform/internal/release"
7 "github.com/carlosframework/platform/internal/status"
8)
9
10// systemChannelEnv is the box's platform channel: canary or stable. Set in
11// host.env, read through the getenv seam like every other CARLOS_* value;
12// the ROOT apply reads it from its own unit environment, never from the
13// agent's request (spec §6 step 2).
14const systemChannelEnv = "CARLOS_SYSTEM_CHANNEL"
15
16// A value that is not a channel at all — a typo, a shell that expanded to
17// nothing useful, a name with a slash too many — falls back to stable
18// rather than travelling into a bucket key and an on-box state file to ask
19// for a pointer nobody publishes. It comes back as invalid so the caller
20// can say so ONCE: this is read per tick, and a line per tick is a line
21// nobody reads.
22func systemChannel(getenv func(string) string) (channel, invalid string) {
23 c := strings.TrimSpace(getenv(systemChannelEnv))
24 switch {
25 case c == "":
26 return "stable", ""
27 case !release.ValidChannel(c):
28 return "stable", c
29 }
30 return c, ""
31}
32
33// boxSystemChannel is systemChannel for the caller that has nowhere to log:
34// the status tick, which publishes this every five minutes.
35func boxSystemChannel(getenv func(string) string) string {
36 c, _ := systemChannel(getenv)
37 return c
38}
39
40// systemStateProbe is root's result.json as the heartbeat carries it, or nil
41// when this box has never been asked to update.
42func systemStateProbe(optDir string) *status.SystemState {
43 r, err := readSystemResult(optDir)
44 if err != nil || r == nil {
45 return nil
46 }
47 return &status.SystemState{Channel: r.Channel, Version: r.Version, PromotedAt: r.PromotedAt, Outcome: r.Outcome, Reason: r.Reason, At: r.At}
48}
49