summaryrefslogtreecommitdiffstats
path: root/doctor_tests/installer/apex.py
blob: aaacb3851b9935e1e99877e41c6c9681ab4d224a (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
##############################################################################
# Copyright (c) 2017 ZTE Corporation and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import getpass
import grp
import os
import pwd
import stat
import subprocess

from doctor_tests.common.utils import get_doctor_test_root_dir
from doctor_tests.common.utils import SSHClient
from doctor_tests.installer.base import BaseInstaller


class ApexInstaller(BaseInstaller):
    node_user_name = 'heat-admin'
    cm_set_script = 'set_ceilometer.py'
    cm_restore_script = 'restore_ceilometer.py'

    def __init__(self, conf, log):
        super(ApexInstaller, self).__init__(conf, log)
        self.client = SSHClient(self.conf.installer.ip,
                                self.conf.installer.username,
                                look_for_keys=True)
        self.key_file = None
        self.controllers = list()
        self.controller_clients = list()
        self.servers = list()
        self.test_dir = get_doctor_test_root_dir()

    def setup(self):
        self.log.info('Setup Apex installer start......')

        self.get_ssh_key_from_installer()
        self.get_controller_ips()
        self.set_apply_patches()
        self.setup_stunnel()

    def cleanup(self):
        self.restore_apply_patches()
        for server in self.servers:
            server.terminate()

    def get_ssh_key_from_installer(self):
        self.log.info('Get SSH keys from Apex installer......')

        if self.key_file is not None:
            self.log.info('Already have SSH keys from Apex installer......')
            return self.key_file

        ssh_key = '{0}/{1}'.format(self.test_dir, 'instack_key')
        self.client.scp('/home/stack/.ssh/id_rsa', ssh_key, method='get')
        user = getpass.getuser()
        uid = pwd.getpwnam(user).pw_uid
        gid = grp.getgrnam(user).gr_gid
        os.chown(ssh_key, uid, gid)
        os.chmod(ssh_key, stat.S_IREAD)
        self.key_file = ssh_key
        return self.key_file

    def get_controller_ips(self):
        self.log.info('Get controller ips from Apex installer......')

        command = "source stackrc; " \
                  "nova list | grep ' overcloud-controller-[0-9] ' " \
                  "| sed -e 's/^.*ctlplane=//' |awk '{print $1}'"
        ret, controllers = self.client.ssh(command)
        if ret:
            raise Exception('Exec command to get controller ips'
                            'in Apex installer failed, ret=%s, output=%s'
                            % (ret, controllers))
        self.log.info('Get controller_ips:%s from Apex installer'
                      % controllers)
        self.controllers = controllers

    def get_host_ip_from_hostname(self, hostname):
        self.log.info('Get host ip from host name in Apex installer......')

        hostname_in_undercloud = hostname.split('.')[0]

        command = "source stackrc; nova show %s | awk '/ ctlplane network /{print $5}'" % (hostname_in_undercloud)   # noqa
        ret, host_ip = self.client.ssh(command)
        if ret:
            raise Exception('Exec command to get host ip from hostname(%s)'
                            'in Apex installer failed, ret=%s, output=%s'
                            % (hostname, ret, host_ip))
        self.log.info('Get host_ip:%s from host_name:%s in Apex installer'
                      % (host_ip, hostname))
        return host_ip[0]

    def setup_stunnel(self):
        self.log.info('Setup ssh stunnel in controller nodes'
                      ' in Apex installer......')
        for node_ip in self.controllers:
            cmd = ("ssh -o UserKnownHostsFile=/dev/null"
                   "-o StrictHostKeyChecking=no"
                   "-i %s %s@%s -R %s:localhost:%s"
                   "sleep 600 > ssh_tunnel.%s.log"
                   "2>&1 < /dev/null &"
                   % (self.key_file,
                      self.node_user_name,
                      node_ip,
                      self.conf.consumer.port,
                      self.conf.consumer.port,
                      node_ip))
            server = subprocess.Popen(cmd, shell=True)
            self.servers.append(server)
            server.communicate()

    def set_apply_patches(self):
        self.log.info('Set apply patches start......')

        for node_ip in self.controllers:
            client = SSHClient(node_ip, self.node_user_name,
                               key_filename=self.key_file)
            self.controller_clients.append(client)
            self._ceilometer_apply_patches(client, self.cm_set_script)

    def restore_apply_patches(self):
        self.log.info('restore apply patches start......')

        for client in self.controller_clients:
            self._ceilometer_apply_patches(client, self.cm_restore_script)

    def _ceilometer_apply_patches(self, ssh_client, script_name):
        installer_dir = os.path.dirname(os.path.realpath(__file__))
        script_abs_path = '{0}/{1}/{2}'.format(installer_dir,
                                               'common', script_name)

        ssh_client.scp(script_abs_path, script_name)
        cmd = 'sudo python %s' % script_name
        ret, output = ssh_client.ssh(cmd)
        if ret:
            raise Exception('Do the ceilometer command in controller'
                            ' node failed, ret=%s, cmd=%s, output=%s'
                            % (ret, cmd, output))
        ssh_client.ssh('sudo systemctl restart '
                       'openstack-ceilometer-notification.service')