Statistics
| Branch: | Tag: | Revision:

root / ci / utils.py @ c29ac11d

History | View | Annotate | Download (17.6 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 c29ac11d Ilias Tsitsimpis
import sys
9 c29ac11d Ilias Tsitsimpis
import time
10 c29ac11d Ilias Tsitsimpis
import logging
11 c29ac11d Ilias Tsitsimpis
import fabric.api as fabric
12 c29ac11d Ilias Tsitsimpis
from ConfigParser import ConfigParser, DuplicateSectionError
13 c29ac11d Ilias Tsitsimpis
14 c29ac11d Ilias Tsitsimpis
from kamaki.clients.astakos import AstakosClient
15 c29ac11d Ilias Tsitsimpis
from kamaki.clients.cyclades import CycladesClient
16 c29ac11d Ilias Tsitsimpis
from kamaki.clients.image import ImageClient
17 c29ac11d Ilias Tsitsimpis
18 c29ac11d Ilias Tsitsimpis
19 c29ac11d Ilias Tsitsimpis
def _run(cmd, verbose):
20 c29ac11d Ilias Tsitsimpis
    """Run fabric with verbose level"""
21 c29ac11d Ilias Tsitsimpis
    if verbose:
22 c29ac11d Ilias Tsitsimpis
        args = ('running',)
23 c29ac11d Ilias Tsitsimpis
    else:
24 c29ac11d Ilias Tsitsimpis
        args = ('running', 'stdout',)
25 c29ac11d Ilias Tsitsimpis
    with fabric.hide(*args):
26 c29ac11d Ilias Tsitsimpis
        return fabric.run(cmd)
27 c29ac11d Ilias Tsitsimpis
28 c29ac11d Ilias Tsitsimpis
29 c29ac11d Ilias Tsitsimpis
def _red(msg):
30 c29ac11d Ilias Tsitsimpis
    """Red color"""
31 c29ac11d Ilias Tsitsimpis
    #return "\x1b[31m" + str(msg) + "\x1b[0m"
32 c29ac11d Ilias Tsitsimpis
    return str(msg)
33 c29ac11d Ilias Tsitsimpis
34 c29ac11d Ilias Tsitsimpis
35 c29ac11d Ilias Tsitsimpis
def _yellow(msg):
36 c29ac11d Ilias Tsitsimpis
    """Yellow color"""
37 c29ac11d Ilias Tsitsimpis
    #return "\x1b[33m" + str(msg) + "\x1b[0m"
38 c29ac11d Ilias Tsitsimpis
    return str(msg)
39 c29ac11d Ilias Tsitsimpis
40 c29ac11d Ilias Tsitsimpis
41 c29ac11d Ilias Tsitsimpis
def _green(msg):
42 c29ac11d Ilias Tsitsimpis
    """Green color"""
43 c29ac11d Ilias Tsitsimpis
    #return "\x1b[32m" + str(msg) + "\x1b[0m"
44 c29ac11d Ilias Tsitsimpis
    return str(msg)
45 c29ac11d Ilias Tsitsimpis
46 c29ac11d Ilias Tsitsimpis
47 c29ac11d Ilias Tsitsimpis
def _check_fabric(fun):
48 c29ac11d Ilias Tsitsimpis
    """Check if fabric env has been set"""
49 c29ac11d Ilias Tsitsimpis
    def wrapper(self, *args):
50 c29ac11d Ilias Tsitsimpis
        """wrapper function"""
51 c29ac11d Ilias Tsitsimpis
        if not self.fabric_installed:
52 c29ac11d Ilias Tsitsimpis
            self.setup_fabric()
53 c29ac11d Ilias Tsitsimpis
        return fun(self, *args)
54 c29ac11d Ilias Tsitsimpis
    return wrapper
55 c29ac11d Ilias Tsitsimpis
56 c29ac11d Ilias Tsitsimpis
57 c29ac11d Ilias Tsitsimpis
def _check_kamaki(fun):
58 c29ac11d Ilias Tsitsimpis
    """Check if kamaki has been initialized"""
59 c29ac11d Ilias Tsitsimpis
    def wrapper(self, *args):
60 c29ac11d Ilias Tsitsimpis
        """wrapper function"""
61 c29ac11d Ilias Tsitsimpis
        if not self.kamaki_installed:
62 c29ac11d Ilias Tsitsimpis
            self.setup_kamaki()
63 c29ac11d Ilias Tsitsimpis
        return fun(self, *args)
64 c29ac11d Ilias Tsitsimpis
    return wrapper
65 c29ac11d Ilias Tsitsimpis
66 c29ac11d Ilias Tsitsimpis
67 c29ac11d Ilias Tsitsimpis
class _MyFormatter(logging.Formatter):
68 c29ac11d Ilias Tsitsimpis
    """Logging Formatter"""
69 c29ac11d Ilias Tsitsimpis
    def format(self, record):
70 c29ac11d Ilias Tsitsimpis
        format_orig = self._fmt
71 c29ac11d Ilias Tsitsimpis
        if record.levelno == logging.DEBUG:
72 c29ac11d Ilias Tsitsimpis
            self._fmt = "  %(msg)s"
73 c29ac11d Ilias Tsitsimpis
        elif record.levelno == logging.INFO:
74 c29ac11d Ilias Tsitsimpis
            self._fmt = "%(msg)s"
75 c29ac11d Ilias Tsitsimpis
        elif record.levelno == logging.WARNING:
76 c29ac11d Ilias Tsitsimpis
            self._fmt = _yellow("[W] %(msg)s")
77 c29ac11d Ilias Tsitsimpis
        elif record.levelno == logging.ERROR:
78 c29ac11d Ilias Tsitsimpis
            self._fmt = _red("[E] %(msg)s")
79 c29ac11d Ilias Tsitsimpis
        result = logging.Formatter.format(self, record)
80 c29ac11d Ilias Tsitsimpis
        self._fmt = format_orig
81 c29ac11d Ilias Tsitsimpis
        return result
82 c29ac11d Ilias Tsitsimpis
83 c29ac11d Ilias Tsitsimpis
84 c29ac11d Ilias Tsitsimpis
class SynnefoCI(object):
85 c29ac11d Ilias Tsitsimpis
    """SynnefoCI python class"""
86 c29ac11d Ilias Tsitsimpis
87 c29ac11d Ilias Tsitsimpis
    def __init__(self, cleanup_config=False):
88 c29ac11d Ilias Tsitsimpis
        """ Initialize SynnefoCI python class
89 c29ac11d Ilias Tsitsimpis

90 c29ac11d Ilias Tsitsimpis
        Setup logger, local_dir, config and kamaki
91 c29ac11d Ilias Tsitsimpis
        """
92 c29ac11d Ilias Tsitsimpis
        # Setup logger
93 c29ac11d Ilias Tsitsimpis
        self.logger = logging.getLogger('synnefo-ci')
94 c29ac11d Ilias Tsitsimpis
        self.logger.setLevel(logging.DEBUG)
95 c29ac11d Ilias Tsitsimpis
        handler = logging.StreamHandler()
96 c29ac11d Ilias Tsitsimpis
        handler.setFormatter(_MyFormatter())
97 c29ac11d Ilias Tsitsimpis
        self.logger.addHandler(handler)
98 c29ac11d Ilias Tsitsimpis
99 c29ac11d Ilias Tsitsimpis
        # Get our local dir
100 c29ac11d Ilias Tsitsimpis
        self.ci_dir = os.path.dirname(os.path.abspath(__file__))
101 c29ac11d Ilias Tsitsimpis
        self.repo_dir = os.path.dirname(self.ci_dir)
102 c29ac11d Ilias Tsitsimpis
103 c29ac11d Ilias Tsitsimpis
        # Read config file
104 c29ac11d Ilias Tsitsimpis
        self.conffile = os.path.join(self.ci_dir, "new_config")
105 c29ac11d Ilias Tsitsimpis
        self.config = ConfigParser()
106 c29ac11d Ilias Tsitsimpis
        self.config.optionxform = str
107 c29ac11d Ilias Tsitsimpis
        self.config.read(self.conffile)
108 c29ac11d Ilias Tsitsimpis
        temp_config = self.config.get('Global', 'temporary_config')
109 c29ac11d Ilias Tsitsimpis
        if cleanup_config:
110 c29ac11d Ilias Tsitsimpis
            try:
111 c29ac11d Ilias Tsitsimpis
                os.remove(temp_config)
112 c29ac11d Ilias Tsitsimpis
            except:
113 c29ac11d Ilias Tsitsimpis
                pass
114 c29ac11d Ilias Tsitsimpis
        else:
115 c29ac11d Ilias Tsitsimpis
            self.config.read(self.config.get('Global', 'temporary_config'))
116 c29ac11d Ilias Tsitsimpis
117 c29ac11d Ilias Tsitsimpis
        # Initialize variables
118 c29ac11d Ilias Tsitsimpis
        self.fabric_installed = False
119 c29ac11d Ilias Tsitsimpis
        self.kamaki_installed = False
120 c29ac11d Ilias Tsitsimpis
        self.cyclades_client = None
121 c29ac11d Ilias Tsitsimpis
        self.image_client = None
122 c29ac11d Ilias Tsitsimpis
123 c29ac11d Ilias Tsitsimpis
    def setup_kamaki(self):
124 c29ac11d Ilias Tsitsimpis
        """Initialize kamaki
125 c29ac11d Ilias Tsitsimpis

126 c29ac11d Ilias Tsitsimpis
        Setup cyclades_client and image_client
127 c29ac11d Ilias Tsitsimpis
        """
128 c29ac11d Ilias Tsitsimpis
        self.logger.info("Setup kamaki client..")
129 c29ac11d Ilias Tsitsimpis
        auth_url = self.config.get('Deployment', 'auth_url')
130 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Authentication URL is %s" % _green(auth_url))
131 c29ac11d Ilias Tsitsimpis
        token = self.config.get('Deployment', 'token')
132 c29ac11d Ilias Tsitsimpis
        #self.logger.debug("Token is %s" % _green(token))
133 c29ac11d Ilias Tsitsimpis
134 c29ac11d Ilias Tsitsimpis
        astakos_client = AstakosClient(auth_url, token)
135 c29ac11d Ilias Tsitsimpis
136 c29ac11d Ilias Tsitsimpis
        cyclades_url = \
137 c29ac11d Ilias Tsitsimpis
            astakos_client.get_service_endpoints('compute')['publicURL']
138 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Cyclades API url is %s" % _green(cyclades_url))
139 c29ac11d Ilias Tsitsimpis
        self.cyclades_client = CycladesClient(cyclades_url, token)
140 c29ac11d Ilias Tsitsimpis
        self.cyclades_client.CONNECTION_RETRY_LIMIT = 2
141 c29ac11d Ilias Tsitsimpis
142 c29ac11d Ilias Tsitsimpis
        image_url = \
143 c29ac11d Ilias Tsitsimpis
            astakos_client.get_service_endpoints('image')['publicURL']
144 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Images API url is %s" % _green(image_url))
145 c29ac11d Ilias Tsitsimpis
        self.image_client = ImageClient(cyclades_url, token)
146 c29ac11d Ilias Tsitsimpis
        self.image_client.CONNECTION_RETRY_LIMIT = 2
147 c29ac11d Ilias Tsitsimpis
148 c29ac11d Ilias Tsitsimpis
    def _wait_transition(self, server_id, current_status, new_status):
149 c29ac11d Ilias Tsitsimpis
        """Wait for server to go from current_status to new_status"""
150 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Waiting for server to become %s" % new_status)
151 c29ac11d Ilias Tsitsimpis
        timeout = self.config.getint('Global', 'build_timeout')
152 c29ac11d Ilias Tsitsimpis
        sleep_time = 5
153 c29ac11d Ilias Tsitsimpis
        while True:
154 c29ac11d Ilias Tsitsimpis
            server = self.cyclades_client.get_server_details(server_id)
155 c29ac11d Ilias Tsitsimpis
            if server['status'] == new_status:
156 c29ac11d Ilias Tsitsimpis
                return server
157 c29ac11d Ilias Tsitsimpis
            elif timeout < 0:
158 c29ac11d Ilias Tsitsimpis
                self.logger.error(
159 c29ac11d Ilias Tsitsimpis
                    "Waiting for server to become %s timed out" % new_status)
160 c29ac11d Ilias Tsitsimpis
                self.destroy_server(False)
161 c29ac11d Ilias Tsitsimpis
                sys.exit(-1)
162 c29ac11d Ilias Tsitsimpis
            elif server['status'] == current_status:
163 c29ac11d Ilias Tsitsimpis
                # Sleep for #n secs and continue
164 c29ac11d Ilias Tsitsimpis
                timeout = timeout - sleep_time
165 c29ac11d Ilias Tsitsimpis
                time.sleep(sleep_time)
166 c29ac11d Ilias Tsitsimpis
            else:
167 c29ac11d Ilias Tsitsimpis
                self.logger.error(
168 c29ac11d Ilias Tsitsimpis
                    "Server failed with status %s" % server['status'])
169 c29ac11d Ilias Tsitsimpis
                self.destroy_server(False)
170 c29ac11d Ilias Tsitsimpis
                sys.exit(-1)
171 c29ac11d Ilias Tsitsimpis
172 c29ac11d Ilias Tsitsimpis
    @_check_kamaki
173 c29ac11d Ilias Tsitsimpis
    def destroy_server(self, wait=True):
174 c29ac11d Ilias Tsitsimpis
        """Destroy slave server"""
175 c29ac11d Ilias Tsitsimpis
        server_id = self.config.getint('Temporary Options', 'server_id')
176 c29ac11d Ilias Tsitsimpis
        self.logger.info("Destoying server with id %s " % server_id)
177 c29ac11d Ilias Tsitsimpis
        self.cyclades_client.delete_server(server_id)
178 c29ac11d Ilias Tsitsimpis
        if wait:
179 c29ac11d Ilias Tsitsimpis
            self._wait_transition(server_id, "ACTIVE", "DELETED")
180 c29ac11d Ilias Tsitsimpis
181 c29ac11d Ilias Tsitsimpis
    @_check_kamaki
182 c29ac11d Ilias Tsitsimpis
    def create_server(self):
183 c29ac11d Ilias Tsitsimpis
        """Create slave server"""
184 c29ac11d Ilias Tsitsimpis
        self.logger.info("Create a new server..")
185 c29ac11d Ilias Tsitsimpis
        image = self._find_image()
186 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Will use image \"%s\"" % _green(image['name']))
187 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Image has id %s" % _green(image['id']))
188 c29ac11d Ilias Tsitsimpis
        server = self.cyclades_client.create_server(
189 c29ac11d Ilias Tsitsimpis
            self.config.get('Deployment', 'server_name'),
190 c29ac11d Ilias Tsitsimpis
            self.config.getint('Deployment', 'flavor_id'),
191 c29ac11d Ilias Tsitsimpis
            image['id'])
