-
Notifications
You must be signed in to change notification settings - Fork 55
/
install.sh
254 lines (222 loc) · 8.49 KB
/
install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#!/bin/bash
set -xeuo pipefail
# This scripts runs in a container with ansible installed.
. ./install/ansible/install_defaults.sh
# Ignore ansible ssh host key checking by default
export ANSIBLE_HOST_KEY_CHECKING=False
# Scheduler provider can be in kubernetes or swarm mode
scheduler_provider=${CONTIV_SCHEDULER_PROVIDER:-"native-swarm"}
# Specify the etcd or cluster store here
# If an etcd or consul cluster store is not provided, we will start an etcd instance
cluster_store=""
install_etcd=true
# Should the scheduler stack (docker swarm or k8s be installed)
install_scheduler=false
# This is the netmaster IP that needs to be provided for the installation to proceed
netmaster=""
contiv_v2plugin_install=""
usage() {
echo "Usage:"
echo "./install.sh -n <netmaster IP> -a <ansible options> -i <install scheduler stack> -m <network mode - standalone/aci> -d <fwd mode - routing/bridge> -v <ACI image>"
echo "This script is to be launched using the install_swarm.sh script. See the documentation for install_swarm.sh for a detailed description of options."
exit 1
}
# Return printing the error
error_ret() {
echo ""
echo "$1"
exit 1
}
while getopts ":n:a:im:d:v:pe:c:s:" opt; do
case $opt in
n)
netmaster=$OPTARG
;;
a)
# make a bash array from the ansible argument
# it interprets single and double quotes from CLI as you might expect
# creating proper bash "words" for eventually passing to ansible
# by letting the array declaration do all the interpreting
# note: ans_opts=($OPTARG) and ans_opts("$OPTARG") do not work
# Example:
# "-v --ssh-common-args=\"-o ProxyCommand='nc -x 192.168.2.1 %h %p'\"
declare -a 'ans_opts=('"$OPTARG"')'
;;
i)
install_scheduler=true
;;
m)
contiv_network_mode=$OPTARG
;;
d)
fwd_mode=$OPTARG
;;
v)
aci_image=$OPTARG
;;
p)
contiv_v2plugin_install=true
;;
e)
# etcd endpoint option
cluster_store_type=etcd
cluster_store_urls=$OPTARG
install_etcd=false
;;
c)
# consul endpoint option
cluster_store_type=consul
cluster_store_urls=$OPTARG
install_etcd=false
;;
s)
# backward compatibility
echo "-s option has been deprecated, use -e or -c instead"
local cluster_store=$OPTARG
if [[ "$cluster_store" =~ ^etcd://.+ ]]; then
cluster_store_type=etcd
cluster_store_urls=$(echo $cluster_store | sed s/etcd/http/)
elif [[ "$cluster_store" =~ ^consul://.+ ]]; then
cluster_store_type=consul
cluster_store_urls=$(echo $cluster_store | sed s/consul/http/)
fi
install_etcd=false
;;
:)
echo "An argument required for $OPTARG was not passed"
usage
;;
?)
usage
;;
esac
done
echo "Generating Ansible configuration"
inventory="/.gen"
inventory_log="/var/contiv/host_inventory.log"
mkdir -p "$inventory"
host_inventory="$inventory/contiv_hosts"
node_info="$inventory/contiv_nodes"
# TODO: use python to generate the inventory
# This python generated inventory contains
# 1. groups and host
# 2. ssh info for each host
# 3. control interface for each host
# 4. data interface for each host
# 5. aci info
# 6. fwd_mode(bridge/routing), net_mode(vlan/vxlan), contiv_network_mode(standalone/aci)
# then below sed against env_file set rest of them, they should be combined as one
./install/genInventoryFile.py "$contiv_config" "$host_inventory" "$node_info" $contiv_network_mode $fwd_mode
if [ "$netmaster" = "" ]; then
# Use the first master node as netmaster
netmaster=$(grep -A 5 netplugin-master "$host_inventory" | grep -m 1 ansible_ssh_host | awk '{print $2}' | awk -F "=" '{print $2}' | xargs)
echo "Using $netmaster as the master node"
fi
if [ "$netmaster" = "" ]; then
usage
fi
if [ "$install_scheduler" = "true" ] && [ "$contiv_v2plugin_install" = "true" ]; then
echo "ERROR: -p and -i are mutually exclusive"
usage
fi
ansible_path=./ansible
env_file=install/ansible/env.json
# Verify ansible can reach all hosts
echo "Verifying ansible reachability"
ansible all "${ans_opts[@]}" -i $host_inventory -m setup -a 'filter=ansible_distribution*' | tee $inventory_log
if egrep -q 'FAIL|UNREACHABLE' $inventory_log; then
echo "WARNING Some of the hosts are not accessible via passwordless SSH"
echo " "
echo "This means either the host is unreachable or passwordless SSH is not"
echo "set up for it. Please resolve this before proceeding."
exit 1
fi
# Get the netmaster control interface
netmaster_control_if=$(grep -A10 $netmaster $contiv_config | grep -m 1 control | awk -F ":" '{print $2}' | xargs)
# Get the ansible node
node_name=$(grep $netmaster $host_inventory | awk '{print $1}' | xargs)
# Get the service VIP for netmaster for the control interface
service_vip=$(ansible $node_name -m setup "${ans_opts[@]}" -i $host_inventory | grep -A 100 ansible_$netmaster_control_if | grep -A 4 ipv4 | grep address | awk -F \" '{print $4}' | xargs)
if [ "$service_vip" == "" ]; then
service_vip=$netmaster
fi
if [ "$cluster_store" = "" ]; then
cluster_store_type="etcd"
cluster_store_urls="http://localhost:2379"
fi
# variables already replaced by build.sh will not pattern match
sed -i.bak 's#__NETMASTER_IP__#'"$service_vip"'#g' "$env_file"
sed -i.bak 's#__CLUSTER_STORE_TYPE__#'"$cluster_store_type"'#g' "$env_file"
sed -i.bak 's#__CLUSTER_STORE_URLS__#'"$cluster_store_urls"'#g' "$env_file"
sed -i.bak 's#__DOCKER_RESET_CONTAINER_STATE__#false#g' "$env_file"
sed -i.bak 's#__DOCKER_RESET_IMAGE_STATE__#false#g' "$env_file"
sed -i.bak 's#__ETCD_CLEANUP_STATE__#false#g' "$env_file"
sed -i.bak 's#__AUTH_PROXY_LOCAL_INSTALL__#false#g' "$env_file"
sed -i.bak 's#__CONTIV_NETWORK_LOCAL_INSTALL__#false#g' "$env_file"
# Copy certs
cp /var/contiv/cert.pem /ansible/roles/auth_proxy/files/
cp /var/contiv/key.pem /ansible/roles/auth_proxy/files/
if [ "$aci_image" != "" ]; then
sed -i.bak 's#__ACI_GW_VERSION__#'"$aci_image"'#g' "$env_file"
fi
if [ "$contiv_v2plugin_install" == "true" ]; then
# docker uses 4789 port for container ingress network, uses 8472 by default to avoid conflicting
# https://docs.docker.com/engine/swarm/ingress/
sed -i.bak 's#__VXLAN_PORT__#8472#g' "$env_file"
sed -i.bak 's#__CONTIV_V2PLUGIN_INSTALL__#true#g' "$env_file"
else
sed -i.bak 's#__VXLAN_PORT__#4789#g' "$env_file"
sed -i.bak 's#__CONTIV_V2PLUGIN_INSTALL__#false#g' "$env_file"
fi
echo "Installing Contiv"
# Always install the base, install the scheduler stack/etcd if required
rm -f $ansible_path/install_plays.yml
touch $ansible_path/install_plays.yml
if [ "$install_scheduler" == "true" ]; then
echo '- include: install_base.yml' >$ansible_path/install_plays.yml
echo '- include: install_docker.yml' >>$ansible_path/install_plays.yml
echo '- include: install_etcd.yml' >>$ansible_path/install_plays.yml
echo '- include: install_scheduler.yml' >>$ansible_path/install_plays.yml
else
if [ "$install_etcd" == "true" ]; then
echo '- include: install_etcd.yml' >$ansible_path/install_plays.yml
fi
fi
# Install contiv & API Proxy
echo '- include: install_contiv.yml' >>$ansible_path/install_plays.yml
echo '- include: install_auth_proxy.yml' >>$ansible_path/install_plays.yml
log_file_name="contiv_install_$(date -u +%m-%d-%Y.%H-%M-%S.UTC).log"
log_file="/var/contiv/$log_file_name"
echo "Ansible extra vars from env.json:"
cat "$env_file"
# run playbook
ansible-playbook "${ans_opts[@]}" -i "$host_inventory" -e@"$env_file" $ansible_path/install_plays.yml | tee $log_file
rm -rf "$env_file.bak"
unreachable=$(grep "PLAY RECAP" -A 9999 $log_file | awk -F "unreachable=" '{print $2}' | awk '{print $1}' | grep -v "0" | xargs)
failed=$(grep "PLAY RECAP" -A 9999 $log_file | awk -F "failed=" '{print $2}' | awk '{print $1}' | grep -v "0" | xargs)
chmod 666 $inventory_log
chmod 666 $env_file
chmod 666 $log_file
set +x
if [ "$unreachable" = "" ] && [ "$failed" = "" ]; then
echo "Installation is complete"
echo "========================================================="
echo " "
echo "Please export DOCKER_HOST=tcp://$netmaster:2375 in your shell before proceeding"
echo "Contiv UI is available at https://$netmaster:10000"
echo "Please use the first run wizard or configure the setup as follows:"
echo " Configure ACI mode (optional)"
echo " netctl global set --fabric-mode aci --vlan-range <start>-<end>"
echo " Create a default network"
echo " netctl net create -t default --subnet=<CIDR> default-net"
echo " For example, netctl net create -t default --subnet=20.1.1.0/24 default-net"
echo " "
echo "========================================================="
exit 0
else
echo "Installation failed"
echo "========================================================="
echo " Please check ./config/$log_file_name for errors."
echo "========================================================="
exit 1
fi