PageRenderTime 56ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/bcfg2-1.2.3/src/lib/Server/Admin/Viz.py

#
Python | 119 lines | 104 code | 9 blank | 6 comment | 17 complexity | 332dacc4ad13d423006dfaed5cbfb852 MD5 | raw file
  1. import getopt
  2. from subprocess import Popen, PIPE
  3. import sys
  4. import pipes
  5. import Bcfg2.Server.Admin
  6. class Viz(Bcfg2.Server.Admin.MetadataCore):
  7. __shorthelp__ = "Produce graphviz diagrams of metadata structures"
  8. __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin viz [--includehosts] "
  9. "[--includebundles] [--includekey] "
  10. "[--only-client clientname] "
  11. "[-o output.<ext>]\n")
  12. __usage__ = ("bcfg2-admin viz [options]\n\n"
  13. " %-32s%s\n"
  14. " %-32s%s\n"
  15. " %-32s%s\n"
  16. " %-32s%s\n"
  17. " %-32s%s\n" %
  18. ("-H, --includehosts",
  19. "include hosts in the viz output",
  20. "-b, --includebundles",
  21. "include bundles in the viz output",
  22. "-k, --includekey",
  23. "show a key for different digraph shapes",
  24. "-c, --only-client <clientname>",
  25. "show only the groups, bundles for the named client",
  26. "-o, --outfile <file>",
  27. "write viz output to an output file"))
  28. colors = ['steelblue1', 'chartreuse', 'gold', 'magenta',
  29. 'indianred1', 'limegreen', 'orange1', 'lightblue2',
  30. 'green1', 'blue1', 'yellow1', 'darkturquoise', 'gray66']
  31. __plugin_blacklist__ = ['DBStats', 'Snapshots', 'Cfg', 'Pkgmgr', 'Packages',
  32. 'Rules', 'Account', 'Decisions', 'Deps', 'Git',
  33. 'Svn', 'Fossil', 'Bzr', 'Bundler', 'TGenshi',
  34. 'SGenshi', 'Base']
  35. def __call__(self, args):
  36. Bcfg2.Server.Admin.MetadataCore.__call__(self, args)
  37. # First get options to the 'viz' subcommand
  38. try:
  39. opts, args = getopt.getopt(args, 'Hbkc:o:',
  40. ['includehosts', 'includebundles',
  41. 'includekey', 'only-client=', 'outfile='])
  42. except getopt.GetoptError:
  43. msg = sys.exc_info()[1]
  44. print(msg)
  45. print(self.__longhelp__)
  46. raise SystemExit(1)
  47. hset = False
  48. bset = False
  49. kset = False
  50. only_client = None
  51. outputfile = False
  52. for opt, arg in opts:
  53. if opt in ("-H", "--includehosts"):
  54. hset = True
  55. elif opt in ("-b", "--includebundles"):
  56. bset = True
  57. elif opt in ("-k", "--includekey"):
  58. kset = True
  59. elif opt in ("-c", "--only-client"):
  60. only_client = arg
  61. elif opt in ("-o", "--outfile"):
  62. outputfile = arg
  63. data = self.Visualize(self.setup['repo'], hset, bset,
  64. kset, only_client, outputfile)
  65. if data:
  66. print(data)
  67. raise SystemExit(0)
  68. def Visualize(self, repopath, hosts=False,
  69. bundles=False, key=False, only_client=None, output=False):
  70. """Build visualization of groups file."""
  71. if output:
  72. format = output.split('.')[-1]
  73. else:
  74. format = 'png'
  75. cmd = ["dot", "-T", format]
  76. if output:
  77. cmd.extend(["-o", output])
  78. try:
  79. dotpipe = Popen(cmd, stdin=PIPE, stdout=PIPE, close_fds=True)
  80. except OSError:
  81. # on some systems (RHEL 6), you cannot run dot with
  82. # shell=True. on others (Gentoo with Python 2.7), you
  83. # must. In yet others (RHEL 5), either way works. I have
  84. # no idea what the difference is, but it's kind of a PITA.
  85. cmd = ["dot", "-T", pipes.quote(format)]
  86. if output:
  87. cmd.extend(["-o", pipes.quote(output)])
  88. dotpipe = Popen(cmd, shell=True,
  89. stdin=PIPE, stdout=PIPE, close_fds=True)
  90. try:
  91. dotpipe.stdin.write("digraph groups {\n")
  92. except:
  93. print("write to dot process failed. Is graphviz installed?")
  94. raise SystemExit(1)
  95. dotpipe.stdin.write('\trankdir="LR";\n')
  96. dotpipe.stdin.write(self.metadata.viz(hosts, bundles,
  97. key, only_client, self.colors))
  98. if key:
  99. dotpipe.stdin.write("\tsubgraph cluster_key {\n")
  100. dotpipe.stdin.write('''\tstyle="filled";\n''')
  101. dotpipe.stdin.write('''\tcolor="lightblue";\n''')
  102. dotpipe.stdin.write('''\tBundle [ shape="septagon" ];\n''')
  103. dotpipe.stdin.write('''\tGroup [shape="ellipse"];\n''')
  104. dotpipe.stdin.write('''\tProfile [style="bold", shape="ellipse"];\n''')
  105. dotpipe.stdin.write('''\tHblock [label="Host1|Host2|Host3", shape="record"];\n''')
  106. dotpipe.stdin.write('''\tlabel="Key";\n''')
  107. dotpipe.stdin.write("\t}\n")
  108. dotpipe.stdin.write("}\n")
  109. dotpipe.stdin.close()
  110. return dotpipe.stdout.read()