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