]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-sim.in
ovs-sim: New utility for multi-node OVS and OVN simulation.
[mirror_ovs.git] / utilities / ovs-sim.in
1 #! /usr/bin/env bash
2 #
3 # Copyright (c) 2013, 2015 Nicira, Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at:
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 set -e
18
19 sim_builddir='@abs_builddir@'; export sim_builddir
20 sim_srcdir='@abs_top_srcdir@'; export sim_srcdir
21 interactive=false
22 scripts=
23
24 for option; do
25 case $option in
26 -h|--help)
27 cat <<EOF
28 $0, for starting sandboxed dummy Open vSwitch environments
29 usage: $0 [OPTION...] [SCRIPT...]
30
31 Options:
32 -i, --interactive Prompt for interactive input (default if no SCRIPTs)
33 -h, --help Print this usage message.
34 EOF
35 exit 0
36 ;;
37
38 -i|--i*)
39 interactive=:
40 ;;
41
42 -*)
43 echo "unrecognized option $option (use --help for help)" >&2
44 exit 1
45 ;;
46 *)
47 case $option in
48 /*) ;;
49 *) option=`pwd`/$option ;;
50 esac
51 scripts="$scripts $option"
52 ;;
53 esac
54 shift
55 done
56
57 if test -z "$scripts"; then
58 interactive=:
59 fi
60
61 # Check that we've got proper builddir and srcdir.
62 if test ! -e "$sim_builddir"/vswitchd/ovs-vswitchd; then
63 echo "$sim_builddir/vswitchd/ovs-vswitchd does not exist (need to run \"make\"?)" >&2
64 exit 1
65 fi
66 if test ! -e "$sim_srcdir"/WHY-OVS.md; then
67 echo "$sim_srcdir/WHY-OVS.md does not exist" >&2
68 exit 1
69 fi
70
71 # Put built tools early in $PATH.
72 PATH=$sim_builddir/ovsdb:$sim_builddir/vswitchd:$sim_builddir/utilities:$PATH
73 PATH=$sim_builddir/ovn:$sim_srcdir/ovn:$sim_builddir/ovn/controller:$sim_builddir/ovn/northd:$PATH
74 export PATH
75
76 rm -rf sandbox
77 mkdir sandbox
78 cd sandbox
79 sim_base=`pwd`; export sim_base
80
81 trap_signals() {
82 for signal in 0 1 2 3 13 14 15; do
83 trap "
84 set +e
85 cd '$sim_base' && (kill \`cat */*.pid\`) >/dev/null 2>&1
86 trap - $signal
87 kill -$signal $$" $signal
88 done
89 }
90 export -f trap_signals
91 trap_signals
92
93 sim_setvars() {
94 sandbox=$1
95 OVS_RUNDIR=$sim_base/$1; export OVS_RUNDIR
96 OVS_LOGDIR=$sim_base/$1; export OVS_LOGDIR
97 OVS_DBDIR=$sim_base/$1; export OVS_DBDIR
98 OVS_SYSCONFDIR=$sim_base/$1; export OVS_SYSCONFDIR
99 PS1="|$1: $sim_PS1"
100 }
101 export -f sim_setvars
102
103 as() {
104 case $# in
105 0)
106 echo >&2 "$FUNCNAME: missing arguments (use --help for help)"
107 return 1
108 ;;
109 1)
110 if test "$1" != --help; then
111 sim_setvars $1
112 else
113 cat <<EOF
114 $FUNCNAME: set the default sandbox for Open vSwitch commands
115 usage: $FUNCNAME SANDBOX [COMMAND ARG...]
116 where SANDBOX is the name of the desired sandbox.
117
118 With COMMAND arguments, this command sets the default target for that
119 single command, which it runs directly. Otherwise, it sets the default
120 target for all following commands.
121 EOF
122 fi
123 ;;
124 *)
125 (sim_setvars $1; shift; $@)
126 ;;
127 esac
128 }
129 export -f as
130
131 sim_add() {
132 if test "$1" == --help; then
133 cat <<EOF
134 $FUNCNAME: create a new sandboxed Open vSwitch instance
135 usage: $FUNCNAME SANDBOX
136
137 where SANDBOX is the name of the new sandbox, which will be created in
138 a directory named $sim_base/SANDBOX.
139 Afterward, use "as SANDBOX" to execute OVS commands in the sandbox's
140 context.
141 EOF
142 return 0
143 fi
144 if test $# != 1; then
145 echo >&2 "$FUNCNAME: missing argument (use --help for help)"
146 return 1
147 fi
148
149 set X $1; shift
150 if test $# != 1; then
151 echo >&2 "$FUNCNAME: sandbox name must be a single word"
152 return 1
153 fi
154
155 if test -e "$sim_base/$1"; then
156 echo >&2 "$1 already exists"
157 return 1
158 fi
159
160 # Create sandbox.
161 mkdir "$sim_base"/$1 || return 1
162
163 daemon_opts="--detach --no-chdir --pidfile -vconsole:off --log-file"
164
165 # Create database and start ovsdb-server.
166 touch $sim_base/$1/.conf.db.~lock~
167 as $1 ovsdb-tool create $sim_base/$1/conf.db "$sim_srcdir/vswitchd/vswitch.ovsschema"
168 as $1 ovsdb-server $daemon_opts --remote=punix:"$sim_base"/$1/db.sock
169
170 # Initialize database.
171 as $1 ovs-vsctl --no-wait -- init
172
173 # Start ovs-vswitchd.
174 as $1 ovs-vswitchd $daemon_opts --enable-dummy=system -vvconn -vnetdev_dummy
175 }
176 export -f sim_add
177
178 net_add() {
179 if test "$1" == --help; then
180 cat <<EOF
181 $FUNCNAME: create a new interconnection network
182 usage: $FUNCNAME NETWORK
183
184 where NETWORK is the name of the new network. Interconnection networks
185 are used with net_attach and ovn_attach.
186 EOF
187 return 0
188 fi
189 if test $# != 1; then
190 echo >&2 "$FUNCNAME: missing argument (use --help for help)"
191 return 1
192 fi
193
194 as main ovs-vsctl add-br "$1"
195 }
196 export -f net_add
197
198 net_attach() {
199 if test "$1" == --help; then
200 cat <<EOF
201 $FUNCNAME: attach the default sandbox to an interconnection network
202 usage: $FUNCNAME NETWORK BRIDGE
203
204 Adds a port to BRIDGE within the default sandbox that connects BRIDGE
205 to the interconnection network NETWORK. (Use "as" to set the default
206 sandbox.)
207 EOF
208 return 0
209 fi
210 if test $# != 2; then
211 echo >&2 "$FUNCNAME: wrong number of arguments (use --help for help)"
212 return 1
213 fi
214 if test $sandbox = main; then
215 echo >&2 "$FUNCNAME: can only attach interconnection networks to sandboxes other than main"
216 return 1
217 fi
218
219 local net=$1 bridge=$2
220
221 port=${sandbox}_$bridge
222 as main ovs-vsctl \
223 -- add-port $net "$port" \
224 -- set Interface "$port" options:pstream="punix:$sim_base/main/$port.sock" options:rxq_pcap="$sim_base/main/$port-rx.pcap" options:tx_pcap="$sim_base/main/$port-tx.pcap" options:header=extended
225
226 ovs-vsctl \
227 -- set Interface $bridge options:tx_pcap="$sim_base/$sandbox/$bridge-tx.pcap" options:rxq_pcap="$sim_base/$sandbox/$bridge-rx.pcap" \
228 -- add-port $bridge ${bridge}_$net \
229 -- set Interface ${bridge}_$net options:stream="unix:$sim_base/main/$port.sock" options:rxq_pcap="$sim_base/$sandbox/${bridge}_$net-rx.pcap" options:tx_pcap="$sim_base/$sandbox/${bridge}_$net-tx.pcap" options:header=extended
230 }
231 export -f net_attach
232
233 ovn_start() {
234 if test "$1" == --help; then
235 cat <<EOF
236 $FUNCNAME: start OVN central databases and daemons
237 usage: $FUNCNAME
238
239 This creates and initializes the central OVN databases (northbound and
240 southbound), starts their ovsdb-server daemons, and starts the ovn-northd
241 daemon.
242 EOF
243 return 0
244 fi
245 if test $# != 0; then
246 echo >&2 "$FUNCNAME: no arguments accepted (use --help for help)"
247 return 1
248 fi
249
250 if test -d ovn-sb || test -d ovn-nb; then
251 echo >&2 "OVN already started"
252 exit 1
253 fi
254
255 daemon_opts="--detach --no-chdir --pidfile -vconsole:off --log-file"
256 for db in ovn-sb ovn-nb; do
257 mkdir "$sim_base"/$db
258 touch "$sim_base"/$db/.$db.db.~lock~
259 as $db ovsdb-tool create "$sim_base"/$db/$db.db "$sim_srcdir"/ovn/$db.ovsschema
260 as $db ovsdb-server $daemon_opts --remote=punix:"$sim_base"/$db/$db.sock "$sim_base"/$db/$db.db
261 done
262
263 OVN_NB_DB=unix:$sim_base/ovn-nb/ovn-nb.sock; export OVN_NB_DB
264
265 mkdir "$sim_base"/northd
266 as northd ovn-northd $daemon_opts \
267 --ovnnb-db=unix:"$sim_base"/ovn-nb/ovn-nb.sock \
268 --ovnsb-db=unix:"$sim_base"/ovn-sb/ovn-sb.sock
269 }
270 export -f ovn_start
271
272 ovn_attach() {
273 if test "$1" == --help; then
274 cat <<EOF
275 $FUNCNAME: attach default sandbox to an interconnection network for OVN
276 usage: $FUNCNAME NETWORK BRIDGE IP [MASKLEN]
277
278 This starts by doing everything that net_attach does. Then it configures the
279 specified IP and MASKLEN (e.g. 192.168.0.1 and 24) on BRIDGE and starts
280 and configures ovn-controller.
281
282 MASKLEN defaults to 24 if it is not specified.
283 EOF
284 return 0
285 fi
286 if test $# != 3 && test $# != 4; then
287 echo >&2 "$FUNCNAME: wrong number of arguments (use --help for help)"
288 return 1
289 fi
290
291 local net=$1 bridge=$2 ip=$3 masklen=${4-24}
292 net_attach $net $bridge || return $?
293
294 ovs-appctl netdev-dummy/ip4addr $bridge $ip/$masklen >/dev/null
295 ovs-appctl ovs/route/add $ip/$masklen $bridge > /dev/null
296 ovs-vsctl \
297 -- set Open_vSwitch . external-ids:system-id=$sandbox \
298 -- set Open_vSwitch . external-ids:ovn-remote=unix:$sim_base/ovn-sb/ovn-sb.sock \
299 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
300 -- set Open_vSwitch . external-ids:ovn-encap-ip=$ip\
301 -- add-br br-int \
302 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
303 ovn-controller --detach --no-chdir --pidfile -vconsole:off --log-file
304 }
305 export -f ovn_attach
306
307 # Easy access to OVS manpages.
308 mkdir $sim_base/man
309 mandir=`cd $sim_base/man && pwd`
310 (cd "$sim_builddir" && ${MAKE-make} install-man mandir=$mandir >/dev/null)
311 MANPATH=$mandir:; export MANPATH
312
313 export scripts
314 export interactive
315 rc='
316 if [ -f /etc/bashrc ]; then
317 . /etc/bashrc
318 fi
319 if [ -f ~/.bashrc ]; then
320 . ~/.bashrc
321 fi
322
323 trap_signals
324 sim_PS1=$PS1
325 sim_add main
326 as main
327
328 for script in $scripts; do
329 . $script || exit $?
330 done
331
332 $interactive || exit 0
333
334 cat <<EOF
335 ______________________________________________________________________
336 |
337 | You are running in a nested shell environment meant for Open vSwitch
338 | and OVN testing in simulation. The OVS manpages are available via
339 | "man". Please see ovs-sim(1) for more information.
340 |
341 | Exit the shell to kill the running daemons and leave the simulation
342 | environment.
343 EOF
344 '
345
346 status=0; bash --rcfile <(echo "$rc") || status=$?
347
348 if $interactive; then
349 cat <<EOF
350 |______________________________________________________________________
351
352 EOF
353 fi
354
355 exit $status