192 c29ac11d Ilias Tsitsimpis
        server_id = server['id']
193 c29ac11d Ilias Tsitsimpis
        self.write_config('server_id', server_id)
194 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Server got id %s" % _green(server_id))
195 c29ac11d Ilias Tsitsimpis
        server_user = server['metadata']['users']
196 c29ac11d Ilias Tsitsimpis
        self.write_config('server_user', server_user)
197 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Server's admin user is %s" % _green(server_user))
198 c29ac11d Ilias Tsitsimpis
        server_passwd = server['adminPass']
199 c29ac11d Ilias Tsitsimpis
        self.write_config('server_passwd', server_passwd)
200 c29ac11d Ilias Tsitsimpis
        self.logger.debug(
201 c29ac11d Ilias Tsitsimpis
            "Server's admin password is %s" % _green(server_passwd))
202 c29ac11d Ilias Tsitsimpis
203 c29ac11d Ilias Tsitsimpis
        server = self._wait_transition(server_id, "BUILD", "ACTIVE")
204 c29ac11d Ilias Tsitsimpis
        self._get_server_ip_and_port(server)
205 c29ac11d Ilias Tsitsimpis
206 c29ac11d Ilias Tsitsimpis
        self.setup_fabric()
207 c29ac11d Ilias Tsitsimpis
        self.logger.info("Setup firewall")
