]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-dev.py
ovs-tcpdump: Do not import unused "select" module.
[mirror_ovs.git] / utilities / ovs-dev.py
CommitLineData
c6b581b9
JS
1#!/usr/bin/env python
2# Copyright (c) 2013, 2014, 2015, 2016 Nicira, Inc.
fef5244f
EJ
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
c6b581b9 21import time
fef5244f
EJ
22
23ENV = os.environ
24HOME = ENV["HOME"]
9bf2f075 25PWD = os.getcwd()
fef5244f 26OVS_SRC = HOME + "/ovs"
223908d6 27if os.path.exists(PWD + "/WHY-OVS.rst"):
9bf2f075 28 OVS_SRC = PWD # Use current directory as OVS source tree
0c001985 29RUNDIR = OVS_SRC + "/_run"
30fbc7b6
EJ
30BUILD_GCC = OVS_SRC + "/_build-gcc"
31BUILD_CLANG = OVS_SRC + "/_build-clang"
fef5244f
EJ
32
33options = None
34parser = None
35commands = []
36
c6b581b9 37
97695cf7
EJ
38def set_path(build):
39 PATH = "%(ovs)s/utilities:%(ovs)s/ovsdb:%(ovs)s/vswitchd" % {"ovs": build}
40
41 ENV["PATH"] = PATH + ":" + ENV["PATH"]
fef5244f 42
c6b581b9 43
fef5244f 44def _sh(*args, **kwargs):
c6b581b9 45 print("------> " + " ".join(args))
fef5244f
EJ
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():
4591ed3a 57 return _sh("uname", "-r", capture=True)[0].decode().strip()
fef5244f
EJ
58
59
c5c9cb9e
AZ
60def sudo():
61 if os.geteuid() != 0:
62 _sh(" ".join(["sudo"] + sys.argv), check=True)
63 sys.exit(0)
64
c6b581b9 65
fef5244f
EJ
66def conf():
67 tag()
47e501e1 68
30fbc7b6
EJ
69 try:
70 os.remove(OVS_SRC + "/Makefile")
71 except OSError:
72 pass
73
0c001985
AZ
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"]
fef5244f 79
25dfecf8
EJ
80 cflags = "-g -fno-omit-frame-pointer"
81
fef5244f
EJ
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
25dfecf8
EJ
91 if options.with_dpdk:
92 configure.append("--with-dpdk=" + options.with_dpdk)
c6b581b9 93 cflags += " -Wno-cast-align -Wno-bad-function-cast" # DPDK warnings.
25dfecf8 94
a2a2ac7b
EJ
95 if options.optimize is None:
96 options.optimize = 0
25dfecf8 97
1bcf46c6 98 cflags += " -O%s" % str(options.optimize)
25dfecf8
EJ
99
100 ENV["CFLAGS"] = cflags
a2a2ac7b 101
fef5244f 102 _sh("./boot.sh")
30fbc7b6
EJ
103
104 try:
105 os.mkdir(BUILD_GCC)
106 except OSError:
c6b581b9 107 pass # Directory exists.
30fbc7b6
EJ
108
109 os.chdir(BUILD_GCC)
a3ea1821 110 _sh(*(configure + ["--with-linux=/lib/modules/%s/build" % uname()]))
30fbc7b6
EJ
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:
c6b581b9 128 pass # Directory exists.
30fbc7b6
EJ
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))
c0b0b096 148 mf.write("\ncheck-valgrind:\n")
30fbc7b6
EJ
149 mf.write("\ncheck:\n")
150 mf.write(make_str % BUILD_GCC)
151 mf.close()
fef5244f
EJ
152commands.append(conf)
153
154
155def make(args=""):
156 make = "make -s -j 8 " + args
fef5244f
EJ
157 _sh(make)
158commands.append(make)
159
160
161def check():
de146e5d 162 flags = ""
6a223e8e
JS
163 if options.jobs:
164 flags += "-j%d " % options.jobs
165 else:
166 flags += "-j8 "
de146e5d
JS
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
fef5244f
EJ
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():
c5c9cb9e 197 sudo()
fef5244f 198 for proc in ["ovs-vswitchd", "ovsdb-server"]:
0c001985 199 if os.path.exists("%s/run/openvswitch/%s.pid" % (RUNDIR, proc)):
fef5244f
EJ
200 _sh("ovs-appctl", "-t", proc, "exit", check=False)
201 time.sleep(.1)
c5c9cb9e 202 _sh("killall", "-q", "-2", proc, check=False)
fef5244f
EJ
203commands.append(kill)
204
205
206def reset():
c5c9cb9e 207 sudo()
fef5244f 208 kill()
0c001985
AZ
209 if os.path.exists(RUNDIR):
210 shutil.rmtree(RUNDIR)
fef5244f 211 for dp in _sh("ovs-dpctl dump-dps", capture=True):
4591ed3a 212 _sh("ovs-dpctl", "del-dp", dp.decode().strip())
fef5244f
EJ
213commands.append(reset)
214
215
216def run():
c5c9cb9e 217 sudo()
fef5244f
EJ
218 kill()
219 for d in ["log", "run"]:
0c001985 220 d = "%s/%s" % (RUNDIR, d)
fef5244f
EJ
221 shutil.rmtree(d, ignore_errors=True)
222 os.makedirs(d)
223
0c001985 224 pki_dir = RUNDIR + "/pki"
fef5244f
EJ
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
0c001985
AZ
232 if not os.path.exists(RUNDIR + "/conf.db"):
233 _sh("ovsdb-tool", "create", RUNDIR + "/conf.db",
fef5244f
EJ
234 OVS_SRC + "/vswitchd/vswitch.ovsschema")
235
3bacde2a 236 opts = ["--pidfile", "--log-file"]
fef5244f 237
c543ef57
AZ
238 if (options.user == "") or (options.user == "root:root"):
239 _sh("chown", "root:root", "-R", RUNDIR)
240 if '--user' in sys.argv:
c6b581b9 241 sys.argv.remove("--user")
c543ef57 242 else:
c6b581b9 243 _sh("chown", options.user, "-R", RUNDIR)
c543ef57
AZ
244 opts = ["--user", options.user] + opts
245
bf66c067
AZ
246 if (options.monitor):
247 opts = ["--monitor"] + opts
248
fef5244f 249 _sh(*(["ovsdb-server",
0c001985 250 "--remote=punix:%s/run/db.sock" % RUNDIR,
fef5244f
EJ
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
c6b581b9 257 _sh("ovs-vsctl --no-wait --bootstrap set-ssl %s/ovsclient-privkey.pem"
fef5244f
EJ
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)
4591ed3a 261 version = version[0].decode().strip().split()[3]
fef5244f 262 root_uuid = _sh("ovs-vsctl --no-wait --bare list Open_vSwitch",
4591ed3a 263 capture=True)[0].decode().strip()
fef5244f
EJ
264 _sh("ovs-vsctl --no-wait set Open_vSwitch %s ovs_version=%s"
265 % (root_uuid, version))
266
97695cf7
EJ
267 build = BUILD_CLANG if options.clang else BUILD_GCC
268 cmd = [build + "/vswitchd/ovs-vswitchd"]
1a90b839
DDP
269
270 if options.dpdk:
c6b581b9 271 _sh("ovs-vsctl --no-wait set Open_vSwitch %s "
bab69409 272 "other_config:dpdk-init=true" % root_uuid)
c6b581b9 273 _sh("ovs-vsctl --no-wait set Open_vSwitch %s other_config:"
eac84432 274 "dpdk-extra=\"%s\"" % (root_uuid, ' '.join(options.dpdk)))
bab69409 275 else:
c6b581b9 276 _sh("ovs-vsctl --no-wait set Open_vSwitch %s "
bab69409 277 "other_config:dpdk-init=false" % root_uuid)
1a90b839 278
fef5244f
EJ
279 if options.gdb:
280 cmd = ["gdb", "--args"] + cmd
281 elif options.valgrind:
294a5550 282 cmd = ["valgrind", "--track-origins=yes", "--leak-check=full",
1e0879aa
EJ
283 "--suppressions=%s/tests/glibc.supp" % OVS_SRC,
284 "--suppressions=%s/tests/openssl.supp" % OVS_SRC] + cmd
fef5244f 285 else:
3bacde2a 286 opts = opts + ["-vconsole:off", "--detach", "--enable-dummy"]
fef5244f
EJ
287 _sh(*(cmd + opts))
288commands.append(run)
289
290
291def modinst():
292 if not os.path.exists("/lib/modules"):
c6b581b9 293 print("Missing modules directory. Is this a Linux system?")
fef5244f
EJ
294 sys.exit(1)
295
c5c9cb9e 296 sudo()
fef5244f
EJ
297 try:
298 _sh("rmmod", "openvswitch")
c6b581b9 299 except subprocess.CalledProcessError:
fef5244f
EJ
300 pass # Module isn't loaded
301
302 try:
19c12401
BP
303 _sh("rm -f /lib/modules/%s/extra/openvswitch.ko" % uname())
304 _sh("rm -f /lib/modules/%s/extra/vport-*.ko" % uname())
c6b581b9 305 except subprocess.CalledProcessError:
fef5244f
EJ
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")
c6b581b9
JS
314 _sh("find /lib/modules/%s/ -iname vport-*.ko -exec insmod '{}' \;"
315 % uname())
fef5244f
EJ
316commands.append(modinst)
317
318
319def env():
c6b581b9 320 print("export PATH=" + ENV["PATH"])
fef5244f
EJ
321commands.append(env)
322
323
324def doc():
325 parser.print_help()
c6b581b9 326 print("""
fef5244f
EJ
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 \\
bdc30bfb 337 libssl-dev gdb libcap-ng-dev linux-headers-`uname -r`
fef5244f
EJ
338
339 # Next clone the Open vSwitch source.
6d616e99 340 git clone https://github.com/openvswitch/ovs.git %(ovs)s
fef5244f
EJ
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
e8ee793b
TG
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
fef5244f
EJ
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.
c5c9cb9e
AZ
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".
c6b581b9 374""" % {"ovs": OVS_SRC, "v": sys.argv[0], "run": RUNDIR})
fef5244f
EJ
375 sys.exit(0)
376commands.append(doc)
377
c6b581b9 378
1a90b839
DDP
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)
fef5244f 389
c6b581b9 390
fef5244f
EJ
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]
c6b581b9
JS
397 usage = "usage: %prog" + " [options] [%s] ..." % "|".join(cmd_names)
398 parser = optparse.OptionParser(usage=usage, description=description)
fef5244f
EJ
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")
25dfecf8 407 group.add_option("--with-dpdk", dest="with_dpdk", metavar="DPDK_BUILD",
c6b581b9 408 help="built with dpdk libraries located at DPDK_BUILD")
1bcf46c6 409 parser.add_option_group(group)
a2a2ac7b 410
1bcf46c6 411 group = optparse.OptionGroup(parser, "Optimization Flags")
4591ed3a 412 for i in ["s", "g"] + list(range(4)) + ["fast"]:
1bcf46c6
EJ
413 group.add_option("--O%s" % str(i), dest="optimize",
414 action="store_const", const=i,
415 help="compile with -O%s" % str(i))
fef5244f
EJ
416 parser.add_option_group(group)
417
de146e5d 418 group = optparse.OptionGroup(parser, "check")
6a223e8e
JS
419 group.add_option("-j", "--jobs", dest="jobs", metavar="N", type="int",
420 help="Run N tests in parallel")
de146e5d
JS
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
fef5244f
EJ
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")
eac84432
AC
431 group.add_option("--dpdk", dest="dpdk", action="callback",
432 callback=parse_subargs,
433 help="run ovs-vswitchd with dpdk subopts (ended by --)")
97695cf7
EJ
434 group.add_option("--clang", dest="clang", action="store_true",
435 help="Use binaries built by clang")
c543ef57
AZ
436 group.add_option("--user", dest="user", action="store", default="",
437 help="run all daemons as a non root user")
bf66c067
AZ
438 group.add_option("--monitor", dest="monitor", action="store_true",
439 help="run daemons with --monitor option")
440
fef5244f
EJ
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:
c6b581b9 447 print("Unknown argument " + arg)
fef5244f
EJ
448 doc()
449
97695cf7
EJ
450 if options.clang:
451 set_path(BUILD_CLANG)
452 else:
453 set_path(BUILD_GCC)
454
fef5244f
EJ
455 try:
456 os.chdir(OVS_SRC)
457 except OSError:
c6b581b9 458 print("Missing %s." % OVS_SRC)
fef5244f
EJ
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()