summaryrefslogtreecommitdiffstats
path: root/tools/groups-to-dot.py
blob: 5eee8b9c84959c2c6248d60b574eb0706e90aa58 (plain)
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
#!/usr/bin/env python

'''This script generates graphviz diagrams using bcfg2 metadata'''
__revision__ = '$Revision$'

import lxml.etree, sys, popen2

colors = ['steelblue1', 'chartreuse', 'gold', 'magenta', 'indianred1', 'limegreen', 
          'orange1', 'limegreen']

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print "Usage groups-to-dot.py [-r] [-b] [-h] -o <outputfile> <metadatadir>"
        raise SystemExit, 1
    groups = lxml.etree.parse(sys.argv[-1] + '/groups.xml').getroot()
    clients = lxml.etree.parse(sys.argv[-1] + '/clients.xml').getroot()
    if '-r' in sys.argv:
        dotpipe = popen2.Popen4("dd bs=4M 2>/dev/null")
    else:
        dotpipe = popen2.Popen4("dot -Tpng")
    categories = {'default':'grey83'}
    instances = {}
    for group in groups.findall('Group'):
        if group.get('category', False):
            if not categories.has_key(group.get('category')):
                categories[group.get('category')] = colors.pop()
        
    try:
        dotpipe.tochild.write("digraph groups {\n")
    except:
        print "write to dot process failed. Is graphviz installed?"
        raise SystemExit, 1
    dotpipe.tochild.write('\trankdir="LR";\n')
    if '-h' in sys.argv:
        for client in clients.findall('Client'):
            if instances.has_key(client.get('profile')):
                instances[client.get('profile')].append(client.get('name'))
            else:
                instances[client.get('profile')] = [client.get('name')]
        for profile, clist in instances.iteritems():
            clist.sort()
            dotpipe.tochild.write('''\t"%s-instances" [ label="%s", shape="record" ];\n''' % (profile, '|'.join(clist)))
            dotpipe.tochild.write('''\t"%s-instances" -> "group-%s";\n''' % (profile, profile))

    if '-b' in sys.argv:
        bundles = []
        [bundles.append(bund.get('name')) for bund in groups.findall('.//Bundle')
         if bund.get('name') not in bundles]
        bundles.sort()
        for bundle in bundles:
            dotpipe.tochild.write('''\t"bundle-%s" [ label="%s", shape="septagon"];\n''' % (bundle, bundle))
    gseen = []
    for group in groups.findall('Group'):
        color = categories[group.get('category', 'default')]
        if group.get('profile', 'false') == 'true':
            style="filled, bold"
        else:
            style = "filled"
        gseen.append(group.get('name'))
        dotpipe.tochild.write('\t"group-%s" [label="%s", style="%s", fillcolor=%s];\n' %
                              (group.get('name'), group.get('name'), style, color))
        if '-b' in sys.argv:
            for bundle in group.findall('Bundle'):
                dotpipe.tochild.write('\t"group-%s" -> "bundle-%s";\n' %
                                      (group.get('name'), bundle.get('name')))
        
    for group in groups.findall('Group'):
        for parent in group.findall('Group'):
            if parent.get('name') not in gseen:
                dotpipe.tochild.write('\t"group-%s" [label="%s", style="filled", fillcolor="grey83"];\n' %
                                      (parent.get('name'), parent.get('name')))
                gseen.append(parent.get("name"))
            dotpipe.tochild.write('\t"group-%s" -> "group-%s" ;\n' %
                                  (group.get('name'), parent.get('name')))
    dotpipe.tochild.write("\tsubgraph cluster_key {\n")
    dotpipe.tochild.write('''\tstyle="filled";\n''')
    dotpipe.tochild.write('''\tcolor="lightblue";\n''')
    dotpipe.tochild.write('''\tBundle [ shape="septagon" ];\n''')
    dotpipe.tochild.write('''\tGroup [shape="ellipse"];\n''')
    dotpipe.tochild.write('''\tProfile [style="bold", shape="ellipse"];\n''')
    dotpipe.tochild.write('''\tHblock [label="Host1|Host2|Host3", shape="record"];\n''')
    dotpipe.tochild.write('''\tlabel="Key";\n''')
    dotpipe.tochild.write("\t}\n")
    dotpipe.tochild.write("}\n")
    dotpipe.tochild.close()
    data = dotpipe.fromchild.read()
    if '-o' in sys.argv:
        output = open(sys.argv[sys.argv.index('-o') + 1], 'w').write(data)
    else:
        print data