Rename pharos-dashboard and pharos-validator
[pharos-tools.git] / validator / src / validation_tool / src / server.py
1 ##############################################################################
2 # Copyright (c) 2015 Todd Gaunt and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import logging
11 import os
12 import subprocess
13 import time
14
15 # Constant definitions
16 from pharosvalidator.const import *
17
18 def ssh_thread(remoteaddr, returnaddr, port, passes):
19     """
20     ssh_thread: the main loop of a thread the server spawns to connect to a node
21     over ssh.
22
23     input: remoteaddr, returnaddr, and port to forward to run_remote_test;
24     passes to specify how many attempts should be made
25     """
26     for i in range(passes):
27         status = run_remote_test(remoteaddr, returnaddr, port)
28         time.sleep(1)
29
30 def run_remote_test(remoteaddr, returnaddr, port):
31     """
32     run_remote_tests: ssh to a give remote address, and run a test program
33     on the remote machine specifying the address and port of where the results
34     should be sent (usually back to the machine this program was run on)
35
36     input: ip address of the ssh target; Adress of the test results target;
37     Port of the test results target
38
39     output: 0 if the test ran over ssh perfectly, non-zero if the test faild
40     """
41     #TODO add way to keep attempting to ssh until service is up and running aka ping part 2
42     logger = logging.getLogger(__name__)
43
44     cmd = ["ssh", "root@"+remoteaddr, HARDWARE_TEST, \
45             "-p", port, "-H", returnaddr, "hardware"]
46
47     logger.debug("Running: {}".format(" ".join(cmd)))
48     try:
49         with open(os.devnull, 'w') as fn:
50             status = subprocess.check_call(" ".join(cmd), stdout=fn, stderr=fn, shell=True)
51     except subprocess.CalledProcessError as e:
52         status = e.returncode
53         logger.error("ssh attempt to '{}' failed".format(remoteaddr))
54
55     return status
56
57 def ping_network(ip_range_list, ipcnt, passes):
58     """
59     ping_network: Ping a range of ips until the amount of successful pings
60     reaches a number n
61
62     input: List of ip addresses to be pinged; Counter for threshold
63     of successful pings; Number of iterations to pass
64
65     output: List of ip addresses that were found to be up
66     """
67     logger = logging.getLogger("pharosvalidator")
68     assert isinstance(ip_range_list, list)
69     ips_found = 0
70     alive_ips = []
71     for t in range(passes):
72         for addr in list(ip_range_list):
73             cmd = [ \
74                     "ping", \
75                     "-c", "1", \
76                     "-w", "1", \
77                     addr]
78             logger.debug("Running: \"{}\"".format(' '.join(cmd)))
79             try:
80                 with open(os.devnull, 'w') as fn:
81                     status = subprocess.check_call(" ".join(cmd), \
82                             stdout=fn, stderr=fn, shell=True)
83             except subprocess.CalledProcessError as e:
84                 status = e.returncode
85                 logger.error("Ping at '{}' failed".format(addr))
86             # If the ip address was pinged successfully, then remove it from future attempts
87             if status == 0:
88                 ips_found += 1
89                 logger.info("{} is up, {} total nodes up".format(addr, ips_found))
90
91                 # Remove the ip that was successfully pinged from being tested again
92                 ip_range_list.remove(addr)
93
94                 # Add the successfully pinged node to a list of successful pings
95                 alive_ips.append(addr)
96
97             if ips_found >= ipcnt:
98                 break
99
100         if ips_found >= ipcnt:
101             break
102
103     return alive_ips
104
105 def bring_up_admin_ip(ipaddr):
106     """
107     Assign the machine this test is running on an address according to the
108     configuration file
109     """
110     cmd = [""]
111     subprocess.Popen(cmd)