1313#
1414# Open vStorage is distributed in the hope that it will be useful,
1515# but WITHOUT ANY WARRANTY of any kind.
16-
16+ import time
1717from ovs .log .log_handler import LogHandler
18- from ovs .extensions .generic . system import System
18+ from ovs .extensions .services . service import ServiceManager
1919from ovs .extensions .generic .sshclient import SSHClient
20- from ovs .extensions .packages .package import PackageManager
21- from ..helpers .init_manager import InitManager , InitManagerSupported
20+ from ovs .extensions .generic .system import System
2221
2322
2423class SystemHelper (object ):
@@ -31,40 +30,20 @@ def __init__(self):
3130 pass
3231
3332 @staticmethod
34- def get_non_running_ovs_services (storagerouter_ip ):
33+ def get_non_running_ovs_services (client ):
3534 """
3635 get all non-running ovs services
37- :param storagerouter_ip: ip address of a existing storagerouter
38- :type storagerouter_ip: str
36+ :param client: sshclient instance
3937 :return: list of non running ovs services
4038 :rtype: list
4139 """
42- client = SSHClient (storagerouter_ip , username = 'root' )
43- if InitManager .INIT_MANAGER == InitManagerSupported .INIT :
44- ovs_services = [service for service in client .dir_list (InitManager .UPSTART_BASEDIR ) if 'ovs-' in service ]
45- return [ovs_service .split ('.' )[0 ] for ovs_service in ovs_services
46- if not InitManager .service_running (ovs_service .split ('.' )[0 ], storagerouter_ip )]
47- elif InitManager .INIT_MANAGER == InitManagerSupported .SYSTEMD :
48- ovs_services = [service for service in client .dir_list (InitManager .SYSTEMD_BASEDIR ) if 'ovs-' in service ]
49- return [ovs_service .split ('.' )[0 ] for ovs_service in ovs_services
50- if not InitManager .service_running (ovs_service .split ('.' )[0 ], storagerouter_ip )]
51-
52- @staticmethod
53- def get_missing_packages (ip , required_packages ):
54- """
55- Get all missing packages based on required packages
56-
57- :param ip: ip address of a server
58- :type ip: str
59- :param required_packages: a list of required packages (e.g. ['openvstorage', 'qemu', 'fio'])
60- :type required_packages: list
61- :return: list of missing packages
62- :rtype: list
63- """
64- client = SSHClient (ip , username = 'root' )
65- return [package for package in required_packages
66- if client .run ("dpkg -s {0} | grep Status | cut -d ' ' -f 3" .format (package ),
67- allow_insecure = True ) != "ok" ]
40+ non_running_ovs_services = []
41+ for service in ServiceManager .list_services (client ):
42+ if not service .startswith ('ovs-' ):
43+ continue
44+ if ServiceManager .get_service_status (service , client ) != 'active' :
45+ non_running_ovs_services .append (service )
46+ return non_running_ovs_services
6847
6948 @staticmethod
7049 def get_local_storagerouter ():
@@ -75,31 +54,76 @@ def get_local_storagerouter():
7554 """
7655 return System .get_my_storagerouter ()
7756
78- @staticmethod
79- def get_ovs_version (client ):
57+ @classmethod
58+ def get_ovs_version (cls , storagerouter = None ):
8059 """
8160 Gets the installed ovs version
82- :param client: Sshclient instance
83- :type client: ovs.extensions.generic.sshclient.SSHClient
61+ :param storagerouter: Storagerouter to fetch info from
8462 :return: ovs version identifier. Either ee or ose
8563 :rtype: str
8664 """
87- # @todo replace with storagerouter.features instead
88- # Version mapping with identifier
89- mapping = {'ee' : 'volumedriver-ee-base' ,
90- 'ose' : 'volumedriver-no-dedup-base' }
91- installed_versions = PackageManager .get_installed_versions (client = client )
92- for ovs_version , detection_key in mapping .iteritems ():
93- if detection_key in installed_versions :
94- return ovs_version
65+ if storagerouter is None :
66+ storagerouter = cls .get_local_storagerouter ()
67+ if storagerouter .features ['alba' ]['edition' ] == 'community' :
68+ return 'ose'
69+ else :
70+ return 'ee'
9571
9672 @staticmethod
97- def upper_case_first_letter ( x ):
73+ def idle_till_ovs_is_up ( ip , username , password = None , connection_timeout = 300 , service_timeout = 60 , logger = LOGGER ):
9874 """
99- Upper case the first letter of a string
100- :param x: a normal string
101- :type x: str
102- :return: a normal string with the first letter uppercases
103- :rtype: str
75+ wait until a node is back up and all ovs related are running (or potentially stuck)
76+ :param ip: ip of the node
77+ :param username: username to login with
78+ :param password: password to login with
79+ :param connection_timeout: raise when not online after these seconds
80+ :param service_timeout: poll for x seconds when checking services
81+ :param logger: logging instance
82+ :raise RuntimeError: when the timeout has been reached
83+ :return: dict with services mapped by their state
10484 """
105- return x [0 ].upper () + x [1 :]
85+ # neutral_states = ['inactive', 'deactivating']
86+ failed_states = ['failed' , 'error' ]
87+ active_states = ['active' , 'reloading' ]
88+ activating_state = 'activating'
89+ start_time = time .time ()
90+ client = None
91+ while client is None :
92+ delta = time .time () - start_time
93+ if delta > connection_timeout :
94+ raise RuntimeError ('Idling has timed out after {0}s' .format (delta ))
95+ try :
96+ client = SSHClient (ip , username = username , password = password )
97+ except :
98+ logger .debug ('Could not establish a connection yet to {0} after {1}s' .format (ip , delta ))
99+ time .sleep (1 )
100+ ovs_services = [service for service in ServiceManager .list_services (client ) if service .startswith ('ovs-' )]
101+ active_services = []
102+ failed_service = []
103+ activating_services = []
104+ # Initially class these services
105+ for service in ovs_services :
106+ logger .debug ('Initially classifying {0}' .format (service ))
107+ service_state = ServiceManager .get_service_status (service , client )
108+ logger .debug ('Service {0} - State {1}' .format (service , service_state ))
109+ if service_state in failed_states :
110+ failed_service .append (service )
111+ elif service_state in active_states :
112+ active_services .append (service )
113+ elif service_state == activating_state :
114+ activating_services .append (service )
115+ else :
116+ logger .error ('Unable to process service state {0}' .format (service_state ))
117+ start_time = time .time ()
118+ while len (activating_services ) > 0 :
119+ if time .time () - start_time > service_timeout :
120+ break
121+ service = activating_services .pop ()
122+ service_state = ServiceManager .get_service_status (service , client )
123+ if service_state in failed_states :
124+ failed_service .append (service )
125+ elif service_state in active_states :
126+ active_services .append (service )
127+ elif service_state == activating_state :
128+ activating_services .append (service )
129+ return {'active' : active_services , 'failed' : failed_service , 'activating' : activating_services }
0 commit comments