2 # Copyright (c) 2013, 2014, 2015, 2016 Nicira, Inc.
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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
26 OVS_SRC = HOME + "/ovs"
27 if os.path.exists(PWD + "/WHY-OVS.md"):
28 OVS_SRC = PWD # Use current directory as OVS source tree
29 RUNDIR = OVS_SRC + "/_run"
30 BUILD_GCC = OVS_SRC + "/_build-gcc"
31 BUILD_CLANG = OVS_SRC + "/_build-clang"
39 PATH = "%(ovs)s/utilities:%(ovs)s/ovsdb:%(ovs)s/vswitchd" % {"ovs": build}
41 ENV["PATH"] = PATH + ":" + ENV["PATH"]
44 def _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)
53 subprocess.call(args, shell=shell)
57 return _sh("uname", "-r", capture=True)[0].decode().strip()
62 _sh(" ".join(["sudo"] + sys.argv), check=True)
70 os.remove(OVS_SRC + "/Makefile")
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"]
80 cflags = "-g -fno-omit-frame-pointer"
83 configure.append("--enable-Werror")
85 if options.cache_time:
86 configure.append("--enable-cache-time")
89 configure.append("--mandir=" + options.mandir)
92 configure.append("--with-dpdk=" + options.with_dpdk)
93 cflags += " -Wno-cast-align -Wno-bad-function-cast" # DPDK warnings.
95 if options.optimize is None:
98 cflags += " -O%s" % str(options.optimize)
100 ENV["CFLAGS"] = cflags
107 pass # Directory exists.
110 _sh(*(configure + ["--with-linux=/lib/modules/%s/build" % uname()]))
113 _sh("clang --version", check=True)
115 except subprocess.CalledProcessError:
119 _sh("sparse --version", check=True)
121 except subprocess.CalledProcessError:
126 os.mkdir(BUILD_CLANG)
128 pass # Directory exists.
131 os.chdir(BUILD_CLANG)
141 make_str = "\t$(MAKE) -C %s $@\n"
143 mf = open(OVS_SRC + "/Makefile", "w")
144 mf.write("all:\n%:\n")
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)
152 commands.append(conf)
156 make = "make -s -j 8 " + args
158 commands.append(make)
164 flags += "-j%d " % options.jobs
168 for arg in str.split(options.tests):
172 flags += "-k %s " % arg
173 ENV["TESTSUITEFLAGS"] = flags
175 commands.append(check)
179 ctags = ['ctags', '-R', '-f', '.tags']
182 _sh(*(ctags + ['--exclude="datapath/"']))
185 _sh(*ctags) # Some versions of ctags don't have --exclude
190 _sh('cscope', '-R', '-b')
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)
202 _sh("killall", "-q", "-2", proc, check=False)
203 commands.append(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())
213 commands.append(reset)
219 for d in ["log", "run"]:
220 d = "%s/%s" % (RUNDIR, d)
221 shutil.rmtree(d, ignore_errors=True)
224 pki_dir = RUNDIR + "/pki"
225 if not os.path.exists(pki_dir):
229 _sh("ovs-pki req+sign ovsclient")
232 if not os.path.exists(RUNDIR + "/conf.db"):
233 _sh("ovsdb-tool", "create", RUNDIR + "/conf.db",
234 OVS_SRC + "/vswitchd/vswitch.ovsschema")
236 opts = ["--pidfile", "--log-file"]
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")
243 _sh("chown", options.user, "-R", RUNDIR)
244 opts = ["--user", options.user] + opts
246 if (options.monitor):
247 opts = ["--monitor"] + opts
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))
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))
267 build = BUILD_CLANG if options.clang else BUILD_GCC
268 cmd = [build + "/vswitchd/ovs-vswitchd"]
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)))
276 _sh("ovs-vsctl --no-wait set Open_vSwitch %s "
277 "other_config:dpdk-init=false" % root_uuid)
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
286 opts = opts + ["-vconsole:off", "--detach", "--enable-dummy"]
292 if not os.path.exists("/lib/modules"):
293 print("Missing modules directory. Is this a Linux system?")
298 _sh("rmmod", "openvswitch")
299 except subprocess.CalledProcessError:
300 pass # Module isn't loaded
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
310 make("modules_install")
312 _sh("modprobe", "openvswitch")
313 _sh("dmesg | grep openvswitch | tail -1")
314 _sh("find /lib/modules/%s/ -iname vport-*.ko -exec insmod '{}' \;"
316 commands.append(modinst)
320 print("export PATH=" + ENV["PATH"])
327 This program is designed to help developers build and run Open vSwitch without
328 necessarily needing to know the gory details. Given some basic requirements
329 (described below), it can be used to build and run Open vSwitch, keeping
330 runtime files in the user's home directory.
333 # This section can be run as a script on ubuntu systems.
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`
339 # Next clone the Open vSwitch source.
340 git clone https://github.com/openvswitch/ovs.git %(ovs)s
342 # Setup environment variables.
348 # Install the kernel module
349 sudo insmod %(ovs)s/datapath/linux/openvswitch.ko
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
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.
367 modinst - Build ovs and install the kernel module.
368 env - Print the required path environment variable.
369 doc - Print this message.
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})
379 def parse_subargs(option, opt_str, value, parser):
383 dpdkarg = parser.rargs.pop(0)
386 subopts.append(dpdkarg)
388 setattr(parser.values, option.dest, subopts)
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)
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)
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)
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)
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")
441 parser.add_option_group(group)
443 options, args = parser.parse_args()
446 if arg not in cmd_names:
447 print("Unknown argument " + arg)
451 set_path(BUILD_CLANG)
458 print("Missing %s." % OVS_SRC)
463 if arg == cmd.__name__:
467 if __name__ == '__main__':