208 c29ac11d Ilias Tsitsimpis
        accept_ssh_from = self.config.get('Global', 'filter_access_network')
209 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Block ssh except from %s" % accept_ssh_from)
210 c29ac11d Ilias Tsitsimpis
        cmd = """
211 c29ac11d Ilias Tsitsimpis
        iptables -A INPUT -s localhost -j ACCEPT
212 c29ac11d Ilias Tsitsimpis
        iptables -A INPUT -s {0} -p tcp --dport 22 -j ACCEPT
213 c29ac11d Ilias Tsitsimpis
        iptables -A INPUT -p tcp --dport 22 -j DROP
214 c29ac11d Ilias Tsitsimpis
        """.format(accept_ssh_from)
215 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
216 c29ac11d Ilias Tsitsimpis
217 c29ac11d Ilias Tsitsimpis
    def _find_image(self):
218 c29ac11d Ilias Tsitsimpis
        """Find a suitable image to use
219 c29ac11d Ilias Tsitsimpis

220 c29ac11d Ilias Tsitsimpis
        It has to belong to the `system_uuid' user and
221 c29ac11d Ilias Tsitsimpis
        contain the word `image_name'
222 c29ac11d Ilias Tsitsimpis
        """
223 c29ac11d Ilias Tsitsimpis
        system_uuid = self.config.get('Deployment', 'system_uuid')
