~jamesodhunt/ubuntu/natty/upstart/proposed-stage2

« back to all changes in this revision

Viewing changes to scripts/initctl2dot.py

* New upstream release 0.9.4:
  - scripts/initctl2dot.py: Fixes to handle 'emits' glob syntax.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
# Usage:
33
33
#
34
34
#   initctl show-config -e > initctl.out
35
 
#   initctl2dot.py -f initctl.out -o upstart.dot
 
35
#   initctl2dot -f initctl.out -o upstart.dot
36
36
#   dot -Tpng -o upstart.png upstart.dot
37
37
#
38
38
# Or more simply:
39
39
#
40
 
#  initctl2dot.py -o - | dot -Tpng -o upstart.png
 
40
#  initctl2dot -o - | dot -Tpng -o upstart.png
41
41
#
42
42
# See also:
43
43
#
48
48
 
49
49
import sys
50
50
import re
 
51
import fnmatch
51
52
import os
52
53
from string import split
53
54
import datetime
78
79
def header(ofh):
79
80
  global options
80
81
 
81
 
  str  = "digraph upstart {"
82
 
  str += "  node [shape=record];"
83
 
  str += "  rankdir=LR;"
84
 
  str += "  overlap=false;"
85
 
  str += "  bgcolor=\"%s\";" % options.color_bg
86
 
  str += "  fontcolor=\"%s\";" % options.color_text
 
82
  str  = "digraph upstart {\n"
 
83
 
 
84
  # make the default node an event to simplify glob code
 
85
  str += "  node [shape=\"diamond\", fontcolor=\"%s\", fillcolor=\"%s\", style=\"filled\"];\n" \
 
86
    % (options.color_event_text, options.color_event)
 
87
  str += "  rankdir=LR;\n"
 
88
  str += "  overlap=false;\n"
 
89
  str += "  bgcolor=\"%s\";\n" % options.color_bg
 
90
  str += "  fontcolor=\"%s\";\n" % options.color_text
87
91
 
88
92
  ofh.write(str)
89
93
 
107
111
      (cmd, os.uname()[1])
108
112
 
109
113
  epilog += "Boxes of color %s denote jobs.\\n" % options.color_job
110
 
  epilog += "Diamonds of color %s denote events.\\n" % options.color_event
 
114
  epilog += "Solid diamonds of color %s denote events.\\n" % options.color_event
 
115
  epilog += "Dotted diamonds denote 'glob' events.\\n"
111
116
  epilog += "Emits denoted by %s lines.\\n" % options.color_emits
112
117
  epilog += "Start on denoted by %s lines.\\n" % options.color_start_on
113
118
  epilog += "Stop on denoted by %s lines.\\n" % options.color_stop_on
114
 
  epilog += "\";"
 
119
  epilog += "\";\n"
115
120
  epilog += "}\n"
116
121
  ofh.write(epilog)
117
122
 
121
126
def sanitise(s):
122
127
  return s.replace('-', '_').replace('$', 'dollar_').replace('[', \
123
128
  'lbracket').replace(']', 'rbracket').replace('!', \
124
 
  'bang').replace(':', '_')
 
129
  'bang').replace(':', '_').replace('*', 'star').replace('?', 'question')
125
130
 
126
131
 
127
132
# Convert a dollar in @name to a unique-ish new name, based on @job and
148
153
 
149
154
def show_event(ofh, name):
150
155
    global options
151
 
    ofh.write("""
152
 
    %s [label=\"%s\", shape=diamond, fontcolor=\"%s\", fillcolor=\"%s\", style=\"filled\"];
153
 
    """ % (mk_event_node_name(name), name, options.color_event_text, options.color_event))
154
 
 
 
156
    str = "%s [label=\"%s\", shape=diamond, fontcolor=\"%s\", fillcolor=\"%s\"," % \
 
157
      (mk_event_node_name(name), name, options.color_event_text, options.color_event)
 
158
 
 
159
    if '*' in name:
 
160
      str += " style=\"dotted\""
 
161
    else:
 
162
      str += " style=\"filled\""
 
163
 
 
164
    str += "];\n"
 
165
 
 
166
    ofh.write(str)
155
167
 
156
168
def show_events(ofh):
157
169
  global events
193
205
  global options
194
206
 
195
207
  ofh.write("""
196
 
    %s [label=\"<job> %s | { <start> start on | <stop> stop on }\", fontcolor=\"%s\", style=\"filled\", fillcolor=\"%s\"];
 
208
    %s [shape=\"record\", label=\"<job> %s | { <start> start on | <stop> stop on }\", fontcolor=\"%s\", style=\"filled\", fillcolor=\"%s\"];
197
209
    """ % (mk_job_node_name(name), name, options.color_job_text, options.color_job))
198
210
 
199
211
 
288
300
  global options
289
301
  global restrictions_list
290
302
 
 
303
  glob_jobs = {}
 
304
 
291
305
  if restrictions_list:
292
306
    jobs_list = restrictions_list
293
307
  else:
308
322
      show_stop_on_event_edge(ofh, job, s)
309
323
 
310
324
    for e in jobs[job]['emits']:
 
325
      if '*' in e:
 
326
        # handle glob patterns in 'emits'
 
327
        glob_events = []
 
328
        for _e in events:
 
329
          if e != _e and fnmatch.fnmatch(_e, e):
 
330
            glob_events.append(_e)
 
331
        glob_jobs[job] = glob_events
 
332
 
311
333
      show_job_emits_edge(ofh, job, e)
312
334
 
313
335
    if not restrictions_list:
325
347
      for e in jobs[j]['emits']:
326
348
        show_job_emits_edge(ofh, j, e)
327
349
 
 
350
  # Create links from jobs (which advertise they emits a class of
 
351
  # events, via the glob syntax) to all the events they create.
 
352
  for g in glob_jobs:
 
353
    for ge in glob_jobs[g]:
 
354
      show_job_emits_edge(ofh, g, ge)
 
355
 
328
356
  if not restrictions_list:
329
357
    return
330
358