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