summaryrefslogtreecommitdiffstats
path: root/openshift-storage-libs/openshiftstoragelibs/node_ops.py
blob: 8ca5674b500796a5f5a5ed184a49003b8058c1ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import time

from glustolibs.gluster.exceptions import ExecutionError
from glusto.core import Glusto as g

from openshiftstoragelibs.cloundproviders.vmware import VmWare
from openshiftstoragelibs import exceptions
from openshiftstoragelibs import waiter


CLOUD_PROVIDER = None


def node_reboot_by_command(node, timeout=600, wait_step=10):
    """Reboot node and wait to start for given timeout.

    Args:
        node (str)     : Node which needs to be rebooted.
        timeout (int)  : Seconds to wait before node to be started.
        wait_step (int): Interval in seconds to wait before checking
                         status of node again.
    """
    cmd = "sleep 3; /sbin/shutdown -r now 'Reboot triggered by Glusto'"
    ret, out, err = g.run(node, cmd)
    if ret != 255:
        err_msg = "failed to reboot host '%s' error %s" % (node, err)
        g.log.error(err_msg)
        raise AssertionError(err_msg)

    try:
        g.ssh_close_connection(node)
    except Exception as e:
        g.log.error("failed to close connection with host %s "
                    "with error: %s" % (node, e))
        raise

    # added sleep as node will restart after 3 sec
    time.sleep(3)

    for w in waiter.Waiter(timeout=timeout, interval=wait_step):
        try:
            if g.rpyc_get_connection(node, user="root"):
                g.rpyc_close_connection(node, user="root")
                return
        except Exception as err:
            g.log.info("exception while getting connection: '%s'" % err)

    if w.expired:
        error_msg = ("exceeded timeout %s sec, node '%s' is "
                     "not reachable" % (timeout, node))
        g.log.error(error_msg)
        raise exceptions.ExecutionError(error_msg)


def wait_for_ssh_connection(hostname, timeout=600, interval=10):
    """Wait for ssh conection to be ready within given timeout.

    Args:
        hostname (str): hostname of a machine.
    Returns:
        None
    Raises:
        CloudProviderError: In case of any failures.
    """
    for w in waiter.Waiter(timeout, interval):
        try:
            # Run random command to verify ssh connection
            g.run(hostname, 'ls')
            return
        except (exceptions.ExecutionError, ExecutionError):
            g.log.info("Waiting for ssh connection on host '%s'" % hostname)

    msg = 'Not able to connect with the %s' % hostname
    g.log.error(msg)
    raise exceptions.CloudProviderError(msg)


def _get_cloud_provider():
    """Gather cloud provider facts"""

    global CLOUD_PROVIDER
    if CLOUD_PROVIDER:
        return CLOUD_PROVIDER

    try:
        cloud_provider_name = g.config['cloud_provider']['name']
    except KeyError:
        msg = "Incorrect config file. Cloud provider name is missing."
        g.log.error(msg)
        raise exceptions.ConfigError(msg)

    if cloud_provider_name == 'vmware':
        CLOUD_PROVIDER = VmWare()
    else:
        msg = "Cloud Provider %s is not supported." % cloud_provider_name
        g.log.error(msg)
        raise NotImplementedError(msg)

    return CLOUD_PROVIDER


def find_vm_name_by_ip_or_hostname(ip_or_hostname):
    """Find VM name from the ip or hostname.

    Args:
        ip_or_hostname (str): IP address or hostname of VM.
    Returns:
        str: Name of the VM.
    """
    cloudProvider = _get_cloud_provider()
    g.log.info('getting the name of vm for ip or hostname %s' % ip_or_hostname)
    return cloudProvider.find_vm_name_by_ip_or_hostname(ip_or_hostname)


def get_power_state_of_vm_by_name(name):
    """Get the power state of VM.

    Args:
        name (str): name of the VM for which state has to be find.
    Returns:
        str: Power state of the VM.
    """
    cloudProvider = _get_cloud_provider()
    g.log.info('getting the power state of vm "%s"' % name)
    return cloudProvider.get_power_state_of_vm_by_name(name)


def power_off_vm_by_name(name):
    """Power off the virtual machine.

    Args:
        name (str): name of the VM which needs to be powered off.
    Returns:
        None
    """
    cloudProvider = _get_cloud_provider()
    g.log.info('powering off the vm "%s"' % name)
    cloudProvider.power_off_vm_by_name(name)
    g.log.info('powered off the vm "%s" successfully' % name)


def power_on_vm_by_name(name, timeout=600, interval=10):
    """Power on the virtual machine and wait for SSH ready within given
    timeout.

    Args:
        name (str): name of the VM which needs to be powered on.
    Returns:
        None
    Raises:
        CloudProviderError: In case of any failures.
    """
    cloudProvider = _get_cloud_provider()
    g.log.info('powering on the VM "%s"' % name)
    cloudProvider.power_on_vm_by_name(name)
    g.log.info('Powered on the VM "%s" successfully' % name)

    # Wait for hostname to get assigned
    _waiter = waiter.Waiter(timeout, interval)
    for w in _waiter:
        try:
            hostname = cloudProvider.wait_for_hostname(name, 1, 1)
            # NOTE(vponomar): Reset attempts for waiter to avoid redundant
            # sleep equal to 'interval' on the next usage.
            _waiter._attempt = 0
            break
        except Exception as e:
            g.log.info(e)
    if w.expired:
        raise exceptions.CloudProviderError(e)

    # Wait for hostname to ssh connection ready
    for w in _waiter:
        try:
            wait_for_ssh_connection(hostname, 1, 1)
            break
        except Exception as e:
            g.log.info(e)
    if w.expired:
        raise exceptions.CloudProviderError(e)