Commit Graph

66 Commits

Author SHA1 Message Date
James Bardin 8cf0a8ca9c faster DAG transitive reduction
In the case of highly-connected graphs, the TransitiveReduction process
was far too computationally intensive. Since no operations are applied
to the nodes, and the walk order is not even user visible, we don't need
to sort them n^2 times.
2017-10-03 11:24:59 -04:00
Radek Simko 93613ee526
terraform+dag: Set lower log levels 2017-08-14 11:43:45 +02:00
Martin Atkins b28fc1cd20 dag: method for filtering a set on arbitrary criteria 2017-05-11 11:57:46 -07:00
Edward Betts be265479a9 correct spelling mistakes (#13979) 2017-04-27 02:10:04 +12:00
James Bardin bfa6ab4617 Fix removeEdge test failures
The removeEdge test could fail intermittently with the wrong order.

The precondition of a 1->2->3 order wasn't met, because there was no
edge from 1->3, so 3->1->2 was also a valid ordering.

The other failure was a bookkeeping error, were the recorded order may
not match the visited order. What happened in this case was the gateCh
was closed by V2, allowing V3 to run which could beat V2 to recording
its visit. Now the visit is recorded as part of the vertex walk, and the
gate is released as the final operation.

The order is deterministic now, so remove the brute-force test loop.
2017-02-20 19:54:34 -05:00
James Bardin d01b0b0647 Remove intermittent failure from newEdge test
Because the vertex visit was record after the Update call, Updated
vertices may have been visited before the visit was recorded, causing
occasional test failures.

The order is now deterministic, and we can remove the brute-force loop.
2017-02-20 19:54:34 -05:00
James Bardin 7bf33c2a7f Remove loop from TestWalker_removeVertex
There's no timing dependent behavior here, since V1 must be visited
before V2, Remove and Update must be called before V2 is visited.
2017-02-20 19:54:34 -05:00
James Bardin 0fb24c1a7a Remove sleep-based concurrency from newVertex test
Add a synchronization channel for the TestWalker_newVertex test, rather
than using a sleep and running it multiple times.
2017-02-20 19:54:13 -05:00
Mitchell Hashimoto 6702a22074
dag: require acyclic graph 2017-02-03 21:18:34 +01:00
Mitchell Hashimoto 07ce5a7624
dag: cleanup some code that had no effect anymore 2017-02-03 21:18:34 +01:00
Mitchell Hashimoto 6366488809
dag: Update can be called with a nil graph 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 65752cd51a
dag: improve docs and read access during a lock 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 72a717f2de
dag: change the type sig of Update to Graph so its external friendly 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 28fff99ea8
dag: replace dag.Walk with our walker 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto b1aa6fd598
dag: improved comments 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 7f61f11723
dag: support removing edges 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 5d49e7e6b6
dag: tests for adding edges/vertices during walk-time 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto cbc71d9508
dag: basic working update-able walker 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto 77c445a838
dag: Set difference 2017-02-03 21:18:33 +01:00
Mitchell Hashimoto c8df3e5995
dag: string DotOpts through to vertex
Fixes #11052

It appears that historically nodes did not expect DotOpts to ever be
nil. To avoid nil panics in general I'm in agreement with this behavior
so this modifies dag to always pass in a non-nil DotOpts. Tests
included.
2017-01-08 11:59:18 -08:00
Mitchell Hashimoto 8a9e1c1527
dag: call into DotNode to get attributes 2016-12-03 15:17:14 -08:00
James Bardin ace06f9759 Merge pull request #10149 from hashicorp/jbardin/debug-cmd
Add debug command with json2dot
2016-11-21 17:35:19 -05:00
James Bardin b8adf10236 Add debug command with json2dot
Add `terraform debug json2dot` to convert debug log graphs to dot
format. This is not meant to be in place of more advanced debug
visualization, but may continue to be a useful way to work with the
debug output.
2016-11-21 11:59:20 -05:00
James Bardin 6d30b60144 Add DebugVisitInfo
This encodes vertex debug information into the graph log when a vertex
is visited during a walk operation. These can ordered to show how the
Graph was walked.

Add a mutex to the encoder so it can be used during a parallel walk.

Moved string literal constants used for marshaling to pre-defined constants.
Did some renaming to make the marshal* structures more consistent.
2016-11-15 10:39:08 -05:00
James Bardin 1be8e8c5a0 Add Graph.DebugOperation test 2016-11-14 14:36:06 -05:00
James Bardin de0cb17a39 Add Graph.DebugOperation
The method marks the start of a set of operations on the Graph, with
extra information optionally provided in the second paramter. This
returns a function with a single End method to mark the end of the set
in the logs.

Refactor the existing graph Begin/End Operation calls to use this single
method. Remove the *string types in the marshal structs, these are
strictly informational and don't need to differentiate empty vs unset
strings.

Add calls to DebugOperation for each step while building the graph.
2016-11-14 12:47:51 -05:00
James Bardin 7e66df3290 Rename annotation methods
Change AnnotateVertex and AnnotateEdge to VertexDebugInfo EdgeDebugInfo
to avoid confusion between debug output and future graph annotations.
2016-11-14 11:06:52 -05:00
James Bardin f37b2fafed Remove sync.Once from dag.Graph
dag.Graph is used as a value, but contains a sync data structure. This
prevents copying the value, and is needed if one wants to upgrade a Graph
to an AcyclicGraph.

The sync.Once only guards the init() method, which can be guarded
internally with nil checks on the fields. The init method could be
removed entirely with a proper constructor later on of we so choose.
2016-11-14 08:52:18 -05:00
James Bardin 7bbd6bfbd7 Add methods to annotate Graph vertices and edges
The AnnotateVertex and AnnotateEdge Graph methods will allow terraform
to insert arbitray information into the encoded graph stream for later
processing.
2016-11-14 08:52:18 -05:00
James Bardin 82b1a2abc2 Add graph transformation recording
The external api provided here is simply
dag.Graph.SetDebugWriter(io.Writer). When a writer is provided to a
Graph, it will immediately encode itself to the stream, and subsequently
encode any additional transformations to the graph. This will allow
easier logging of graph transformations without writing complete graphs
to the logs at every step. Since the marshalGraph can also be dot
encoded, this will allow translation from the JSON logs to dot graphs.
2016-11-14 08:50:34 -05:00
James Bardin 6f347ebb3a Remove dot package
Unify all dot functionality in the dag package
2016-11-14 08:50:34 -05:00
James Bardin 8a5d71b0ac Implement dag.GraphNodeDotter (temporarily)
To maintain the same output, the Graph.Dot implementation needs to be
aware of GraphNodeDotter. Copy the interface into the dag package, and
make the Dot marshaler aware of which nodes implemented the interface.
This way we can remove most of the remaining dot code from terraform.
2016-11-14 08:50:34 -05:00
James Bardin 7b774f771b implement dag.Subgrapher interface
This allows the dag package to detect subgraphs, even when impelemnted
by types from other packages
2016-11-14 08:50:34 -05:00
James Bardin 28d406c040 Provider a marshaler for dag.Graph
The dot format generation was done with a mix of code from the terraform
package and the dot package. Unify the dot generation code, and it into
the dag package.

Use an intermediate structure to allow a dag.Graph to marshal itself
directly. This structure will be ablt to marshal directly to JSON, or be
translated to dot format. This was we can record more information about
the graph in the debug logs, and provide a way to translate those logged
structures to dot, which is convenient for viewing the graphs.
2016-11-14 08:50:33 -05:00
Mitchell Hashimoto 83b1c82e93
terraform: put quotes before vertex name to avoid false panicwrap
Fixes #9395
2016-10-23 14:23:36 -07:00
Mitchell Hashimoto 6e632ec2ba
dag: test for EdgesFrom, EdgesTo 2016-10-19 13:38:53 -07:00
Mitchell Hashimoto 4e8e6cd661
dag: add EdgesFrom, EdgesTo, needs tests 2016-10-19 13:38:53 -07:00
James Bardin 1af7ee87a2 Silence log output when not verbose
Set the default log package output to iotuil.Discard during tests if the
`-v` flag isn't set. If we are verbose, then apply the filter according
to the TF_LOG env variable.
2016-08-01 17:19:14 -04:00
Paul Hinze b45f53eef4
dag: fix ReverseDepthFirstWalk when nodes remove themselves
The report in #7378 led us into a deep rabbit hole that turned out to
expose a bug in the graph walk implementation being used by the
`NoopTransformer`. The problem ended up being when two nodes in a single
dependency chain both reported `Noop() -> true` and needed to be
removed. This was breaking the walk and preventing the second node from
ever being visited.

Fixes #7378
2016-07-15 13:43:28 -06:00
Paul Hinze a4c96e5619
dag: Fix graph printing type mismatch
Dependencies were being sorted, but their types were not, causing
incorrect printing.
2016-07-15 13:42:08 -06:00
James Nugent 0d289f982c core: Print node types in traces
This makes it clearer when looking at  output as to which types of node
are involved in a particular graph.
2016-04-13 10:20:18 -07:00
Mitchell Hashimoto 5d5045fdd6 dag: add HasVertex, HasEdge 2016-01-14 13:52:01 -08:00
Mitchell Hashimoto 05794199af dag: use hashcodes to as map key to edge sets 2015-10-27 11:58:34 -07:00
Paul Hinze 9cd88810f4 core: log every 5s while waiting for dependencies
Helps to flush out deadlocks in the dependency graph
2015-08-10 15:50:36 -05:00
Paul Hinze baa33d7326 core: dag errors should cascade to all descendents
We weren't marking skipped nodes as failing, so any
grandchild-and-deeper dependencies would still evaluate.

For example:

    A -> B -> C -> D

If B failed, C would be skipped, but D would still be evaluated.

This fixes the behavior so C, D, and any further descendents will all be
skipped when B fails.

Addresses crashing aspect of #2955 and likely a lot of other confusing
failure modes.
2015-08-07 11:38:58 -05:00
Mitchell Hashimoto caef7769ae dag: Replace with the same values is a no-op 2015-05-07 11:22:07 -07:00
Paul Hinze ce49dd6080 core: graph command gets -verbose and -draw-cycles
When you specify `-verbose` you'll get the whole graph of operations,
which gives a better idea of the operations terraform performs and in
what order.

The DOT graph is now generated with a small internal library instead of
simple string building. This allows us to ensure the graph generation is
as consistent as possible, among other benefits.

We set `newrank = true` in the graph, which I've found does just as good
a job organizing things visually as manually attempting to rank the nodes
based on depth.

This also fixes `-module-depth`, which was broken post-AST refector.
Modules are now expanded into subgraphs with labels and borders. We
have yet to regain the plan graphing functionality, so I removed that
from the docs for now.

Finally, if `-draw-cycles` is added, extra colored edges will be drawn
to indicate the path of any cycles detected in the graph.

A notable implementation change included here is that
{Reverse,}DepthFirstWalk has been made deterministic. (Before it was
dependent on `map` ordering.) This turned out to be unnecessary to gain
determinism in the final DOT-level implementation, but it seemed
a desirable enough of a property that I left it in.
2015-04-27 09:23:47 -05:00
Paul Hinze 97acccd3ed core: targeted operations
Add `-target=resource` flag to core operations, allowing users to
target specific resources in their infrastructure. When `-target` is
used, the operation will only apply to that resource and its
dependencies.

The calculated dependencies are different depending on whether we're
running a normal operation or a `terraform destroy`.

Generally, "dependencies" refers to ancestors: resources falling
_before_ the target in the graph, because their changes are required to
accurately act on the target.

For destroys, "dependencies" are descendents: those resources which fall
_after_ the target. These resources depend on our target, which is going
to be destroyed, so they should also be destroyed.
2015-03-31 14:49:38 -05:00
Mitchell Hashimoto 865de51816 dag: do a DFS for each vertex 2015-02-27 19:37:59 -08:00
Mitchell Hashimoto ed2075e384 dag: TransitiveReduction 2015-02-27 19:12:19 -08:00