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