224 c29ac11d Ilias Tsitsimpis
        image_name = self.config.get('Deployment', 'image_name').lower()
225 c29ac11d Ilias Tsitsimpis
        images = self.image_client.list_public(detail=True)['images']
226 c29ac11d Ilias Tsitsimpis
        # Select images by `system_uuid' user
227 c29ac11d Ilias Tsitsimpis
        images = [x for x in images if x['user_id'] == system_uuid]
228 c29ac11d Ilias Tsitsimpis
        # Select images with `image_name' in their names
229 c29ac11d Ilias Tsitsimpis
        images = \
230 c29ac11d Ilias Tsitsimpis
            [x for x in images if x['name'].lower().find(image_name) != -1]
231 c29ac11d Ilias Tsitsimpis
        # Let's select the first one
232 c29ac11d Ilias Tsitsimpis
        return images[0]
233 c29ac11d Ilias Tsitsimpis
234 c29ac11d Ilias Tsitsimpis
    def _get_server_ip_and_port(self, server):
235 c29ac11d Ilias Tsitsimpis
        """Compute server's IPv4 and ssh port number"""
236 c29ac11d Ilias Tsitsimpis
        self.logger.info("Get server connection details..")
237 c29ac11d Ilias Tsitsimpis
        # XXX: check if this IP is from public network
238 c29ac11d Ilias Tsitsimpis
        server_ip = server['attachments'][0]['ipv4']
239 c29ac11d Ilias Tsitsimpis
        if eval(self.config.get('Deployment', 'deploy_on_io')):
240 c29ac11d Ilias Tsitsimpis
            tmp1 = int(server_ip.split(".")[2])
241 c29ac11d Ilias Tsitsimpis
            tmp2 = int(server_ip.split(".")[3])
242 c29ac11d Ilias Tsitsimpis
            server_ip = "gate.okeanos.io"
243 c29ac11d Ilias Tsitsimpis
            server_port = 10000 + tmp1 * 256 + tmp2
244 c29ac11d Ilias Tsitsimpis
        else:
245 c29ac11d Ilias Tsitsimpis
            server_port = 22
246 c29ac11d Ilias Tsitsimpis
        self.write_config('server_ip', server_ip)
