def set_mode(self, mode): ha_cli = client.HAClient() if mode not in ( 'local', 'global', 'none', ): sys.stderr.write( _('Invalid maintenance mode: {0}\n').format(mode) ) return False m_local = (mode == 'local') m_global = (mode == 'global') try: ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.LOCAL, value=m_local, ) ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.GLOBAL, value=m_global, ) except socket.error: sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n') ) return False return True
def __get_ha_status(self): def dict_from_string(string): return json.loads(string) host = None ha_cli = client.HAClient() try: vm_status = ha_cli.get_all_host_stats() except: vm_status = "Cannot connect to HA daemon, please check the logs" return vm_status else: for v in vm_status.values(): if dict_from_string(v['engine-status'])['health'] == "good": host = "Here" if v['host-id'] == \ ha_cli.get_local_host_id() else v['hostname'] host = v['hostname'] if not host: vm_status = "Engine is down or not deployed." else: vm_status = "Engine is running on {host}".format(host=host) return vm_status
def _get_all_host_stats(self): ha_cli = client.HAClient() try: all_host_stats = ha_cli.get_all_host_stats() except (socket.error, BrokerConnectionError) as e: self.log_error( _('{0}\nCannot connect to the HA daemon, ' 'please check the logs.\n').format(str(e))) # there is no reason to continue if we can't connect to the daemon raise RuntimeError(_('Unable to connect the HA Broker ')) return all_host_stats
def _isHostedEngineDeployed(): if not haClient: return False client = haClient.HAClient() try: is_deployed = client.is_deployed except AttributeError: logging.warning("The installed version of hosted engine doesn't " "support the checking of deployment status.") return False return is_deployed()
def set_mode(self, mode): ha_cli = client.HAClient() if mode not in ( 'local', 'global', 'none', ): sys.stderr.write( _('Invalid maintenance mode: {0}\n').format(mode) ) return False m_local = (mode == 'local') m_global = (mode == 'global') if m_local: # Check that the engine VM is not running here vm_id = config.Config().get(config.ENGINE, const.HEVMID) cli = ohautil.connect_vdsm_json_rpc() try: vm_list = cli.Host.getVMList() except ServerError as e: sys.stderr.write( _("Failed communicating with VDSM: {e}").format(e=e) ) return False if vm_id in [ item['vmId'] for item in vm_list ]: sys.stderr.write(_( "Unable to enter local maintenance mode: " "the engine VM is running on the current host, " "please migrate it before entering local " "maintenance mode.\n" )) return False try: ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.LOCAL, value=m_local, ) ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.GLOBAL, value=m_global, ) ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.LOCAL_MANUAL, value=m_local, ) except socket.error: sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n') ) return False return True
def _get_cluster_stats(self): ha_cli = client.HAClient() try: cluster_stats = ha_cli.get_all_stats( client.HAClient.StatModes.GLOBAL)[0] except KeyError: # Stats were retrieved but the global section is missing. # This is not an error. cluster_stats = {} except (socket.error, AttributeError, IndexError): self.log_error( _('Cannot connect to the HA daemon, please check the logs.\n')) cluster_stats = {} return cluster_stats
def print_status(self): ha_cli = client.HAClient() try: all_host_stats = ha_cli.get_all_host_stats() except (socket.error, BrokerConnectionError) as e: sys.stderr.write(_('{0}\n'.format(str(e)))) sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n')) # there is no reason to continue if we can't connect to the daemon return try: cluster_stats = ha_cli.get_all_stats( client.HAClient.StatModes.GLOBAL)[0] except KeyError: # Stats were retrieved but the global section is missing. # This is not an error. cluster_stats = {} except (socket.error, AttributeError, IndexError): sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n')) cluster_stats = {} if cluster_stats.get(client.HAClient.GlobalMdFlags.MAINTENANCE, False): print _('\n\n!! Cluster is in GLOBAL MAINTENANCE mode !!\n') for host_id, host_stats in all_host_stats.items(): print _('\n\n--== Host {host_id} status ==--\n').format( host_id=host_id) for key in host_stats.keys(): if (key == 'engine-status' and not host_stats.get('live-data', True)): print _('{key:35}: {value}').format( key=self.DESCRIPTIONS.get(key, key), value=_('unknown stale-data'), ) elif key != 'extra': print _('{key:35}: {value}').format( key=self.DESCRIPTIONS.get(key, key), value=host_stats[key], ) if 'extra' in host_stats.keys(): key = 'extra' print _('{key:35}:').format( key=self.DESCRIPTIONS.get(key, key)) for line in host_stats[key].splitlines(): print '\t{value}'.format(value=line) return all_host_stats
def _getHaInfo(): """ Return Hosted Engine HA information for this host. """ i = { 'configured': False, 'active': False, 'score': 0, 'globalMaintenance': False, 'localMaintenance': False, } if haClient: try: instance = haClient.HAClient() host_id = instance.get_local_host_id() # If a host id is available, consider HA configured if host_id: i['configured'] = True else: return i stats = instance.get_all_stats() if 0 in stats: i['globalMaintenance'] = stats[0].get( haClient.HAClient.GlobalMdFlags.MAINTENANCE, False) if host_id in stats: i['active'] = stats[host_id]['live-data'] i['score'] = stats[host_id]['score'] i['localMaintenance'] = stats[host_id]['maintenance'] except IOError as ex: if ex.errno == errno.ENOENT: logging.error( ("failed to retrieve Hosted Engine HA score '{0}'" "Is the Hosted Engine setup finished?") .format(str(ex)) ) else: logging.exception( "failed to retrieve Hosted Engine HA score" ) except Exception: logging.exception("failed to retrieve Hosted Engine HA info") return i
def set_mode(self, mode): ha_cli = client.HAClient() if mode not in ( 'local', 'global', 'none', ): sys.stderr.write(_('Invalid maintenance mode: {0}\n').format(mode)) return False m_local = (mode == 'local') m_global = (mode == 'global') if m_local: # Check that we have a host where to migrate VM to. _host_id = int(config.Config().get(config.ENGINE, const.HOST_ID)) candidates = ha_cli.get_all_host_stats() candidates = [ h for h in candidates if candidates[h]["score"] > 0 and candidates[h]["host-id"] != _host_id and candidates[h]["live-data"] ] if not candidates: sys.stderr.write( _("Unable to enter local maintenance mode: " "there are no available hosts capable " "of running the engine VM.\n")) return False try: ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.LOCAL, value=m_local, ) ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.GLOBAL, value=m_global, ) ha_cli.set_maintenance_mode( mode=ha_cli.MaintenanceMode.LOCAL_MANUAL, value=m_local, ) except socket.error: sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n')) return False return True
def _getHaInfo(): """ Return Hosted Engine HA information for this host. """ i = { 'configured': False, 'active': False, 'score': 0, 'globalMaintenance': False, 'localMaintenance': False, } if haClient: try: instance = haClient.HAClient() host_id = instance.get_local_host_id() # If a host id is available, consider HA configured if host_id: i['configured'] = True else: return i # TODO: move to a periodic worker and cache the result stats = instance.get_all_stats(timeout=5) if 0 in stats: i['globalMaintenance'] = stats[0].get( haClient.HAClient.GlobalMdFlags.MAINTENANCE, False) if host_id in stats: i['active'] = stats[host_id]['live-data'] i['score'] = stats[host_id]['score'] i['localMaintenance'] = stats[host_id]['maintenance'] except IOError as e: if e.errno == errno.ENOENT: logging.warning( "Failed to retrieve Hosted Engine HA info, is Hosted " "Engine setup finished?") else: logging.warning( "Failed to retrieve Hosted Engine HA info: %s", e) except Exception: logging.exception("Failed to retrieve Hosted Engine HA info") return i
def __vm_status(self): ha_cli = client.HAClient() level = None try: level = "global" if ha_cli.get_all_stats( client.HAClient.StatModes.GLOBAL)[0]["maintenance"] else None except KeyError: # Stats returned but no global section pass if level is None: try: level = "local" if ha_cli.get_all_stats()[1]["maintenance"] \ else "none" except: self.plugin.logger.debug("Couldn't get HA stats!", exc_info=True) return level
def set_shared_config(self, key, value, config_type): ha_cli = client.HAClient() try: ha_cli.set_shared_config(key, value, config_type) except socket.error: sys.stderr.write( _('Cannot connect to the HA daemon, please check the logs.\n')) return False except KeyError: config_keys_for_type = ha_cli.get_all_config_keys(config_type) sys.stderr.write( _('Invalid configuration key {key}.\n'.format(key=key))) sys.stderr.write(_('Available keys are:\n')) for c_type in config_keys_for_type: sys.stderr.write( _('{c_type} : {keys}\n'.format( c_type=c_type, keys=config_keys_for_type[c_type]))) return False except Exception as e: sys.stderr.write(str(e) + '\n') return False return True
# # ovirt-hosted-engine-setup -- ovirt hosted engine setup # Copyright (C) 2015 Red Hat, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # """Connect storage server""" from ovirt_hosted_engine_ha.client import client from ovirt_hosted_engine_setup import constants as ohostedcons if __name__ == "__main__": ha_cli = client.HAClient() ha_cli.connect_storage_server( timeout=ohostedcons.Const.STORAGE_SERVER_TIMEOUT, )
def _validation(self): """ Check that host id is not already in use """ if self.storageType in ( ohostedcons.VDSMConstants.ISCSI_DOMAIN, ohostedcons.VDSMConstants.FC_DOMAIN, ): # For iSCSI we need to connect the pool for # having /rhev populated. self._storagePoolConnection() # And we need also to connect metadata LVMs # Prepare the Backend interface # Get UUIDs of the storage lockspace = self.environment[ ohostedcons.SanlockEnv.LOCKSPACE_NAME ] activate_devices = { lockspace + '.lockspace': ( storage_backends.VdsmBackend.Device( image_uuid=self.environment[ ohostedcons.StorageEnv. LOCKSPACE_IMAGE_UUID ], volume_uuid=self.environment[ ohostedcons.StorageEnv. LOCKSPACE_VOLUME_UUID ], ) ), lockspace + '.metadata': ( storage_backends.VdsmBackend.Device( image_uuid=self.environment[ ohostedcons.StorageEnv. METADATA_IMAGE_UUID ], volume_uuid=self.environment[ ohostedcons.StorageEnv. METADATA_VOLUME_UUID ], ) ), } backend = storage_backends.VdsmBackend( sd_uuid=self.environment[ ohostedcons.StorageEnv.SD_UUID ], sp_uuid=self.environment[ ohostedcons.StorageEnv.SP_UUID ], dom_type=self.environment[ ohostedcons.StorageEnv.DOMAIN_TYPE ], **activate_devices ) with ohostedutil.VirtUserContext( self.environment, # umask 007 umask=stat.S_IRWXO ): backend.connect() all_host_stats = {} with ohostedutil.VirtUserContext( environment=self.environment, umask=stat.S_IWGRP | stat.S_IWOTH, ): ha_cli = client.HAClient() all_host_stats = ha_cli.get_all_host_stats_direct( dom_type=self.environment[ ohostedcons.StorageEnv.DOMAIN_TYPE ], sd_uuid=self.environment[ ohostedcons.StorageEnv.SD_UUID ], service_type=self.environment[ ohostedcons.SanlockEnv.LOCKSPACE_NAME ] + ".metadata", ) if ( int( self.environment[ohostedcons.StorageEnv.HOST_ID] ) in all_host_stats.keys() and not self._re_deploying_host() ): raise RuntimeError( _('Invalid value for Host ID: already used') )
def _validation(self): """ Check that host id is not already in use """ if self.storageType in ( ohostedcons.VDSMConstants.ISCSI_DOMAIN, ohostedcons.VDSMConstants.FC_DOMAIN, ): # For iSCSI/FC we need to explicitly call getStorageDomainStats # to create/refresh the storage domain directory tree. result = self.cli.getStorageDomainStats( self.environment[ohostedcons.StorageEnv.SD_UUID], ) self.logger.debug('getStorageDomainStats: {result}'.format( result=result, )) if result['status']['code'] != 0: raise RuntimeError( 'Unable to get storage domain stats: {message}'.format( message=result['status']['message'], )) # We need to connect metadata LVMs # Prepare the Backend interface # Get UUIDs of the storage lockspace = self.environment[ohostedcons.SanlockEnv.LOCKSPACE_NAME] activate_devices = { lockspace + '.lockspace': (storage_backends.VdsmBackend.Device( image_uuid=self.environment[ ohostedcons.StorageEnv.LOCKSPACE_IMAGE_UUID], volume_uuid=self.environment[ ohostedcons.StorageEnv.LOCKSPACE_VOLUME_UUID], )), lockspace + '.metadata': (storage_backends.VdsmBackend.Device( image_uuid=self.environment[ ohostedcons.StorageEnv.METADATA_IMAGE_UUID], volume_uuid=self.environment[ ohostedcons.StorageEnv.METADATA_VOLUME_UUID], )), } backend = storage_backends.VdsmBackend( sd_uuid=self.environment[ohostedcons.StorageEnv.SD_UUID], sp_uuid=self.environment[ohostedcons.StorageEnv.SP_UUID], dom_type=self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE], **activate_devices) with ohostedutil.VirtUserContext( self.environment, # umask 007 umask=stat.S_IRWXO): backend.connect() # prepareImage to populate /var/run/vdsm/storage for imgVolUUID in [ [ self.environment[ohostedcons.StorageEnv.IMG_UUID], self.environment[ohostedcons.StorageEnv.VOL_UUID] ], [ self.environment[ohostedcons.StorageEnv.METADATA_IMAGE_UUID], self.environment[ohostedcons.StorageEnv.METADATA_VOLUME_UUID] ], [ self.environment[ohostedcons.StorageEnv.LOCKSPACE_IMAGE_UUID], self.environment[ohostedcons.StorageEnv.LOCKSPACE_VOLUME_UUID] ], [ self.environment[ohostedcons.StorageEnv.CONF_IMG_UUID], self.environment[ohostedcons.StorageEnv.CONF_VOL_UUID] ], ]: self.cli.prepareImage( self.environment[ohostedcons.StorageEnv.SP_UUID], self.environment[ohostedcons.StorageEnv.SD_UUID], imgVolUUID[0], imgVolUUID[1], ) all_host_stats = {} with ohostedutil.VirtUserContext( environment=self.environment, umask=stat.S_IWGRP | stat.S_IWOTH, ): ha_cli = client.HAClient() all_host_stats = ha_cli.get_all_host_stats_direct( dom_type=self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE], sd_uuid=self.environment[ohostedcons.StorageEnv.SD_UUID], service_type=self.environment[ ohostedcons.SanlockEnv.LOCKSPACE_NAME] + ".metadata", ) if (self.environment[ohostedcons.StorageEnv.HOST_ID] in all_host_stats.keys() and not self._re_deploying_host()): raise RuntimeError(_('Invalid value for Host ID: already used'))