2 # Copyright (c) 2013, 2014, 2015 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
30 BUILD_GCC = OVS_SRC + "/_build-gcc"
31 BUILD_CLANG = OVS_SRC + "/_build-clang"
38 PATH = "%(ovs)s/utilities:%(ovs)s/ovsdb:%(ovs)s/vswitchd" % {"ovs": build}
40 ENV["PATH"] = PATH + ":" + ENV["PATH"]
42 def _sh(*args, **kwargs):
43 print "------> " + " ".join(args)
44 shell = len(args) == 1
45 if kwargs.get("capture", False):
46 proc = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell)
47 return proc.stdout.readlines()
48 elif kwargs.get("check", True):
49 subprocess.check_call(args, shell=shell)
51 subprocess.call(args, shell=shell)
55 return _sh("uname", "-r", capture=True)[0].strip()
62 os.remove(OVS_SRC + "/Makefile")
66 configure = ["../configure", "--prefix=" + ROOT, "--localstatedir=" + ROOT,
67 "--with-logdir=%s/log" % ROOT, "--with-rundir=%s/run" % ROOT,
68 "--enable-silent-rules", "--with-dbdir=" + ROOT, "--silent"]
70 cflags = "-g -fno-omit-frame-pointer"
73 configure.append("--enable-Werror")
75 if options.cache_time:
76 configure.append("--enable-cache-time")
79 configure.append("--mandir=" + options.mandir)
82 configure.append("--with-dpdk=" + options.with_dpdk)
83 cflags += " -Wno-cast-align -Wno-bad-function-cast" # DPDK warnings.
85 if options.optimize is None:
88 cflags += " -O%s" % str(options.optimize)
90 ENV["CFLAGS"] = cflags
97 pass # Directory exists.
100 _sh(*(configure + ["--with-linux=/lib/modules/%s/build" % uname()]))
103 _sh("clang --version", check=True)
105 except subprocess.CalledProcessError:
109 _sh("sparse --version", check=True)
111 except subprocess.CalledProcessError:
116 os.mkdir(BUILD_CLANG)
118 pass # Directory exists.
121 os.chdir(BUILD_CLANG)
131 make_str = "\t$(MAKE) -C %s $@\n"
133 mf = open(OVS_SRC + "/Makefile", "w")
134 mf.write("all:\n%:\n")
136 mf.write(make_str % BUILD_CLANG)
137 mf.write("\t$(MAKE) -C %s %s $@\n" % (BUILD_GCC, c1))
138 mf.write("\ncheck-valgrind:\n")
139 mf.write("\ncheck:\n")
140 mf.write(make_str % BUILD_GCC)
142 commands.append(conf)
146 make = "make -s -j 8 " + args
148 commands.append(make)
154 flags += "-j%d " % options.jobs
158 for arg in str.split(options.tests):
162 flags += "-k %s " % arg
163 ENV["TESTSUITEFLAGS"] = flags
165 commands.append(check)
169 ctags = ['ctags', '-R', '-f', '.tags']
172 _sh(*(ctags + ['--exclude="datapath/"']))
175 _sh(*ctags) # Some versions of ctags don't have --exclude
180 _sh('cscope', '-R', '-b')
187 for proc in ["ovs-vswitchd", "ovsdb-server"]:
188 if os.path.exists("%s/run/openvswitch/%s.pid" % (ROOT, proc)):
189 _sh("ovs-appctl", "-t", proc, "exit", check=False)
191 _sh("sudo", "killall", "-q", "-2", proc, check=False)
192 commands.append(kill)
197 if os.path.exists(ROOT):
199 for dp in _sh("ovs-dpctl dump-dps", capture=True):
200 _sh("ovs-dpctl", "del-dp", dp.strip())
201 commands.append(reset)
206 for d in ["log", "run"]:
207 d = "%s/%s" % (ROOT, d)
208 shutil.rmtree(d, ignore_errors=True)
211 pki_dir = ROOT + "/pki"
212 if not os.path.exists(pki_dir):
216 _sh("ovs-pki req+sign ovsclient")
219 if not os.path.exists(ROOT + "/conf.db"):
220 _sh("ovsdb-tool", "create", ROOT + "/conf.db",
221 OVS_SRC + "/vswitchd/vswitch.ovsschema")
223 opts = ["--pidfile", "--log-file"]
225 _sh(*(["ovsdb-server",
226 "--remote=punix:%s/run/db.sock" % ROOT,
227 "--remote=db:Open_vSwitch,Open_vSwitch,manager_options",
228 "--private-key=db:Open_vSwitch,SSL,private_key",
229 "--certificate=db:Open_vSwitch,SSL,certificate",
230 "--bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert",
231 "--detach", "-vconsole:off"] + opts))
233 _sh("ovs-vsctl --no-wait --bootstrap set-ssl %s/ovsclient-privkey.pem" \
234 " %s/ovsclient-cert.pem %s/vswitchd.cacert"
235 % (pki_dir, pki_dir, pki_dir))
236 version = _sh("ovs-vsctl --no-wait --version", capture=True)
237 version = version[0].strip().split()[3]
238 root_uuid = _sh("ovs-vsctl --no-wait --bare list Open_vSwitch",
239 capture=True)[0].strip()
240 _sh("ovs-vsctl --no-wait set Open_vSwitch %s ovs_version=%s"
241 % (root_uuid, version))
243 build = BUILD_CLANG if options.clang else BUILD_GCC
244 cmd = [build + "/vswitchd/ovs-vswitchd"]
248 cmd.extend(options.dpdk)
252 cmd = ["gdb", "--args"] + cmd
253 elif options.valgrind:
254 cmd = ["valgrind", "--track-origins=yes", "--leak-check=full",
255 "--suppressions=%s/tests/glibc.supp" % OVS_SRC,
256 "--suppressions=%s/tests/openssl.supp" % OVS_SRC] + cmd
259 opts = opts + ["-vconsole:off", "--detach", "--enable-dummy"]
265 if not os.path.exists("/lib/modules"):
266 print "Missing modules directory. Is this a Linux system?"
270 _sh("rmmod", "openvswitch")
271 except subprocess.CalledProcessError, e:
272 pass # Module isn't loaded
275 _sh("rm -f /lib/modules/%s/extra/openvswitch.ko" % uname())
276 _sh("rm -f /lib/modules/%s/extra/vport-*.ko" % uname())
277 except subprocess.CalledProcessError, e:
278 pass # Module isn't installed
282 make("modules_install")
284 _sh("modprobe", "openvswitch")
285 _sh("dmesg | grep openvswitch | tail -1")
286 _sh("find /lib/modules/%s/ -iname vport-*.ko -exec insmod '{}' \;" % uname())
287 commands.append(modinst)
291 print "export PATH=" + ENV["PATH"]
299 This program is designed to help developers build and run Open vSwitch without
300 necessarily needing to know the gory details. Given some basic requirements
301 (described below), it can be used to build and run Open vSwitch, keeping
302 runtime files in the user's home directory.
305 # This section can be run as a script on ubuntu systems.
307 # First install the basic requirements needed to build Open vSwitch.
308 sudo apt-get install git build-essential libtool autoconf pkg-config \\
309 libssl-dev gdb linux-headers-`uname -r`
311 # Next clone the Open vSwitch source.
312 git clone https://github.com/openvswitch/ovs.git %(ovs)s
314 # Setup environment variables.
320 # Install the kernel module
321 sudo insmod %(ovs)s/datapath/linux/openvswitch.ko
323 # If needed, manually load all required vport modules:
324 sudo insmod %(ovs)s/datapath/linux/vport-vxlan.ko
325 sudo insmod %(ovs)s/datapath/linux/vport-geneve.ko
332 conf - Configure the ovs source.
333 make - Build the source (must have been configured).
334 check - Run the unit tests.
335 tag - Run ctags and cscope over the source.
336 kill - Kill all running instances of ovs.
337 reset - Reset any runtime configuration in %(run)s.
339 modinst - Build ovs and install the kernel module.
340 env - Print the required path environment variable.
341 doc - Print this message.
342 """ % {"ovs": OVS_SRC, "v": sys.argv[0], "run": ROOT}
346 def parse_subargs(option, opt_str, value, parser):
350 dpdkarg = parser.rargs.pop(0)
353 subopts.append(dpdkarg)
355 setattr(parser.values, option.dest, subopts)
361 description = "Open vSwitch developer configuration. Try `%prog doc`."
362 cmd_names = [c.__name__ for c in commands]
363 parser = optparse.OptionParser(usage="usage: %prog"
364 + " [options] [%s] ..."
365 % "|".join(cmd_names),
366 description=description)
368 group = optparse.OptionGroup(parser, "conf")
369 group.add_option("--disable-Werror", dest="werror", action="store_false",
370 default=True, help="compile without the Werror flag")
371 group.add_option("--cache-time", dest="cache_time",
372 action="store_true", help="configure with cached timing")
373 group.add_option("--mandir", dest="mandir", metavar="MANDIR",
374 help="configure the man documentation install directory")
375 group.add_option("--with-dpdk", dest="with_dpdk", metavar="DPDK_BUILD",
376 help="built with dpdk libraries located at DPDK_BUILD");
377 parser.add_option_group(group)
379 group = optparse.OptionGroup(parser, "Optimization Flags")
380 for i in ["s", "g"] + range(4) + ["fast"]:
381 group.add_option("--O%s" % str(i), dest="optimize",
382 action="store_const", const=i,
383 help="compile with -O%s" % str(i))
384 parser.add_option_group(group)
386 group = optparse.OptionGroup(parser, "check")
387 group.add_option("-j", "--jobs", dest="jobs", metavar="N", type="int",
388 help="Run N tests in parallel")
389 group.add_option("--tests", dest="tests", metavar="FILTER",
390 help="""run specific tests and/or a test category
391 eg, --tests=\"1-10 megaflow\"""")
392 parser.add_option_group(group)
394 group = optparse.OptionGroup(parser, "run")
395 group.add_option("-g", "--gdb", dest="gdb", action="store_true",
396 help="run ovs-vswitchd under gdb")
397 group.add_option("--valgrind", dest="valgrind", action="store_true",
398 help="run ovs-vswitchd under valgrind")
399 group.add_option("--dpdk", dest="dpdk", action="callback",
400 callback=parse_subargs,
401 help="run ovs-vswitchd with dpdk subopts (ended by --)")
402 group.add_option("--clang", dest="clang", action="store_true",
403 help="Use binaries built by clang")
405 parser.add_option_group(group)
407 options, args = parser.parse_args()
410 if arg not in cmd_names:
411 print "Unknown argument " + arg
415 set_path(BUILD_CLANG)
422 print "Missing %s." % OVS_SRC
427 if arg == cmd.__name__:
431 if __name__ == '__main__':