package host import ( "context" "os" "path/filepath" "github.com/carlosframework/platform/internal/hostbox" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/layout" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/release" "github.com/carlosframework/platform/internal/rootstate" ) func (h ClaimRootHTTP) rootEmptyCensus() *hostbox.EmptyInstallationCensus { census := *h.Reconcile.Census census.OtherPath = h.rootSiblingPath return &census } func (h ClaimRootHTTP) rootSiblingPath(ctx context.Context, selected, root, rel string) (bool, error) { parent := filepath.ToSlash(filepath.Dir(rel)) instance, instancePath := layout.InstanceCensusName(rel) if !(root == "data" && instancePath || root == "opt" && (parent == "live" || parent == "previous")) { return false, nil } payloads, err := h.Launches.GenerationPayloads(ctx) if err != nil { return false, err } for _, p := range payloads { in := p.Inventory if in.Host == selected { continue } candidate := root == "data" && (instance == provision.InstanceID(in.Host)) || root == "opt" && (rel == "live/"+in.Host || rel == "previous/"+in.Host) if !candidate { continue } own, err := h.Stop.Coordinator.Guard.Root.Installation(ctx, in.Host, hostguard.Captured{Incarnation: in.Incarnation, Stamp: in.InstallationStamp}) if err != nil { return false, err } if own.Stamp != in.InstallationStamp { continue } 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) { return false, os.ErrPermission } if root == "data" { for _, e := range in.Entries { if e.Kind == "path" && e.ManagedRoot == root && e.RelativePath == filepath.ToSlash(filepath.Join("instances", provision.InstanceID(in.Host))) && e.Materialization == "materialized" { err := generationPayloadFiles(ctx, h.Roots[root], []hostbox.GenerationPayload{{Inventory: hostbox.StopInventory{Entries: []hostbox.StopInventoryEntry{e}}}}) if err == nil && rel != e.RelativePath { err = layout.VerifyInstanceCensusAlias(h.Roots[root], rel, in.Host) } return err == nil, err } } return false, nil } state, err := rootstate.Open(release.RootGenerationsDir, false, false) if err != nil { return false, err } pins, err := (&release.RootGenerations{Store: state}).Reservations(ctx) state.Close() if err != nil { return false, err } target, err := os.Readlink(filepath.Join(h.Roots[root], rel)) if err != nil { return false, err } for _, pin := range pins { b := pin.Binding 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) { return true, nil } } return false, os.ErrPermission } return false, nil }