carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "crypto/ed25519"
6 "os"
7 "time"
8
9 "github.com/carlosframework/platform/internal/registry"
10)
11
12type RootUpdateInput struct {
13 Begin func(version, digest, attempt string) (func(invocation string, failure error, verify func() error) error, error)
14 Route registry.Route
15 Build BuildStateCopy
16 Consumed *Consumed
17 Installed string
18 Failed func(string) bool
19 Save func(Consumed) error
20}
21
22type RootUpdateInputs struct {
23 Resolve func(context.Context, string) (RootUpdateInput, error)
24 Close func() error
25 selected map[string]RootUpdateInput
26}
27
28type RootUpdateOpener func(context.Context, Store, ed25519.PublicKey) (*RootUpdateInputs, error)
29
30func WithRootUpdateInputs(open RootUpdateOpener) PassOption {
31 return func(c *passConfig) { c.openRootUpdates = open }
32}
33
34func (r *RootUpdateInputs) routes(ctx context.Context, rows []registry.Route) ([]registry.Route, error) {
35 if r.Resolve == nil {
36 return nil, os.ErrPermission
37 }
38 r.selected = map[string]RootUpdateInput{}
39 out := make([]registry.Route, 0, len(rows))
40 for _, hint := range rows {
41 in, err := r.Resolve(ctx, hint.Host)
42 if err != nil {
43 return nil, err
44 }
45 if in.Route.Host != hint.Host || in.Failed == nil || in.Save == nil {
46 return nil, os.ErrPermission
47 }
48 r.selected[hint.Host] = in
49 out = append(out, in.Route)
50 }
51 return out, nil
52}
53
54func (r *RootUpdateInputs) target(ctx context.Context, rt registry.Route, ptr *ChannelPointer, bake *FirstSeen, now time.Time, cfg passConfig, holds map[string]time.Duration, ignore bool) (string, TargetDecision, bool) {
55 in, err := r.Resolve(ctx, rt.Host)
56 if err != nil {
57 return "", TargetDecision{}, true
58 }
59 selected, ok := r.selected[rt.Host]
60 if !ok || in.Route != selected.Route {
61 return "", TargetDecision{}, true
62 }
63 u, err := ParseUpdateSettingsLenient(in.Route.UpdateSettings)
64 if err != nil {
65 return "", TargetDecision{}, true
66 }
67 target := TargetInput{Route: in.Route, Pointer: ptr, Settings: u, Build: in.Build, Consumed: in.Consumed, Installed: in.Installed, Failed: in.Failed}
68 if ptr != nil {
69 target.HeadHeld = Hold(bake, rt.Account, rt.App, rt.Channel, ptr.Version, holds, ignore || ptr.FastTrack, now)
70 target.HeadTag = cfg.tags[rt.Account+"/"+rt.App][ptr.Version]
71 }
72 dec := Target(target)
73 if err := in.Save(NextConsumed(target, dec)); err != nil {
74 return "", dec, true
75 }
76 return dec.Version, dec, dec.Version == ""
77}
78
79func CombinePassOptions(options ...PassOption) PassOption {
80 return func(c *passConfig) {
81 for _, option := range options {
82 option(c)
83 }
84 }
85}
86