juju_scaleway.MachineOp   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 11
Duplicated Lines 0 %
Metric Value
dl 0
loc 11
rs 10
wmc 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 6 1
A run() 0 2 1
1
# -*- coding: utf-8 -*-
2
#
3
# Copyright (c) 2014-2015 Online SAS and Contributors. All Rights Reserved.
4
#                         Edouard Bonlieu <[email protected]>
5
#                         Julien Castets <[email protected]>
6
#                         Manfred Touron <[email protected]>
7
#                         Kevin Deldycke <[email protected]>
8
#
9
# Licensed under the BSD 2-Clause License (the "License"); you may not use this
10
# file except in compliance with the License. You may obtain a copy of the
11
# License at http://opensource.org/licenses/BSD-2-Clause
12
13
import logging
14
import time
15
import subprocess
16
17
from juju_scaleway.exceptions import TimeoutError
18
from juju_scaleway import ssh
19
20
21
logger = logging.getLogger("juju.scaleway")
22
23
24
class MachineOp(object):
25
26
    def __init__(self, provider, env, params, **options):
27
        self.provider = provider
28
        self.env = env
29
        self.params = params
30
        self.created = time.time()
31
        self.options = options
32
33
    def run(self):
34
        raise NotImplementedError()
35
36
37
class MachineAdd(MachineOp):
38
39
    timeout = 360
40
    delay = 8
41
42
    def run(self):
43
        server = self.provider.launch_server(self.params)
44
        self.provider.wait_on(server)
45
        server = self.provider.get_server(server.id)
46
        self.verify_ssh(server)
47
        return server
48
49
    def verify_ssh(self, server):
50
        """Workaround for manual provisioning and ssh availability.
51
        Manual provider bails immediately upon failure to connect on
52
        ssh, we loop to allow the server time to start ssh.
53
        """
54
        max_time = self.timeout + time.time()
55
        running = False
56
        while max_time > time.time():
57
            try:
58
                if ssh.check_ssh(server.public_ip['address']):
59
                    running = True
60
                    break
61
            except subprocess.CalledProcessError as exc:
62
                if ("Connection refused" in exc.output or
63
                        "Connection timed out" in exc.output or
64
                        "Connection closed" in exc.output or
65
                        "Connection reset by peer" in exc.output):
66
                    logger.debug(
67
                        "Waiting for ssh on id:%s ip:%s name:%s remaining:%d",
68
                        server.id, server.public_ip['address'], server.name,
69
                        int(max_time-time.time()))
70
                    time.sleep(self.delay)
71
                else:
72
                    logger.error(
73
                        "Could not ssh to server name: %s id: %s ip: %s\n%s",
74
                        server.name, server.id, server.public_ip['address'],
75
                        exc.output)
76
                    raise
77
78
        if running is False:
79
            raise TimeoutError(
80
                "Could not provision id:%s name:%s ip:%s before timeout" % (
81
                    server.id, server.name, server.public_ip['address']))
82
83
84
class MachineRegister(MachineAdd):
85
86
    def run(self):
87
        server = super(MachineRegister, self).run()
88
        try:
89
            machine_id = self.env.add_machine(
90
                "ssh:root@%s" % server.public_ip['address'],
91
                key=self.options.get('key'))
92
        except:
93
            self.provider.terminate_server(server.id)
94
            raise
95
        return server, machine_id
96
97
98
class MachineDestroy(MachineOp):
99
100
    def run(self):
101
        if not self.options.get('iaas_only'):
102
            self.env.terminate_machines([self.params['machine_id']])
103
        if self.options.get('env_only'):
104
            return
105
        logger.debug("Destroying server %s", self.params['server_id'])
106
        self.provider.terminate_server(self.params['server_id'])
107