root / ci / utils.py @ ad21ffa9
History | View | Annotate | Download (23.9 kB)
1 | c29ac11d | Ilias Tsitsimpis | #!/usr/bin/env python
|
---|---|---|---|
2 | c29ac11d | Ilias Tsitsimpis | |
3 | c29ac11d | Ilias Tsitsimpis | """
|
4 | c29ac11d | Ilias Tsitsimpis | Synnefo ci utils module
|
5 | c29ac11d | Ilias Tsitsimpis | """
|
6 | c29ac11d | Ilias Tsitsimpis | |
7 | c29ac11d | Ilias Tsitsimpis | import os |
8 | ad21ffa9 | Ilias Tsitsimpis | import re |
9 | c29ac11d | Ilias Tsitsimpis | import sys |
10 | c29ac11d | Ilias Tsitsimpis | import time |
11 | c29ac11d | Ilias Tsitsimpis | import logging |
12 | c29ac11d | Ilias Tsitsimpis | import fabric.api as fabric |
13 | b69b55ca | Christos Stavrakakis | import subprocess |
14 | 88e6558b | Christos Stavrakakis | import tempfile |
15 | c29ac11d | Ilias Tsitsimpis | from ConfigParser import ConfigParser, DuplicateSectionError |
16 | c29ac11d | Ilias Tsitsimpis | |
17 | c1b1d444 | Christos Stavrakakis | from kamaki.cli import config as kamaki_config |
18 | c29ac11d | Ilias Tsitsimpis | from kamaki.clients.astakos import AstakosClient |
19 | c29ac11d | Ilias Tsitsimpis | from kamaki.clients.cyclades import CycladesClient |
20 | c29ac11d | Ilias Tsitsimpis | from kamaki.clients.image import ImageClient |
21 | ad21ffa9 | Ilias Tsitsimpis | from kamaki.clients.compute import ComputeClient |
22 | c29ac11d | Ilias Tsitsimpis | |
23 | 6ca8f81a | Christos Stavrakakis | DEFAULT_CONFIG_FILE = "new_config"
|
24 | 62f3f54f | Ilias Tsitsimpis | # UUID of owner of system images
|
25 | 62f3f54f | Ilias Tsitsimpis | DEFAULT_SYSTEM_IMAGES_UUID = [ |
26 | 62f3f54f | Ilias Tsitsimpis | "25ecced9-bf53-4145-91ee-cf47377e9fb2", # production (okeanos.grnet.gr) |
27 | 62f3f54f | Ilias Tsitsimpis | "04cbe33f-29b7-4ef1-94fb-015929e5fc06", # testing (okeanos.io) |
28 | 62f3f54f | Ilias Tsitsimpis | ] |
29 | 6ca8f81a | Christos Stavrakakis | |
30 | c29ac11d | Ilias Tsitsimpis | |
31 | c29ac11d | Ilias Tsitsimpis | def _run(cmd, verbose): |
32 | c29ac11d | Ilias Tsitsimpis | """Run fabric with verbose level"""
|
33 | c29ac11d | Ilias Tsitsimpis | if verbose:
|
34 | c29ac11d | Ilias Tsitsimpis | args = ('running',)
|
35 | c29ac11d | Ilias Tsitsimpis | else:
|
36 | c29ac11d | Ilias Tsitsimpis | args = ('running', 'stdout',) |
37 | e2a0abb8 | Ilias Tsitsimpis | with fabric.hide(*args): # Used * or ** magic. pylint: disable-msg=W0142 |
38 | c29ac11d | Ilias Tsitsimpis | return fabric.run(cmd)
|
39 | c29ac11d | Ilias Tsitsimpis | |
40 | c29ac11d | Ilias Tsitsimpis | |
41 | 6868804a | Ilias Tsitsimpis | def _put(local, remote): |
42 | 6868804a | Ilias Tsitsimpis | """Run fabric put command without output"""
|
43 | 6868804a | Ilias Tsitsimpis | with fabric.quiet():
|
44 | 6868804a | Ilias Tsitsimpis | fabric.put(local, remote) |
45 | 6868804a | Ilias Tsitsimpis | |
46 | 6868804a | Ilias Tsitsimpis | |
47 | c29ac11d | Ilias Tsitsimpis | def _red(msg): |
48 | c29ac11d | Ilias Tsitsimpis | """Red color"""
|
49 | c29ac11d | Ilias Tsitsimpis | #return "\x1b[31m" + str(msg) + "\x1b[0m"
|
50 | c29ac11d | Ilias Tsitsimpis | return str(msg) |
51 | c29ac11d | Ilias Tsitsimpis | |
52 | c29ac11d | Ilias Tsitsimpis | |
53 | c29ac11d | Ilias Tsitsimpis | def _yellow(msg): |
54 | c29ac11d | Ilias Tsitsimpis | """Yellow color"""
|
55 | c29ac11d | Ilias Tsitsimpis | #return "\x1b[33m" + str(msg) + "\x1b[0m"
|
56 | c29ac11d | Ilias Tsitsimpis | return str(msg) |
57 | c29ac11d | Ilias Tsitsimpis | |
58 | c29ac11d | Ilias Tsitsimpis | |
59 | c29ac11d | Ilias Tsitsimpis | def _green(msg): |
60 | c29ac11d | Ilias Tsitsimpis | """Green color"""
|
61 | c29ac11d | Ilias Tsitsimpis | #return "\x1b[32m" + str(msg) + "\x1b[0m"
|
62 | c29ac11d | Ilias Tsitsimpis | return str(msg) |
63 | c29ac11d | Ilias Tsitsimpis | |
64 | c29ac11d | Ilias Tsitsimpis | |
65 | c29ac11d | Ilias Tsitsimpis | def _check_fabric(fun): |
66 | c29ac11d | Ilias Tsitsimpis | """Check if fabric env has been set"""
|
67 | 43a22402 | Christos Stavrakakis | def wrapper(self, *args, **kwargs): |
68 | c29ac11d | Ilias Tsitsimpis | """wrapper function"""
|
69 | c29ac11d | Ilias Tsitsimpis | if not self.fabric_installed: |
70 | c29ac11d | Ilias Tsitsimpis | self.setup_fabric()
|
71 | 43a22402 | Christos Stavrakakis | return fun(self, *args, **kwargs) |
72 | c29ac11d | Ilias Tsitsimpis | return wrapper
|
73 | c29ac11d | Ilias Tsitsimpis | |
74 | c29ac11d | Ilias Tsitsimpis | |
75 | c29ac11d | Ilias Tsitsimpis | def _check_kamaki(fun): |
76 | c29ac11d | Ilias Tsitsimpis | """Check if kamaki has been initialized"""
|
77 | 43a22402 | Christos Stavrakakis | def wrapper(self, *args, **kwargs): |
78 | c29ac11d | Ilias Tsitsimpis | """wrapper function"""
|
79 | c29ac11d | Ilias Tsitsimpis | if not self.kamaki_installed: |
80 | c29ac11d | Ilias Tsitsimpis | self.setup_kamaki()
|
81 | 43a22402 | Christos Stavrakakis | return fun(self, *args, **kwargs) |
82 | c29ac11d | Ilias Tsitsimpis | return wrapper
|
83 | c29ac11d | Ilias Tsitsimpis | |
84 | c29ac11d | Ilias Tsitsimpis | |
85 | c29ac11d | Ilias Tsitsimpis | class _MyFormatter(logging.Formatter): |
86 | c29ac11d | Ilias Tsitsimpis | """Logging Formatter"""
|
87 | c29ac11d | Ilias Tsitsimpis | def format(self, record): |
88 | c29ac11d | Ilias Tsitsimpis | format_orig = self._fmt
|
89 | c29ac11d | Ilias Tsitsimpis | if record.levelno == logging.DEBUG:
|
90 | c29ac11d | Ilias Tsitsimpis | self._fmt = " %(msg)s" |
91 | c29ac11d | Ilias Tsitsimpis | elif record.levelno == logging.INFO:
|
92 | c29ac11d | Ilias Tsitsimpis | self._fmt = "%(msg)s" |
93 | c29ac11d | Ilias Tsitsimpis | elif record.levelno == logging.WARNING:
|
94 | c29ac11d | Ilias Tsitsimpis | self._fmt = _yellow("[W] %(msg)s") |
95 | c29ac11d | Ilias Tsitsimpis | elif record.levelno == logging.ERROR:
|
96 | c29ac11d | Ilias Tsitsimpis | self._fmt = _red("[E] %(msg)s") |
97 | c29ac11d | Ilias Tsitsimpis | result = logging.Formatter.format(self, record)
|
98 | c29ac11d | Ilias Tsitsimpis | self._fmt = format_orig
|
99 | c29ac11d | Ilias Tsitsimpis | return result
|
100 | c29ac11d | Ilias Tsitsimpis | |
101 | c29ac11d | Ilias Tsitsimpis | |
102 | 56ee1bbc | Ilias Tsitsimpis | # Too few public methods. pylint: disable-msg=R0903
|
103 | 56ee1bbc | Ilias Tsitsimpis | class _InfoFilter(logging.Filter): |
104 | 56ee1bbc | Ilias Tsitsimpis | """Logging Filter that allows DEBUG and INFO messages only"""
|
105 | 56ee1bbc | Ilias Tsitsimpis | def filter(self, rec): |
106 | 56ee1bbc | Ilias Tsitsimpis | """The filter"""
|
107 | 56ee1bbc | Ilias Tsitsimpis | return rec.levelno in (logging.DEBUG, logging.INFO) |
108 | 56ee1bbc | Ilias Tsitsimpis | |
109 | 56ee1bbc | Ilias Tsitsimpis | |
110 | 56ee1bbc | Ilias Tsitsimpis | # Too many instance attributes. pylint: disable-msg=R0902
|
111 | c29ac11d | Ilias Tsitsimpis | class SynnefoCI(object): |
112 | c29ac11d | Ilias Tsitsimpis | """SynnefoCI python class"""
|
113 | c29ac11d | Ilias Tsitsimpis | |
114 | 6ca8f81a | Christos Stavrakakis | def __init__(self, config_file=None, cleanup_config=False, cloud=None): |
115 | c29ac11d | Ilias Tsitsimpis | """ Initialize SynnefoCI python class
|
116 | c29ac11d | Ilias Tsitsimpis |
|
117 | c29ac11d | Ilias Tsitsimpis | Setup logger, local_dir, config and kamaki
|
118 | c29ac11d | Ilias Tsitsimpis | """
|
119 | c29ac11d | Ilias Tsitsimpis | # Setup logger
|
120 | c29ac11d | Ilias Tsitsimpis | self.logger = logging.getLogger('synnefo-ci') |
121 | c29ac11d | Ilias Tsitsimpis | self.logger.setLevel(logging.DEBUG)
|
122 | 56ee1bbc | Ilias Tsitsimpis | |
123 | 56ee1bbc | Ilias Tsitsimpis | handler1 = logging.StreamHandler(sys.stdout) |
124 | 56ee1bbc | Ilias Tsitsimpis | handler1.setLevel(logging.DEBUG) |
125 | 56ee1bbc | Ilias Tsitsimpis | handler1.addFilter(_InfoFilter()) |
126 | 56ee1bbc | Ilias Tsitsimpis | handler1.setFormatter(_MyFormatter()) |
127 | 56ee1bbc | Ilias Tsitsimpis | handler2 = logging.StreamHandler(sys.stderr) |
128 | 56ee1bbc | Ilias Tsitsimpis | handler2.setLevel(logging.WARNING) |
129 | 56ee1bbc | Ilias Tsitsimpis | handler2.setFormatter(_MyFormatter()) |
130 | 56ee1bbc | Ilias Tsitsimpis | |
131 | 56ee1bbc | Ilias Tsitsimpis | self.logger.addHandler(handler1)
|
132 | 56ee1bbc | Ilias Tsitsimpis | self.logger.addHandler(handler2)
|
133 | c29ac11d | Ilias Tsitsimpis | |
134 | c29ac11d | Ilias Tsitsimpis | # Get our local dir
|
135 | c29ac11d | Ilias Tsitsimpis | self.ci_dir = os.path.dirname(os.path.abspath(__file__))
|
136 | c29ac11d | Ilias Tsitsimpis | self.repo_dir = os.path.dirname(self.ci_dir) |
137 | c29ac11d | Ilias Tsitsimpis | |
138 | c29ac11d | Ilias Tsitsimpis | # Read config file
|
139 | 6ca8f81a | Christos Stavrakakis | if config_file is None: |
140 | 6ca8f81a | Christos Stavrakakis | config_file = DEFAULT_CONFIG_FILE |
141 | 6ca8f81a | Christos Stavrakakis | if not os.path.isabs(config_file): |
142 | 6ca8f81a | Christos Stavrakakis | config_file = os.path.join(self.ci_dir, config_file)
|
143 | e908a902 | Christos Stavrakakis | |
144 | c29ac11d | Ilias Tsitsimpis | self.config = ConfigParser()
|
145 | c29ac11d | Ilias Tsitsimpis | self.config.optionxform = str |
146 | 6ca8f81a | Christos Stavrakakis | self.config.read(config_file)
|
147 | c29ac11d | Ilias Tsitsimpis | temp_config = self.config.get('Global', 'temporary_config') |
148 | c29ac11d | Ilias Tsitsimpis | if cleanup_config:
|
149 | c29ac11d | Ilias Tsitsimpis | try:
|
150 | c29ac11d | Ilias Tsitsimpis | os.remove(temp_config) |
151 | e2a0abb8 | Ilias Tsitsimpis | except OSError: |
152 | c29ac11d | Ilias Tsitsimpis | pass
|
153 | c29ac11d | Ilias Tsitsimpis | else:
|
154 | c29ac11d | Ilias Tsitsimpis | self.config.read(self.config.get('Global', 'temporary_config')) |
155 | c29ac11d | Ilias Tsitsimpis | |
156 | c1b1d444 | Christos Stavrakakis | # Set kamaki cloud
|
157 | c1b1d444 | Christos Stavrakakis | if cloud is not None: |
158 | c1b1d444 | Christos Stavrakakis | self.kamaki_cloud = cloud
|
159 | c1b1d444 | Christos Stavrakakis | elif self.config.has_option("Deployment", "kamaki_cloud"): |
160 | c1b1d444 | Christos Stavrakakis | kamaki_cloud = self.config.get("Deployment", "kamaki_cloud") |
161 | c1b1d444 | Christos Stavrakakis | if kamaki_cloud == "": |
162 | c1b1d444 | Christos Stavrakakis | self.kamaki_cloud = None |
163 | c1b1d444 | Christos Stavrakakis | else:
|
164 | c1b1d444 | Christos Stavrakakis | self.kamaki_cloud = None |
165 | c1b1d444 | Christos Stavrakakis | |
166 | c29ac11d | Ilias Tsitsimpis | # Initialize variables
|
167 | c29ac11d | Ilias Tsitsimpis | self.fabric_installed = False |
168 | c29ac11d | Ilias Tsitsimpis | self.kamaki_installed = False |
169 | c29ac11d | Ilias Tsitsimpis | self.cyclades_client = None |
170 | ad21ffa9 | Ilias Tsitsimpis | self.compute_client = None |
171 | c29ac11d | Ilias Tsitsimpis | self.image_client = None |
172 | c29ac11d | Ilias Tsitsimpis | |
173 | c29ac11d | Ilias Tsitsimpis | def setup_kamaki(self): |
174 | c29ac11d | Ilias Tsitsimpis | """Initialize kamaki
|
175 | c29ac11d | Ilias Tsitsimpis |
|
176 | ad21ffa9 | Ilias Tsitsimpis | Setup cyclades_client, image_client and compute_client
|
177 | c29ac11d | Ilias Tsitsimpis | """
|
178 | c1b1d444 | Christos Stavrakakis | |
179 | c1b1d444 | Christos Stavrakakis | config = kamaki_config.Config() |
180 | c1b1d444 | Christos Stavrakakis | if self.kamaki_cloud is None: |
181 | c1b1d444 | Christos Stavrakakis | self.kamaki_cloud = config.get_global("default_cloud") |
182 | c1b1d444 | Christos Stavrakakis | |
183 | c1b1d444 | Christos Stavrakakis | self.logger.info("Setup kamaki client, using cloud '%s'.." % |
184 | c1b1d444 | Christos Stavrakakis | self.kamaki_cloud)
|
185 | c1b1d444 | Christos Stavrakakis | auth_url = config.get_cloud(self.kamaki_cloud, "url") |
186 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Authentication URL is %s" % _green(auth_url)) |
187 | c1b1d444 | Christos Stavrakakis | token = config.get_cloud(self.kamaki_cloud, "token") |
188 | c29ac11d | Ilias Tsitsimpis | #self.logger.debug("Token is %s" % _green(token))
|
189 | c29ac11d | Ilias Tsitsimpis | |
190 | c29ac11d | Ilias Tsitsimpis | astakos_client = AstakosClient(auth_url, token) |
191 | c29ac11d | Ilias Tsitsimpis | |
192 | c29ac11d | Ilias Tsitsimpis | cyclades_url = \ |
193 | c29ac11d | Ilias Tsitsimpis | astakos_client.get_service_endpoints('compute')['publicURL'] |
194 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Cyclades API url is %s" % _green(cyclades_url)) |
195 | c29ac11d | Ilias Tsitsimpis | self.cyclades_client = CycladesClient(cyclades_url, token)
|
196 | c29ac11d | Ilias Tsitsimpis | self.cyclades_client.CONNECTION_RETRY_LIMIT = 2 |
197 | c29ac11d | Ilias Tsitsimpis | |
198 | c29ac11d | Ilias Tsitsimpis | image_url = \ |
199 | c29ac11d | Ilias Tsitsimpis | astakos_client.get_service_endpoints('image')['publicURL'] |
200 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Images API url is %s" % _green(image_url)) |
201 | c29ac11d | Ilias Tsitsimpis | self.image_client = ImageClient(cyclades_url, token)
|
202 | c29ac11d | Ilias Tsitsimpis | self.image_client.CONNECTION_RETRY_LIMIT = 2 |
203 | c29ac11d | Ilias Tsitsimpis | |
204 | ad21ffa9 | Ilias Tsitsimpis | compute_url = \ |
205 | ad21ffa9 | Ilias Tsitsimpis | astakos_client.get_service_endpoints('compute')['publicURL'] |
206 | ad21ffa9 | Ilias Tsitsimpis | self.logger.debug("Compute API url is %s" % _green(compute_url)) |
207 | ad21ffa9 | Ilias Tsitsimpis | self.compute_client = ComputeClient(compute_url, token)
|
208 | ad21ffa9 | Ilias Tsitsimpis | self.compute_client.CONNECTION_RETRY_LIMIT = 2 |
209 | ad21ffa9 | Ilias Tsitsimpis | |
210 | c29ac11d | Ilias Tsitsimpis | def _wait_transition(self, server_id, current_status, new_status): |
211 | c29ac11d | Ilias Tsitsimpis | """Wait for server to go from current_status to new_status"""
|
212 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Waiting for server to become %s" % new_status) |
213 | c29ac11d | Ilias Tsitsimpis | timeout = self.config.getint('Global', 'build_timeout') |
214 | c29ac11d | Ilias Tsitsimpis | sleep_time = 5
|
215 | c29ac11d | Ilias Tsitsimpis | while True: |
216 | c29ac11d | Ilias Tsitsimpis | server = self.cyclades_client.get_server_details(server_id)
|
217 | c29ac11d | Ilias Tsitsimpis | if server['status'] == new_status: |
218 | c29ac11d | Ilias Tsitsimpis | return server
|
219 | c29ac11d | Ilias Tsitsimpis | elif timeout < 0: |
220 | c29ac11d | Ilias Tsitsimpis | self.logger.error(
|
221 | c29ac11d | Ilias Tsitsimpis | "Waiting for server to become %s timed out" % new_status)
|
222 | c29ac11d | Ilias Tsitsimpis | self.destroy_server(False) |
223 | c29ac11d | Ilias Tsitsimpis | sys.exit(-1)
|
224 | c29ac11d | Ilias Tsitsimpis | elif server['status'] == current_status: |
225 | c29ac11d | Ilias Tsitsimpis | # Sleep for #n secs and continue
|
226 | c29ac11d | Ilias Tsitsimpis | timeout = timeout - sleep_time |
227 | c29ac11d | Ilias Tsitsimpis | time.sleep(sleep_time) |
228 | c29ac11d | Ilias Tsitsimpis | else:
|
229 | c29ac11d | Ilias Tsitsimpis | self.logger.error(
|
230 | c29ac11d | Ilias Tsitsimpis | "Server failed with status %s" % server['status']) |
231 | c29ac11d | Ilias Tsitsimpis | self.destroy_server(False) |
232 | c29ac11d | Ilias Tsitsimpis | sys.exit(-1)
|
233 | c29ac11d | Ilias Tsitsimpis | |
234 | c29ac11d | Ilias Tsitsimpis | @_check_kamaki
|
235 | c29ac11d | Ilias Tsitsimpis | def destroy_server(self, wait=True): |
236 | c29ac11d | Ilias Tsitsimpis | """Destroy slave server"""
|
237 | c29ac11d | Ilias Tsitsimpis | server_id = self.config.getint('Temporary Options', 'server_id') |
238 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Destoying server with id %s " % server_id) |
239 | c29ac11d | Ilias Tsitsimpis | self.cyclades_client.delete_server(server_id)
|
240 | c29ac11d | Ilias Tsitsimpis | if wait:
|
241 | c29ac11d | Ilias Tsitsimpis | self._wait_transition(server_id, "ACTIVE", "DELETED") |
242 | c29ac11d | Ilias Tsitsimpis | |
243 | c29ac11d | Ilias Tsitsimpis | @_check_kamaki
|
244 | ad21ffa9 | Ilias Tsitsimpis | def create_server(self, image_id=None, flavor_name=None, ssh_keys=None): |
245 | c29ac11d | Ilias Tsitsimpis | """Create slave server"""
|
246 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Create a new server..") |
247 | 43a22402 | Christos Stavrakakis | if image_id is None: |
248 | 43a22402 | Christos Stavrakakis | image = self._find_image()
|
249 | 43a22402 | Christos Stavrakakis | self.logger.debug("Will use image \"%s\"" % _green(image['name'])) |
250 | 43a22402 | Christos Stavrakakis | image_id = image["id"]
|
251 | 43a22402 | Christos Stavrakakis | self.logger.debug("Image has id %s" % _green(image_id)) |
252 | ad21ffa9 | Ilias Tsitsimpis | flavor_id = self._find_flavor(flavor_name)
|
253 | c29ac11d | Ilias Tsitsimpis | server = self.cyclades_client.create_server(
|
254 | c29ac11d | Ilias Tsitsimpis | self.config.get('Deployment', 'server_name'), |
255 | 43a22402 | Christos Stavrakakis | flavor_id, |
256 | 43a22402 | Christos Stavrakakis | image_id) |
257 | c29ac11d | Ilias Tsitsimpis | server_id = server['id']
|
258 | c29ac11d | Ilias Tsitsimpis | self.write_config('server_id', server_id) |
259 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Server got id %s" % _green(server_id)) |
260 | c29ac11d | Ilias Tsitsimpis | server_user = server['metadata']['users'] |
261 | c29ac11d | Ilias Tsitsimpis | self.write_config('server_user', server_user) |
262 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Server's admin user is %s" % _green(server_user)) |
263 | c29ac11d | Ilias Tsitsimpis | server_passwd = server['adminPass']
|
264 | c29ac11d | Ilias Tsitsimpis | self.write_config('server_passwd', server_passwd) |
265 | c29ac11d | Ilias Tsitsimpis | |
266 | c29ac11d | Ilias Tsitsimpis | server = self._wait_transition(server_id, "BUILD", "ACTIVE") |
267 | c29ac11d | Ilias Tsitsimpis | self._get_server_ip_and_port(server)
|
268 | 6868804a | Ilias Tsitsimpis | self._copy_ssh_keys(ssh_keys)
|
269 | c29ac11d | Ilias Tsitsimpis | |
270 | c29ac11d | Ilias Tsitsimpis | self.setup_fabric()
|
271 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Setup firewall") |
272 | 6868804a | Ilias Tsitsimpis | accept_ssh_from = self.config.get('Global', 'accept_ssh_from') |
273 | 1c75c4dd | Christos Stavrakakis | if accept_ssh_from != "": |
274 | 1c75c4dd | Christos Stavrakakis | self.logger.debug("Block ssh except from %s" % accept_ssh_from) |
275 | 1c75c4dd | Christos Stavrakakis | cmd = """
|
276 | 1c75c4dd | Christos Stavrakakis | local_ip=$(/sbin/ifconfig eth0 | grep 'inet addr:' | \
|
277 | 1c75c4dd | Christos Stavrakakis | cut -d':' -f2 | cut -d' ' -f1)
|
278 | 1c75c4dd | Christos Stavrakakis | iptables -A INPUT -s localhost -j ACCEPT
|
279 | 1c75c4dd | Christos Stavrakakis | iptables -A INPUT -s $local_ip -j ACCEPT
|
280 | 1c75c4dd | Christos Stavrakakis | iptables -A INPUT -s {0} -p tcp --dport 22 -j ACCEPT
|
281 | 1c75c4dd | Christos Stavrakakis | iptables -A INPUT -p tcp --dport 22 -j DROP
|
282 | 1c75c4dd | Christos Stavrakakis | """.format(accept_ssh_from)
|
283 | 1c75c4dd | Christos Stavrakakis | _run(cmd, False)
|
284 | c29ac11d | Ilias Tsitsimpis | |
285 | ad21ffa9 | Ilias Tsitsimpis | def _find_flavor(self, flavor_name): |
286 | ad21ffa9 | Ilias Tsitsimpis | """Given a flavor_name (reg expression) find a flavor id to use"""
|
287 | ad21ffa9 | Ilias Tsitsimpis | if flavor_name is None: |
288 | ad21ffa9 | Ilias Tsitsimpis | flavor_name = self.config.get('Deployment', 'flavor_name') |
289 | ad21ffa9 | Ilias Tsitsimpis | self.logger.debug("Try to find a flavor with name \"%s\"" % flavor_name) |
290 | ad21ffa9 | Ilias Tsitsimpis | |
291 | ad21ffa9 | Ilias Tsitsimpis | flavors = self.compute_client.list_flavors()
|
292 | ad21ffa9 | Ilias Tsitsimpis | flavors = [f for f in flavors |
293 | ad21ffa9 | Ilias Tsitsimpis | if re.search(flavor_name, f['name']) is not None] |
294 | ad21ffa9 | Ilias Tsitsimpis | |
295 | ad21ffa9 | Ilias Tsitsimpis | if flavors:
|
296 | ad21ffa9 | Ilias Tsitsimpis | self.logger.debug("Will use %s with id %s" |
297 | ad21ffa9 | Ilias Tsitsimpis | % (flavors[0]['name'], flavors[0]['id'])) |
298 | ad21ffa9 | Ilias Tsitsimpis | return flavors[0]['id'] |
299 | ad21ffa9 | Ilias Tsitsimpis | else:
|
300 | ad21ffa9 | Ilias Tsitsimpis | self.logger.error("No matching flavor found.. aborting") |
301 | ad21ffa9 | Ilias Tsitsimpis | sys.exit(1)
|
302 | ad21ffa9 | Ilias Tsitsimpis | |
303 | c29ac11d | Ilias Tsitsimpis | def _find_image(self): |
304 | c29ac11d | Ilias Tsitsimpis | """Find a suitable image to use
|
305 | c29ac11d | Ilias Tsitsimpis |
|
306 | 62f3f54f | Ilias Tsitsimpis | It has to belong to one of the `DEFAULT_SYSTEM_IMAGES_UUID'
|
307 | 62f3f54f | Ilias Tsitsimpis | users and contain the word given by `image_name' option.
|
308 | c29ac11d | Ilias Tsitsimpis | """
|
309 | c29ac11d | Ilias Tsitsimpis | image_name = self.config.get('Deployment', 'image_name').lower() |
310 | c29ac11d | Ilias Tsitsimpis | images = self.image_client.list_public(detail=True)['images'] |
311 | c29ac11d | Ilias Tsitsimpis | # Select images by `system_uuid' user
|
312 | 62f3f54f | Ilias Tsitsimpis | images = [x for x in images |
313 | 62f3f54f | Ilias Tsitsimpis | if x['user_id'] in DEFAULT_SYSTEM_IMAGES_UUID] |
314 | c29ac11d | Ilias Tsitsimpis | # Select images with `image_name' in their names
|
315 | 62f3f54f | Ilias Tsitsimpis | images = [x for x in images |
316 | 62f3f54f | Ilias Tsitsimpis | if x['name'].lower().find(image_name) != -1] |
317 | c29ac11d | Ilias Tsitsimpis | # Let's select the first one
|
318 | c29ac11d | Ilias Tsitsimpis | return images[0] |
319 | c29ac11d | Ilias Tsitsimpis | |
320 | c29ac11d | Ilias Tsitsimpis | def _get_server_ip_and_port(self, server): |
321 | c29ac11d | Ilias Tsitsimpis | """Compute server's IPv4 and ssh port number"""
|
322 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Get server connection details..") |
323 | c29ac11d | Ilias Tsitsimpis | server_ip = server['attachments'][0]['ipv4'] |
324 | 3b26ae00 | Christos Stavrakakis | if ".okeanos.io" in self.cyclades_client.base_url: |
325 | c29ac11d | Ilias Tsitsimpis | tmp1 = int(server_ip.split(".")[2]) |
326 | c29ac11d | Ilias Tsitsimpis | tmp2 = int(server_ip.split(".")[3]) |
327 | c29ac11d | Ilias Tsitsimpis | server_ip = "gate.okeanos.io"
|
328 | c29ac11d | Ilias Tsitsimpis | server_port = 10000 + tmp1 * 256 + tmp2 |
329 | c29ac11d | Ilias Tsitsimpis | else:
|
330 | c29ac11d | Ilias Tsitsimpis | server_port = 22
|
331 | c29ac11d | Ilias Tsitsimpis | self.write_config('server_ip', server_ip) |
332 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Server's IPv4 is %s" % _green(server_ip)) |
333 | c29ac11d | Ilias Tsitsimpis | self.write_config('server_port', server_port) |
334 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Server's ssh port is %s" % _green(server_port)) |
335 | 6868804a | Ilias Tsitsimpis | self.logger.debug("Access server using \"ssh -p %s %s@%s\"" % |
336 | 4b743650 | Ilias Tsitsimpis | (server_port, server['metadata']['users'], server_ip)) |
337 | c29ac11d | Ilias Tsitsimpis | |
338 | e480f0ce | Christos Stavrakakis | @_check_fabric
|
339 | 6868804a | Ilias Tsitsimpis | def _copy_ssh_keys(self, ssh_keys): |
340 | e2a0abb8 | Ilias Tsitsimpis | """Upload/Install ssh keys to server"""
|
341 | 4b743650 | Ilias Tsitsimpis | self.logger.debug("Check for authentication keys to use") |
342 | 6868804a | Ilias Tsitsimpis | if ssh_keys is None: |
343 | 6868804a | Ilias Tsitsimpis | ssh_keys = self.config.get("Deployment", "ssh_keys") |
344 | 6868804a | Ilias Tsitsimpis | |
345 | 4b743650 | Ilias Tsitsimpis | if ssh_keys != "": |
346 | 4b743650 | Ilias Tsitsimpis | self.logger.debug("Will use %s authentication keys file" % ssh_keys) |
347 | e480f0ce | Christos Stavrakakis | keyfile = '/tmp/%s.pub' % fabric.env.user
|
348 | e480f0ce | Christos Stavrakakis | _run('mkdir -p ~/.ssh && chmod 700 ~/.ssh', False) |
349 | 4b743650 | Ilias Tsitsimpis | if ssh_keys.startswith("http://") or \ |
350 | 4b743650 | Ilias Tsitsimpis | ssh_keys.startswith("https://") or \ |
351 | 4b743650 | Ilias Tsitsimpis | ssh_keys.startswith("ftp://"):
|
352 | 4b743650 | Ilias Tsitsimpis | cmd = """
|
353 | 4b743650 | Ilias Tsitsimpis | apt-get update
|
354 | 4b743650 | Ilias Tsitsimpis | apt-get install wget --yes
|
355 | 4b743650 | Ilias Tsitsimpis | wget {0} -O {1} --no-check-certificate
|
356 | 4b743650 | Ilias Tsitsimpis | """.format(ssh_keys, keyfile)
|
357 | 4b743650 | Ilias Tsitsimpis | _run(cmd, False)
|
358 | 4b743650 | Ilias Tsitsimpis | elif os.path.exists(ssh_keys):
|
359 | 4b743650 | Ilias Tsitsimpis | _put(ssh_keys, keyfile) |
360 | 4b743650 | Ilias Tsitsimpis | else:
|
361 | 4b743650 | Ilias Tsitsimpis | self.logger.debug("No ssh keys found") |
362 | e480f0ce | Christos Stavrakakis | _run('cat %s >> ~/.ssh/authorized_keys' % keyfile, False) |
363 | e480f0ce | Christos Stavrakakis | _run('rm %s' % keyfile, False) |
364 | e480f0ce | Christos Stavrakakis | self.logger.debug("Uploaded ssh authorized keys") |
365 | e480f0ce | Christos Stavrakakis | else:
|
366 | e480f0ce | Christos Stavrakakis | self.logger.debug("No ssh keys found") |
367 | e480f0ce | Christos Stavrakakis | |
368 | c29ac11d | Ilias Tsitsimpis | def write_config(self, option, value, section="Temporary Options"): |
369 | c29ac11d | Ilias Tsitsimpis | """Write changes back to config file"""
|
370 | c29ac11d | Ilias Tsitsimpis | try:
|
371 | c29ac11d | Ilias Tsitsimpis | self.config.add_section(section)
|
372 | c29ac11d | Ilias Tsitsimpis | except DuplicateSectionError:
|
373 | c29ac11d | Ilias Tsitsimpis | pass
|
374 | c29ac11d | Ilias Tsitsimpis | self.config.set(section, option, str(value)) |
375 | c29ac11d | Ilias Tsitsimpis | temp_conf_file = self.config.get('Global', 'temporary_config') |
376 | c29ac11d | Ilias Tsitsimpis | with open(temp_conf_file, 'wb') as tcf: |
377 | c29ac11d | Ilias Tsitsimpis | self.config.write(tcf)
|
378 | c29ac11d | Ilias Tsitsimpis | |
379 | c29ac11d | Ilias Tsitsimpis | def setup_fabric(self): |
380 | c29ac11d | Ilias Tsitsimpis | """Setup fabric environment"""
|
381 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Setup fabric parameters..") |
382 | c29ac11d | Ilias Tsitsimpis | fabric.env.user = self.config.get('Temporary Options', 'server_user') |
383 | c29ac11d | Ilias Tsitsimpis | fabric.env.host_string = \ |
384 | c29ac11d | Ilias Tsitsimpis | self.config.get('Temporary Options', 'server_ip') |
385 | e908a902 | Christos Stavrakakis | fabric.env.port = self.config.getint('Temporary Options', |
386 | e908a902 | Christos Stavrakakis | 'server_port')
|
387 | e908a902 | Christos Stavrakakis | fabric.env.password = self.config.get('Temporary Options', |
388 | e908a902 | Christos Stavrakakis | 'server_passwd')
|
389 | c29ac11d | Ilias Tsitsimpis | fabric.env.connection_attempts = 10
|
390 | c29ac11d | Ilias Tsitsimpis | fabric.env.shell = "/bin/bash -c"
|
391 | c29ac11d | Ilias Tsitsimpis | fabric.env.disable_known_hosts = True
|
392 | c29ac11d | Ilias Tsitsimpis | fabric.env.output_prefix = None
|
393 | c29ac11d | Ilias Tsitsimpis | |
394 | c29ac11d | Ilias Tsitsimpis | def _check_hash_sum(self, localfile, remotefile): |
395 | c29ac11d | Ilias Tsitsimpis | """Check hash sums of two files"""
|
396 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Check hash sum for local file %s" % localfile) |
397 | c29ac11d | Ilias Tsitsimpis | hash1 = os.popen("sha256sum %s" % localfile).read().split(' ')[0] |
398 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Local file has sha256 hash %s" % hash1) |
399 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Check hash sum for remote file %s" % remotefile) |
400 | c29ac11d | Ilias Tsitsimpis | hash2 = _run("sha256sum %s" % remotefile, False) |
401 | c29ac11d | Ilias Tsitsimpis | hash2 = hash2.split(' ')[0] |
402 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Remote file has sha256 hash %s" % hash2) |
403 | c29ac11d | Ilias Tsitsimpis | if hash1 != hash2:
|
404 | c29ac11d | Ilias Tsitsimpis | self.logger.error("Hashes differ.. aborting") |
405 | c29ac11d | Ilias Tsitsimpis | sys.exit(-1)
|
406 | c29ac11d | Ilias Tsitsimpis | |
407 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
408 | c29ac11d | Ilias Tsitsimpis | def clone_repo(self): |
409 | c29ac11d | Ilias Tsitsimpis | """Clone Synnefo repo from slave server"""
|
410 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Configure repositories on remote server..") |
411 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Setup apt, install curl and git") |
412 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
413 | c29ac11d | Ilias Tsitsimpis | echo 'APT::Install-Suggests "false";' >> /etc/apt/apt.conf
|
414 | c29ac11d | Ilias Tsitsimpis | apt-get update
|
415 | c29ac11d | Ilias Tsitsimpis | apt-get install curl git --yes
|
416 | c29ac11d | Ilias Tsitsimpis | echo -e "\n\ndeb {0}" >> /etc/apt/sources.list
|
417 | c29ac11d | Ilias Tsitsimpis | curl https://dev.grnet.gr/files/apt-grnetdev.pub | apt-key add -
|
418 | c29ac11d | Ilias Tsitsimpis | apt-get update
|
419 | c29ac11d | Ilias Tsitsimpis | git config --global user.name {1}
|
420 | b52c7bb0 | Christos Stavrakakis | git config --global user.email {2}
|
421 | c29ac11d | Ilias Tsitsimpis | """.format(self.config.get('Global', 'apt_repo'), |
422 | c29ac11d | Ilias Tsitsimpis | self.config.get('Global', 'git_config_name'), |
423 | c29ac11d | Ilias Tsitsimpis | self.config.get('Global', 'git_config_mail')) |
424 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
425 | c29ac11d | Ilias Tsitsimpis | |
426 | c29ac11d | Ilias Tsitsimpis | synnefo_repo = self.config.get('Global', 'synnefo_repo') |
427 | b69b55ca | Christos Stavrakakis | synnefo_branch = self.config.get("Global", "synnefo_branch") |
428 | b69b55ca | Christos Stavrakakis | if synnefo_branch == "": |
429 | e2a0abb8 | Ilias Tsitsimpis | synnefo_branch = \ |
430 | e2a0abb8 | Ilias Tsitsimpis | subprocess.Popen( |
431 | e2a0abb8 | Ilias Tsitsimpis | ["git", "rev-parse", "--abbrev-ref", "HEAD"], |
432 | b69b55ca | Christos Stavrakakis | stdout=subprocess.PIPE).communicate()[0].strip()
|
433 | b69b55ca | Christos Stavrakakis | if synnefo_branch == "HEAD": |
434 | b69b55ca | Christos Stavrakakis | synnefo_branch = \ |
435 | e2a0abb8 | Ilias Tsitsimpis | subprocess.Popen( |
436 | e2a0abb8 | Ilias Tsitsimpis | ["git", "rev-parse", "--short", "HEAD"], |
437 | b69b55ca | Christos Stavrakakis | stdout=subprocess.PIPE).communicate()[0].strip()
|
438 | b69b55ca | Christos Stavrakakis | self.logger.info("Will use branch %s" % synnefo_branch) |
439 | c29ac11d | Ilias Tsitsimpis | # Currently clonning synnefo can fail unexpectedly
|
440 | e908a902 | Christos Stavrakakis | cloned = False
|
441 | b69b55ca | Christos Stavrakakis | for i in range(10): |
442 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Clone synnefo from %s" % synnefo_repo) |
443 | c29ac11d | Ilias Tsitsimpis | try:
|
444 | b69b55ca | Christos Stavrakakis | _run("git clone %s synnefo" % synnefo_repo, False) |
445 | e908a902 | Christos Stavrakakis | cloned = True
|
446 | c29ac11d | Ilias Tsitsimpis | break
|
447 | e2a0abb8 | Ilias Tsitsimpis | except BaseException: |
448 | e908a902 | Christos Stavrakakis | self.logger.warning("Clonning synnefo failed.. retrying %s" |
449 | e908a902 | Christos Stavrakakis | % i) |
450 | e2a0abb8 | Ilias Tsitsimpis | cmd = """
|
451 | b69b55ca | Christos Stavrakakis | cd synnefo
|
452 | e2a0abb8 | Ilias Tsitsimpis | for branch in `git branch -a | grep remotes | \
|
453 | e2a0abb8 | Ilias Tsitsimpis | grep -v HEAD | grep -v master`; do
|
454 | b69b55ca | Christos Stavrakakis | git branch --track ${branch##*/} $branch
|
455 | b69b55ca | Christos Stavrakakis | done
|
456 | b69b55ca | Christos Stavrakakis | git checkout %s
|
457 | b69b55ca | Christos Stavrakakis | """ % (synnefo_branch)
|
458 | b69b55ca | Christos Stavrakakis | _run(cmd, False)
|
459 | b69b55ca | Christos Stavrakakis | |
460 | e908a902 | Christos Stavrakakis | if not cloned: |
461 | e908a902 | Christos Stavrakakis | self.logger.error("Can not clone Synnefo repo.") |
462 | e908a902 | Christos Stavrakakis | sys.exit(-1)
|
463 | c29ac11d | Ilias Tsitsimpis | |
464 | c29ac11d | Ilias Tsitsimpis | deploy_repo = self.config.get('Global', 'deploy_repo') |
465 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Clone snf-deploy from %s" % deploy_repo) |
466 | e908a902 | Christos Stavrakakis | _run("git clone --depth 1 %s" % deploy_repo, False) |
467 | c29ac11d | Ilias Tsitsimpis | |
468 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
469 | c29ac11d | Ilias Tsitsimpis | def build_synnefo(self): |
470 | c29ac11d | Ilias Tsitsimpis | """Build Synnefo packages"""
|
471 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Build Synnefo packages..") |
472 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Install development packages") |
473 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
474 | c29ac11d | Ilias Tsitsimpis | apt-get update
|
475 | c29ac11d | Ilias Tsitsimpis | apt-get install zlib1g-dev dpkg-dev debhelper git-buildpackage \
|
476 | c29ac11d | Ilias Tsitsimpis | python-dev python-all python-pip --yes
|
477 | c29ac11d | Ilias Tsitsimpis | pip install devflow
|
478 | c29ac11d | Ilias Tsitsimpis | """
|
479 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
480 | c29ac11d | Ilias Tsitsimpis | |
481 | e908a902 | Christos Stavrakakis | if self.config.get('Global', 'patch_pydist') == "True": |
482 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Patch pydist.py module") |
483 | c29ac11d | Ilias Tsitsimpis | cmd = r"""
|
484 | c29ac11d | Ilias Tsitsimpis | sed -r -i 's/(\(\?P<name>\[A-Za-z\]\[A-Za-z0-9_\.)/\1\\\-/' \ |
485 | c29ac11d | Ilias Tsitsimpis | /usr/share/python/debpython/pydist.py |
486 | c29ac11d | Ilias Tsitsimpis | """
|
487 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
488 | c29ac11d | Ilias Tsitsimpis |
|
489 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Build snf-deploy package")
|
490 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
491 | c29ac11d | Ilias Tsitsimpis | git checkout -t origin/debian |
492 | c29ac11d | Ilias Tsitsimpis | git-buildpackage --git-upstream-branch=master \ |
493 | c29ac11d | Ilias Tsitsimpis | --git-debian-branch=debian \ |
494 | c29ac11d | Ilias Tsitsimpis | --git-export-dir=../snf-deploy_build-area \ |
495 | c29ac11d | Ilias Tsitsimpis | -uc -us |
496 | c29ac11d | Ilias Tsitsimpis | """
|
497 | c29ac11d | Ilias Tsitsimpis | with fabric.cd("snf-deploy"):
|
498 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
499 | c29ac11d | Ilias Tsitsimpis |
|
500 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Install snf-deploy package")
|
501 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
502 | c29ac11d | Ilias Tsitsimpis | dpkg -i snf-deploy*.deb |
503 | c29ac11d | Ilias Tsitsimpis | apt-get -f install --yes |
504 | c29ac11d | Ilias Tsitsimpis | """
|
505 | c29ac11d | Ilias Tsitsimpis | with fabric.cd("snf-deploy_build-area"):
|
506 | c29ac11d | Ilias Tsitsimpis | with fabric.settings(warn_only=True):
|
507 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
508 | c29ac11d | Ilias Tsitsimpis |
|
509 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Build synnefo packages")
|
510 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
511 | c29ac11d | Ilias Tsitsimpis | devflow-autopkg snapshot -b ~/synnefo_build-area --no-sign |
512 | c29ac11d | Ilias Tsitsimpis | """
|
513 | c29ac11d | Ilias Tsitsimpis | with fabric.cd("synnefo"):
|
514 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
515 | c29ac11d | Ilias Tsitsimpis |
|
516 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Copy synnefo debs to snf-deploy packages dir")
|
517 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
518 | c29ac11d | Ilias Tsitsimpis | cp ~/synnefo_build-area/*.deb /var/lib/snf-deploy/packages/ |
519 | c29ac11d | Ilias Tsitsimpis | """
|
520 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
521 | c29ac11d | Ilias Tsitsimpis |
|
522 | 88e6558b | Christos Stavrakakis | @_check_fabric
|
523 | 88e6558b | Christos Stavrakakis | def build_documentation(self):
|
524 | e2a0abb8 | Ilias Tsitsimpis | """Build Synnefo documentation""" |
525 | 88e6558b | Christos Stavrakakis | self.logger.info("Build Synnefo documentation..")
|
526 | 88e6558b | Christos Stavrakakis | _run("pip install -U Sphinx", False)
|
527 | 88e6558b | Christos Stavrakakis | with fabric.cd("synnefo"):
|
528 | e2a0abb8 | Ilias Tsitsimpis | _run("devflow-update-version; "
|
529 | e2a0abb8 | Ilias Tsitsimpis | "./ci/make_docs.sh synnefo_documentation", False)
|
530 | 88e6558b | Christos Stavrakakis |
|
531 | 88e6558b | Christos Stavrakakis | def fetch_documentation(self, dest=None):
|
532 | e2a0abb8 | Ilias Tsitsimpis | """Fetch Synnefo documentation""" |
533 | e2a0abb8 | Ilias Tsitsimpis | self.logger.info("Fetch Synnefo documentation..")
|
534 | 88e6558b | Christos Stavrakakis | if dest is None:
|
535 | 88e6558b | Christos Stavrakakis | dest = "synnefo_documentation"
|
536 | 88e6558b | Christos Stavrakakis | dest = os.path.abspath(dest)
|
537 | 88e6558b | Christos Stavrakakis | if not os.path.exists(dest):
|
538 | 88e6558b | Christos Stavrakakis | os.makedirs(dest)
|
539 | 88e6558b | Christos Stavrakakis | self.fetch_compressed("synnefo/synnefo_documentation", dest)
|
540 | 88e6558b | Christos Stavrakakis | self.logger.info("Downloaded documentation to %s" %
|
541 | 88e6558b | Christos Stavrakakis | _green(dest))
|
542 | 88e6558b | Christos Stavrakakis |
|
543 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
544 | ec8bc030 | Christos Stavrakakis | def deploy_synnefo(self, schema=None):
|
545 | c29ac11d | Ilias Tsitsimpis | """Deploy Synnefo using snf-deploy""" |
546 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Deploy Synnefo..")
|
547 | ec8bc030 | Christos Stavrakakis | if schema is None:
|
548 | ec8bc030 | Christos Stavrakakis | schema = self.config.get('Global', 'schema')
|
549 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Will use %s schema" % schema)
|
550 | c29ac11d | Ilias Tsitsimpis |
|
551 | ec8bc030 | Christos Stavrakakis | schema_dir = os.path.join(self.ci_dir, "schemas/%s" % schema)
|
552 | ec8bc030 | Christos Stavrakakis | if not (os.path.exists(schema_dir) and os.path.isdir(schema_dir)):
|
553 | ec8bc030 | Christos Stavrakakis | raise ValueError("Unknown schema: %s" % schema)
|
554 | ec8bc030 | Christos Stavrakakis |
|
555 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Upload schema files to server")
|
556 | 6868804a | Ilias Tsitsimpis | _put(os.path.join(schema_dir, "*"), "/etc/snf-deploy/")
|
557 | c29ac11d | Ilias Tsitsimpis |
|
558 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Change password in nodes.conf file")
|
559 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
560 | c29ac11d | Ilias Tsitsimpis | sed -i 's/^password =.*/password = {0}/' /etc/snf-deploy/nodes.conf
|
561 | c29ac11d | Ilias Tsitsimpis | """.format(fabric.env.password)
|
562 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
563 | c29ac11d | Ilias Tsitsimpis |
|
564 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Run snf-deploy")
|
565 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
566 | c29ac11d | Ilias Tsitsimpis | snf-deploy all --autoconf
|
567 | c29ac11d | Ilias Tsitsimpis | """
|
568 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
569 | c29ac11d | Ilias Tsitsimpis |
|
570 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
571 | c29ac11d | Ilias Tsitsimpis | def unit_test(self):
|
572 | c29ac11d | Ilias Tsitsimpis | """Run Synnefo unit test suite""" |
573 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Run Synnefo unit test suite")
|
574 | c29ac11d | Ilias Tsitsimpis | component = self.config.get('Unit Tests', 'component')
|
575 | c29ac11d | Ilias Tsitsimpis |
|
576 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Install needed packages")
|
577 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
578 | c29ac11d | Ilias Tsitsimpis | pip install mock |
579 | c29ac11d | Ilias Tsitsimpis | pip install factory_boy |
580 | c29ac11d | Ilias Tsitsimpis | """
|
581 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
582 | c29ac11d | Ilias Tsitsimpis |
|
583 | 861b437e | Ilias Tsitsimpis | self.logger.debug("Upload tests.sh file")
|
584 | 861b437e | Ilias Tsitsimpis | unit_tests_file = os.path.join(self.ci_dir, "tests.sh")
|
585 | 6868804a | Ilias Tsitsimpis | _put(unit_tests_file, ".")
|
586 | c29ac11d | Ilias Tsitsimpis |
|
587 | c29ac11d | Ilias Tsitsimpis | self.logger.debug("Run unit tests")
|
588 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
589 | 861b437e | Ilias Tsitsimpis | bash tests.sh {0}
|
590 | c29ac11d | Ilias Tsitsimpis | """.format(component)
|
591 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
592 | c29ac11d | Ilias Tsitsimpis |
|
593 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
594 | c29ac11d | Ilias Tsitsimpis | def run_burnin(self):
|
595 | c29ac11d | Ilias Tsitsimpis | """Run burnin functional test suite""" |
596 | c29ac11d | Ilias Tsitsimpis | self.logger.info("Run Burnin functional test suite")
|
597 | c29ac11d | Ilias Tsitsimpis | cmd = """
|
598 | c29ac11d | Ilias Tsitsimpis | auth_url=$(grep -e '^url =' .kamakirc | cut -d' ' -f3) |
599 | c29ac11d | Ilias Tsitsimpis | token=$(grep -e '^token =' .kamakirc | cut -d' ' -f3) |
600 | c29ac11d | Ilias Tsitsimpis | images_user=$(kamaki image list -l | grep owner | \ |
601 | c29ac11d | Ilias Tsitsimpis | cut -d':' -f2 | tr -d ' ') |
602 | c29ac11d | Ilias Tsitsimpis | snf-burnin --auth-url=$auth_url --token=$token \ |
603 | c29ac11d | Ilias Tsitsimpis | --force-flavor=2 --image-id=all \ |
604 | c29ac11d | Ilias Tsitsimpis | --system-images-user=$images_user \
|
605 | c29ac11d | Ilias Tsitsimpis | {0}
|
606 | c29ac11d | Ilias Tsitsimpis | log_folder=$(ls -1d /var/log/burnin/* | tail -n1) |
607 | c29ac11d | Ilias Tsitsimpis | for i in $(ls $log_folder/*/details*); do |
608 | c29ac11d | Ilias Tsitsimpis | echo -e "\\n\\n"
|
609 | c29ac11d | Ilias Tsitsimpis | echo -e "***** $i\\n"
|
610 | c29ac11d | Ilias Tsitsimpis | cat $i
|
611 | c29ac11d | Ilias Tsitsimpis | done |
612 | c29ac11d | Ilias Tsitsimpis | """.format(self.config.get('Burnin', 'cmd_options'))
|
613 | c29ac11d | Ilias Tsitsimpis | _run(cmd, True)
|
614 | c29ac11d | Ilias Tsitsimpis |
|
615 | c29ac11d | Ilias Tsitsimpis | @_check_fabric
|
616 | 88e6558b | Christos Stavrakakis | def fetch_compressed(self, src, dest=None):
|
617 | e2a0abb8 | Ilias Tsitsimpis | """Create a tarball and fetch it locally""" |
618 | 88e6558b | Christos Stavrakakis | self.logger.debug("Creating tarball of %s" % src)
|
619 | 88e6558b | Christos Stavrakakis | basename = os.path.basename(src)
|
620 | 88e6558b | Christos Stavrakakis | tar_file = basename + ".tgz"
|
621 | 88e6558b | Christos Stavrakakis | cmd = "tar czf %s %s" % (tar_file, src)
|
622 | c29ac11d | Ilias Tsitsimpis | _run(cmd, False)
|
623 | 88e6558b | Christos Stavrakakis | if not os.path.exists(dest):
|
624 | 88e6558b | Christos Stavrakakis | os.makedirs(dest)
|
625 | c29ac11d | Ilias Tsitsimpis |
|
626 | 88e6558b | Christos Stavrakakis | tmp_dir = tempfile.mkdtemp()
|
627 | 88e6558b | Christos Stavrakakis | fabric.get(tar_file, tmp_dir)
|
628 | c29ac11d | Ilias Tsitsimpis |
|
629 | 88e6558b | Christos Stavrakakis | dest_file = os.path.join(tmp_dir, tar_file)
|
630 | 88e6558b | Christos Stavrakakis | self._check_hash_sum(dest_file, tar_file)
|
631 | 88e6558b | Christos Stavrakakis | self.logger.debug("Untar packages file %s" % dest_file)
|
632 | e2dc37b2 | Christos Stavrakakis | cmd = """
|
633 | e2dc37b2 | Christos Stavrakakis | cd %s |
634 | 88e6558b | Christos Stavrakakis | tar xzf %s |
635 | 88e6558b | Christos Stavrakakis | cp -r %s/* %s |
636 | 88e6558b | Christos Stavrakakis | rm -r %s |
637 | 88e6558b | Christos Stavrakakis | """ % (tmp_dir, tar_file, src, dest, tmp_dir)
|
638 | e2dc37b2 | Christos Stavrakakis | os.system(cmd)
|
639 | 88e6558b | Christos Stavrakakis | self.logger.info("Downloaded %s to %s" %
|
640 | 88e6558b | Christos Stavrakakis | (src, _green(dest)))
|
641 | 88e6558b | Christos Stavrakakis |
|
642 | 88e6558b | Christos Stavrakakis | @_check_fabric
|
643 | 88e6558b | Christos Stavrakakis | def fetch_packages(self, dest=None):
|
644 | e2a0abb8 | Ilias Tsitsimpis | """Fetch Synnefo packages""" |
645 | 88e6558b | Christos Stavrakakis | if dest is None:
|
646 | 88e6558b | Christos Stavrakakis | dest = self.config.get('Global', 'pkgs_dir')
|
647 | 88e6558b | Christos Stavrakakis | dest = os.path.abspath(dest)
|
648 | 88e6558b | Christos Stavrakakis | if not os.path.exists(dest):
|
649 | 88e6558b | Christos Stavrakakis | os.makedirs(dest)
|
650 | 88e6558b | Christos Stavrakakis | self.fetch_compressed("synnefo_build-area", dest)
|
651 | 464e58e9 | Christos Stavrakakis | self.logger.info("Downloaded debian packages to %s" %
|
652 | 88e6558b | Christos Stavrakakis | _green(dest)) |