1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/usr/bin/env ruby
#
# Created by Luke A. Kanies on 2006-11-24.
# Copyright (c) 2006. All rights reserved.
require 'puppet/gratr/digraph'
require 'puppet/gratr/import'
require 'puppet/gratr/dot'
require 'puppet/relationship'
# This class subclasses a graph class in order to handle relationships
# among resources.
class Puppet::PGraph < GRATR::Digraph
# This is the type used for splicing.
attr_accessor :container_type
# The dependencies for a given resource.
def dependencies(resource)
tree_from_vertex(resource, :dfs).keys
end
# Override this method to use our class instead.
def edge_class()
Puppet::Relationship
end
# Determine all of the leaf nodes below a given vertex.
def leaves(vertex, type = :dfs)
tree = tree_from_vertex(vertex, type)
leaves = tree.keys.find_all { |c| adjacent(c, :direction => :out).empty? }
return leaves
end
# Collect all of the edges that the passed events match. Returns
# an array of edges.
def matching_edges(events)
events.collect do |event|
source = event.source
unless vertex?(source)
Puppet.warning "Got an event from invalid vertex %s" % source.ref
next
end
# Get all of the edges that this vertex should forward events
# to, which is the same thing as saying all edges directly below
# This vertex in the graph.
adjacent(source, :direction => :out, :type => :edges).find_all do |edge|
edge.match?(event.event)
end.each { |edge|
target = edge.target
if target.respond_to?(:ref)
source.info "Scheduling %s of %s" %
[edge.callback, target.ref]
end
}
end.flatten
end
# Take container information from another graph and use it
# to replace any container vertices with their respective leaves.
# This creates direct relationships where there were previously
# indirect relationships through the containers.
def splice!(other, type)
vertices.each do |vertex|
# Go through each vertex and replace the edges with edges
# to the leaves instead
next unless vertex.is_a?(type)
leaves = other.leaves(vertex)
if leaves.empty?
remove_vertex!(vertex)
next
end
# First create new edges for each of the :in edges
adjacent(vertex, :direction => :in, :type => :edges).each do |edge|
leaves.each do |leaf|
add_edge!(edge.source, leaf, edge.label)
if cyclic?
raise ArgumentError,
"%s => %s results in a loop" %
[up, leaf]
end
end
end
# Then for each of the out edges
adjacent(vertex, :direction => :out, :type => :edges).each do |edge|
leaves.each do |leaf|
add_edge!(leaf, edge.target, edge.label)
if cyclic?
raise ArgumentError,
"%s => %s results in a loop" %
[leaf, down]
end
end
end
# And finally, remove the vertex entirely.
remove_vertex!(vertex)
end
end
# For some reason, unconnected vertices do not show up in
# this graph.
def to_jpg(name)
gv = vertices()
Dir.chdir("/Users/luke/Desktop/pics") do
induced_subgraph(gv).write_to_graphic_file('jpg', name)
end
end
end
# $Id$
|