247 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Server's IPv4 is %s" % _green(server_ip))
248 c29ac11d Ilias Tsitsimpis
        self.write_config('server_port', server_port)
249 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Server's ssh port is %s" % _green(server_port))
250 c29ac11d Ilias Tsitsimpis
251 c29ac11d Ilias Tsitsimpis
    def write_config(self, option, value, section="Temporary Options"):
252 c29ac11d Ilias Tsitsimpis
        """Write changes back to config file"""
253 c29ac11d Ilias Tsitsimpis
        try:
254 c29ac11d Ilias Tsitsimpis
            self.config.add_section(section)
255 c29ac11d Ilias Tsitsimpis
        except DuplicateSectionError:
256 c29ac11d Ilias Tsitsimpis
            pass
257 c29ac11d Ilias Tsitsimpis
        self.config.set(section, option, str(value))
258 c29ac11d Ilias Tsitsimpis
        temp_conf_file = self.config.get('Global', 'temporary_config')
259 c29ac11d Ilias Tsitsimpis
        with open(temp_conf_file, 'wb') as tcf:
260 c29ac11d Ilias Tsitsimpis
            self.config.write(tcf)
261 c29ac11d Ilias Tsitsimpis
262 c29ac11d Ilias Tsitsimpis
    def setup_fabric(self):
263 c29ac11d Ilias Tsitsimpis
        """Setup fabric environment"""
264 c29ac11d Ilias Tsitsimpis
        self.logger.info("Setup fabric parameters..")
265 c29ac11d Ilias Tsitsimpis
        fabric.env.user = self.config.get('Temporary Options', 'server_user')
266 c29ac11d Ilias Tsitsimpis
        fabric.env.host_string = \
267 c29ac11d Ilias Tsitsimpis
            self.config.get('Temporary Options', 'server_ip')
268 c29ac11d Ilias Tsitsimpis
        fabric.env.port = self.config.getint('Temporary Options', 'server_port')
269 c29ac11d Ilias Tsitsimpis
        fabric.env.password = \
270 c29ac11d Ilias Tsitsimpis
            self.config.get('Temporary Options', 'server_passwd')
271 c29ac11d Ilias Tsitsimpis
        fabric.env.connection_attempts = 10
272 c29ac11d Ilias Tsitsimpis
        fabric.env.shell = "/bin/bash -c"
273 c29ac11d Ilias Tsitsimpis
        fabric.env.disable_known_hosts = True
274 c29ac11d Ilias Tsitsimpis
        fabric.env.output_prefix = None
275 c29ac11d Ilias Tsitsimpis
276 c29ac11d Ilias Tsitsimpis
    def _check_hash_sum(self, localfile, remotefile):
277 c29ac11d Ilias Tsitsimpis
        """Check hash sums of two files"""
278 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Check hash sum for local file %s" % localfile)
279 c29ac11d Ilias Tsitsimpis
        hash1 = os.popen("sha256sum %s" % localfile).read().split(' ')[0]
280 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Local file has sha256 hash %s" % hash1)
281 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Check hash sum for remote file %s" % remotefile)
282 c29ac11d Ilias Tsitsimpis
        hash2 = _run("sha256sum %s" % remotefile, False)
283 c29ac11d Ilias Tsitsimpis
        hash2 = hash2.split(' ')[0]
284 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Remote file has sha256 hash %s" % hash2)
285 c29ac11d Ilias Tsitsimpis
        if hash1 != hash2:
286 c29ac11d Ilias Tsitsimpis
            self.logger.error("Hashes differ.. aborting")
287 c29ac11d Ilias Tsitsimpis
            sys.exit(-1)
288 c29ac11d Ilias Tsitsimpis
289 c29ac11d Ilias Tsitsimpis
    @_check_fabric
290 c29ac11d Ilias Tsitsimpis
    def clone_repo(self):
291 c29ac11d Ilias Tsitsimpis
        """Clone Synnefo repo from slave server"""
292 c29ac11d Ilias Tsitsimpis
        self.logger.info("Configure repositories on remote server..")
293 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Setup apt, install curl and git")
294 c29ac11d Ilias Tsitsimpis
        cmd = """
295 c29ac11d Ilias Tsitsimpis
        echo 'APT::Install-Suggests "false";' >> /etc/apt/apt.conf
296 c29ac11d Ilias Tsitsimpis
        apt-get update
297 c29ac11d Ilias Tsitsimpis
        apt-get install curl git --yes
298 c29ac11d Ilias Tsitsimpis
        echo -e "\n\ndeb {0}" >> /etc/apt/sources.list
299 c29ac11d Ilias Tsitsimpis
        curl https://dev.grnet.gr/files/apt-grnetdev.pub | apt-key add -
300 c29ac11d Ilias Tsitsimpis
        apt-get update
301 c29ac11d Ilias Tsitsimpis
        git config --global user.name {1}
302 c29ac11d Ilias Tsitsimpis
        git config --global user.mail {2}
303 c29ac11d Ilias Tsitsimpis
        """.format(self.config.get('Global', 'apt_repo'),
304 c29ac11d Ilias Tsitsimpis
                   self.config.get('Global', 'git_config_name'),
305 c29ac11d Ilias Tsitsimpis
                   self.config.get('Global', 'git_config_mail'))
