Try some weird hacks

Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
Christian Mesh
2025-05-22 17:27:37 -04:00
parent ccdbb06c58
commit c1893cccd8
10 changed files with 130 additions and 14 deletions

View File

@@ -14,6 +14,7 @@ import (
"os"
"path/filepath"
"runtime"
"runtime/pprof"
"strings"
"time"
@@ -68,6 +69,14 @@ func main() {
func realMain() int {
defer logging.PanicHandler()
f, err := os.Create("./profile")
if err != nil {
log.Fatal(err)
}
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
ctx, err := tracing.OpenTelemetryInit(context.Background())
if err != nil {
// openTelemetryInit can only fail if OpenTofu was run with an

View File

@@ -102,18 +102,21 @@ func (g *AcyclicGraph) TransitiveReduction() {
// v such that the edge (u,v) exists (v is a direct descendant of u).
//
// For each v-prime reachable from v, remove the edge (u, v-prime).
removed := 0
for _, u := range g.Vertices() {
uTargets := g.downEdgesNoCopy(u)
g.DepthFirstWalk(g.downEdgesNoCopy(u), func(v Vertex, d int) error {
shared := uTargets.Intersection(g.downEdgesNoCopy(v))
for _, vPrime := range shared {
removed += 1
g.RemoveEdge(BasicEdge(u, vPrime))
}
return nil
})
}
println(removed)
}
// Validate validates the DAG. A DAG is valid if it has a single root

View File

@@ -327,7 +327,7 @@ func (s *Scope) evalContext(parent *hcl.EvalContext, refs []*addrs.Reference, se
// Calling NewChild() on a nil parent will
// produce an EvalContext with no parent.
ctx := parent.NewChild()
ctx.Functions = make(map[string]function.Function)
ctx.Functions = make(map[string]function.Function, len(s.Functions()))
ctx.Variables = make(map[string]cty.Value)
for name, fn := range s.Functions() {

View File

@@ -245,7 +245,7 @@ func performSetValueChecks(expr hcl.Expression, hclCtx *hcl.EvalContext, forEach
// markSafeLengthInt allows calling LengthInt on marked values safely
func markSafeLengthInt(val cty.Value) int {
v, _ := val.UnmarkDeep()
v, _ := val.Unmark()
return v.LengthInt()
}

View File

@@ -28,11 +28,19 @@ var impureFunctions = []string{
// This should probably be replaced with addrs.Function everywhere
const CoreNamespace = addrs.FunctionNamespaceCore + "::"
var hack map[string]function.Function
// Functions returns the set of functions that should be used to when evaluating
// expressions in the receiving scope.
func (s *Scope) Functions() map[string]function.Function {
s.funcsLock.Lock()
defer s.funcsLock.Unlock()
if s.funcs == nil {
if hack != nil {
s.funcs = hack
return hack
}
s.funcs = makeBaseFunctionTable(s.BaseDir)
if s.ConsoleMode {
// The type function is only available in OpenTofu console.
@@ -64,8 +72,8 @@ func (s *Scope) Functions() map[string]function.Function {
for _, name := range coreNames {
s.funcs[CoreNamespace+name] = s.funcs[name]
}
hack = s.funcs
}
s.funcsLock.Unlock()
return s.funcs
}

View File

@@ -175,6 +175,21 @@ func ExtractDeprecatedDiagnosticsWithExpr(val cty.Value, expr hcl.Expression) (c
}
func unmarkDeepWithPathsDeprecated(val cty.Value) (cty.Value, []cty.PathValueMarks) {
// quick check for marks
containsMark := false
_ = cty.Walk(val, func(p cty.Path, v cty.Value) (bool, error) {
for m := range v.Marks() {
if _, ok := m.(deprecationMark); ok {
containsMark = true
return false, nil
}
}
return true, nil
})
if !containsMark {
return val, nil
}
unmarked, pathMarks := val.UnmarkDeepWithPaths()
var deprecationMarks []cty.PathValueMarks

View File

@@ -925,9 +925,12 @@ func (n *NodeAbstractResourceInstance) plan(
}
// Evaluate the configuration
forEach, _ := evaluateForEachExpression(n.Config.ForEach, ctx, n.Addr)
/*forEach, _ := evaluateForEachExpression(n.Config.ForEach, ctx, n.Addr)
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)*/
if n.Addr.Resource.Key != nil {
keyData = ctx.InstanceExpander().GetResourceInstanceRepetitionData(n.Addr)
}
checkDiags := evalCheckRules(
addrs.ResourcePrecondition,

View File

@@ -0,0 +1,32 @@
package tofu
import (
"context"
"github.com/opentofu/opentofu/internal/addrs"
"github.com/opentofu/opentofu/internal/tfdiags"
)
type NodeResourceHack struct {
NodeAbstractResource
}
var (
_ GraphNodeExecutable = (*NodeResourceHack)(nil)
_ GraphNodeReferenceable = (*NodeResourceHack)(nil)
)
func (n *NodeResourceHack) Name() string {
return n.Addr.String() + " (HACK)"
}
func (n *NodeResourceHack) ReferenceableAddrs() []addrs.Referenceable {
return []addrs.Referenceable{
n.Addr.Resource,
}
}
func (n *NodeResourceHack) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
println("HACK THE PLANET")
return nil
}

View File

@@ -84,6 +84,8 @@ func (t *DiffTransformer) Transform(_ context.Context, g *Graph) error {
resourceNodes[addr] = append(resourceNodes[addr], rn)
}
resourceRoots := map[string]dag.Vertex{}
for _, rc := range changes.Resources {
addr := rc.Addr
dk := rc.DeposedKey
@@ -208,6 +210,15 @@ func (t *DiffTransformer) Transform(_ context.Context, g *Graph) error {
for _, rsrcNode := range resourceNodes[rsrcAddr] {
g.Connect(dag.BasicEdge(node, rsrcNode))
}
root, ok := resourceRoots[rsrcAddr]
if !ok {
root = &NodeResourceHack{abstract.NodeAbstractResource}
g.Add(root)
resourceRoots[rsrcAddr] = root
}
g.Connect(dag.BasicEdge(root, node))
}
if delete {

View File

@@ -17,6 +17,7 @@ import (
"github.com/opentofu/opentofu/internal/configs/configschema"
"github.com/opentofu/opentofu/internal/dag"
"github.com/opentofu/opentofu/internal/lang"
"github.com/opentofu/opentofu/internal/logging"
)
// GraphNodeReferenceable must be implemented by any node that represents
@@ -120,7 +121,7 @@ type ReferenceTransformer struct{}
func (t *ReferenceTransformer) Transform(_ context.Context, g *Graph) error {
// Build a reference map so we can efficiently look up the references
vs := g.Vertices()
m := NewReferenceMap(vs)
m := NewReferenceMap(g)
// Find the things that reference things and connect them
for _, v := range vs {
@@ -131,13 +132,15 @@ func (t *ReferenceTransformer) Transform(_ context.Context, g *Graph) error {
}
parents := m.References(v)
parentsDbg := make([]string, len(parents))
for i, v := range parents {
parentsDbg[i] = dag.VertexName(v)
if logging.IsDebugOrHigher() {
parentsDbg := make([]string, len(parents))
for i, v := range parents {
parentsDbg[i] = dag.VertexName(v)
}
log.Printf(
"[DEBUG] ReferenceTransformer: %q references: %v",
dag.VertexName(v), parentsDbg)
}
log.Printf(
"[DEBUG] ReferenceTransformer: %q references: %v",
dag.VertexName(v), parentsDbg)
for _, parent := range parents {
// A destroy plan relies solely on the state, so we only need to
@@ -191,7 +194,7 @@ func (t attachDataResourceDependsOnTransformer) Transform(_ context.Context, g *
// This is very similar to what's done in ReferenceTransformer, but we keep
// implementation separate as they may need to change independently.
vertices := g.Vertices()
refMap := NewReferenceMap(vertices)
refMap := NewReferenceMap(g)
for _, v := range vertices {
depender, ok := v.(graphNodeAttachDataResourceDependsOn)
@@ -312,6 +315,9 @@ func (m ReferenceMap) References(v dag.Vertex) []dag.Vertex {
}
}
//var resources []dag.Vertex
//var resourceInstances []dag.Vertex
for _, ref := range rn.References() {
matches = append(matches, m.addReference(vertexReferencePath(v), v, ref)...)
}
@@ -357,6 +363,7 @@ func (m ReferenceMap) addReference(path addrs.Module, current dag.Vertex, ref *a
}
matches = append(matches, rv)
}
return matches
}
@@ -558,7 +565,9 @@ func (m *ReferenceMap) referenceMapKey(referrer dag.Vertex, addr addrs.Reference
// NewReferenceMap is used to create a new reference map for the
// given set of vertices.
func NewReferenceMap(vs []dag.Vertex) ReferenceMap {
func NewReferenceMap(g *Graph) ReferenceMap {
vs := g.Vertices()
// Build the lookup table
m := make(ReferenceMap)
for _, v := range vs {
@@ -577,6 +586,32 @@ func NewReferenceMap(vs []dag.Vertex) ReferenceMap {
}
}
for key, val := range m {
if len(val) == 1 {
continue
}
println(key)
// Locate root
var potentialRoots []dag.Vertex
for _, vr := range val {
if _, ok := vr.(*NodeResourceHack); ok {
potentialRoots = append(potentialRoots, vr)
}
}
println(len(potentialRoots))
if len(potentialRoots) == 1 {
println("OVERRIDE")
m[key] = potentialRoots
/*parent := potentialRoots[0]
for _, v := range val {
if v != parent {
g.Connect(dag.BasicEdge(v, parent))
}
}*/
}
}
return m
}