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