306 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
307 c29ac11d Ilias Tsitsimpis
308 c29ac11d Ilias Tsitsimpis
        synnefo_repo = self.config.get('Global', 'synnefo_repo')
309 c29ac11d Ilias Tsitsimpis
        # Currently clonning synnefo can fail unexpectedly
310 c29ac11d Ilias Tsitsimpis
        for i in range(3):
311 c29ac11d Ilias Tsitsimpis
            self.logger.debug("Clone synnefo from %s" % synnefo_repo)
312 c29ac11d Ilias Tsitsimpis
            try:
313 c29ac11d Ilias Tsitsimpis
                _run("git clone %s" % synnefo_repo, False)
314 c29ac11d Ilias Tsitsimpis
                break
315 c29ac11d Ilias Tsitsimpis
            except:
316 c29ac11d Ilias Tsitsimpis
                self.logger.warning("Clonning synnefo failed.. retrying %s" % i)
317 c29ac11d Ilias Tsitsimpis
318 c29ac11d Ilias Tsitsimpis
        synnefo_branch = self.config.get('Global', 'synnefo_branch')
319 c29ac11d Ilias Tsitsimpis
        if synnefo_branch == "HEAD":
320 c29ac11d Ilias Tsitsimpis
            # Get current branch
321 c29ac11d Ilias Tsitsimpis
            synnefo_branch = os.popen("git rev-parse HEAD").read().strip()
322 c29ac11d Ilias Tsitsimpis
            self.logger.debug(
323 c29ac11d Ilias Tsitsimpis
                "Checkout %s in feature-ci branch" % synnefo_branch)
324 c29ac11d Ilias Tsitsimpis
            with fabric.cd("synnefo"):
325 c29ac11d Ilias Tsitsimpis
                _run("git checkout -b feature-ci %s" % synnefo_branch, False)
326 c29ac11d Ilias Tsitsimpis
        elif synnefo_branch == "origin/master":
327 c29ac11d Ilias Tsitsimpis
            pass
328 c29ac11d Ilias Tsitsimpis
        elif "origin" in synnefo_branch:
329 c29ac11d Ilias Tsitsimpis
            self.logger.debug("Checkout %s branch" % synnefo_branch)
330 c29ac11d Ilias Tsitsimpis
            with fabric.cd("synnefo"):
331 c29ac11d Ilias Tsitsimpis
                _run("git checkout -t %s" % synnefo_branch, False)
332 c29ac11d Ilias Tsitsimpis
        else:
333 c29ac11d Ilias Tsitsimpis
            self.logger.debug(
334 c29ac11d Ilias Tsitsimpis
                "Checkout %s in feature-ci branch" % synnefo_branch)
335 c29ac11d Ilias Tsitsimpis
            with fabric.cd("synnefo"):
336 c29ac11d Ilias Tsitsimpis
                _run("git checkout -b feature-ci %s" % synnefo_branch, False)
337 c29ac11d Ilias Tsitsimpis
338 c29ac11d Ilias Tsitsimpis
        deploy_repo = self.config.get('Global', 'deploy_repo')
339 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Clone snf-deploy from %s" % deploy_repo)
340 c29ac11d Ilias Tsitsimpis
        _run("git clone %s" % deploy_repo, False)
341 c29ac11d Ilias Tsitsimpis
342 c29ac11d Ilias Tsitsimpis
    @_check_fabric
343 c29ac11d Ilias Tsitsimpis
    def build_synnefo(self):
344 c29ac11d Ilias Tsitsimpis
        """Build Synnefo packages"""
345 c29ac11d Ilias Tsitsimpis
        self.logger.info("Build Synnefo packages..")
346 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Install development packages")
347 c29ac11d Ilias Tsitsimpis
        cmd = """
348 c29ac11d Ilias Tsitsimpis
        apt-get update
349 c29ac11d Ilias Tsitsimpis
        apt-get install zlib1g-dev dpkg-dev debhelper git-buildpackage \
350 c29ac11d Ilias Tsitsimpis
                python-dev python-all python-pip --yes
351 c29ac11d Ilias Tsitsimpis
        pip install devflow
352 c29ac11d Ilias Tsitsimpis
        """
353 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
354 c29ac11d Ilias Tsitsimpis
355 c29ac11d Ilias Tsitsimpis
        if eval(self.config.get('Global', 'patch_pydist')):
356 c29ac11d Ilias Tsitsimpis
            self.logger.debug("Patch pydist.py module")
357 c29ac11d Ilias Tsitsimpis
            cmd = r"""
358 c29ac11d Ilias Tsitsimpis
            sed -r -i 's/(\(\?P<name>\[A-Za-z\]\[A-Za-z0-9_\.)/\1\\\-/' \
359 c29ac11d Ilias Tsitsimpis
                /usr/share/python/debpython/pydist.py
360 c29ac11d Ilias Tsitsimpis
            """
