Revision d5a2a550

b/.gitignore
72 72
# lib
73 73
/lib/_autoconf.py
74 74
/lib/_vcsversion.py
75
/lib/_generated_rpc.py
75 76

  
76 77
# man
77 78
/man/*.[0-9]
b/Makefile.am
28 28
DOCPP = $(top_srcdir)/autotools/docpp
29 29
REPLACE_VARS_SED = autotools/replace_vars.sed
30 30
CONVERT_CONSTANTS = $(top_srcdir)/autotools/convert-constants
31
BUILD_RPC = $(top_srcdir)/autotools/build-rpc
31 32

  
32 33
# Note: these are automake-specific variables, and must be named after
33 34
# the directory + 'dir' suffix
......
144 145
	doc/examples/ganeti.cron \
145 146
	doc/examples/gnt-config-backup \
146 147
	doc/examples/hooks/ipsec \
148
	lib/_generated_rpc.py \
147 149
	$(man_MANS) \
148 150
	$(manhtml) \
149 151
	tools/kvm-ifup \
......
164 166

  
165 167
BUILT_PYTHON_SOURCES = \
166 168
	lib/_autoconf.py \
167
	lib/_vcsversion.py
169
	lib/_vcsversion.py \
170
	lib/_generated_rpc.py
168 171

  
169 172
nodist_pkgpython_PYTHON = \
170 173
	$(BUILT_PYTHON_SOURCES)
171 174

  
172 175
noinst_PYTHON = \
173 176
	lib/build/__init__.py \
177
	lib/build/rpc_definitions.py \
174 178
	lib/build/sphinx_ext.py
175 179

  
176 180
pkgpython_PYTHON = \
......
555 559
	epydoc.conf.in \
556 560
	pylintrc \
557 561
	autotools/build-bash-completion \
562
	autotools/build-rpc \
558 563
	autotools/check-python-code \
559 564
	autotools/check-imports \
560 565
	autotools/check-man \
......
1015 1020
	  echo "VCS_VERSION = '$$VCSVER'"; \
1016 1021
	} > $@
1017 1022

  
1023
lib/_generated_rpc.py: lib/build/rpc_definitions.py $(BUILD_RPC) | lib/.dir
1024
	PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(BUILD_RPC) $< > $@
1025

  
1018 1026
$(REPLACE_VARS_SED): Makefile
1019 1027
	set -e; \
1020 1028
	{ echo 's#@PREFIX@#$(prefix)#g'; \
b/autotools/build-rpc
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

  
21

  
22
"""Script to generate RPC code.
23

  
24
"""
25

  
26
# pylint: disable=C0103
27
# [C0103] Invalid name
28

  
29
import sys
30
import re
31
import itertools
32
import textwrap
33
from cStringIO import StringIO
34

  
35
from ganeti import utils
36
from ganeti import compat
37
from ganeti import build
38

  
39

  
40
_SINGLE = "single-node"
41
_MULTI = "multi-node"
42

  
43

  
44
def _WritePreamble(sw):
45
  """Writes a preamble for the RPC wrapper output.
46

  
47
  """
48
  sw.Write("# This code is automatically generated at build time.")
49
  sw.Write("# Do not modify manually.")
50
  sw.Write("")
51
  sw.Write("\"\"\"Automatically generated RPC client wrappers.")
52
  sw.Write("")
53
  sw.Write("\"\"\"")
54
  sw.Write("")
55

  
56

  
57
def _WrapCode(line):
58
  """Wraps Python code.
59

  
60
  """
61
  return textwrap.wrap(line, width=70, expand_tabs=False,
62
                       fix_sentence_endings=False, break_long_words=False,
63
                       replace_whitespace=True,
64
                       subsequent_indent=utils.ShellWriter.INDENT_STR)
65

  
66

  
67
def _WriteDocstring(sw, name, timeout, kind, args, desc):
68
  """Writes a docstring for an RPC wrapper.
69

  
70
  """
71
  sw.Write("\"\"\"Wrapper for RPC call '%s'", name)
72
  sw.Write("")
73
  if desc:
74
    sw.Write(desc)
75
    sw.Write("")
76

  
77
  note = ["This is a %s call" % kind]
78
  if timeout:
79
    note.append(" with a timeout of %s" % utils.FormatSeconds(timeout))
80
  sw.Write("@note: %s", "".join(note))
81

  
82
  if kind == _SINGLE:
83
    sw.Write("@type node: string")
84
    sw.Write("@param node: Node name")
85
  else:
86
    sw.Write("@type node_list: list of string")
87
    sw.Write("@param node_list: List of node names")
88

  
89
  if args:
90
    for (argname, _, argtext) in args:
91
      if argtext:
92
        docline = "@param %s: %s" % (argname, argtext)
93
        for line in _WrapCode(docline):
94
          sw.Write(line)
95
  sw.Write("")
96
  sw.Write("\"\"\"")
97

  
98

  
99
def _MakeArgument((argname, wrapper, _)):
100
  """Format argument for function call.
101

  
102
  """
103
  if wrapper:
104
    return wrapper % argname
105
  else:
106
    return argname
107

  
108

  
109
def _WriteBaseClass(sw, clsname, calls):
110
  """Write RPC wrapper class.
111

  
112
  """
113
  sw.Write("")
114
  sw.Write("class %s(object):", clsname)
115
  sw.IncIndent()
116
  try:
117
    sw.Write("# E1101: Non-existent members")
118
    sw.Write("# R0904: Too many public methods")
119
    sw.Write("# pylint: disable=E1101,R0904")
120

  
121
    if not calls:
122
      sw.Write("pass")
123
      return
124

  
125
    for (name, kind, timeout, args, postproc, desc) in calls:
126
      funcargs = ["self"]
127

  
128
      if kind == _SINGLE:
129
        funcargs.append("node")
130
      elif kind == _MULTI:
131
        funcargs.append("node_list")
132
      else:
133
        raise Exception("Unknown kind '%s'" % kind)
134

  
135
      funcargs.extend(map(compat.fst, args))
136

  
137
      assert "read_timeout" not in funcargs
138
      funcargs.append("read_timeout=%s" % timeout)
139

  
140
      funcdef = "def call_%s(%s):" % (name, utils.CommaJoin(funcargs))
141
      for line in _WrapCode(funcdef):
142
        sw.Write(line)
143

  
144
      sw.IncIndent()
145
      try:
146
        _WriteDocstring(sw, name, timeout, kind, args, desc)
147

  
148
        buf = StringIO()
149
        buf.write("return ")
150

  
151
        # In case line gets too long and is wrapped in a bad spot
152
        buf.write("( ")
153

  
154
        if postproc:
155
          buf.write("%s(" % postproc)
156
        buf.write("self._Call(")
157
        if kind == _SINGLE:
158
          buf.write("[node]")
159
        else:
160
          buf.write("node_list")
161
        buf.write(", \"%s\", read_timeout, [%s])" %
162
                  (name, utils.CommaJoin(map(_MakeArgument, args))))
163
        if kind == _SINGLE:
164
          buf.write("[node]")
165
        if postproc:
166
          buf.write(")")
167
        buf.write(")")
168

  
169
        for line in _WrapCode(buf.getvalue()):
170
          sw.Write(line)
171
      finally:
172
        sw.DecIndent()
173
      sw.Write("")
174
  finally:
175
    sw.DecIndent()
176

  
177

  
178
def main():
179
  """Main function.
180

  
181
  """
182
  buf = StringIO()
183
  sw = utils.ShellWriter(buf)
184

  
185
  _WritePreamble(sw)
186

  
187
  for filename in sys.argv[1:]:
188
    sw.Write("# Definitions from '%s'", filename)
189

  
190
    module = build.LoadModule(filename)
191

  
192
    # Call types are re-defined in definitions file to avoid imports. Verify
193
    # here to ensure they're equal to local constants.
194
    assert module.SINGLE == _SINGLE
195
    assert module.MULTI == _MULTI
196

  
197
    for (clsname, calls) in module.CALLS.items():
198
      _WriteBaseClass(sw, clsname, calls)
199

  
200
  print buf.getvalue()
201

  
202

  
203
if __name__ == "__main__":
204
  main()
b/lib/build/rpc_definitions.py
1
#
2
#
3

  
4
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

  
21
"""RPC definitions for communication between master and node daemons.
22

  
23
"""
24

  
25

  
26
# Various time constants for the timeout table
27
TMO_URGENT = 60 # one minute
28
TMO_FAST = 5 * 60 # five minutes
29
TMO_NORMAL = 15 * 60 # 15 minutes
30
TMO_SLOW = 3600 # one hour
31
TMO_4HRS = 4 * 3600
32
TMO_1DAY = 86400
33

  
34
SINGLE = "single-node"
35
MULTI = "multi-node"
36

  
37
CALLS = {
38
  "RpcClientDefault": [
39
    ],
40
  }

Also available in: Unified diff