ovs-dev.py: do not pass --enable-dummy to ovsdb
[cascardo/ovs.git] / utilities / ovs-dev.py
1 #!/usr/bin/python
2 # Copyright (c) 2013, 2014 Nicira, Inc.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import optparse
17 import os
18 import shutil
19 import subprocess
20 import sys
21 import tempfile
22
23 ENV = os.environ
24 HOME = ENV["HOME"]
25 OVS_SRC = HOME + "/ovs"
26 ROOT = HOME + "/root"
27 BUILD_GCC = OVS_SRC + "/_build-gcc"
28 BUILD_CLANG = OVS_SRC + "/_build-clang"
29 PATH = "%(ovs)s/utilities:%(ovs)s/ovsdb:%(ovs)s/vswitchd" % {"ovs": BUILD_GCC}
30
31 ENV["PATH"] = PATH + ":" + ENV["PATH"]
32
33 options = None
34 parser = None
35 commands = []
36
37
38 def _sh(*args, **kwargs):
39     print "------> " + " ".join(args)
40     shell = len(args) == 1
41     if kwargs.get("capture", False):
42         proc = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell)
43         return proc.stdout.readlines()
44     elif kwargs.get("check", True):
45         subprocess.check_call(args, shell=shell)
46     else:
47         subprocess.call(args, shell=shell)
48
49
50 def uname():
51     return _sh("uname", "-r", capture=True)[0].strip()
52
53
54 def conf():
55     tag()
56
57     try:
58         os.remove(OVS_SRC + "/Makefile")
59     except OSError:
60         pass
61
62     configure = ["../configure", "--prefix=" + ROOT, "--localstatedir=" + ROOT,
63                  "--with-logdir=%s/log" % ROOT, "--with-rundir=%s/run" % ROOT,
64                  "--enable-silent-rules", "--with-dbdir=" + ROOT, "--silent"]
65
66     cflags = "-g -fno-omit-frame-pointer"
67
68     if options.werror:
69         configure.append("--enable-Werror")
70
71     if options.cache_time:
72         configure.append("--enable-cache-time")
73
74     if options.mandir:
75         configure.append("--mandir=" + options.mandir)
76
77     if options.with_dpdk:
78         configure.append("--with-dpdk=" + options.with_dpdk)
79         cflags += " -Wno-cast-align -Wno-bad-function-cast" # DPDK warnings.
80
81     if options.optimize is None:
82         options.optimize = 0
83
84     cflags += " -O%d" % options.optimize
85
86     ENV["CFLAGS"] = cflags
87
88     _sh("./boot.sh")
89
90     try:
91         os.mkdir(BUILD_GCC)
92     except OSError:
93         pass # Directory exists.
94
95     os.chdir(BUILD_GCC)
96     _sh(*(configure + ["--with-linux=/lib/modules/%s/build" % uname()]))
97
98     try:
99         _sh("clang --version", check=True)
100         clang = True
101     except subprocess.CalledProcessError:
102         clang = False
103
104     try:
105         _sh("sparse --version", check=True)
106         sparse = True
107     except subprocess.CalledProcessError:
108         sparse = False
109
110     if clang:
111         try:
112             os.mkdir(BUILD_CLANG)
113         except OSError:
114             pass # Directory exists.
115
116         ENV["CC"] = "clang"
117         os.chdir(BUILD_CLANG)
118         _sh(*configure)
119
120     if sparse:
121         c1 = "C=1"
122     else:
123         c1 = ""
124
125     os.chdir(OVS_SRC)
126
127     make_str = "\t$(MAKE) -C %s $@\n"
128
129     mf = open(OVS_SRC + "/Makefile", "w")
130     mf.write("all:\n%:\n")
131     if clang:
132         mf.write(make_str % BUILD_CLANG)
133     mf.write("\t$(MAKE) -C %s %s $@\n" % (BUILD_GCC, c1))
134     mf.write("\ncheck-valgrind:\n")
135     mf.write("\ncheck:\n")
136     mf.write(make_str % BUILD_GCC)
137     mf.close()
138 commands.append(conf)
139
140
141 def make(args=""):
142     make = "make -s -j 8 " + args
143     _sh(make)
144 commands.append(make)
145
146
147 def check():
148     flags = ""
149     if options.jobs:
150         flags += "-j%d " % options.jobs
151     else:
152         flags += "-j8 "
153     if options.tests:
154         for arg in str.split(options.tests):
155             if arg[0].isdigit():
156                 flags += "%s " % arg
157             else:
158                 flags += "-k %s " % arg
159     ENV["TESTSUITEFLAGS"] = flags
160     make("check")
161 commands.append(check)
162
163
164 def tag():
165     ctags = ['ctags', '-R', '-f', '.tags']
166
167     try:
168         _sh(*(ctags + ['--exclude="datapath/"']))
169     except:
170         try:
171             _sh(*ctags)  # Some versions of ctags don't have --exclude
172         except:
173             pass
174
175     try:
176         _sh('cscope', '-R', '-b')
177     except:
178         pass
179 commands.append(tag)
180
181
182 def kill():
183     for proc in ["ovs-vswitchd", "ovsdb-server"]:
184         if os.path.exists("%s/run/openvswitch/%s.pid" % (ROOT, proc)):
185             _sh("ovs-appctl", "-t", proc, "exit", check=False)
186             time.sleep(.1)
187         _sh("sudo", "killall", "-q", "-2", proc, check=False)
188 commands.append(kill)
189
190
191 def reset():
192     kill()
193     if os.path.exists(ROOT):
194         shutil.rmtree(ROOT)
195     for dp in _sh("ovs-dpctl dump-dps", capture=True):
196         _sh("ovs-dpctl", "del-dp", dp.strip())
197 commands.append(reset)
198
199
200 def run():
201     kill()
202     for d in ["log", "run"]:
203         d = "%s/%s" % (ROOT, d)
204         shutil.rmtree(d, ignore_errors=True)
205         os.makedirs(d)
206
207     pki_dir = ROOT + "/pki"
208     if not os.path.exists(pki_dir):
209         os.mkdir(pki_dir)
210         os.chdir(pki_dir)
211         _sh("ovs-pki init")
212         _sh("ovs-pki req+sign ovsclient")
213         os.chdir(OVS_SRC)
214
215     if not os.path.exists(ROOT + "/conf.db"):
216         _sh("ovsdb-tool", "create", ROOT + "/conf.db",
217             OVS_SRC + "/vswitchd/vswitch.ovsschema")
218
219     opts = ["--pidfile", "--log-file"]
220
221     _sh(*(["ovsdb-server",
222            "--remote=punix:%s/run/db.sock" % ROOT,
223            "--remote=db:Open_vSwitch,Open_vSwitch,manager_options",
224            "--private-key=db:Open_vSwitch,SSL,private_key",
225            "--certificate=db:Open_vSwitch,SSL,certificate",
226            "--bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert",
227            "--detach", "-vconsole:off"] + opts))
228
229     _sh("ovs-vsctl --no-wait --bootstrap set-ssl %s/ovsclient-privkey.pem" \
230         " %s/ovsclient-cert.pem %s/vswitchd.cacert"
231         % (pki_dir, pki_dir, pki_dir))
232     version = _sh("ovs-vsctl --no-wait --version", capture=True)
233     version = version[0].strip().split()[3]
234     root_uuid = _sh("ovs-vsctl --no-wait --bare list Open_vSwitch",
235                     capture=True)[0].strip()
236     _sh("ovs-vsctl --no-wait set Open_vSwitch %s ovs_version=%s"
237         % (root_uuid, version))
238
239     cmd = [BUILD_GCC + "/vswitchd/ovs-vswitchd"]
240
241     if options.dpdk:
242         cmd.append("--dpdk")
243         cmd.extend(options.dpdk)
244         cmd.append("--")
245
246     if options.gdb:
247         cmd = ["gdb", "--args"] + cmd
248     elif options.valgrind:
249         cmd = ["valgrind", "--track-origins=yes", "--leak-check=full",
250                "--suppressions=%s/tests/glibc.supp" % OVS_SRC,
251                "--suppressions=%s/tests/openssl.supp" % OVS_SRC] + cmd
252     else:
253         cmd = ["sudo"] + cmd
254         opts = opts + ["-vconsole:off", "--detach", "--enable-dummy"]
255     _sh(*(cmd + opts))
256 commands.append(run)
257
258
259 def modinst():
260     if not os.path.exists("/lib/modules"):
261         print "Missing modules directory.  Is this a Linux system?"
262         sys.exit(1)
263
264     try:
265         _sh("rmmod", "openvswitch")
266     except subprocess.CalledProcessError, e:
267         pass  # Module isn't loaded
268
269     try:
270         _sh("rm /lib/modules/%s/extra/openvswitch.ko" % uname())
271     except subprocess.CalledProcessError, e:
272         pass  # Module isn't installed
273
274     conf()
275     make()
276     make("modules_install")
277
278     _sh("modprobe", "openvswitch")
279     _sh("dmesg | grep openvswitch | tail -1")
280 commands.append(modinst)
281
282
283 def env():
284     print "export PATH=" + ENV["PATH"]
285 commands.append(env)
286
287
288 def doc():
289     parser.print_help()
290     print \
291 """
292 This program is designed to help developers build and run Open vSwitch without
293 necessarily needing to know the gory details. Given some basic requirements
294 (described below), it can be used to build and run Open vSwitch, keeping
295 runtime files in the user's home directory.
296
297 Basic Configuration:
298     # This section can be run as a script on ubuntu systems.
299
300     # First install the basic requirements needed to build Open vSwitch.
301     sudo apt-get install git build-essential libtool autoconf pkg-config \\
302             libssl-dev gdb linux-headers-`uname -r`
303
304     # Next clone the Open vSwitch source.
305     git clone https://github.com/openvswitch/ovs.git %(ovs)s
306
307     # Setup environment variables.
308     `%(v)s env`
309
310     # Build the switch.
311     %(v)s conf make
312
313     # Install the kernel module
314     sudo insmod %(ovs)s/datapath/linux/openvswitch.ko
315
316     # Run the switch.
317     %(v)s run
318
319 Commands:
320     conf    - Configure the ovs source.
321     make    - Build the source (must have been configured).
322     check   - Run the unit tests.
323     tag     - Run ctags and cscope over the source.
324     kill    - Kill all running instances of ovs.
325     reset   - Reset any runtime configuration in %(run)s.
326     run     - Run ovs.
327     modinst - Build ovs and install the kernel module.
328     env     - Print the required path environment variable.
329     doc     - Print this message.
330 """ % {"ovs": OVS_SRC, "v": sys.argv[0], "run": ROOT}
331     sys.exit(0)
332 commands.append(doc)
333
334 def parse_subargs(option, opt_str, value, parser):
335     subopts = []
336
337     while parser.rargs:
338         dpdkarg = parser.rargs.pop(0)
339         if dpdkarg == "--":
340             break
341         subopts.append(dpdkarg)
342
343     setattr(parser.values, option.dest, subopts)
344
345 def main():
346     global options
347     global parser
348
349     description = "Open vSwitch developer configuration. Try `%prog doc`."
350     cmd_names = [c.__name__ for c in commands]
351     parser = optparse.OptionParser(usage="usage: %prog"
352                                    + " [options] [%s] ..."
353                                    % "|".join(cmd_names),
354                                    description=description)
355
356     group = optparse.OptionGroup(parser, "conf")
357     group.add_option("--disable-Werror", dest="werror", action="store_false",
358                      default=True, help="compile without the Werror flag")
359     group.add_option("--cache-time", dest="cache_time",
360                      action="store_true", help="configure with cached timing")
361     group.add_option("--mandir", dest="mandir", metavar="MANDIR",
362                      help="configure the man documentation install directory")
363     group.add_option("--with-dpdk", dest="with_dpdk", metavar="DPDK_BUILD",
364                      help="built with dpdk libraries located at DPDK_BUILD");
365
366     for i in range(4):
367         group.add_option("--O%d" % i, dest="optimize", action="store_const",
368                          const=i, help="compile with -O%d" % i)
369     parser.add_option_group(group)
370
371     group = optparse.OptionGroup(parser, "check")
372     group.add_option("-j", "--jobs", dest="jobs", metavar="N", type="int",
373                      help="Run N tests in parallel")
374     group.add_option("--tests", dest="tests", metavar="FILTER",
375                      help="""run specific tests and/or a test category
376                           eg, --tests=\"1-10 megaflow\"""")
377     parser.add_option_group(group)
378
379     group = optparse.OptionGroup(parser, "run")
380     group.add_option("-g", "--gdb", dest="gdb", action="store_true",
381                      help="run ovs-vswitchd under gdb")
382     group.add_option("--valgrind", dest="valgrind", action="store_true",
383                      help="run ovs-vswitchd under valgrind")
384     group.add_option("--dpdk", dest="dpdk", action="callback",
385                      callback=parse_subargs,
386                      help="run ovs-vswitchd with dpdk subopts (ended by --)")
387     parser.add_option_group(group)
388
389     options, args = parser.parse_args()
390
391     for arg in args:
392         if arg not in cmd_names:
393             print "Unknown argument " + arg
394             doc()
395
396     try:
397         os.chdir(OVS_SRC)
398     except OSError:
399         print "Missing %s." % OVS_SRC
400         doc()
401
402     for arg in args:
403         for cmd in commands:
404             if arg == cmd.__name__:
405                 cmd()
406
407
408 if __name__ == '__main__':
409     main()