2 # Copyright 2017 AT&T Intellectual Property, Inc
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 #. What this is: Setup script for the VES monitoring framework.
17 #. With this script VES support can be installed in one or more hosts, with:
18 #. - a dedicated or shared Kafka server for collection of events from collectd
19 #. - VES collectd agents running in host or guest mode
20 #. - VES monitor (test collector)
21 #. A typical multi-node install could involve these steps:
22 #. - Install the VES collector (for testing) on one of the hosts, or use a
23 #. pre-installed VES collector e.g. from the ONAP project.
24 #. - Install Kafka server on one of the hosts, or use a pre-installed server
25 #. accessible from the agent hosts.
26 #. - Install collectd on each host.
27 #. - Install the VES agent on each host.
28 #. - As needed, install the VES agent on each virtual host. This could include
29 #. pre-installed VES agents in VM or container images, which are configured
30 #. upon virtual host deployment, or agent install/config as part of virtual
31 #. host deploy. NOTE: support for pre-installed VES agents is a WIP.
34 #. - Ubuntu Xenial (Centos support to be provided)
35 #. - passwordless sudo setup for user running this script
36 #. - shell environment variables setup as below (for non-default setting)
37 #. ves_mode: install mode (node|guest) for VES collectd plugin (default: node)
38 #. ves_host: VES collector IP or hostname (default: 127.0.0.1)
39 #. ves_port: VES collector port (default: 30000)
40 #. ves_path: REST path optionalRoutingPath element (default: empty)
41 #. ves_topic: REST path topicName element (default: empty)
42 #. ves_https: use HTTPS instead of HTTP (default: false)
43 #. ves_user: username for basic auth with collector (default: empty)
44 #. ves_pass: password for basic auth with collector (default: empty)
45 #. ves_interval: frequency in sec for collectd data reports (default: 20)
46 #. ves_version: VES API version (default: 5.1)
47 #. ves_kafka_port: kafka port (default: 9092)
48 #. ves_kafka_host: kafka host IP or hostname (default: 127.0.0.1)
51 #. git clone https://gerrit.opnfv.org/gerrit/ves /tmp/ves
52 #. bash /tmp/ves/ves-setup.sh <collector|kafka|collectd|agent>
53 #. collector: setup VES collector (test collector)
54 #. kafka: setup kafka server for VES events from collect agent(s)
55 #. collectd: setup collectd with libvirt plugin, as a kafka publisher
56 #. agent: setup VES agent in host or guest mode, as a kafka consumer
57 #. See demo_deploy.sh in this repo for a recommended sequence of the above.
59 #. Status: this is a work in progress, under test.
61 # http://docs.opnfv.org/en/latest/submodules/barometer/docs/release/userguide/collectd.ves.userguide.html
69 f=$(caller 0 | awk '{print $2}')
70 l=$(caller 0 | awk '{print $1}')
72 echo "$f:$l ($(date)) $1"
75 function common_prereqs() {
76 log "install common prerequisites"
77 if [[ ! -f /.dockerenv ]]; then dosudo="sudo"; fi
78 $dosudo apt-get update
79 $dosudo apt-get install -y git
81 $dosudo apt-get install -y default-jre
82 $dosudo apt-get install -y zookeeperd
83 $dosudo apt-get install -y python-pip
84 $dosudo pip install kafka-python
85 # Required for building collectd
86 $dosudo apt-get install -y pkg-config
89 function setup_env() {
90 if [[ ! -d /tmp/ves ]]; then mkdir /tmp/ves; fi
92 if [[ ! -f /tmp/ves/ves_env.sh ]]; then
93 cat <<EOF >/tmp/ves/ves_env.sh
95 ves_mode="${ves_mode:=node}"
96 ves_host="${ves_host:=127.0.0.1}"
97 ves_hostname="${ves_hostname:=localhost}"
98 ves_port="${ves_port:=30000}"
99 ves_path="${ves_path:=}"
100 ves_topic="${ves_topic:=}"
101 ves_https="${ves_https:=false}"
102 ves_user="${ves_user:=}"
103 ves_pass="${ves_pass:=}"
104 ves_interval="${ves_interval:=20}"
105 ves_version="${ves_version:=5.1}"
106 ves_kafka_host="${ves_kafka_host:=127.0.0.1}"
107 ves_kafka_port="${ves_kafka_port:=9092}"
118 export ves_kafka_hostame
119 export ves_kafka_port
122 source /tmp/ves/ves_env.sh
125 function setup_kafka() {
126 log "setup kafka server"
132 log "get and unpack kafka_2.11-$ver.tgz"
133 wget "http://www-eu.apache.org/dist/kafka/$ver/kafka_2.11-$ver.tgz"
134 tar -xvzf kafka_2.11-$ver.tgz
136 log "set delete.topic.enable=true"
137 sed -i -- 's/#delete.topic.enable=true/delete.topic.enable=true/' \
138 kafka_2.11-$ver/config/server.properties
139 grep delete.topic.enable kafka_2.11-$ver/config/server.properties
140 # TODO: Barometer VES guide to clarify hostname must be in /etc/hosts
141 sudo nohup kafka_2.11-$ver/bin/kafka-server-start.sh \
142 kafka_2.11-$ver/config/server.properties \
143 > kafka_2.11-$ver/kafka.log 2>&1 &
146 function setup_kafka_client() {
147 log "Install Apache Kafka C/C++ client library"
148 if [[ ! -f /.dockerenv ]]; then dosudo="sudo"; fi
149 $dosudo apt-get install -y build-essential
150 git clone https://github.com/edenhill/librdkafka.git ~/librdkafka
152 git checkout -b v0.9.5 v0.9.5
153 # TODO: Barometer VES guide to clarify specific prerequisites for Ubuntu
154 $dosudo apt-get install -y libpthread-stubs0-dev
155 $dosudo apt-get install -y libssl-dev
156 $dosudo apt-get install -y libsasl2-dev
157 $dosudo apt-get install -y liblz4-dev
158 ./configure --prefix=/usr
163 function setup_collectd() {
168 log "cleanup any previous failed install"
169 sudo rm -rf ~/collectd-virt
170 sudo rm -rf ~/librdkafka
171 sudo rm -rf ~/collectd
175 log "Build collectd with Kafka support"
176 git clone https://github.com/collectd/collectd.git ~/collectd
178 # TODO: Barometer VES guide to clarify specific prerequisites for Ubuntu
179 sudo apt-get install -y flex bison
180 sudo apt-get install -y autoconf
181 sudo apt-get install -y libtool
183 ./configure --with-librdkafka=/usr --without-perl-bindings --enable-perl=no
187 # TODO: Barometer VES guide to clarify collectd.service is correct
188 log "install collectd as a service"
189 sed -i -- 's~ExecStart=/usr/sbin/collectd~ExecStart=/opt/collectd/sbin/collectd~'\
190 contrib/systemd.collectd.service
191 sed -i -- 's~EnvironmentFile=-/etc/sysconfig/collectd~EnvironmentFile=-/opt/collectd/etc/~'\
192 contrib/systemd.collectd.service
193 sed -i -- 's~EnvironmentFile=-/etc/default/collectd~EnvironmentFile=-/opt/collectd/etc/~'\
194 contrib/systemd.collectd.service
195 sed -i -- 's~CapabilityBoundingSet=~CapabilityBoundingSet=CAP_SETUID CAP_SETGID~'\
196 contrib/systemd.collectd.service
198 sudo cp contrib/systemd.collectd.service /etc/systemd/system/
199 cd /etc/systemd/system/
200 sudo mv systemd.collectd.service collectd.service
201 sudo chmod +x collectd.service
202 sudo systemctl daemon-reload
203 sudo systemctl start collectd.service
205 log "setup VES collectd config for VES $ves_mode mode"
206 if [[ "$ves_mode" == "node" ]]; then
207 # TODO: Barometer VES guide to clarify prerequisites install for Ubuntu
208 log "setup additional prerequisites for VES host mode"
209 sudo apt-get install -y libxml2-dev libpciaccess-dev libyajl-dev \
212 # TODO: install libvirt from source to enable all features per
213 # http://docs.opnfv.org/en/latest/submodules/barometer/docs/release/userguide/feature.userguide.html#virt-plugin
214 sudo systemctl start libvirtd
216 # TODO: supposed to be merged with main collectd repo, but without this
217 # collectd still fails "plugin_load: Could not find plugin "virt" in /opt/collectd/lib/collectd"
218 rm -rf /tmp/ves/collectd-virt
219 git clone https://github.com/maryamtahhan/collectd /tmp/ves/collectd-virt
220 cd /tmp/ves/collectd-virt
222 ./configure --enable-syslog --enable-logfile --enable-debug
226 # TODO: fix for journalctl -xe report "... is marked executable"
227 sudo chmod 744 /etc/systemd/system/collectd.service
229 cat <<EOF | sudo tee -a /opt/collectd/etc/collectd.conf
241 DataDir "/work-dir/collectd/install/var/lib/csv"
247 # Connection "qemu:///system"
249 # HostnameFormat uuid
250 # PluginInstanceFormat name
251 # ExtraStats "cpu_util"
254 LoadPlugin target_set
255 LoadPlugin match_regex
257 <Rule "mark_memory_as_host">
262 PluginInstance "host"
271 ValuesPercentage true
280 LoadPlugin write_kafka
282 Property "metadata.broker.list" "$ves_kafka_host:$ves_kafka_port"
289 cat <<EOF | sudo tee -a /opt/collectd/etc/collectd.conf
303 ValuesPercentage true
317 LoadPlugin write_kafka
319 Property "metadata.broker.list" "$ves_kafka_host:$ves_kafka_port"
325 LoadPlugin target_set
326 LoadPlugin match_regex
328 <Rule "mark_memory_as_guest">
333 PluginInstance "guest"
340 if [[ $(grep -c $ves_hostname /etc/hosts) -eq 0 ]]; then
341 log "add to /etc/hosts: $ves_kafka_host $ves_hostname"
342 echo "$ves_kafka_host $ves_hostname" | sudo tee -a /etc/hosts
344 log "restart collectd to apply updated config"
345 sudo systemctl restart collectd
348 function setup_agent() {
349 log "setup VES agent"
350 if [[ ! -f /.dockerenv ]]; then
351 log "start the ves-agent container"
352 sudo docker run -it -d -v /tmp/ves:/opt/ves --name=ves-agent \
353 ubuntu:xenial /bin/bash
354 log "execute the agent setup script in the container"
355 sudo docker exec ves-agent /bin/bash /opt/ves/ves-setup.sh agent
358 log "setup the VES environment"
359 source /opt/ves/ves_env.sh
360 log "install agent prerequisites"
365 log "clone OPNFV Barometer"
366 rm -rf /opt/ves/barometer
367 git clone https://gerrit.opnfv.org/gerrit/barometer /opt/ves/barometer
369 cd /opt/ves/barometer
370 git fetch https://gerrit.opnfv.org/gerrit/barometer refs/changes/27/47427/1 && git checkout FETCH_HEAD
372 log "setup ves_app_config.conf"
373 source /opt/ves/ves_env.sh
374 cd /opt/ves/barometer/3rd_party/collectd-ves-app/ves_app
375 cat <<EOF >ves_app_config.conf
381 UseHttps = $ves_https
384 SendEventInterval = $ves_interval
385 ApiVersion = $ves_version
386 KafkaPort = $ves_kafka_port
387 KafkaBroker = $ves_kafka_host
390 # log "add guest.yaml measurements to host.yaml (enables actual host data)"
391 # tail --lines=+24 guest.yaml >>host.yaml
393 log "start VES agent"
394 echo "$ves_kafka_host $ves_hostname">>/etc/hosts
395 nohup python ves_app.py --events-schema=$ves_mode.yaml --loglevel ERROR \
396 --config=ves_app_config.conf > /opt/ves/ves_app.stdout.log 2>&1 &
400 function setup_collector() {
401 log "setup collector"
402 log "install prerequistes"
403 sudo apt-get install -y jq
405 ves_hostname=$HOSTNAME
407 ves_host=$(ip route get 8.8.8.8 | awk '{print $NF; exit}')
411 log "setup influxdb container"
412 sudo docker run -d --name=ves-influxdb -p 8086:8086 influxdb
413 status=$(sudo docker inspect ves-influxdb | jq -r '.[0].State.Status')
414 while [[ "x$status" != "xrunning" ]]; do
415 log "InfluxDB container state is ($status)"
417 status=$(sudo docker inspect ves-influxdb | jq -r '.[0].State.Status')
419 log "InfluxDB container state is $status"
421 log "wait for InfluxDB API to be active"
422 while ! curl http://$ves_host:8086/ping ; do
423 log "InfluxDB API is not yet responding... waiting 10 seconds"
427 log "setup InfluxDB database"
428 curl -X POST http://$ves_host:8086/query \
429 --data-urlencode "q=CREATE DATABASE veseventsdb"
431 log "install Grafana container"
432 sudo docker run -d --name ves-grafana -p 3001:3000 grafana/grafana
433 status=$(sudo docker inspect ves-grafana | jq -r '.[0].State.Status')
434 while [[ "x$status" != "xrunning" ]]; do
435 log "Grafana container state is ($status)"
437 status=$(sudo docker inspect ves-grafana | jq -r '.[0].State.Status')
439 log "Grafana container state is $status"
441 log "wait for Grafana API to be active"
442 while ! curl http://$ves_host:3001 ; do
443 log "Grafana API is not yet responding... waiting 10 seconds"
447 log "add VESEvents datasource to Grafana"
448 cat <<EOF >/tmp/ves/datasource.json
449 { "name":"VESEvents",
452 "url":"http://$ves_host:8086",
455 "database":"veseventsdb",
458 "basicAuthPassword":"",
459 "withCredentials":false,
465 curl -H "Accept: application/json" -H "Content-type: application/json" \
466 -X POST -d @/tmp/ves/datasource.json \
467 http://admin:admin@$ves_host:3001/api/datasources
469 log "add VES dashboard to Grafana"
470 curl -H "Accept: application/json" -H "Content-type: application/json" \
472 -d @/tmp/ves/tools/grafana/Dashboard.json\
473 http://admin:admin@$ves_host:3001/api/dashboards/db
475 log "setup collector container"
478 rm -rf /tmp/ves/evel-test-collector
479 git clone https://github.com/att/evel-test-collector.git
481 "s~log_file = /var/log/att/collector.log~log_file = /opt/ves/collector.log~" \
482 evel-test-collector/config/collector.conf
483 sed -i -- "s/vel_domain = 127.0.0.1/vel_domain = $ves_host/g" \
484 evel-test-collector/config/collector.conf
485 sed -i -- "s/vel_username =/vel_username = $ves_user/g" \
486 evel-test-collector/config/collector.conf
487 sed -i -- "s/vel_password =/vel_password = $ves_pass/g" \
488 evel-test-collector/config/collector.conf
489 sed -i -- "s~vel_path = vendor_event_listener/~vel_path = $ves_path~g" \
490 evel-test-collector/config/collector.conf
491 sed -i -- "s~vel_topic_name = example_vnf~vel_topic_name = $ves_topic~g" \
492 evel-test-collector/config/collector.conf
493 sed -i -- "/vel_topic_name = /a influxdb = $ves_host" \
494 evel-test-collector/config/collector.conf
496 cp /tmp/ves/tools/monitor.py \
497 evel-test-collector/code/collector/monitor.py
499 # Note below: python (2.7) is required due to dependency on module 'ConfigParser'
500 cat <<EOF >/tmp/ves/setup-collector.sh
503 apt-get install -y python python-jsonschema python-pip
505 python /opt/ves/evel-test-collector/code/collector/monitor.py \
506 --config /opt/ves/evel-test-collector/config/collector.conf \
507 --influxdb $ves_host \
508 --section default > /opt/ves/monitor.log 2>&1 &
511 sudo docker run -it -d -v /tmp/ves:/opt/ves --name=ves-collector \
512 -p 30000:30000 ubuntu:xenial /bin/bash
513 sudo docker exec ves-collector /bin/bash /opt/ves/setup-collector.sh
515 # sudo docker exec -it ves-collector apt-get install -y tcpdump
516 # sudo docker exec -it ves-collector tcpdump -A -v -s 0 -i any port 30000
517 # curl http://$ves_host:30000
518 # sudo docker exec -it ves-collector /bin/bash
519 # ~/kafka_2.11-0.11.0.2/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic collectd
523 log "clean installation for $1 at $2"
524 if [[ "$1" == "master" ]]; then
525 cs="ves-agent ves-collector ves-grafana ves-influxdb"
527 log "stop and remove container $c"
532 log "remove collectd config for VES"
533 sudo sed -i -- '/VES plugin/,$d' /opt/collectd/etc/collectd.conf
534 sudo systemctl restart collectd
538 dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`
539 if [[ $(grep -c $HOSTNAME /etc/hosts) -eq 0 ]]; then
540 echo "$(ip route get 8.8.8.8 | awk '{print $NF; exit}') $HOSTNAME" |\
541 sudo tee -a /etc/hosts