5 |
5 |
"""
|
6 |
6 |
|
7 |
7 |
import os
|
|
8 |
import re
|
8 |
9 |
import sys
|
9 |
10 |
import time
|
10 |
11 |
import logging
|
... | ... | |
17 |
18 |
from kamaki.clients.astakos import AstakosClient
|
18 |
19 |
from kamaki.clients.cyclades import CycladesClient
|
19 |
20 |
from kamaki.clients.image import ImageClient
|
|
21 |
from kamaki.clients.compute import ComputeClient
|
20 |
22 |
|
21 |
23 |
DEFAULT_CONFIG_FILE = "new_config"
|
22 |
24 |
# UUID of owner of system images
|
... | ... | |
165 |
167 |
self.fabric_installed = False
|
166 |
168 |
self.kamaki_installed = False
|
167 |
169 |
self.cyclades_client = None
|
|
170 |
self.compute_client = None
|
168 |
171 |
self.image_client = None
|
169 |
172 |
|
170 |
173 |
def setup_kamaki(self):
|
171 |
174 |
"""Initialize kamaki
|
172 |
175 |
|
173 |
|
Setup cyclades_client and image_client
|
|
176 |
Setup cyclades_client, image_client and compute_client
|
174 |
177 |
"""
|
175 |
178 |
|
176 |
179 |
config = kamaki_config.Config()
|
... | ... | |
198 |
201 |
self.image_client = ImageClient(cyclades_url, token)
|
199 |
202 |
self.image_client.CONNECTION_RETRY_LIMIT = 2
|
200 |
203 |
|
|
204 |
compute_url = \
|
|
205 |
astakos_client.get_service_endpoints('compute')['publicURL']
|
|
206 |
self.logger.debug("Compute API url is %s" % _green(compute_url))
|
|
207 |
self.compute_client = ComputeClient(compute_url, token)
|
|
208 |
self.compute_client.CONNECTION_RETRY_LIMIT = 2
|
|
209 |
|
201 |
210 |
def _wait_transition(self, server_id, current_status, new_status):
|
202 |
211 |
"""Wait for server to go from current_status to new_status"""
|
203 |
212 |
self.logger.debug("Waiting for server to become %s" % new_status)
|
... | ... | |
232 |
241 |
self._wait_transition(server_id, "ACTIVE", "DELETED")
|
233 |
242 |
|
234 |
243 |
@_check_kamaki
|
235 |
|
def create_server(self, image_id=None, flavor_id=None, ssh_keys=None):
|
|
244 |
def create_server(self, image_id=None, flavor_name=None, ssh_keys=None):
|
236 |
245 |
"""Create slave server"""
|
237 |
246 |
self.logger.info("Create a new server..")
|
238 |
247 |
if image_id is None:
|
... | ... | |
240 |
249 |
self.logger.debug("Will use image \"%s\"" % _green(image['name']))
|
241 |
250 |
image_id = image["id"]
|
242 |
251 |
self.logger.debug("Image has id %s" % _green(image_id))
|
243 |
|
if flavor_id is None:
|
244 |
|
flavor_id = self.config.getint("Deployment", "flavor_id")
|
|
252 |
flavor_id = self._find_flavor(flavor_name)
|
245 |
253 |
server = self.cyclades_client.create_server(
|
246 |
254 |
self.config.get('Deployment', 'server_name'),
|
247 |
255 |
flavor_id,
|
... | ... | |
274 |
282 |
""".format(accept_ssh_from)
|
275 |
283 |
_run(cmd, False)
|
276 |
284 |
|
|
285 |
def _find_flavor(self, flavor_name):
|
|
286 |
"""Given a flavor_name (reg expression) find a flavor id to use"""
|
|
287 |
if flavor_name is None:
|
|
288 |
flavor_name = self.config.get('Deployment', 'flavor_name')
|
|
289 |
self.logger.debug("Try to find a flavor with name \"%s\"" % flavor_name)
|
|
290 |
|
|
291 |
flavors = self.compute_client.list_flavors()
|
|
292 |
flavors = [f for f in flavors
|
|
293 |
if re.search(flavor_name, f['name']) is not None]
|
|
294 |
|
|
295 |
if flavors:
|
|
296 |
self.logger.debug("Will use %s with id %s"
|
|
297 |
% (flavors[0]['name'], flavors[0]['id']))
|
|
298 |
return flavors[0]['id']
|
|
299 |
else:
|
|
300 |
self.logger.error("No matching flavor found.. aborting")
|
|
301 |
sys.exit(1)
|
|
302 |
|
277 |
303 |
def _find_image(self):
|
278 |
304 |
"""Find a suitable image to use
|
279 |
305 |
|