361 c29ac11d Ilias Tsitsimpis
            _run(cmd, False)
362 c29ac11d Ilias Tsitsimpis

363 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Build snf-deploy package")
364 c29ac11d Ilias Tsitsimpis
        cmd = """
365 c29ac11d Ilias Tsitsimpis
        git checkout -t origin/debian
366 c29ac11d Ilias Tsitsimpis
        git-buildpackage --git-upstream-branch=master \
367 c29ac11d Ilias Tsitsimpis
                --git-debian-branch=debian \
368 c29ac11d Ilias Tsitsimpis
                --git-export-dir=../snf-deploy_build-area \
369 c29ac11d Ilias Tsitsimpis
                -uc -us
370 c29ac11d Ilias Tsitsimpis
        """
371 c29ac11d Ilias Tsitsimpis
        with fabric.cd("snf-deploy"):
372 c29ac11d Ilias Tsitsimpis
            _run(cmd, True)
373 c29ac11d Ilias Tsitsimpis

374 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Install snf-deploy package")
375 c29ac11d Ilias Tsitsimpis
        cmd = """
376 c29ac11d Ilias Tsitsimpis
        dpkg -i snf-deploy*.deb
377 c29ac11d Ilias Tsitsimpis
        apt-get -f install --yes
378 c29ac11d Ilias Tsitsimpis
        """
379 c29ac11d Ilias Tsitsimpis
        with fabric.cd("snf-deploy_build-area"):
380 c29ac11d Ilias Tsitsimpis
            with fabric.settings(warn_only=True):
381 c29ac11d Ilias Tsitsimpis
                _run(cmd, True)
382 c29ac11d Ilias Tsitsimpis

383 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Build synnefo packages")
384 c29ac11d Ilias Tsitsimpis
        cmd = """
385 c29ac11d Ilias Tsitsimpis
        devflow-autopkg snapshot -b ~/synnefo_build-area --no-sign
386 c29ac11d Ilias Tsitsimpis
        """
387 c29ac11d Ilias Tsitsimpis
        with fabric.cd("synnefo"):
388 c29ac11d Ilias Tsitsimpis
            _run(cmd, True)
389 c29ac11d Ilias Tsitsimpis

390 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Copy synnefo debs to snf-deploy packages dir")
391 c29ac11d Ilias Tsitsimpis
        cmd = """
392 c29ac11d Ilias Tsitsimpis
        cp ~/synnefo_build-area/*.deb /var/lib/snf-deploy/packages/
393 c29ac11d Ilias Tsitsimpis
        """
394 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
395 c29ac11d Ilias Tsitsimpis

396 c29ac11d Ilias Tsitsimpis
    @_check_fabric
397 c29ac11d Ilias Tsitsimpis
    def deploy_synnefo(self):
398 c29ac11d Ilias Tsitsimpis
        """Deploy Synnefo using snf-deploy"""
399 c29ac11d Ilias Tsitsimpis
        self.logger.info("Deploy Synnefo..")
400 c29ac11d Ilias Tsitsimpis
        schema = self.config.get('Global', 'schema')
401 c29ac11d Ilias Tsitsimpis
        schema_files = os.path.join(self.ci_dir, "schemas/%s/*" % schema)
402 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Will use %s schema" % schema)
403 c29ac11d Ilias Tsitsimpis

404 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Upload schema files to server")
405 c29ac11d Ilias Tsitsimpis
        with fabric.quiet():
406 c29ac11d Ilias Tsitsimpis
            fabric.put(schema_files, "/etc/snf-deploy/")
407 c29ac11d Ilias Tsitsimpis

408 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Change password in nodes.conf file")
409 c29ac11d Ilias Tsitsimpis
        cmd = """
410 c29ac11d Ilias Tsitsimpis
        sed -i 's/^password =.*/password = {0}/' /etc/snf-deploy/nodes.conf
411 c29ac11d Ilias Tsitsimpis
        """.format(fabric.env.password)
412 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
413 c29ac11d Ilias Tsitsimpis

414 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Run snf-deploy")
415 c29ac11d Ilias Tsitsimpis
        cmd = """
416 c29ac11d Ilias Tsitsimpis
        snf-deploy all --autoconf
417 c29ac11d Ilias Tsitsimpis
        """
418 c29ac11d Ilias Tsitsimpis
        _run(cmd, True)
419 c29ac11d Ilias Tsitsimpis

420 c29ac11d Ilias Tsitsimpis
    @_check_fabric
421 c29ac11d Ilias Tsitsimpis
    def unit_test(self):
422 c29ac11d Ilias Tsitsimpis
        """Run Synnefo unit test suite"""
423 c29ac11d Ilias Tsitsimpis
        self.logger.info("Run Synnefo unit test suite")
424 c29ac11d Ilias Tsitsimpis
        component = self.config.get('Unit Tests', 'component')
425 c29ac11d Ilias Tsitsimpis

