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