carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package provision
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/carlosframework/platform/internal/release"
8)
9
10// InstallRequest is one "Update now" (spec §4.2).
11type InstallRequest struct {
12 ID uint64 `json:"id"`
13 FastTrack bool `json:"fast_track,omitempty"`
14 At time.Time `json:"at"`
15 By string `json:"by,omitempty"`
16}
17
18// UpdatePolicy is the app's instance update policy (spec §3.2). The default
19// channel is the manifest's own Channel (index Q4).
20type UpdatePolicy struct {
21 InstanceControl []string `json:"instance_control,omitempty"`
22 DefaultUpdates string `json:"default_updates,omitempty"`
23 DefaultMajor *int `json:"default_major,omitempty"`
24}
25
26// EffectiveUpdates resolves one instance's settings: its own explicit values,
27// else the app's defaults, else today's. A major hold off stable is dropped:
28// only stable promotions cut tags (spec §3.1), so it could never hold.
29func EffectiveUpdates(rec Record, p *UpdatePolicy) release.UpdateSettings {
30 u := release.UpdateSettings{Updates: release.UpdatesAuto, Channel: rec.Channel, Pin: rec.Pin}
31 if p != nil {
32 if p.DefaultUpdates != "" {
33 u.Updates = p.DefaultUpdates
34 }
35 u.Major = p.DefaultMajor
36 u.Control = append([]string(nil), p.InstanceControl...)
37 }
38 if rec.Updates != "" {
39 u.Updates = rec.Updates
40 }
41 if rec.Major != nil {
42 u.Major = rec.Major
43 }
44 if u.Channel != "stable" {
45 u.Major = nil
46 }
47 if rec.InstallRequest != nil {
48 u.InstallRequest, u.InstallFastTrack = rec.InstallRequest.ID, rec.InstallRequest.FastTrack
49 }
50 return u
51}
52
53// ValidateUpdates is the record's door check (the console's PUT).
54func ValidateUpdates(rec Record) error {
55 if rec.Updates != "" && rec.Updates != release.UpdatesAuto && rec.Updates != release.UpdatesManual {
56 return fmt.Errorf("updates must be auto or manual")
57 }
58 if rec.Major != nil && *rec.Major < 0 {
59 return fmt.Errorf("major must be a whole number, 0 or more")
60 }
61 if rec.Major != nil && rec.Channel != "stable" {
62 return fmt.Errorf("major applies only to the stable channel")
63 }
64 if rec.Pin != "" && (!release.ValidVersion(rec.Pin) || rec.Pin == "dev") {
65 return fmt.Errorf("invalid pin %q", rec.Pin)
66 }
67 return nil
68}
69
70// ValidatePolicy is the app policy's door check.
71func ValidatePolicy(p *UpdatePolicy) error {
72 if p == nil {
73 return nil
74 }
75 if !release.ValidControl(p.InstanceControl) {
76 return fmt.Errorf("instance_control must name updates, channel, major or pin, each once")
77 }
78 if p.DefaultUpdates != "" && p.DefaultUpdates != release.UpdatesAuto && p.DefaultUpdates != release.UpdatesManual {
79 return fmt.Errorf("default_updates must be auto or manual")
80 }
81 if p.DefaultMajor != nil && *p.DefaultMajor < 0 {
82 return fmt.Errorf("default_major must be a whole number, 0 or more")
83 }
84 return nil
85}
86