github.com/SUSE/skuba@v1.4.17/ci/infra/testrunner/platforms/platform.py (about) 1 import logging 2 import os 3 4 import requests 5 from timeout_decorator import timeout 6 7 from utils import (step, Utils) 8 9 logger = logging.getLogger('testrunner') 10 11 12 class Platform: 13 def __init__(self, conf): 14 self.conf = conf 15 self.utils = Utils(conf) 16 self.utils.setup_ssh() 17 18 # Which logs will be collected from the nodes 19 self.logs = { 20 "files": [], 21 "dirs": ["/var/log/pods", "/etc/crio", "/etc/containers"], 22 "services": ["kubelet", "crio"] 23 } 24 25 # Files that will be deleted during the cleanup stage 26 self.tmp_files = [] 27 28 @step 29 def cleanup(self): 30 """Clean up""" 31 try: 32 self._cleanup_platform() 33 except Exception as ex: 34 logger.warning("Received the following error '{}'\nAttempting to finish cleanup".format(ex)) 35 raise Exception("Failure(s) during cleanup") 36 finally: 37 self.utils.cleanup_files(self.tmp_files) 38 self.utils.ssh_cleanup() 39 40 @timeout(600) 41 @step 42 def gather_logs(self): 43 logging_errors = False 44 45 node_ips = { 46 "master": self.get_nodes_ipaddrs("master"), 47 "worker": self.get_nodes_ipaddrs("worker") 48 } 49 50 if not os.path.isdir(self.conf.platform.log_dir): 51 os.mkdir(self.conf.platform.log_dir) 52 logger.info(f"Created log dir {self.conf.platform.log_dir}") 53 54 for node_type in node_ips: 55 for ip_address in node_ips[node_type]: 56 node_log_dir = self._create_node_log_dir(ip_address, node_type, self.conf.platform.log_dir) 57 logging_error = self.utils.collect_remote_logs(ip_address, self.logs, node_log_dir) 58 59 if logging_error: 60 logging_errors = logging_error 61 62 platform_log_error = self._get_platform_logs() 63 64 if platform_log_error: 65 logging_errors = platform_log_error 66 67 return logging_errors 68 69 def get_lb_ipaddr(self): 70 """ 71 Get the IP of the Load Balancer 72 :return: 73 """ 74 pass 75 76 def get_nodes_names(self, role): 77 """ 78 Get the names of the given type of node 79 :param role: the type of node 80 :return: 81 """ 82 return [f'caasp-{role}+{n}' for n in range(self.get_num_nodes(role))] 83 84 def get_nodes_ipaddrs(self, role): 85 """ 86 Get the IP addresses of the given type of node 87 :param role: the type of node 88 :return: 89 """ 90 return [] 91 92 def get_num_nodes(self, role): 93 """ 94 Get the number of nodes of a given type 95 :param role: the type of node 96 :return: num of nodes 97 """ 98 pass 99 100 @step 101 def provision(self, num_master=-1, num_worker=-1): 102 """Provision a cluster""" 103 if num_master > -1 or num_worker > -1: 104 logger.warning("Overriding number of nodes") 105 if num_master > -1: 106 logger.warning(" Masters:{} ".format(num_master)) 107 108 if num_worker > -1: 109 logger.warning(" Workers:{} ".format(num_worker)) 110 111 self._provision_platform(num_master, num_worker) 112 113 def ssh_run(self, role, nr, cmd): 114 ip_addrs = self.get_nodes_ipaddrs(role) 115 if nr >= len(ip_addrs): 116 raise ValueError(f'Node {role}-{nr} not deployed in platform') 117 118 return self.utils.ssh_run(ip_addrs[nr], cmd) 119 120 @staticmethod 121 def _create_node_log_dir(ip_address, node_type, log_dir_path): 122 node_log_dir_path = os.path.join(log_dir_path, f"{node_type}_{ip_address.replace('.', '_')}") 123 124 if not os.path.isdir(node_log_dir_path): 125 os.mkdir(node_log_dir_path) 126 logger.info(f"Created log dir {node_log_dir_path}") 127 128 return node_log_dir_path 129 130 def _cleanup_platform(self): 131 """Platform specific cleanup. Expected to be overridden by platforms""" 132 133 def _env_setup_cmd(self): 134 """Returns the command for setting up the platform environment""" 135 return "" 136 137 def _provision_platform(self): 138 """Platform specific provisioning""" 139 140 def _get_platform_logs(self): 141 """Platform specific logs to collect. Expected to be overridden by platforms""" 142 return False 143 144 def all_apiservers_responsive(self): 145 """Check if all apiservers are responsive to make sure the load balancer can function correctly""" 146 ip_addrs = self.get_nodes_ipaddrs("master") 147 for ip in ip_addrs: 148 try: 149 response = requests.get("https://{}:6443/healthz".format(ip), verify=False) 150 except requests.exceptions.RequestException: 151 return False 152 if response.status_code != 200: 153 return False 154 return True 155 156 def setup_cloud_provider(self): 157 raise ValueError("Cloud provider is not supported for this platform")