Merge "Use ConfigParser to write yardstick.conf"
[yardstick.git] / api / resources / env_action.py
1 ##############################################################################
2 # Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import logging
10 import threading
11 import subprocess
12 import time
13 import json
14 import os
15 import errno
16 import ConfigParser
17
18 from docker import Client
19
20 from yardstick.common import constants as config
21 from yardstick.common import utils as yardstick_utils
22 from yardstick.common.httpClient import HttpClient
23 from api import conf as api_conf
24 from api.utils import influx
25 from api.utils.common import result_handler
26
27 logger = logging.getLogger(__name__)
28
29
30 def createGrafanaContainer(args):
31     thread = threading.Thread(target=_create_grafana)
32     thread.start()
33     return result_handler('success', [])
34
35
36 def _create_grafana():
37     client = Client(base_url=config.DOCKER_URL)
38
39     try:
40         if not _check_image_exist(client, '%s:%s' % (config.GRAFANA_IMAGE,
41                                                      config.GRAFANA_TAGS)):
42             client.pull(config.GRAFANA_IMAGE, config.GRAFANA_TAGS)
43
44         _create_grafana_container(client)
45
46         time.sleep(5)
47
48         _create_data_source()
49
50         _create_dashboard()
51     except Exception as e:
52         logger.debug('Error: %s', e)
53
54
55 def _create_dashboard():
56     url = 'http://admin:admin@%s:3000/api/dashboards/db' % api_conf.GATEWAY_IP
57     with open('../dashboard/ping_dashboard.json') as dashboard_json:
58         data = json.load(dashboard_json)
59     HttpClient().post(url, data)
60
61
62 def _create_data_source():
63     url = 'http://admin:admin@%s:3000/api/datasources' % api_conf.GATEWAY_IP
64     data = {
65         "name": "yardstick",
66         "type": "influxdb",
67         "access": "proxy",
68         "url": "http://%s:8086" % api_conf.GATEWAY_IP,
69         "password": "root",
70         "user": "root",
71         "database": "yardstick",
72         "basicAuth": True,
73         "basicAuthUser": "admin",
74         "basicAuthPassword": "admin",
75         "isDefault": False,
76     }
77     HttpClient().post(url, data)
78
79
80 def _create_grafana_container(client):
81     ports = [3000]
82     port_bindings = {k: k for k in ports}
83     host_config = client.create_host_config(port_bindings=port_bindings)
84
85     container = client.create_container(image='%s:%s' % (config.GRAFANA_IMAGE,
86                                                          config.GRAFANA_TAGS),
87                                         ports=ports,
88                                         detach=True,
89                                         tty=True,
90                                         host_config=host_config)
91     client.start(container)
92
93
94 def _check_image_exist(client, t):
95     return any(t in a['RepoTags'][0] for a in client.images() if a['RepoTags'])
96
97
98 def createInfluxDBContainer(args):
99     thread = threading.Thread(target=_create_influxdb)
100     thread.start()
101     return result_handler('success', [])
102
103
104 def _create_influxdb():
105     client = Client(base_url=config.DOCKER_URL)
106
107     try:
108         _change_output_to_influxdb()
109
110         if not _check_image_exist(client, '%s:%s' % (config.INFLUXDB_IMAGE,
111                                                      config.INFLUXDB_TAG)):
112             client.pull(config.INFLUXDB_IMAGE, tag=config.INFLUXDB_TAG)
113
114         _create_influxdb_container(client)
115
116         time.sleep(5)
117
118         _config_influxdb()
119     except Exception as e:
120         logger.debug('Error: %s', e)
121
122
123 def _create_influxdb_container(client):
124
125     ports = [8083, 8086]
126     port_bindings = {k: k for k in ports}
127     host_config = client.create_host_config(port_bindings=port_bindings)
128
129     container = client.create_container(image='%s:%s' % (config.INFLUXDB_IMAGE,
130                                                          config.INFLUXDB_TAG),
131                                         ports=ports,
132                                         detach=True,
133                                         tty=True,
134                                         host_config=host_config)
135     client.start(container)
136
137
138 def _config_influxdb():
139     try:
140         client = influx.get_data_db_client()
141         client.create_user(config.USER, config.PASSWORD, config.DATABASE)
142         client.create_database(config.DATABASE)
143         logger.info('Success to config influxDB')
144     except Exception as e:
145         logger.debug('Failed to config influxDB: %s', e)
146
147
148 def _change_output_to_influxdb():
149     yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
150
151     parser = ConfigParser.ConfigParser()
152     parser.read(config.YARDSTICK_CONFIG_SAMPLE_FILE)
153
154     parser.set('DEFAULT', 'dispatcher', 'influxdb')
155     parser.set('dispatcher_influxdb', 'target',
156                'http://%s:8086' % api_conf.GATEWAY_IP)
157
158     with open(config.YARDSTICK_CONFIG_FILE, 'w') as f:
159         parser.write(f)
160
161
162 def prepareYardstickEnv(args):
163     thread = threading.Thread(target=_prepare_env_daemon)
164     thread.start()
165     return result_handler('success', [])
166
167
168 def _prepare_env_daemon():
169
170     installer_ip = os.environ.get('INSTALLER_IP', 'undefined')
171     installer_type = os.environ.get('INSTALLER_TYPE', 'undefined')
172
173     _check_variables(installer_ip, installer_type)
174
175     _create_directories()
176
177     rc_file = config.OPENSTACK_RC_FILE
178
179     _get_remote_rc_file(rc_file, installer_ip, installer_type)
180
181     _source_file(rc_file)
182
183     _append_external_network(rc_file)
184
185     # update the external_network
186     _source_file(rc_file)
187
188     _clean_images()
189
190     _load_images()
191
192
193 def _check_variables(installer_ip, installer_type):
194
195     if installer_ip == 'undefined':
196         raise SystemExit('Missing INSTALLER_IP')
197
198     if installer_type == 'undefined':
199         raise SystemExit('Missing INSTALLER_TYPE')
200     elif installer_type not in config.INSTALLERS:
201         raise SystemExit('INSTALLER_TYPE is not correct')
202
203
204 def _create_directories():
205     yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
206
207
208 def _source_file(rc_file):
209     yardstick_utils.source_env(rc_file)
210
211
212 def _get_remote_rc_file(rc_file, installer_ip, installer_type):
213
214     os_fetch_script = os.path.join(config.RELENG_DIR, config.OS_FETCH_SCRIPT)
215
216     try:
217         cmd = [os_fetch_script, '-d', rc_file, '-i', installer_type,
218                '-a', installer_ip]
219         p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
220         p.communicate()[0]
221
222         if p.returncode != 0:
223             logger.debug('Failed to fetch credentials from installer')
224     except OSError as e:
225         if e.errno != errno.EEXIST:
226             raise
227
228
229 def _append_external_network(rc_file):
230     neutron_client = yardstick_utils.get_neutron_client()
231     networks = neutron_client.list_networks()['networks']
232     try:
233         ext_network = next(n['name'] for n in networks if n['router:external'])
234     except StopIteration:
235         logger.warning("Can't find external network")
236     else:
237         cmd = 'export EXTERNAL_NETWORK=%s' % ext_network
238         try:
239             with open(rc_file, 'a') as f:
240                 f.write(cmd + '\n')
241         except OSError as e:
242             if e.errno != errno.EEXIST:
243                 raise
244
245
246 def _clean_images():
247     cmd = [config.CLEAN_IMAGES_SCRIPT]
248     p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
249                          cwd=config.YARDSTICK_REPOS_DIR)
250     output = p.communicate()[0]
251     logger.debug('The result is: %s', output)
252
253
254 def _load_images():
255     cmd = [config.LOAD_IMAGES_SCRIPT]
256     p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
257                          cwd=config.YARDSTICK_REPOS_DIR)
258     output = p.communicate()[0]
259     logger.debug('The result is: %s', output)