provision.sh revision 17fdb321
1#!/usr/bin/env bash
2#
3# Copyright (c) 2016 Intel Corporation
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
16PACKAGE_REPO="https://nexus.fd.io/content/repositories/fd.io.stable.1704.ubuntu.xenial.main/"
17HOME_DIR="/home/$USER"
18RC_LOCAL="/etc/rc.local"
19SSH_OPTIONS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
20APT_PROXY_CONF="/etc/apt/apt.conf.d/01proxy"
21ENV_FILE="/etc/environment"
22UNAMER=$(uname -r)
23
24# LXC gives backend interfaces horrible names, give them a better name.
25function rename_veth_interface() {
26
27    local cntr="$1"
28    local nifname="$2"
29
30    ifr_index=`sudo lxc-attach -n $cntr -- ip -o link | tail -n 1 | awk -F : '{print $1}'`
31    ifr_index=$((ifr_index+1))
32
33    for dir in /sys/class/net/*/
34    do
35        ifindex=`cat $dir/ifindex`
36        if [ $ifindex == $ifr_index ]
37            then ifname=`basename $dir`
38        fi
39    done
40
41    sudo ip link set $ifname down
42    sudo ip link set $ifname name $nifname
43    sudo ip link set $nifname up
44}
45
46function add_to_rc_local()
47{
48    local str="$1"
49
50    echo -e "$str" | sudo tee -a $RC_LOCAL
51}
52
53function sudo_exec() {
54
55   CMD="$1"
56   add_to_rc_local="${2:-0}"
57
58   if [ "$add_to_rc_local" == "1" ]; then
59       add_to_rc_local "$CMD"
60   fi
61
62   CMD="sudo $CMD"
63
64   eval "${CMD}"
65}
66
67function lxc_exec() {
68
69    cntr="$1"
70    rCMD="$2"
71    add_to_rc_local="${3:-0}"
72 
73    CMD="lxc-attach -n $cntr  -- $rCMD"
74
75    echo "$CMD"
76    sudo_exec "$CMD" $add_to_rc_local
77}
78
79function get_field() {
80    file="$1"
81    field="$2"
82
83    value=$(grep $field $file | awk -F : '{print $2}' | sed -e 's/^[ ]*//' | sed -e 's/kernver/"$UNAMER"/')
84    echo $value
85}
86
87echo "deb $PACKAGE_REPO ./" | sudo tee -a /etc/apt/sources.list.d/99fd.io.list
88sudo apt-get -qq update
89sudo apt-get -qq install -y --force-yes linux-image-extra-$(uname -r) lxc bridge-utils tmux
90sudo apt-get -qq install -y --force-yes vpp vpp vpp-dpdk-dkms vpp-plugins
91
92#Disable DPDK to make memory requirements more modest
93sudo sed -i_dpdk '47,52d' /etc/vpp/startup.conf
94echo -e "plugins {\n\tplugin dpdk_plugin.so { disable }\n}" | sudo tee -a /etc/vpp/startup.conf
95
96#Fix VPP on the host to use 32 hugepages
97echo -e "heapsize 64M" | sudo tee -a /etc/vpp/startup.conf
98sudo sed -i 's/vm.nr_hugepages=1024/vm.nr_hugepages=32/' /etc/sysctl.d/80-vpp.conf
99sudo sed -i 's/kernel.shmmax=2147483648/kernel.shmmax=67018864/' /etc/sysctl.d/80-vpp.conf
100
101#Provision containers with two network connections, second connection is unconnected
102echo -e "lxc.network.name=veth0" | sudo tee -a /etc/lxc/default.conf
103echo -e "lxc.network.type = veth" | sudo tee -a /etc/lxc/default.conf
104echo -e "lxc.network.hwaddr = 00:17:3e:xx:xx:xx\n" | sudo tee -a /etc/lxc/default.conf
105echo -e "lxc.network.name=veth_link1" | sudo tee -a /etc/lxc/default.conf
106
107sudo lxc-checkconfig
108
109# update rc.local to be interpreted with bash
110sudo sed -i '1 s/^.*$/#!\/bin\/bash/g' $RC_LOCAL
111# remove the exit 0 from rc.local.
112sudo sed -i 's/exit 0//' $RC_LOCAL
113
114# add rename_veth_interface to /etc/rc.local
115read -r -d '' TMP_RVI <<'EOF'
116function rename_veth_interface() {
117
118    local cntr="$1"
119    local nifname="$2"
120
121    ifr_index=`sudo lxc-attach -n $cntr -- ip -o link | tail -n 1 | awk -F : '{print $1}'`
122    ifr_index=$((ifr_index+1))
123
124    for dir in /sys/class/net/*/
125    do
126        ifindex=`cat $dir/ifindex`
127        if [ $ifindex == $ifr_index ]
128            then ifname=`basename $dir`
129        fi
130    done
131
132    sudo ip link set $ifname down
133    sudo ip link set $ifname name $nifname
134    sudo ip link set $nifname up
135}
136EOF
137add_to_rc_local "$TMP_RVI"
138
139# For the moment just cross connect the host, will more clever later.
140read -r -d '' TMP_CCI <<'EOF'
141function cross_connect_interfaces() {
142
143   sudo vppctl create host-interface name veth-cone
144   sudo vppctl create host-interface name veth-ctwo
145   sudo vppctl set int l2 xconnect host-veth-cone host-veth-ctwo
146   sudo vppctl set int l2 xconnect host-veth-ctwo host-veth-cone
147   sudo vppctl set int state host-veth-cone up
148   sudo vppctl set int state host-veth-ctwo up
149}
150EOF
151add_to_rc_local "$TMP_CCI"
152
153ssh-keygen -t rsa -b 1024 -N "" -f ~/.ssh/id_rsa
154openssh_pubkey=`cat ~/.ssh/id_rsa.pub`
155
156#Ensure that virtual bridge comes up after boot
157add_to_rc_local "#autostart vpp on the host"
158sudo_exec "service vpp start" 1
159
160for f in $(ls /vagrant/containers/*.cntr)
161do
162    i=$(basename $f | sed s/.cntr//)
163    dist=$(get_field $f DIST)
164    ver=$(get_field $f VER)
165    packages=$(get_field $f PACKAGES)
166    pip=$(get_field $f PIP)
167    provision_file="/vagrant/containers/"$i".provision.sh"
168 
169    sudo lxc-create -t download -n $i -- --dist $dist --release $ver --arch amd64
170
171    #autostart container after a reboot (standard lxc way doesn't work).
172    add_to_rc_local "#autostart container $i"
173
174    sudo_exec "lxc-start -n $i -d" 1
175	
176    lxc_exec $i "resolvconf -d veth0"
177
178    #dhcp after boot
179    lxc_exec $i "dhclient veth0" 1
180
181    #insert delay to allow completion before starting ssh service
182    add_to_rc_local "sleep 1"
183
184    lxc_exec $i "apt-get -qq install -y git openssh-server"
185    lxc_exec $i "apt-get -qq update"
186
187    lxc_exec $i "adduser --disabled-password --gecos \"\" $USER"
188
189    lxc_exec $i "mkdir -p /root/.ssh/"
190    lxc_exec $i "mkdir -p $HOME_DIR/.ssh/"
191
192    lxc_exec $i "sh -c 'echo $openssh_pubkey >> /root/.ssh/authorized_keys'"
193    lxc_exec $i "sh -c 'echo $openssh_pubkey >> $HOME_DIR/.ssh/authorized_keys'"
194
195    lxc_exec $i "chmod 0600 /root/.ssh/authorized_keys"
196    lxc_exec $i "chmod 0600 $HOME_DIR/.ssh/authorized_keys"
197
198    lxc_exec $i "chown -R $USER.$USER $HOME_DIR/.ssh/"
199
200    lxc_exec $i "sh -c 'echo \"%$USER ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/10_$USER'"
201
202    lxc_exec $i "update-alternatives --install /bin/sh sh /bin/bash 100"
203
204    lxc_exec $i "apt-get -qq install $packages"
205
206    lxc_exec $i "service ssh restart" 1
207
208    ip_address=$(sudo lxc-ls -f | grep $i | awk '{print $5}')
209    echo $ip_address $i | sudo tee -a /etc/hosts
210
211    if [ -s $APT_PROXY_CONF ]
212    then
213        scp $SSH_OPTIONS $APT_PROXY_CONF root@$i:$APT_PROXY_CONF
214    fi
215
216    if [ -s $ENV_FILE ]
217    then
218        scp $SSH_OPTIONS $ENV_FILE root@$i:$ENV_FILE
219    fi
220
221    #rename the backend interface to something sensible
222    rename_veth_interface $i "veth-$i"
223    add_to_rc_local "rename_veth_interface $i 'veth-$i'"
224
225    if [ -s $provision_file ]
226    then
227       tmpname=$(mktemp)".sh"
228       scp $SSH_OPTIONS $provision_file $USER@$i:$tmpname
229       ssh $SSH_OPTIONS $USER@$i "sh -c $tmpname"
230    fi
231
232    #install any pip packages
233    if [ ! -z "$pip" ]
234    then
235       ssh -t $SSH_OPTIONS $USER@$i "sudo -E pip install $pip"
236    fi
237
238done
239
240#cross connect the containers
241add_to_rc_local "sleep 1"
242add_to_rc_local "cross_connect_interfaces"
243
244add_to_rc_local "exit 0"
245
246#setting password to username
247echo "$USER:$USER" | sudo chpasswd
248
249echo -e "List of containers deployed in the dev environment:" | sudo tee -a /etc/motd
250for f in $(ls /vagrant/containers/*.cntr)
251do
252     i=$(basename $f | sed s/.cntr//)
253     desc=$(get_field $f DESC)
254     echo -e $i":\t"$desc | sudo tee -a /etc/motd
255done
256
257echo "To access the environment, type 'vagrant ssh'"
258