426 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Install needed packages")
427 c29ac11d Ilias Tsitsimpis
        cmd = """
428 c29ac11d Ilias Tsitsimpis
        pip install mock
429 c29ac11d Ilias Tsitsimpis
        pip install factory_boy
430 c29ac11d Ilias Tsitsimpis
        """
431 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
432 c29ac11d Ilias Tsitsimpis

433 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Upload local_unit_tests.sh file")
434 c29ac11d Ilias Tsitsimpis
        unit_tests_file = os.path.join(self.ci_dir, "local_unit_tests.sh")
435 c29ac11d Ilias Tsitsimpis
        with fabric.quiet():
436 c29ac11d Ilias Tsitsimpis
            fabric.put(unit_tests_file, ".")
437 c29ac11d Ilias Tsitsimpis

438 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Run unit tests")
439 c29ac11d Ilias Tsitsimpis
        cmd = """
440 c29ac11d Ilias Tsitsimpis
        bash local_unit_tests.sh {0}
441 c29ac11d Ilias Tsitsimpis
        """.format(component)
442 c29ac11d Ilias Tsitsimpis
        _run(cmd, True)
443 c29ac11d Ilias Tsitsimpis

444 c29ac11d Ilias Tsitsimpis
    @_check_fabric
445 c29ac11d Ilias Tsitsimpis
    def run_burnin(self):
446 c29ac11d Ilias Tsitsimpis
        """Run burnin functional test suite"""
447 c29ac11d Ilias Tsitsimpis
        self.logger.info("Run Burnin functional test suite")
448 c29ac11d Ilias Tsitsimpis
        cmd = """
449 c29ac11d Ilias Tsitsimpis
        auth_url=$(grep -e '^url =' .kamakirc | cut -d' ' -f3)
450 c29ac11d Ilias Tsitsimpis
        token=$(grep -e '^token =' .kamakirc | cut -d' ' -f3)
451 c29ac11d Ilias Tsitsimpis
        images_user=$(kamaki image list -l | grep owner | \
452 c29ac11d Ilias Tsitsimpis
                      cut -d':' -f2 | tr -d ' ')
453 c29ac11d Ilias Tsitsimpis
        snf-burnin --auth-url=$auth_url --token=$token \
454 c29ac11d Ilias Tsitsimpis
            --force-flavor=2 --image-id=all \
455 c29ac11d Ilias Tsitsimpis
            --system-images-user=$images_user \
456 c29ac11d Ilias Tsitsimpis
            {0}
457 c29ac11d Ilias Tsitsimpis
        log_folder=$(ls -1d /var/log/burnin/* | tail -n1)
458 c29ac11d Ilias Tsitsimpis
        for i in $(ls $log_folder/*/details*); do
459 c29ac11d Ilias Tsitsimpis
            echo -e "\\n\\n"
460 c29ac11d Ilias Tsitsimpis
            echo -e "***** $i\\n"
461 c29ac11d Ilias Tsitsimpis
            cat $i
462 c29ac11d Ilias Tsitsimpis
        done
463 c29ac11d Ilias Tsitsimpis
        """.format(self.config.get('Burnin', 'cmd_options'))
464 c29ac11d Ilias Tsitsimpis
        _run(cmd, True)
465 c29ac11d Ilias Tsitsimpis

466 c29ac11d Ilias Tsitsimpis
    @_check_fabric
467 c29ac11d Ilias Tsitsimpis
    def fetch_packages(self):
468 c29ac11d Ilias Tsitsimpis
        """Download Synnefo packages"""
469 c29ac11d Ilias Tsitsimpis
        self.logger.info("Download Synnefo packages")
470 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Create tarball with packages")
471 c29ac11d Ilias Tsitsimpis
        cmd = """
472 c29ac11d Ilias Tsitsimpis
        tar czf synnefo_build-area.tgz synnefo_build-area
473 c29ac11d Ilias Tsitsimpis
        """
474 c29ac11d Ilias Tsitsimpis
        _run(cmd, False)
475 c29ac11d Ilias Tsitsimpis

476 c29ac11d Ilias Tsitsimpis
        pkgs_dir = self.config.get('Global', 'pkgs_dir')
477 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Fetch packages to local dir %s" % pkgs_dir)
478 c29ac11d Ilias Tsitsimpis
        os.makedirs(pkgs_dir)
479 c29ac11d Ilias Tsitsimpis
        with fabric.quiet():
480 c29ac11d Ilias Tsitsimpis
            fabric.get("synnefo_build-area.tgz", pkgs_dir)
481 c29ac11d Ilias Tsitsimpis

482 c29ac11d Ilias Tsitsimpis
        pkgs_file = os.path.join(pkgs_dir, "synnefo_build-area.tgz")
483 c29ac11d Ilias Tsitsimpis
        self._check_hash_sum(pkgs_file, "synnefo_build-area.tgz")
484 c29ac11d Ilias Tsitsimpis

485 c29ac11d Ilias Tsitsimpis
        self.logger.debug("Untar packages file %s" % pkgs_file)
486 c29ac11d Ilias Tsitsimpis
        os.system("cd %s; tar xzf synnefo_build-area.tgz" % pkgs_dir)