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 "context"
5 "os"
6 "path/filepath"
7
8 "github.com/carlosframework/platform/internal/hostbox"
9 "github.com/carlosframework/platform/internal/hostguard"
10 "github.com/carlosframework/platform/internal/layout"
11 "github.com/carlosframework/platform/internal/provision"
12 "github.com/carlosframework/platform/internal/release"
13 "github.com/carlosframework/platform/internal/rootstate"
14)
15
16func (h ClaimRootHTTP) rootEmptyCensus() *hostbox.EmptyInstallationCensus {
17 census := *h.Reconcile.Census
18 census.OtherPath = h.rootSiblingPath
19 return &census
20}
21
22func (h ClaimRootHTTP) rootSiblingPath(ctx context.Context, selected, root, rel string) (bool, error) {
23 parent := filepath.ToSlash(filepath.Dir(rel))
24 instance, instancePath := layout.InstanceCensusName(rel)
25 if !(root == "data" && instancePath || root == "opt" && (parent == "live" || parent == "previous")) {
26 return false, nil
27 }
28 payloads, err := h.Launches.GenerationPayloads(ctx)
29 if err != nil {
30 return false, err
31 }
32 for _, p := range payloads {
33 in := p.Inventory
34 if in.Host == selected {
35 continue
36 }
37 candidate := root == "data" && (instance == provision.InstanceID(in.Host)) || root == "opt" && (rel == "live/"+in.Host || rel == "previous/"+in.Host)
38 if !candidate {
39 continue
40 }
41 own, err := h.Stop.Coordinator.Guard.Root.Installation(ctx, in.Host, hostguard.Captured{Incarnation: in.Incarnation, Stamp: in.InstallationStamp})
42 if err != nil {
43 return false, err
44 }
45 if own.Stamp != in.InstallationStamp {
46 continue
47 }
48 if !in.Complete || own.Host != in.Host || own.Box != in.Box || own.Enrollment != in.Enrollment || own.InventoryRevision != p.Revision || own.Record != provision.RecordKey(own.Account, own.App, own.Host) {
49 return false, os.ErrPermission
50 }
51 if root == "data" {
52 for _, e := range in.Entries {
53 if e.Kind == "path" && e.ManagedRoot == root && e.RelativePath == filepath.ToSlash(filepath.Join("instances", provision.InstanceID(in.Host))) && e.Materialization == "materialized" {
54 err := generationPayloadFiles(ctx, h.Roots[root], []hostbox.GenerationPayload{{Inventory: hostbox.StopInventory{Entries: []hostbox.StopInventoryEntry{e}}}})
55 if err == nil && rel != e.RelativePath {
56 err = layout.VerifyInstanceCensusAlias(h.Roots[root], rel, in.Host)
57 }
58 return err == nil, err
59 }
60 }
61 return false, nil
62 }
63 state, err := rootstate.Open(release.RootGenerationsDir, false, false)
64 if err != nil {
65 return false, err
66 }
67 pins, err := (&release.RootGenerations{Store: state}).Reservations(ctx)
68 state.Close()
69 if err != nil {
70 return false, err
71 }
72 target, err := os.Readlink(filepath.Join(h.Roots[root], rel))
73 if err != nil {
74 return false, err
75 }
76 for _, pin := range pins {
77 b := pin.Binding
78 if b.Target.Host == own.Host && b.Target.Incarnation == own.Incarnation && b.Target.Box == own.Box && b.Target.Enrollment == own.Enrollment && b.Binding.Account == own.Account && b.Binding.App == own.App && b.Record == own.Record && target == b.Path && target == release.VersionPath(h.Roots[root], own.Account, b.Version, own.App) {
79 return true, nil
80 }
81 }
82 return false, os.ErrPermission
83 }
84 return false, nil
85}
86